Skip to content

Commit c81857a

Browse files
dcodeIOkripken
authored andcommitted
Fix hard-wired buffer limit in the JS API (#1394)
1 parent 6bc9700 commit c81857a

File tree

6 files changed

+202
-167
lines changed

6 files changed

+202
-167
lines changed

bin/binaryen.js

Lines changed: 142 additions & 142 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build-js.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,7 @@ export_function "_BinaryenGetDebugInfo"
539539
export_function "_BinaryenSetDebugInfo"
540540
export_function "_BinaryenModuleRunPasses"
541541
export_function "_BinaryenModuleAutoDrop"
542-
export_function "_BinaryenModuleWrite"
543-
export_function "_BinaryenModuleWriteWithSourceMap"
542+
export_function "_BinaryenModuleAllocateAndWrite"
544543
export_function "_BinaryenModuleRead"
545544
export_function "_BinaryenModuleInterpret"
546545
export_function "_BinaryenModuleAddDebugInfoFileName"

src/binaryen-c.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2063,7 +2063,7 @@ void BinaryenSetDebugInfo(int on) {
20632063
std::cout << " BinaryenSetDebugInfo(" << on << ");\n";
20642064
}
20652065

2066-
globalPassOptions.debugInfo = bool(on);
2066+
globalPassOptions.debugInfo = on != 0;
20672067
}
20682068

