| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2015 the V8 project authors. All rights reserved. | 
|  | 2 // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 load("test/mjsunit/wasm/wasm-constants.js"); | 
|  | 6 | 
|  | 7 function testCallFFI(func, check) { | 
|  | 8   var kBodySize = 6; | 
|  | 9   var kNameFunOffset = 24 + kBodySize + 1; | 
|  | 10   var kNameMainOffset = kNameFunOffset + 4; | 
|  | 11 | 
|  | 12   var ffi = new Object(); | 
|  | 13   ffi.fun = func; | 
|  | 14 | 
|  | 15   var data = bytes( | 
|  | 16     // signatures | 
|  | 17     kDeclSignatures, 1, | 
|  | 18     2, kAstI32, kAstF64, kAstF64, // (f64,f64) -> int | 
|  | 19     // -- foreign function | 
|  | 20     kDeclFunctions, 2, | 
|  | 21     kDeclFunctionName | kDeclFunctionImport, | 
|  | 22     0, 0, | 
|  | 23     kNameFunOffset, 0, 0, 0,    // name offset | 
|  | 24     // -- main function | 
|  | 25     kDeclFunctionName | kDeclFunctionExport, | 
|  | 26     0, 0, | 
|  | 27     kNameMainOffset, 0, 0, 0,   // name offset | 
|  | 28     kBodySize, 0, | 
|  | 29     // main body | 
|  | 30     kExprCallFunction, 0,       // -- | 
|  | 31     kExprGetLocal, 0,           // -- | 
|  | 32     kExprGetLocal, 1,           // -- | 
|  | 33     // names | 
|  | 34     kDeclEnd, | 
|  | 35     'f', 'u', 'n', 0,           //  -- | 
|  | 36     'm', 'a', 'i', 'n', 0       //  -- | 
|  | 37   ); | 
|  | 38 | 
|  | 39   var module = WASM.instantiateModule(data, ffi); | 
|  | 40 | 
|  | 41   assertEquals("function", typeof module.main); | 
|  | 42 | 
|  | 43   for (var i = 0; i < 100000; i += 10003) { | 
|  | 44     var a = 22.5 + i, b = 10.5 + i; | 
|  | 45     var r = module.main(a, b); | 
|  | 46     check(r, a, b); | 
|  | 47   } | 
|  | 48 } | 
|  | 49 | 
|  | 50 var global = (function() { return this; })(); | 
|  | 51 var params = [-99, -99, -99, -99]; | 
|  | 52 var was_called = false; | 
|  | 53 var length = -1; | 
|  | 54 | 
|  | 55 function FOREIGN_SUB(a, b) { | 
|  | 56   print("FOREIGN_SUB(" + a + ", " + b + ")"); | 
|  | 57   was_called = true; | 
|  | 58   params[0] = this; | 
|  | 59   params[1] = a; | 
|  | 60   params[2] = b; | 
|  | 61   return (a - b) | 0; | 
|  | 62 } | 
|  | 63 | 
|  | 64 function check_FOREIGN_SUB(r, a, b) { | 
|  | 65     assertEquals(a - b | 0, r); | 
|  | 66     assertTrue(was_called); | 
|  | 67 //    assertEquals(global, params[0]);  // sloppy mode | 
|  | 68     assertEquals(a, params[1]); | 
|  | 69     assertEquals(b, params[2]); | 
|  | 70     was_called = false; | 
|  | 71 } | 
|  | 72 | 
|  | 73 testCallFFI(FOREIGN_SUB, check_FOREIGN_SUB); | 
|  | 74 | 
|  | 75 | 
|  | 76 function FOREIGN_ABCD(a, b, c, d) { | 
|  | 77   print("FOREIGN_ABCD(" + a + ", " + b + ", " + c + ", " + d + ")"); | 
|  | 78   was_called = true; | 
|  | 79   params[0] = this; | 
|  | 80   params[1] = a; | 
|  | 81   params[2] = b; | 
|  | 82   params[3] = c; | 
|  | 83   params[4] = d; | 
|  | 84   return (a * b * 6) | 0; | 
|  | 85 } | 
|  | 86 | 
|  | 87 function check_FOREIGN_ABCD(r, a, b) { | 
|  | 88     assertEquals((a * b * 6) | 0, r); | 
|  | 89     assertTrue(was_called); | 
|  | 90 //    assertEquals(global, params[0]);  // sloppy mode. | 
|  | 91     assertEquals(a, params[1]); | 
|  | 92     assertEquals(b, params[2]); | 
|  | 93     assertEquals(undefined, params[3]); | 
|  | 94     assertEquals(undefined, params[4]); | 
|  | 95     was_called = false; | 
|  | 96 } | 
|  | 97 | 
|  | 98 testCallFFI(FOREIGN_ABCD, check_FOREIGN_ABCD); | 
|  | 99 | 
|  | 100 function FOREIGN_ARGUMENTS0() { | 
|  | 101   print("FOREIGN_ARGUMENTS0"); | 
|  | 102   was_called = true; | 
|  | 103   length = arguments.length; | 
|  | 104   for (var i = 0; i < arguments.length; i++) { | 
|  | 105     params[i] = arguments[i]; | 
|  | 106   } | 
|  | 107   return (arguments[0] * arguments[1] * 7) | 0; | 
|  | 108 } | 
|  | 109 | 
|  | 110 function FOREIGN_ARGUMENTS1(a) { | 
|  | 111   print("FOREIGN_ARGUMENTS1", a); | 
|  | 112   was_called = true; | 
|  | 113   length = arguments.length; | 
|  | 114   for (var i = 0; i < arguments.length; i++) { | 
|  | 115     params[i] = arguments[i]; | 
|  | 116   } | 
|  | 117   return (arguments[0] * arguments[1] * 7) | 0; | 
|  | 118 } | 
|  | 119 | 
|  | 120 function FOREIGN_ARGUMENTS2(a, b) { | 
|  | 121   print("FOREIGN_ARGUMENTS2", a, b); | 
|  | 122   was_called = true; | 
|  | 123   length = arguments.length; | 
|  | 124   for (var i = 0; i < arguments.length; i++) { | 
|  | 125     params[i] = arguments[i]; | 
|  | 126   } | 
|  | 127   return (a * b * 7) | 0; | 
|  | 128 } | 
|  | 129 | 
|  | 130 function FOREIGN_ARGUMENTS3(a, b, c) { | 
|  | 131   print("FOREIGN_ARGUMENTS3", a, b, c); | 
|  | 132   was_called = true; | 
|  | 133   length = arguments.length; | 
|  | 134   for (var i = 0; i < arguments.length; i++) { | 
|  | 135     params[i] = arguments[i]; | 
|  | 136   } | 
|  | 137   return (a * b * 7) | 0; | 
|  | 138 } | 
|  | 139 | 
|  | 140 function FOREIGN_ARGUMENTS4(a, b, c, d) { | 
|  | 141   print("FOREIGN_ARGUMENTS4", a, b, c, d); | 
|  | 142   was_called = true; | 
|  | 143   length = arguments.length; | 
|  | 144   for (var i = 0; i < arguments.length; i++) { | 
|  | 145     params[i] = arguments[i]; | 
|  | 146   } | 
|  | 147   return (a * b * 7) | 0; | 
|  | 148 } | 
|  | 149 | 
|  | 150 function check_FOREIGN_ARGUMENTS(r, a, b) { | 
|  | 151   assertEquals((a * b * 7) | 0, r); | 
|  | 152   assertTrue(was_called); | 
|  | 153   assertEquals(2, length); | 
|  | 154   assertEquals(a, params[0]); | 
|  | 155   assertEquals(b, params[1]); | 
|  | 156   was_called = false; | 
|  | 157 } | 
|  | 158 | 
|  | 159 // Check a bunch of uses of the arguments object. | 
|  | 160 testCallFFI(FOREIGN_ARGUMENTS0, check_FOREIGN_ARGUMENTS); | 
|  | 161 testCallFFI(FOREIGN_ARGUMENTS1, check_FOREIGN_ARGUMENTS); | 
|  | 162 testCallFFI(FOREIGN_ARGUMENTS2, check_FOREIGN_ARGUMENTS); | 
|  | 163 testCallFFI(FOREIGN_ARGUMENTS3, check_FOREIGN_ARGUMENTS); | 
|  | 164 testCallFFI(FOREIGN_ARGUMENTS4, check_FOREIGN_ARGUMENTS); | 
|  | 165 | 
|  | 166 function returnValue(val) { | 
|  | 167   return function(a, b) { | 
|  | 168     print("RETURN_VALUE ", val); | 
|  | 169     return val; | 
|  | 170   } | 
|  | 171 } | 
|  | 172 | 
|  | 173 | 
|  | 174 function checkReturn(expected) { | 
|  | 175   return function(r, a, b) { assertEquals(expected, r); } | 
|  | 176 } | 
|  | 177 | 
|  | 178 // Check that returning weird values doesn't crash | 
|  | 179 testCallFFI(returnValue(undefined), checkReturn(0)); | 
|  | 180 testCallFFI(returnValue(null), checkReturn(0)); | 
|  | 181 testCallFFI(returnValue("0"), checkReturn(0)); | 
|  | 182 testCallFFI(returnValue("-77"), checkReturn(-77)); | 
|  | 183 | 
|  | 184 var objWithValueOf = {valueOf: function() { return 198; }} | 
|  | 185 | 
|  | 186 testCallFFI(returnValue(objWithValueOf), checkReturn(198)); | 
|  | 187 | 
|  | 188 | 
|  | 189 function testCallBinopVoid(type, func, check) { | 
|  | 190   var kBodySize = 10; | 
|  | 191   var kNameFunOffset = 28 + kBodySize + 1; | 
|  | 192   var kNameMainOffset = kNameFunOffset + 4; | 
|  | 193 | 
|  | 194   var ffi = new Object(); | 
|  | 195 | 
|  | 196   var passed_length = -1; | 
|  | 197   var passed_a = -1; | 
|  | 198   var passed_b = -1; | 
|  | 199   var args_a = -1; | 
|  | 200   var args_b = -1; | 
|  | 201 | 
|  | 202   ffi.fun = function(a, b) { | 
|  | 203     passed_length = arguments.length; | 
|  | 204     passed_a = a; | 
|  | 205     passed_b = b; | 
|  | 206     args_a = arguments[0]; | 
|  | 207     args_b = arguments[1]; | 
|  | 208   } | 
|  | 209 | 
|  | 210   var data = bytes( | 
|  | 211     // -- signatures | 
|  | 212     kDeclSignatures, 2, | 
|  | 213     2, kAstStmt, type, type,    // (type,type)->void | 
|  | 214     2, kAstI32, type, type,     // (type,type)->int | 
|  | 215     // -- foreign function | 
|  | 216     kDeclFunctions, 2, | 
|  | 217     kDeclFunctionName | kDeclFunctionImport, | 
|  | 218     0, 0,                       // signature index | 
|  | 219     kNameFunOffset, 0, 0, 0,    // name offset | 
|  | 220     // -- main function | 
|  | 221     kDeclFunctionName | kDeclFunctionExport, | 
|  | 222     1, 0,                       // signature index | 
|  | 223     kNameMainOffset, 0, 0, 0,   // name offset | 
|  | 224     kBodySize, 0,               // body size | 
|  | 225     // main body | 
|  | 226     kExprBlock, 2,              // -- | 
|  | 227     kExprCallFunction, 0,       // -- | 
|  | 228     kExprGetLocal, 0,           // -- | 
|  | 229     kExprGetLocal, 1,           // -- | 
|  | 230     kExprI8Const, 99,           // -- | 
|  | 231     // names | 
|  | 232     kDeclEnd, | 
|  | 233     'f', 'u', 'n', 0,           // -- | 
|  | 234     'm', 'a', 'i', 'n', 0       // -- | 
|  | 235   ); | 
|  | 236 | 
|  | 237   var module = WASM.instantiateModule(data, ffi); | 
|  | 238 | 
|  | 239   assertEquals("function", typeof module.main); | 
|  | 240 | 
|  | 241   print("testCallBinopVoid", type); | 
|  | 242 | 
|  | 243   for (var i = 0; i < 100000; i += 10003.1) { | 
|  | 244     var a = 22.5 + i, b = 10.5 + i; | 
|  | 245     var r = module.main(a, b); | 
|  | 246     assertEquals(99, r); | 
|  | 247     assertEquals(2, passed_length); | 
|  | 248     var expected_a, expected_b; | 
|  | 249     switch (type) { | 
|  | 250       case kAstI32: { | 
|  | 251         expected_a = a | 0; | 
|  | 252         expected_b = b | 0; | 
|  | 253         break; | 
|  | 254       } | 
|  | 255       case kAstF32: { | 
|  | 256         expected_a = Math.fround(a); | 
|  | 257         expected_b = Math.fround(b); | 
|  | 258         break; | 
|  | 259       } | 
|  | 260       case kAstF64: { | 
|  | 261         expected_a = a; | 
|  | 262         expected_b = b; | 
|  | 263         break; | 
|  | 264       } | 
|  | 265     } | 
|  | 266 | 
|  | 267     assertEquals(expected_a, args_a); | 
|  | 268     assertEquals(expected_b, args_b); | 
|  | 269     assertEquals(expected_a, passed_a); | 
|  | 270     assertEquals(expected_b, passed_b); | 
|  | 271   } | 
|  | 272 } | 
|  | 273 | 
|  | 274 | 
|  | 275 testCallBinopVoid(kAstI32); | 
|  | 276 // TODO testCallBinopVoid(kAstI64); | 
|  | 277 testCallBinopVoid(kAstF32); | 
|  | 278 testCallBinopVoid(kAstF64); | 
|  | 279 | 
|  | 280 | 
|  | 281 | 
|  | 282 function testCallPrint() { | 
|  | 283   var kBodySize = 10; | 
|  | 284   var kNamePrintOffset = 10 + 7 + 7 + 9 + kBodySize + 1; | 
|  | 285   var kNameMainOffset = kNamePrintOffset + 6; | 
|  | 286 | 
|  | 287   var ffi = new Object(); | 
|  | 288   ffi.print = print; | 
|  | 289 | 
|  | 290   var data = bytes( | 
|  | 291     // -- signatures | 
|  | 292     kDeclSignatures, 2, | 
|  | 293     1, kAstStmt, kAstI32,       // i32->void | 
|  | 294     1, kAstStmt, kAstF64,       // f64->int | 
|  | 295     kDeclFunctions, 3, | 
|  | 296     // -- import print i32 | 
|  | 297     kDeclFunctionName | kDeclFunctionImport, | 
|  | 298     0, 0,                       // signature index | 
|  | 299     kNamePrintOffset, 0, 0, 0,  // name offset | 
|  | 300     // -- import print f64 | 
|  | 301     kDeclFunctionName | kDeclFunctionImport, | 
|  | 302     1, 0,                       // signature index | 
|  | 303     kNamePrintOffset, 0, 0, 0,  // name offset | 
|  | 304     // -- decl main | 
|  | 305     kDeclFunctionName | kDeclFunctionExport, | 
|  | 306     1, 0,                       // signature index | 
|  | 307     kNameMainOffset, 0, 0, 0,   // name offset | 
|  | 308     kBodySize, 0,               // body size | 
|  | 309     // main body | 
|  | 310     kExprBlock, 2,              // -- | 
|  | 311     kExprCallFunction, 0,       // -- | 
|  | 312     kExprI8Const, 97,           // -- | 
|  | 313     kExprCallFunction, 1,       // -- | 
|  | 314     kExprGetLocal, 0,           // -- | 
|  | 315     // names | 
|  | 316     kDeclEnd, | 
|  | 317     'p', 'r', 'i', 'n', 't', 0, // -- | 
|  | 318     'm', 'a', 'i', 'n', 0       // -- | 
|  | 319   ); | 
|  | 320 | 
|  | 321   var module = WASM.instantiateModule(data, ffi); | 
|  | 322 | 
|  | 323   assertEquals("function", typeof module.main); | 
|  | 324 | 
|  | 325   for (var i = -9; i < 900; i += 6.125) { | 
|  | 326       module.main(i); | 
|  | 327   } | 
|  | 328 } | 
|  | 329 | 
|  | 330 testCallPrint(); | 
|  | 331 testCallPrint(); | 
| OLD | NEW | 
|---|