@@ -383,6 +383,7 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
383383 ret[1 ]->push_back (asmFunc);
384384 ValueBuilder::appendArgumentToFunction (asmFunc, ENV );
385385
386+ // add memory import
386387 if (wasm->memory .exists ) {
387388 if (wasm->memory .imported ()) {
388389 // find memory and buffer in imports
@@ -414,8 +415,15 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
414415 ValueBuilder::makeName (WASM_MEMORY_GROW ))));
415416 }
416417 } else {
417- // find memory as third argument
418- ValueBuilder::appendArgumentToFunction (asmFunc, BUFFER );
418+ Ref theVar = ValueBuilder::makeVar ();
419+ asmFunc[3 ]->push_back (theVar);
420+ ValueBuilder::appendToVar (
421+ theVar,
422+ BUFFER ,
423+ ValueBuilder::makeNew (ValueBuilder::makeCall (
424+ ValueBuilder::makeName (" ArrayBuffer" ),
425+ ValueBuilder::makeInt (Address::address32_t (wasm->memory .initial .addr *
426+ Memory::kPageSize )))));
419427 }
420428 }
421429
@@ -428,6 +436,7 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
428436 FUNCTION_TABLE ,
429437 ValueBuilder::makeDot (ValueBuilder::makeName (ENV ), wasm->table .base ));
430438 }
439+
431440 // create heaps, etc
432441 addBasics (asmFunc[3 ], wasm);
433442 ModuleUtils::iterImportedFunctions (
@@ -503,6 +512,12 @@ void Wasm2JSBuilder::addBasics(Ref ast, Module* wasm) {
503512 addHeap (HEAPU32 , UINT32ARRAY );
504513 addHeap (HEAPF32 , FLOAT32ARRAY );
505514 addHeap (HEAPF64 , FLOAT64ARRAY );
515+ if ((!wasm->memory .segments .empty ()) || wasm->features .hasBulkMemory ()) {
516+ ast->push_back (
517+ ValueBuilder::makeBinary (ValueBuilder::makeName (" bufferView" ),
518+ SET ,
519+ ValueBuilder::makeName (HEAPU8 )));
520+ }
506521 }
507522 // core asm.js imports
508523 auto addMath = [&](IString name, IString base) {
@@ -2299,12 +2314,6 @@ void Wasm2JSBuilder::addMemoryGrowFunc(Ref ast, Module* wasm) {
22992314 IString (" set" )),
23002315 ValueBuilder::makeName (HEAP8 )));
23012316
2302- ValueBuilder::appendToBlock (
2303- block,
2304- ValueBuilder::makeBinary (ValueBuilder::makeName (HEAP8 ),
2305- SET ,
2306- ValueBuilder::makeName (IString (" newHEAP8" ))));
2307-
23082317 auto setHeap = [&](IString name, IString view) {
23092318 ValueBuilder::appendToBlock (
23102319 block,
@@ -2339,7 +2348,15 @@ void Wasm2JSBuilder::addMemoryGrowFunc(Ref ast, Module* wasm) {
23392348 ValueBuilder::makeDot (ValueBuilder::makeName (" memory" ),
23402349 ValueBuilder::makeName (BUFFER )),
23412350 SET ,
2342- ValueBuilder::makeName (IString (" newBuffer" ))));
2351+ ValueBuilder::makeName (BUFFER )));
2352+ }
2353+
2354+ if ((!wasm->memory .segments .empty ()) || wasm->features .hasBulkMemory ()) {
2355+ ValueBuilder::appendToBlock (
2356+ block,
2357+ ValueBuilder::makeBinary (ValueBuilder::makeName (" bufferView" ),
2358+ SET ,
2359+ ValueBuilder::makeName (HEAPU8 )));
23432360 }
23442361
23452362 memoryGrowFunc[3 ]->push_back (
@@ -2373,8 +2390,7 @@ class Wasm2JSGlue {
23732390 void emitPostEmscripten ();
23742391 void emitPostES6 ();
23752392
2376- void emitMemory (std::string buffer,
2377- std::function<std::string(std::string)> accessGlobal);
2393+ void emitMemory (std::function<std::string(std::string)> accessGlobal);
23782394 void emitSpecialSupport ();
23792395};
23802396
@@ -2410,7 +2426,7 @@ void Wasm2JSGlue::emitPre() {
24102426}
24112427
24122428void Wasm2JSGlue::emitPreEmscripten () {
2413- out << " function instantiate(asmLibraryArg, wasmMemory ) {\n " ;
2429+ out << " function instantiate(asmLibraryArg) {\n " ;
24142430}
24152431
24162432void Wasm2JSGlue::emitPreES6 () {
@@ -2449,6 +2465,18 @@ void Wasm2JSGlue::emitPreES6() {
24492465}
24502466
24512467void Wasm2JSGlue::emitPost () {
2468+ // Create a helper bufferView to access the buffer if we need one. We use it
2469+ // for creating memory segments if we have any (we may not if the segments are
2470+ // shipped in a side .mem file, for example), and also in bulk memory
2471+ // operations.
2472+ // This will get assigned during `asmFunc` (and potentially re-assigned
2473+ // during __wasm_memory_grow).
2474+ // TODO: We should probably just share a single HEAPU8 var.
2475+ if (wasm.memory .exists &&
2476+ ((!wasm.memory .segments .empty ()) || wasm.features .hasBulkMemory ())) {
2477+ out << " var bufferView;\n " ;
2478+ }
2479+
24522480 if (flags.emscripten ) {
24532481 emitPostEmscripten ();
24542482 } else {
@@ -2457,13 +2485,13 @@ void Wasm2JSGlue::emitPost() {
24572485}
24582486
24592487void Wasm2JSGlue::emitPostEmscripten () {
2460- emitMemory (" wasmMemory.buffer" , [](std::string globalName) {
2488+ out << " var exports = asmFunc(asmLibraryArg);\n " ;
2489+
2490+ emitMemory ([](std::string globalName) {
24612491 return std::string (" asmLibraryArg['" ) + asmangle (globalName) + " ']" ;
24622492 });
24632493
2464- out << " return asmFunc(asmLibraryArg, wasmMemory.buffer)\n "
2465- << " \n "
2466- << " }" ;
2494+ out << " return exports;\n }" ;
24672495}
24682496
24692497void Wasm2JSGlue::emitPostES6 () {
@@ -2473,12 +2501,9 @@ void Wasm2JSGlue::emitPostES6() {
24732501 //
24742502 // Note that the translation here expects that the lower values of this memory
24752503 // can be used for conversions, so make sure there's at least one page.
2476- if (wasm.memory .exists ) {
2504+ if (wasm.memory .exists && wasm. memory . imported () ) {
24772505 out << " var mem" << moduleName.str << " = new ArrayBuffer("
24782506 << wasm.memory .initial .addr * Memory::kPageSize << " );\n " ;
2479-
2480- emitMemory (std::string (" mem" ) + moduleName.str ,
2481- [](std::string globalName) { return globalName; });
24822507 }
24832508
24842509 // Actually invoke the `asmFunc` generated function, passing in all global
@@ -2514,10 +2539,10 @@ void Wasm2JSGlue::emitPostES6() {
25142539 out << " ,\n " << asmangle (import ->base .str );
25152540 });
25162541
2517- if (wasm. memory . exists && !wasm. memory . imported ()) {
2518- out << " \n }, \n mem " << moduleName. str << " \n ); \n " ;
2519- } else {
2520- out << " \n }); \n " ;
2542+ out << " \n }); \n " ;
2543+
2544+ if (wasm. memory . exists ) {
2545+ emitMemory ([](std::string globalName) { return globalName; }) ;
25212546 }
25222547
25232548 if (flags.allowAsserts ) {
@@ -2550,21 +2575,10 @@ void Wasm2JSGlue::emitPostES6() {
25502575}
25512576
25522577void Wasm2JSGlue::emitMemory (
2553- std::string buffer,
25542578 std::function<std::string(std::string)> accessGlobal) {
2555- if (!wasm.memory .exists ) {
2556- return ;
2557- }
2558- // Create a helper bufferView to access the buffer if we need one. We use it
2559- // for creating memory segments if we have any (we may not if the segments are
2560- // shipped in a side .mem file, for example), and also in bulk memory
2561- // operations.
2562- if (!wasm.memory .segments .empty () || wasm.features .hasBulkMemory ()) {
2563- out << " var bufferView = new Uint8Array(" << buffer << " );\n " ;
2564- }
25652579 // If there are no memory segments, we don't need to emit any support code for
25662580 // segment creation.
2567- if (wasm.memory .segments .empty ()) {
2581+ if ((!wasm. memory . exists ) || wasm.memory .segments .empty ()) {
25682582 return ;
25692583 }
25702584
0 commit comments