20692069
void BinaryenModuleRunPasses(BinaryenModuleRef module, const char **passes, BinaryenIndex numPasses) {
@@ -2139,6 +2139,33 @@ BinaryenBufferSizes BinaryenModuleWriteWithSourceMap(BinaryenModuleRef module, c
21392139
return writeModule((Module*)module, output, outputSize, url, sourceMap, sourceMapSize);
21402140
}
21412141

2142+
BinaryenModuleAllocateAndWriteResult BinaryenModuleAllocateAndWrite(BinaryenModuleRef module, const char* sourceMapUrl) {
2143+
if (tracing) {
2144+
std::cout << " // BinaryenModuleAllocateAndWrite(the_module, ";
2145+
traceNameOrNULL(sourceMapUrl);
2146+
std::cout << ");\n";
2147+
}
2148+
2149+
Module* wasm = (Module*)module;
2150+
BufferWithRandomAccess buffer(false);
2151+
WasmBinaryWriter writer(wasm, buffer, false);
2152+
writer.setNamesSection(globalPassOptions.debugInfo);
2153+
std::ostringstream os;
2154+
if (sourceMapUrl) {
2155+
writer.setSourceMap(&os, sourceMapUrl);
2156+
}
2157+
writer.write();
2158+
void* binary = malloc(buffer.size());
2159+
std::copy_n(buffer.begin(), buffer.size(), static_cast<char*>(binary));
2160+
char* sourceMap = nullptr;
2161+
if (sourceMapUrl) {
2162+
auto str = os.str();
2163+
sourceMap = (char*)malloc(str.length() + 1);
2164+
std::copy_n(str.c_str(), str.length() + 1, sourceMap);
2165+
}
2166+
return { binary, buffer.size(), sourceMap };
2167+
}
2168+
21422169
BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) {
21432170
if (tracing) {
21442171
std::cout << " // BinaryenModuleRead\n";

src/binaryen-c.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,20 @@ typedef struct BinaryenBufferSizes {
707707
// @returns how many bytes were written. This will be less than or equal to outputSize
708708
BinaryenBufferSizes BinaryenModuleWriteWithSourceMap(BinaryenModuleRef module, const char* url, char* output, size_t outputSize, char* sourceMap, size_t sourceMapSize);
709709

710+
// Result structure of BinaryenModuleAllocateAndWrite. Contained buffers have been allocated
711+
// using malloc() and the user is expected to free() them manually once not needed anymore.
712+
typedef struct BinaryenModuleAllocateAndWriteResult {
713+
void* binary;
714+
size_t binaryBytes;
715+
char* sourceMap;
716+
} BinaryenModuleAllocateAndWriteResult;
717+
718+
// Serializes a module into binary form, optionally including its source map if
719+
// sourceMapUrl has been specified. Uses the currently set global debugInfo option.
720+
// Differs from BinaryenModuleWrite in that it implicitly allocates appropriate buffers
721+
// using malloc(), and expects the user to free() them manually once not needed anymore.
722+
BinaryenModuleAllocateAndWriteResult BinaryenModuleAllocateAndWrite(BinaryenModuleRef module, const char* sourceMapUrl);
723+
710724
// Deserialize a module from binary form.
711725
BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize);
712726

src/js/binaryen.js-post.js

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ Module['Module'] = function(module) {
11601160
return Module['_BinaryenModuleOptimize'](module);
11611161
};
11621162
this['optimizeFunction'] = function(func) {
1163-
if (typeof func === "string") func = this['getFunction'](func);
1163+
if (typeof func === 'string') func = this['getFunction'](func);
11641164
return Module['_BinaryenFunctionOptimize'](func, module);
11651165
};
11661166
this['runPasses'] = function(passes) {
@@ -1171,7 +1171,7 @@ Module['Module'] = function(module) {
11711171
});
11721172
};
11731173
this['runPassesOnFunction'] = function(func, passes) {
1174-
if (typeof func === "string") func = this['getFunction'](func);
1174+
if (typeof func === 'string') func = this['getFunction'](func);
11751175
return preserveStack(function() {
11761176
return Module['_BinaryenFunctionRunPasses'](func, module, i32sToStack(
11771177
passes.map(strToStack)
@@ -1184,27 +1184,22 @@ Module['Module'] = function(module) {
11841184
this['dispose'] = function() {
11851185
Module['_BinaryenModuleDispose'](module);
11861186
};
1187-
var MAX = 1024*1024; // TODO: fix this hard-wired limit
1188-
var outputBuffer = null;
1189-
var sourceMapBuffer = null;
11901187
this['emitBinary'] = function(sourceMapUrl) {
1191-
if (!outputBuffer) outputBuffer = _malloc(MAX);
1192-
var bytes = Module['_BinaryenModuleWrite'](module, outputBuffer, MAX);
1193-
assert(bytes < MAX, 'FIXME: hardcoded limit on module size'); // we should not use the whole buffer
1194-
return new Uint8Array(HEAPU8.subarray(outputBuffer, outputBuffer + bytes));
1195-
};
1196-
this['emitBinaryWithSourceMap'] = function(sourceMapUrl) {
1197-
if (!outputBuffer) outputBuffer = _malloc(MAX);
1198-
if (!sourceMapBuffer) sourceMapBuffer = _malloc(MAX);
11991188
return preserveStack(function() {
1200-
Module['_BinaryenModuleWriteWithSourceMap'](temp, module, strToStack(sourceMapUrl), outputBuffer, MAX, sourceMapBuffer, MAX);
1201-
var outputBytes = HEAPU32[temp >>> 2];
1202-
var sourceMapBytes = HEAPU32[(temp + 1) >>> 2];
1203-
assert(outputBytes < MAX && sourceMapBytes < MAX, 'FIXME: hardcoded limit on module size'); // see above
1204-
return {
1205-
'binary': new Uint8Array(HEAPU8.subarray(outputBuffer, outputBuffer + outputBytes)),
1206-
'sourceMap': Pointer_stringify(sourceMapBuffer)
1207-
};
1189+
Module['_BinaryenModuleAllocateAndWrite'](temp, module, strToStack(sourceMapUrl));
1190+
var binaryPtr = HEAPU32[ temp >>> 2 ];
1191+
var binaryBytes = HEAPU32[(temp >>> 2) + 1];
1192+
var sourceMapPtr = HEAPU32[(temp >>> 2) + 2];
1193+
try {
1194+
var buffer = new Uint8Array(binaryBytes);
1195+
buffer.set(HEAPU8.subarray(binaryPtr, binaryPtr + binaryBytes));
1196+
return typeof sourceMapUrl === 'undefined'
1197+
? buffer
1198+
: { 'binary': buffer, 'sourceMap': Pointer_stringify(sourceMapPtr) };
1199+
} finally {
1200+
_free(binaryPtr);
1201+
if (sourceMapPtr) _free(sourceMapPtr);
1202+
}
12081203
});
12091204
};
12101205
this['interpret'] = function() {

test/binaryen.js/sourcemap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ var func = module.addFunction("main", signature, [], body);
1717
module.setDebugLocation(func, expr, fileIndex, 1, 2);
1818
module.setDebugLocation(func, body, fileIndex, 0, 3);
1919

20-
var output = module.emitBinaryWithSourceMap("module.wasm.map");
20+
var output = module.emitBinary("module.wasm.map");
2121

2222
function dumpBinary(buffer) {
2323
var hex = [], o, b, h;

0 commit comments

Comments
 (0)