@@ -60,6 +60,8 @@ class Writer {
60
60
61
61
void createSyntheticInitFunctions ();
62
62
void createInitMemoryFunction ();
63
+ void createMemoryGrowFunction ();
64
+ void createMemorySizeFunction ();
63
65
void createStartFunction ();
64
66
void createApplyDataRelocationsFunction ();
65
67
void createApplyGlobalRelocationsFunction ();
@@ -888,31 +890,33 @@ void Writer::createCommandExportWrappers() {
888
890
toWrap.push_back (f);
889
891
890
892
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 ();
894
897
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 ());
900
903
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 ();
904
907
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 ;
908
911
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 ;
912
915
913
- out.functionSec ->addFunction (func);
916
+ out.functionSec ->addFunction (func);
914
917
915
- createCommandExportWrapper (f->getFunctionIndex (), def);
918
+ createCommandExportWrapper (f->getFunctionIndex (), def);
919
+ }
916
920
}
917
921
}
918
922
@@ -1136,6 +1140,8 @@ void Writer::createSyntheticInitFunctions() {
1136
1140
return ;
1137
1141
1138
1142
static WasmSignature nullSignature = {{}, {}};
1143
+ static WasmSignature memoryGrowSignature = {{ValType::I32}, {ValType::I32}};
1144
+ static WasmSignature memorySizeSignature = {{ValType::I32}, {}};
1139
1145
1140
1146
createApplyDataRelocationsFunction ();
1141
1147
@@ -1156,6 +1162,25 @@ void Writer::createSyntheticInitFunctions() {
1156
1162
}
1157
1163
}
1158
1164
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
+
1159
1184
if (ctx.arg .sharedMemory ) {
1160
1185
if (out.globalSec ->needsTLSRelocations ()) {
1161
1186
ctx.sym .applyGlobalTLSRelocs = symtab->addSyntheticFunction (
@@ -1200,6 +1225,36 @@ void Writer::createSyntheticInitFunctions() {
1200
1225
}
1201
1226
}
1202
1227
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
+
1203
1258
void Writer::createInitMemoryFunction () {
1204
1259
LLVM_DEBUG (dbgs () << " createInitMemoryFunction\n " );
1205
1260
assert (ctx.sym .initMemory );
@@ -1788,6 +1843,12 @@ void Writer::run() {
1788
1843
if (ctx.sym .initMemory ) {
1789
1844
createInitMemoryFunction ();
1790
1845
}
1846
+ if (ctx.sym .memoryGrow ) {
1847
+ createMemoryGrowFunction ();
1848
+ }
1849
+ if (ctx.sym .memorySize ) {
1850
+ createMemorySizeFunction ();
1851
+ }
1791
1852
createStartFunction ();
1792
1853
1793
1854
createCallCtorsFunction ();
0 commit comments