@@ -122,7 +122,7 @@ const interfaceManifest = {
122
122
CALL : {
123
123
name : 'call' ,
124
124
async : true ,
125
- input : [ 'i64' , 'address' , 'i128' , 'readOffset' , 'length' , 'writeOffset' , 'length' ] ,
125
+ input : [ 'i64' , 'address' , 'i128' , 'readOffset' , 'length' ] ,
126
126
output : [ 'i32' ]
127
127
} ,
128
128
CALLCODE : {
@@ -223,13 +223,33 @@ function generateManifest (interfaceManifest, opts) {
223
223
// the wasm memory offset is a new item on the EVM stack
224
224
spOffset ++
225
225
call += `(i32.add (get_global $sp) (i32.const ${ spOffset * 32 } ))`
226
+ } else if ( input === 'i64' && opcode === 'CALL' ) {
227
+ // i64 param for CALL is the gas
228
+ // add 2300 gas subsidy
229
+ // for now this only works if the gas is a 64-bit value
230
+ // TODO: use 256-bit arithmetic
231
+ /*
232
+ call += `(call $check_overflow_i64
233
+ (i64.add (i64.const 2300)
234
+ (i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32}))))
235
+ (i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8})))
236
+ (i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})))
237
+ (i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3}))))`
238
+ */
239
+
240
+ // 2300 gas subsidy is done in Hera
241
+ call += `(call $check_overflow_i64
242
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 } )))
243
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 } )))
244
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 } )))
245
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } ))))`
226
246
} else if ( input === 'i32' ) {
227
247
call += `(call $check_overflow
228
248
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 } )))
229
249
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 } )))
230
250
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 } )))
231
251
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } ))))`
232
- } else if ( input === 'i64' ) {
252
+ } else if ( input === 'i64' && opcode !== 'CALL' ) {
233
253
call += `(call $check_overflow_i64
234
254
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 } )))
235
255
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 } )))
@@ -245,7 +265,44 @@ function generateManifest (interfaceManifest, opts) {
245
265
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 } )))
246
266
(i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } )))))`
247
267
call += `(get_local $offset${ numOfLocals } )`
248
- } else if ( input === 'length' ) {
268
+ } else if ( input === 'length' && opcode === 'CALL' ) {
269
+ // CALLs in EVM have 7 arguments
270
+ // but in ewasm CALLs only have 5 arguments
271
+ // so delete the bottom two stack elements, after processing the 5th argument
272
+
273
+ locals += `(local $length${ numOfLocals } i32)`
274
+ body += `(set_local $length${ numOfLocals }
275
+ (call $check_overflow
276
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 } )))
277
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 } )))
278
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 } )))
279
+ (i64.load (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } )))))
280
+
281
+ (call $memusegas (get_local $offset${ numOfLocals } ) (get_local $length${ numOfLocals } ))
282
+ (set_local $offset${ numOfLocals } (i32.add (get_global $memstart) (get_local $offset${ numOfLocals } )))`
283
+
284
+ call += `(get_local $length${ numOfLocals } )`
285
+ numOfLocals ++
286
+
287
+ // delete 6th stack element
288
+ spOffset --
289
+ call += `
290
+ ;; zero out mem
291
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 4 } )) (i64.const 0))
292
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } )) (i64.const 0))
293
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 } )) (i64.const 0))
294
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 1 } )) (i64.const 0))`
295
+
296
+ // delete 7th stack element
297
+ spOffset --
298
+ call += `
299
+ ;; zero out mem
300
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 4 } )) (i64.const 0))
301
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } )) (i64.const 0))
302
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 } )) (i64.const 0))
303
+ (i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 1 } )) (i64.const 0))`
304
+
305
+ } else if ( input === 'length' && opcode !== 'CALL' ) {
249
306
locals += `(local $length${ numOfLocals } i32)`
250
307
body += `(set_local $length${ numOfLocals }
251
308
(call $check_overflow
@@ -279,10 +336,6 @@ function generateManifest (interfaceManifest, opts) {
279
336
;; zero out mem
280
337
(i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } )) (i64.const 0))
281
338
(i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 } )) (i64.const 0))`
282
-
283
- if ( ! op . async ) {
284
- call += '(drop (call $bswap_m128 (i32.add (i32.const 32)(get_global $sp))))'
285
- }
286
339
} else if ( output === 'address' ) {
287
340
call =
288
341
`${ call } (i32.add (get_global $sp) (i32.const ${ spOffset * 32 } ))`
@@ -292,7 +345,6 @@ function generateManifest (interfaceManifest, opts) {
292
345
}
293
346
294
347
call += `)
295
- (drop (call $bswap_m160 (i32.add (get_global $sp) (i32.const ${ spOffset * 32 } ))))
296
348
;; zero out mem
297
349
(i64.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 3 } )) (i64.const 0))
298
350
(i32.store (i32.add (get_global $sp) (i32.const ${ spOffset * 32 + 8 * 2 + 4 } )) (i32.const 0))`
0 commit comments