1616
1717#include " wasm-emscripten.h"
1818
19- #include < functional>
2019#include < sstream>
2120
2221#include " asm_v_wasm.h"
@@ -33,7 +32,6 @@ namespace wasm {
3332
3433cashew::IString EMSCRIPTEN_ASM_CONST (" emscripten_asm_const" );
3534cashew::IString EM_JS_PREFIX (" __em_js__" );
36- static const char * INVOKE_PREFIX = " invoke_" ;
3735
3836static Name STACK_SAVE (" stackSave" );
3937static Name STACK_RESTORE (" stackRestore" );
@@ -559,12 +557,6 @@ struct AsmConstWalker : public LinearExecutionWalker<AsmConstWalker> {
559557 std::set<std::string> allSigs;
560558 // last sets in the current basic block, per index
561559 std::map<Index, LocalSet*> sets;
562- // table indices that are calls to emscripten_asm_const_*
563- std::map<Index, Name> asmTable;
564- // cache used by tableIndexForName
565- std::map<Name, Literal> tableIndices;
566- // first available index after the table segment for each segment
567- std::vector<int32_t > tableOffsets;
568560
569561 AsmConstWalker (Module& _wasm)
570562 : wasm(_wasm), segmentOffsets(getSegmentOffsets(wasm)) {}
@@ -585,14 +577,7 @@ struct AsmConstWalker : public LinearExecutionWalker<AsmConstWalker> {
585577 void queueImport (Name importName, std::string baseSig);
586578 void addImports ();
587579
588- Index resolveConstIndex (Expression* arg,
589- std::function<void (Expression*)> reportError);
590- Const* resolveConstAddr (Expression* arg, const Name& target);
591- void prepareAsmIndices (Table* table);
592- Literal tableIndexForName (Name name);
593-
594580 std::vector<std::unique_ptr<Function>> queuedImports;
595- std::vector<Name> queuedTableEntries;
596581};
597582
598583void AsmConstWalker::noteNonLinear (Expression* curr) {
@@ -602,109 +587,45 @@ void AsmConstWalker::noteNonLinear(Expression* curr) {
602587
603588void AsmConstWalker::visitLocalSet (LocalSet* curr) { sets[curr->index ] = curr; }
604589
605- Const* AsmConstWalker::resolveConstAddr (Expression* arg, const Name& target) {
606- while (!arg->dynCast <Const>()) {
607- if (auto * get = arg->dynCast <LocalGet>()) {
608- // The argument may be a local.get, in which case, the last set in this
609- // basic block has the value.
610- auto * set = sets[get->index ];
611- if (set) {
612- assert (set->index == get->index );
613- arg = set->value ;
614- }
615- } else if (auto * value = arg->dynCast <Binary>()) {
616- // In the dynamic linking case the address of the string constant
617- // is the result of adding its offset to __memory_base.
618- // In this case are only looking for the offset with the data segment so
619- // the RHS of the addition is just what we want.
620- assert (value->op == AddInt32);
621- arg = value->right ;
622- } else {
623- Fatal () << " Unexpected arg0 type (" << getExpressionName (arg)
624- << " ) in call to to: " << target;
625- }
626- }
627- return arg->cast <Const>();
628- }
629-
630- Index AsmConstWalker::resolveConstIndex (
631- Expression* arg, std::function<void (Expression*)> reportError) {
632- while (!arg->dynCast <Const>()) {
633- if (auto * get = arg->dynCast <LocalGet>()) {
634- // The argument may be a local.get, in which case, the last set in this
635- // basic block has the value.
636- auto * set = sets[get->index ];
637- if (set) {
638- assert (set->index == get->index );
639- arg = set->value ;
640- }
641- } else if (arg->is <GlobalGet>()) {
642- // In the dynamic linking case, indices start at __table_base.
643- // We want the value relative to __table_base.
644- return 0 ;
645- } else {
646- reportError (arg);
647- }
648- }
649- return Index (arg->cast <Const>()->value .geti32 ());
650- }
651-
652590void AsmConstWalker::visitCall (Call* curr) {
653591 auto * import = wasm.getFunction (curr->target );
654- if (!import ->imported ()) {
655- return ;
656- }
657-
658592 // Find calls to emscripten_asm_const* functions whose first argument is
659593 // is always a string constant.
660- if (import ->base .hasSubstring (EMSCRIPTEN_ASM_CONST)) {
594+ if (import ->imported () && import -> base .hasSubstring (EMSCRIPTEN_ASM_CONST)) {
661595 auto baseSig = getSig (curr);
662596 auto sig = fixupNameWithSig (curr->target , baseSig);
663- auto * value = resolveConstAddr (curr->operands [0 ], import ->base );
597+ auto * arg = curr->operands [0 ];
598+ while (!arg->dynCast <Const>()) {
599+ if (auto * get = arg->dynCast <LocalGet>()) {
600+ // The argument may be a local.get, in which case, the last set in this
601+ // basic block has the value.
602+ auto * set = sets[get->index ];
603+ if (set) {
604+ assert (set->index == get->index );
605+ arg = set->value ;
606+ }
607+ } else if (auto * value = arg->dynCast <Binary>()) {
608+ // In the dynamic linking case the address of the string constant
609+ // is the result of adding its offset to __memory_base.
610+ // In this case are only looking for the offset with the data segment so
611+ // the RHS of the addition is just what we want.
612+ assert (value->op == AddInt32);
613+ arg = value->right ;
614+ } else {
615+ if (!value) {
616+ Fatal () << " Unexpected arg0 type (" << getExpressionName (arg)
617+ << " ) in call to to: " << import ->base ;
618+ }
619+ }
620+ }
621+
622+ auto * value = arg->cast <Const>();
664623 auto code = codeForConstAddr (wasm, segmentOffsets, value);
665624 sigsForCode[code].insert (sig);
666625
667626 // Replace the first argument to the call with a Const index
668627 Builder builder (wasm);
669628 curr->operands [0 ] = builder.makeConst (idLiteralForCode (code));
670- } else if (import ->base .startsWith (INVOKE_PREFIX)) {
671- auto idx = resolveConstIndex (curr->operands [0 ], [&](Expression* arg) {
672- Fatal () << " Unexpected table index type (" << getExpressionName (arg)
673- << " ) in call to: " << import ->base ;
674- });
675-
676- // If the address of the invoke call is an emscripten_asm_const_* function:
677- if (asmTable.count (idx)) {
678- auto * value = resolveConstAddr (curr->operands [1 ], asmTable[idx]);
679- auto code = codeForConstAddr (wasm, segmentOffsets, value);
680-
681- // Extract the base signature from the invoke_* function name.
682- std::string baseSig (import ->base .c_str () + sizeof (INVOKE_PREFIX) - 1 );
683- Name name;
684- auto sig = fixupNameWithSig (name, baseSig);
685- sigsForCode[code].insert (sig);
686-
687- Builder builder (wasm);
688- curr->operands [0 ] = builder.makeConst (tableIndexForName (name));
689- curr->operands [1 ] = builder.makeConst (idLiteralForCode (code));
690- }
691- }
692- }
693-
694- void AsmConstWalker::prepareAsmIndices (Table* table) {
695- for (auto & segment : table->segments ) {
696- auto idx = resolveConstIndex (segment.offset , [&](Expression* arg) {
697- Fatal () << " Unexpected table index type (" << getExpressionName (arg)
698- << " ) table" ;
699- });
700- for (auto & name : segment.data ) {
701- auto * func = wasm.getFunction (name);
702- if (func->imported () && func->base .hasSubstring (EMSCRIPTEN_ASM_CONST)) {
703- asmTable[idx] = name;
704- }
705- ++idx;
706- }
707- tableOffsets.push_back (idx);
708629 }
709630}
710631
@@ -721,8 +642,6 @@ void AsmConstWalker::visitTable(Table* curr) {
721642}
722643
723644void AsmConstWalker::process () {
724- // Find table indices that point to emscripten_asm_const_* functions.
725- prepareAsmIndices (&wasm.table );
726645 // Find and queue necessary imports
727646 walkModule (&wasm);
728647 // Add them after the walk, to avoid iterator invalidation on
@@ -778,27 +697,10 @@ void AsmConstWalker::queueImport(Name importName, std::string baseSig) {
778697 queuedImports.push_back (std::unique_ptr<Function>(import ));
779698}
780699
781- Literal AsmConstWalker::tableIndexForName (Name name) {
782- if (tableIndices.count (name)) {
783- return tableIndices[name];
784- }
785- queuedTableEntries.push_back (name);
786- return tableIndices[name] = Literal (tableOffsets[0 ]++);
787- }
788-
789700void AsmConstWalker::addImports () {
790701 for (auto & import : queuedImports) {
791702 wasm.addFunction (import .release ());
792703 }
793-
794- if (!queuedTableEntries.empty ()) {
795- assert (wasm.table .segments .size () == 1 );
796- std::vector<Name>& tableSegmentData = wasm.table .segments [0 ].data ;
797- for (auto & entry : queuedTableEntries) {
798- tableSegmentData.push_back (entry);
799- }
800- wasm.table .initial .addr += queuedTableEntries.size ();
801- }
802704}
803705
804706AsmConstWalker fixEmAsmConstsAndReturnWalker (Module& wasm) {
@@ -933,7 +835,7 @@ struct FixInvokeFunctionNamesWalker
933835 }
934836 std::string sigWoOrigFunc = sig.front () + sig.substr (2 , sig.size () - 2 );
935837 invokeSigs.insert (sigWoOrigFunc);
936- return Name (INVOKE_PREFIX + sigWoOrigFunc);
838+ return Name (" invoke_ " + sigWoOrigFunc);
937839 }
938840
939841 Name fixEmEHSjLjNames (const Name& name, const std::string& sig) {
@@ -1073,7 +975,7 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
1073975 ModuleUtils::iterImportedFunctions (wasm, [&](Function* import ) {
1074976 if (emJsWalker.codeByName .count (import ->base .str ) == 0 &&
1075977 !import ->base .startsWith (EMSCRIPTEN_ASM_CONST.str ) &&
1076- !import ->base .startsWith (INVOKE_PREFIX )) {
978+ !import ->base .startsWith (" invoke_ " )) {
1077979 if (declares.insert (import ->base .str ).second ) {
1078980 meta << nextElement () << ' "' << import ->base .str << ' "' ;
1079981 }
@@ -1127,7 +1029,7 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
11271029 meta << " \" invokeFuncs\" : [" ;
11281030 commaFirst = true ;
11291031 ModuleUtils::iterImportedFunctions (wasm, [&](Function* import ) {
1130- if (import ->base .startsWith (INVOKE_PREFIX )) {
1032+ if (import ->base .startsWith (" invoke_ " )) {
11311033 if (invokeFuncs.insert (import ->base .str ).second ) {
11321034 meta << nextElement () << ' "' << import ->base .str << ' "' ;
11331035 }
0 commit comments