@@ -60,6 +60,8 @@ class Writer {
6060
6161 void createSyntheticInitFunctions ();
6262 void createInitMemoryFunction ();
63+ void createMemoryGrowFunction ();
64+ void createMemorySizeFunction ();
6365 void createStartFunction ();
6466 void createApplyDataRelocationsFunction ();
6567 void createApplyGlobalRelocationsFunction ();
@@ -888,31 +890,33 @@ void Writer::createCommandExportWrappers() {
888890 toWrap.push_back (f);
889891
890892 for (auto *f : toWrap) {
891- auto funcNameStr = (f->getName () + " .command_export" ).str ();
892- commandExportWrapperNames.push_back (funcNameStr);
893- const std::string &funcName = commandExportWrapperNames.back ();
893+ if (!(f->getExportNoWrap ())) {
894+ auto funcNameStr = (f->getName () + " .command_export" ).str ();
895+ commandExportWrapperNames.push_back (funcNameStr);
896+ const std::string &funcName = commandExportWrapperNames.back ();
894897
895- auto func = make<SyntheticFunction>(*f->getSignature (), funcName);
896- if (f->function ->getExportName ())
897- func->setExportName (f->function ->getExportName ()->str ());
898- else
899- func->setExportName (f->getName ().str ());
898+ auto func = make<SyntheticFunction>(*f->getSignature (), funcName);
899+ if (f->function ->getExportName ())
900+ func->setExportName (f->function ->getExportName ()->str ());
901+ else
902+ func->setExportName (f->getName ().str ());
900903
901- DefinedFunction *def =
902- symtab->addSyntheticFunction (funcName, f->flags , func);
903- def->markLive ();
904+ DefinedFunction *def =
905+ symtab->addSyntheticFunction (funcName, f->flags , func);
906+ def->markLive ();
904907
905- def->flags |= WASM_SYMBOL_EXPORTED;
906- def->flags &= ~WASM_SYMBOL_VISIBILITY_HIDDEN;
907- def->forceExport = f->forceExport ;
908+ def->flags |= WASM_SYMBOL_EXPORTED;
909+ def->flags &= ~WASM_SYMBOL_VISIBILITY_HIDDEN;
910+ def->forceExport = f->forceExport ;
908911
909- f->flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
910- f->flags &= ~WASM_SYMBOL_EXPORTED;
911- f->forceExport = false ;
912+ f->flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
913+ f->flags &= ~WASM_SYMBOL_EXPORTED;
914+ f->forceExport = false ;
912915
913- out.functionSec ->addFunction (func);
916+ out.functionSec ->addFunction (func);
914917
915- createCommandExportWrapper (f->getFunctionIndex (), def);
918+ createCommandExportWrapper (f->getFunctionIndex (), def);
919+ }
916920 }
917921}
918922
@@ -1136,6 +1140,8 @@ void Writer::createSyntheticInitFunctions() {
11361140 return ;
11371141
11381142 static WasmSignature nullSignature = {{}, {}};
1143+ static WasmSignature memoryGrowSignature = {{ValType::I32}, {ValType::I32}};
1144+ static WasmSignature memorySizeSignature = {{ValType::I32}, {}};
11391145
11401146 createApplyDataRelocationsFunction ();
11411147
@@ -1156,6 +1162,25 @@ void Writer::createSyntheticInitFunctions() {
11561162 }
11571163 }
11581164
1165+ // Memory grow/size export hooks
1166+ auto memoryGrowFunc =
1167+ make<SyntheticFunction>(memoryGrowSignature, " __wasm_memory_grow" );
1168+ memoryGrowFunc->setExportName (" __wasm_memory_grow" );
1169+ ctx.sym .memoryGrow = symtab->addSyntheticFunction (
1170+ " __wasm_memory_grow" ,
1171+ WASM_SYMBOL_VISIBILITY_DEFAULT | WASM_SYMBOL_EXPORTED, memoryGrowFunc);
1172+ ctx.sym .memoryGrow ->markLive ();
1173+ ctx.sym .memoryGrow ->setExportNoWrap (true );
1174+
1175+ auto memorySizeFunc =
1176+ make<SyntheticFunction>(memorySizeSignature, " __wasm_memory_size" );
1177+ memorySizeFunc->setExportName (" __wasm_memory_size" );
1178+ ctx.sym .memorySize = symtab->addSyntheticFunction (
1179+ " __wasm_memory_size" ,
1180+ WASM_SYMBOL_VISIBILITY_DEFAULT | WASM_SYMBOL_EXPORTED, memorySizeFunc);
1181+ ctx.sym .memorySize ->markLive ();
1182+ ctx.sym .memorySize ->setExportNoWrap (true );
1183+
11591184 if (ctx.arg .sharedMemory ) {
11601185 if (out.globalSec ->needsTLSRelocations ()) {
11611186 ctx.sym .applyGlobalTLSRelocs = symtab->addSyntheticFunction (
@@ -1200,6 +1225,36 @@ void Writer::createSyntheticInitFunctions() {
12001225 }
12011226}
12021227
1228+ void Writer::createMemoryGrowFunction () {
1229+ LLVM_DEBUG (dbgs () << " createMemoryGrowFunction\n " );
1230+ assert (ctx.sym .memoryGrow );
1231+ std::string bodyContent;
1232+ {
1233+ raw_string_ostream os (bodyContent);
1234+ writeUleb128 (os, 0 , " num locals" );
1235+ writeU8 (os, WASM_OPCODE_LOCAL_GET, " local.get" );
1236+ writeUleb128 (os, 0 , " local 0" );
1237+ writeU8 (os, WASM_OPCODE_MEMORY_GROW, " memory grow" );
1238+ writeUleb128 (os, 0 , " reserved memory byte" );
1239+ writeU8 (os, WASM_OPCODE_END, " END" );
1240+ }
1241+ createFunction (ctx.sym .memoryGrow , bodyContent);
1242+ }
1243+
1244+ void Writer::createMemorySizeFunction () {
1245+ LLVM_DEBUG (dbgs () << " createMemorySizeFunction\n " );
1246+ assert (ctx.sym .memorySize );
1247+ std::string bodyContent;
1248+ {
1249+ raw_string_ostream os (bodyContent);
1250+ writeUleb128 (os, 0 , " num locals" );
1251+ writeU8 (os, WASM_OPCODE_MEMORY_SIZE, " memory size" );
1252+ writeUleb128 (os, 0 , " reserved memory byte" );
1253+ writeU8 (os, WASM_OPCODE_END, " END" );
1254+ }
1255+ createFunction (ctx.sym .memorySize , bodyContent);
1256+ }
1257+
12031258void Writer::createInitMemoryFunction () {
12041259 LLVM_DEBUG (dbgs () << " createInitMemoryFunction\n " );
12051260 assert (ctx.sym .initMemory );
@@ -1788,6 +1843,12 @@ void Writer::run() {
17881843 if (ctx.sym .initMemory ) {
17891844 createInitMemoryFunction ();
17901845 }
1846+ if (ctx.sym .memoryGrow ) {
1847+ createMemoryGrowFunction ();
1848+ }
1849+ if (ctx.sym .memorySize ) {
1850+ createMemorySizeFunction ();
1851+ }
17911852 createStartFunction ();
17921853
17931854 createCallCtorsFunction ();
0 commit comments