summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp71
-rw-r--r--src/binaryen-c.h20
-rw-r--r--src/js/binaryen.js-post.js64
3 files changed, 130 insertions, 25 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 63ce7ee6c..c2ba7fa6b 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -2100,19 +2100,43 @@ void BinaryenModuleAutoDrop(BinaryenModuleRef module) {
passRunner.run();
}
-size_t BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t outputSize) {
- if (tracing) {
- std::cout << " // BinaryenModuleWrite\n";
- }
-
+static BinaryenBufferSizes writeModule(BinaryenModuleRef module, char* output, size_t outputSize, const char* sourceMapUrl, char* sourceMap, size_t sourceMapSize) {
Module* wasm = (Module*)module;
BufferWithRandomAccess buffer(false);
WasmBinaryWriter writer(wasm, buffer, false);
writer.setNamesSection(globalPassOptions.debugInfo);
+ std::ostringstream os;
+ if (sourceMapUrl) {
+ writer.setSourceMap(&os, sourceMapUrl);
+ }
writer.write();
size_t bytes = std::min(buffer.size(), outputSize);
std::copy_n(buffer.begin(), bytes, output);
- return bytes;
+ size_t sourceMapBytes = 0;
+ if (sourceMapUrl) {
+ auto str = os.str();
+ sourceMapBytes = std::min(str.length(), sourceMapSize);
+ std::copy_n(str.c_str(), sourceMapBytes, sourceMap);
+ }
+ return { bytes, sourceMapBytes };
+}
+
+size_t BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t outputSize) {
+ if (tracing) {
+ std::cout << " // BinaryenModuleWrite\n";
+ }
+
+ return writeModule((Module*)module, output, outputSize, nullptr, nullptr, 0).outputBytes;
+}
+
+BinaryenBufferSizes BinaryenModuleWriteWithSourceMap(BinaryenModuleRef module, const char* url, char* output, size_t outputSize, char* sourceMap, size_t sourceMapSize) {
+ if (tracing) {
+ std::cout << " // BinaryenModuleWriteWithSourceMap\n";
+ }
+
+ assert(url);
+ assert(sourceMap);
+ return writeModule((Module*)module, output, outputSize, url, sourceMap, sourceMapSize);
}
BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) {
@@ -2144,6 +2168,26 @@ void BinaryenModuleInterpret(BinaryenModuleRef module) {
ModuleInstance instance(*wasm, &interface);
}
+BinaryenIndex BinaryenModuleAddDebugInfoFileName(BinaryenModuleRef module, const char* filename) {
+ if (tracing) {
+ std::cout << " BinaryenModuleAddDebugInfoFileName(the_module, \"" << filename << "\");\n";
+ }
+
+ Module* wasm = (Module*)module;
+ BinaryenIndex index = wasm->debugInfoFileNames.size();
+ wasm->debugInfoFileNames.push_back(filename);
+ return index;
+}
+
+const char* BinaryenModuleGetDebugInfoFileName(BinaryenModuleRef module, BinaryenIndex index) {
+ if (tracing) {
+ std::cout << " BinaryenModuleGetDebugInfoFileName(the_module, \"" << index << "\");\n";
+ }
+
+ Module* wasm = (Module*)module;
+ return index < wasm->debugInfoFileNames.size() ? wasm->debugInfoFileNames.at(index).c_str() : nullptr;
+}
+
//
// ======== FunctionType Operations ========
//
@@ -2275,6 +2319,21 @@ void BinaryenFunctionRunPasses(BinaryenFunctionRef func, BinaryenModuleRef modul
}
passRunner.runOnFunction((Function*)func);
}
+void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func, BinaryenExpressionRef expr, BinaryenIndex fileIndex, BinaryenIndex lineNumber, BinaryenIndex columnNumber) {
+ if (tracing) {
+ std::cout << " BinaryenFunctionSetDebugLocation(functions[" << functions[func] << "], expressions[" << expressions[expr] << "], " << fileIndex << ", " << lineNumber << ", " << columnNumber << ");\n";
+ }
+
+ auto* fn = (Function*)func;
+ auto* ex = (Expression*)expr;
+
+ Function::DebugLocation loc;
+ loc.fileIndex = fileIndex;
+ loc.lineNumber = lineNumber;
+ loc.columnNumber = columnNumber;
+
+ fn->debugLocations[ex] = loc;
+}
//
// =========== Import operations ===========
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index b91689c3f..9033a6950 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -697,6 +697,16 @@ void BinaryenModuleAutoDrop(BinaryenModuleRef module);
// @return how many bytes were written. This will be less than or equal to outputSize
size_t BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t outputSize);
+typedef struct BinaryenBufferSizes {
+ size_t outputBytes;
+ size_t sourceMapBytes;
+} BinaryenBufferSizes;
+
+// Serialize a module into binary form including its source map. Uses the currently set
+// global debugInfo option.
+// @returns how many bytes were written. This will be less than or equal to outputSize
+BinaryenBufferSizes BinaryenModuleWriteWithSourceMap(BinaryenModuleRef module, const char* url, char* output, size_t outputSize, char* sourceMap, size_t sourceMapSize);
+
// Deserialize a module from binary form.
BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize);
@@ -705,6 +715,13 @@ BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize);
// and then destroying the instance.
void BinaryenModuleInterpret(BinaryenModuleRef module);
+// Adds a debug info file name to the module and returns its index.
+BinaryenIndex BinaryenModuleAddDebugInfoFileName(BinaryenModuleRef module, const char* filename);
+
+// Gets the name of the debug info file at the specified index. Returns `NULL` if it
+// does not exist.
+const char* BinaryenModuleGetDebugInfoFileName(BinaryenModuleRef module, BinaryenIndex index);
+
//
// ======== FunctionType Operations ========
//
@@ -747,6 +764,9 @@ void BinaryenFunctionOptimize(BinaryenFunctionRef func, BinaryenModuleRef module
// optimize and shrink level.
void BinaryenFunctionRunPasses(BinaryenFunctionRef func, BinaryenModuleRef module, const char **passes, BinaryenIndex numPasses);
+// Sets the debug location of the specified `Expression` within the specified `Function`.
+void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func, BinaryenExpressionRef expr, BinaryenIndex fileIndex, BinaryenIndex lineNumber, BinaryenIndex columnNumber);
+
//
// ========== Import Operations ==========
//
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 580e9fc4d..5f1ef84fb 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -286,8 +286,8 @@ Module['Module'] = function(module) {
// need to make their own Literals, as the C API handles them by value,
// which means we would leak them. Instead, this is the only API that
// accepts Literals, so fuse it with Literal creation
- var literal = _malloc(16); // a single literal in memory. the LLVM C ABI
- // makes us pass pointers to this.
+ var temp = _malloc(16); // a single literal in memory. the LLVM C ABI
+ // makes us pass pointers to this.
this['i32'] = {
'load': function(offset, align, ptr) {
@@ -315,8 +315,8 @@ Module['Module'] = function(module) {
return Module['_BinaryenStore'](module, 2, offset, align, ptr, value, Module['i32']);
},
'const': function(x) {
- Module['_BinaryenLiteralInt32'](literal, x);
- return Module['_BinaryenConst'](module, literal);
+ Module['_BinaryenLiteralInt32'](temp, x);
+ return Module['_BinaryenConst'](module, temp);
},
'clz': function(value) {
return Module['_BinaryenUnary'](module, Module['ClzInt32'], value);
@@ -556,8 +556,8 @@ Module['Module'] = function(module) {
return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i64']);
},
'const': function(x, y) {
- Module['_BinaryenLiteralInt64'](literal, x, y);
- return Module['_BinaryenConst'](module, literal);
+ Module['_BinaryenLiteralInt64'](temp, x, y);
+ return Module['_BinaryenConst'](module, temp);
},
'clz': function(value) {
return Module['_BinaryenUnary'](module, Module['ClzInt64'], value);
@@ -802,12 +802,12 @@ Module['Module'] = function(module) {
return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['f32']);
},
'const': function(x) {
- Module['_BinaryenLiteralFloat32'](literal, x);
- return Module['_BinaryenConst'](module, literal);
+ Module['_BinaryenLiteralFloat32'](temp, x);
+ return Module['_BinaryenConst'](module, temp);
},
'const_bits': function(x) {
- Module['_BinaryenLiteralFloat32Bits'](literal, x);
- return Module['_BinaryenConst'](module, literal);
+ Module['_BinaryenLiteralFloat32Bits'](temp, x);
+ return Module['_BinaryenConst'](module, temp);
},
'neg': function(value) {
return Module['_BinaryenUnary'](module, Module['NegFloat32'], value);
@@ -901,12 +901,12 @@ Module['Module'] = function(module) {
return Module['_BinaryenStore'](module, 8, offset, align, ptr, value, Module['f64']);
},
'const': function(x) {
- Module['_BinaryenLiteralFloat64'](literal, x);
- return Module['_BinaryenConst'](module, literal);
+ Module['_BinaryenLiteralFloat64'](temp, x);
+ return Module['_BinaryenConst'](module, temp);
},
'const_bits': function(x, y) {
- Module['_BinaryenLiteralFloat64Bits'](literal, x, y);
- return Module['_BinaryenConst'](module, literal);
+ Module['_BinaryenLiteralFloat64Bits'](temp, x, y);
+ return Module['_BinaryenConst'](module, temp);
},
'neg': function(value) {
return Module['_BinaryenUnary'](module, Module['NegFloat64'], value);
@@ -1185,16 +1185,42 @@ Module['Module'] = function(module) {
Module['_BinaryenModuleDispose'](module);
};
var MAX = 1024*1024; // TODO: fix this hard-wired limit
- var writeBuffer = null;
- this['emitBinary'] = function() {
- if (!writeBuffer) writeBuffer = _malloc(MAX);
- var bytes = Module['_BinaryenModuleWrite'](module, writeBuffer, MAX);
+ var outputBuffer = null;
+ var sourceMapBuffer = null;
+ this['emitBinary'] = function(sourceMapUrl) {
+ if (!outputBuffer) outputBuffer = _malloc(MAX);
+ var bytes = Module['_BinaryenModuleWrite'](module, outputBuffer, MAX);
assert(bytes < MAX, 'FIXME: hardcoded limit on module size'); // we should not use the whole buffer
- return new Uint8Array(HEAPU8.subarray(writeBuffer, writeBuffer + bytes));
+ return new Uint8Array(HEAPU8.subarray(outputBuffer, outputBuffer + bytes));
+ };
+ this['emitBinaryWithSourceMap'] = function(sourceMapUrl) {
+ if (!outputBuffer) outputBuffer = _malloc(MAX);
+ if (!sourceMapBuffer) sourceMapBuffer = _malloc(MAX);
+ return preserveStack(function() {
+ Module['_BinaryenModuleWriteWithSourceMap'](temp, module, strToStack(sourceMapUrl), outputBuffer, MAX, sourceMapBuffer, MAX);
+ var outputBytes = HEAPU32[temp >>> 2];
+ var sourceMapBytes = HEAPU32[(temp + 1) >>> 2];
+ assert(outputBytes < MAX && sourceMapBytes < MAX, 'FIXME: hardcoded limit on module size'); // see above
+ return {
+ 'binary': new Uint8Array(HEAPU8.subarray(outputBuffer, outputBuffer + outputBytes)),
+ 'sourceMap': Pointer_stringify(sourceMapBuffer)
+ };
+ });
};
this['interpret'] = function() {
return Module['_BinaryenModuleInterpret'](module);
};
+ this['addDebugInfoFileName'] = function(filename) {
+ return preserveStack(function() {
+ return Module['_BinaryenModuleAddDebugInfoFileName'](module, strToStack(filename));
+ });
+ };
+ this['getDebugInfoFileName'] = function(index) {
+ return Pointer_stringify(Module['_BinaryenModuleGetDebugInfoFileName'](module, index));
+ };
+ this['setDebugLocation'] = function(func, expr, fileIndex, lineNumber, columnNumber) {
+ return Module['_BinaryenFunctionSetDebugLocation'](func, expr, fileIndex, lineNumber, columnNumber);
+ };
};
// 'Relooper' interface