summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Wirtz <dcode@dcode.io>2019-03-13 16:58:45 +0100
committerAlon Zakai <alonzakai@gmail.com>2019-03-13 08:58:45 -0700
commit65446aeade5b5a1acab6ae2a605ae1702251fda2 (patch)
tree5f6fe5423bfa98248f2d64b21ea9b142ce2bd45c /src
parentf0ec4b02fb797387040c65d63f690b3856b1183e (diff)
downloadbinaryen-65446aeade5b5a1acab6ae2a605ae1702251fda2.tar.gz
binaryen-65446aeade5b5a1acab6ae2a605ae1702251fda2.tar.bz2
binaryen-65446aeade5b5a1acab6ae2a605ae1702251fda2.zip
Add BinaryenConstGetValueV128 to C/JS-API (#1931)
This PR adds void BinaryenConstGetValueV128(BinaryenExpressionRef expr, uint8_t* out); to the C-API and uses it in Binaryen.getExpressionInfo in the JS-API.
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp17
-rw-r--r--src/binaryen-c.h1
-rw-r--r--src/js/binaryen.js-post.js95
3 files changed, 80 insertions, 33 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index c554b0a23..71cd92da4 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -1616,6 +1616,15 @@ double BinaryenConstGetValueF64(BinaryenExpressionRef expr) {
assert(expression->is<Const>());
return static_cast<Const*>(expression)->value.getf64();
}
+void BinaryenConstGetValueV128(BinaryenExpressionRef expr, uint8_t* out) {
+ if (tracing) {
+ std::cout << " BinaryenConstGetValueV128(expressions[" << expressions[expr] << "], " << out << ");\n";
+ }
+
+ auto* expression = (Expression*)expr;
+ assert(expression->is<Const>());
+ memcpy(out, static_cast<Const*>(expression)->value.getv128().data(), 16);
+}
// Unary
BinaryenOp BinaryenUnaryGetOp(BinaryenExpressionRef expr) {
if (tracing) {
@@ -1945,7 +1954,7 @@ BinaryenExpressionRef BinaryenSIMDShuffleGetRight(BinaryenExpressionRef expr) {
}
void BinaryenSIMDShuffleGetMask(BinaryenExpressionRef expr, uint8_t *mask) {
if (tracing) {
- std::cout << " BinaryenSIMDShuffleGetMask(expressions[" << expressions[expr] << "]);\n";
+ std::cout << " BinaryenSIMDShuffleGetMask(expressions[" << expressions[expr] << "], " << mask << ");\n";
}
auto* expression = (Expression*)expr;
@@ -3067,6 +3076,12 @@ size_t BinaryenSizeofLiteral(void) {
return sizeof(Literal);
}
+// Returns the size of an allocate and write result object.
+EMSCRIPTEN_KEEPALIVE
+size_t BinaryenSizeofAllocateAndWriteResult(void) {
+ return sizeof(BinaryenModuleAllocateAndWriteResult);
+}
+
#endif
} // extern "C"
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 5355ceeeb..787bfb242 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -618,6 +618,7 @@ int32_t BinaryenConstGetValueI64Low(BinaryenExpressionRef expr);
int32_t BinaryenConstGetValueI64High(BinaryenExpressionRef expr);
float BinaryenConstGetValueF32(BinaryenExpressionRef expr);
double BinaryenConstGetValueF64(BinaryenExpressionRef expr);
+void BinaryenConstGetValueV128(BinaryenExpressionRef expr, uint8_t* out);
BinaryenOp BinaryenUnaryGetOp(BinaryenExpressionRef expr);
BinaryenExpressionRef BinaryenUnaryGetValue(BinaryenExpressionRef expr);
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 1eef5757e..aee41255c 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -365,6 +365,13 @@ Module['ConvertUVecI32x4ToVecF32x4'] = Module['_BinaryenConvertUVecI32x4ToVecF32
Module['ConvertSVecI64x2ToVecF64x2'] = Module['_BinaryenConvertSVecI64x2ToVecF64x2']();
Module['ConvertUVecI64x2ToVecF64x2'] = Module['_BinaryenConvertUVecI64x2ToVecF64x2']();
+// The size of a single literal in memory as used in Const creation,
+// which is a little different: we don't want users to need to make
+// their own Literals, as the C API handles them by value, which means
+// we would leak them. Instead, Const creation is fused together with
+// an intermediate stack allocation of this size to pass the value.
+var sizeOfLiteral = _BinaryenSizeofLiteral();
+
// 'Module' interface
Module['Module'] = function(module) {
assert(!module); // guard against incorrect old API usage
@@ -482,13 +489,6 @@ function wrapModule(module, self) {
}
}
- // The Const creation API is a little different: we don't want users to
- // 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 temp = _malloc(Module['_BinaryenSizeofLiteral']()); // a single literal in memory. the LLVM C ABI
- // makes us pass pointers to this.
-
self['i32'] = {
'load': function(offset, align, ptr) {
return Module['_BinaryenLoad'](module, 4, true, offset, align, Module['i32'], ptr);
@@ -515,8 +515,11 @@ function wrapModule(module, self) {
return Module['_BinaryenStore'](module, 2, offset, align, ptr, value, Module['i32']);
},
'const': function(x) {
- Module['_BinaryenLiteralInt32'](temp, x);
- return Module['_BinaryenConst'](module, temp);
+ return preserveStack(function() {
+ var tempLiteral = stackAlloc(sizeOfLiteral);
+ Module['_BinaryenLiteralInt32'](tempLiteral, x);
+ return Module['_BinaryenConst'](module, tempLiteral);
+ });
},
'clz': function(value) {
return Module['_BinaryenUnary'](module, Module['ClzInt32'], value);
@@ -778,8 +781,11 @@ function wrapModule(module, self) {
return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i64']);
},
'const': function(x, y) {
- Module['_BinaryenLiteralInt64'](temp, x, y);
- return Module['_BinaryenConst'](module, temp);
+ return preserveStack(function() {
+ var tempLiteral = stackAlloc(sizeOfLiteral);
+ Module['_BinaryenLiteralInt64'](tempLiteral, x, y);
+ return Module['_BinaryenConst'](module, tempLiteral);
+ });
},
'clz': function(value) {
return Module['_BinaryenUnary'](module, Module['ClzInt64'], value);
@@ -1049,12 +1055,18 @@ function wrapModule(module, self) {
return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['f32']);
},
'const': function(x) {
- Module['_BinaryenLiteralFloat32'](temp, x);
- return Module['_BinaryenConst'](module, temp);
+ return preserveStack(function() {
+ var tempLiteral = stackAlloc(sizeOfLiteral);
+ Module['_BinaryenLiteralFloat32'](tempLiteral, x);
+ return Module['_BinaryenConst'](module, tempLiteral);
+ });
},
'const_bits': function(x) {
- Module['_BinaryenLiteralFloat32Bits'](temp, x);
- return Module['_BinaryenConst'](module, temp);
+ return preserveStack(function() {
+ var tempLiteral = stackAlloc(sizeOfLiteral);
+ Module['_BinaryenLiteralFloat32Bits'](tempLiteral, x);
+ return Module['_BinaryenConst'](module, tempLiteral);
+ });
},
'neg': function(value) {
return Module['_BinaryenUnary'](module, Module['NegFloat32'], value);
@@ -1148,12 +1160,18 @@ function wrapModule(module, self) {
return Module['_BinaryenStore'](module, 8, offset, align, ptr, value, Module['f64']);
},
'const': function(x) {
- Module['_BinaryenLiteralFloat64'](temp, x);
- return Module['_BinaryenConst'](module, temp);
+ return preserveStack(function() {
+ var tempLiteral = stackAlloc(sizeOfLiteral);
+ Module['_BinaryenLiteralFloat64'](tempLiteral, x);
+ return Module['_BinaryenConst'](module, tempLiteral);
+ });
},
'const_bits': function(x, y) {
- Module['_BinaryenLiteralFloat64Bits'](temp, x, y);
- return Module['_BinaryenConst'](module, temp);
+ return preserveStack(function() {
+ var tempLiteral = stackAlloc(sizeOfLiteral);
+ Module['_BinaryenLiteralFloat64Bits'](tempLiteral, x, y);
+ return Module['_BinaryenConst'](module, tempLiteral);
+ });
},
'neg': function(value) {
return Module['_BinaryenUnary'](module, Module['NegFloat64'], value);
@@ -1248,8 +1266,9 @@ function wrapModule(module, self) {
},
'const': function(i8s) {
return preserveStack(function() {
- Module['_BinaryenLiteralVec128'](temp, i8sToStack(i8s));
- return Module['_BinaryenConst'](module, temp);
+ var tempLiteral = stackAlloc(sizeOfLiteral);
+ Module['_BinaryenLiteralVec128'](tempLiteral, i8sToStack(i8s));
+ return Module['_BinaryenConst'](module, tempLiteral);
});
},
'not': function(value) {
@@ -1729,7 +1748,7 @@ function wrapModule(module, self) {
});
};
self['removeFunctionType'] = function(name) {
- return preserveStack(function () {
+ return preserveStack(function() {
return Module['_BinaryenRemoveFunctionType'](module, strToStack(name));
});
};
@@ -1754,7 +1773,7 @@ function wrapModule(module, self) {
});
}
self['removeGlobal'] = function(name) {
- return preserveStack(function () {
+ return preserveStack(function() {
return Module['_BinaryenRemoveGlobal'](module, strToStack(name));
});
}
@@ -1900,10 +1919,11 @@ function wrapModule(module, self) {
};
self['emitBinary'] = function(sourceMapUrl) {
return preserveStack(function() {
- Module['_BinaryenModuleAllocateAndWrite'](temp, module, strToStack(sourceMapUrl));
- var binaryPtr = HEAPU32[ temp >>> 2 ];
- var binaryBytes = HEAPU32[(temp >>> 2) + 1];
- var sourceMapPtr = HEAPU32[(temp >>> 2) + 2];
+ var tempBuffer = stackAlloc(_BinaryenSizeofAllocateAndWriteResult());
+ Module['_BinaryenModuleAllocateAndWrite'](tempBuffer, module, strToStack(sourceMapUrl));
+ var binaryPtr = HEAPU32[ tempBuffer >>> 2 ];
+ var binaryBytes = HEAPU32[(tempBuffer >>> 2) + 1];
+ var sourceMapPtr = HEAPU32[(tempBuffer >>> 2) + 2];
try {
var buffer = new Uint8Array(binaryBytes);
buffer.set(HEAPU8.subarray(binaryPtr, binaryPtr + binaryBytes));
@@ -2090,7 +2110,18 @@ Module['getExpressionInfo'] = function(expr) {
case Module['i32']: value = Module['_BinaryenConstGetValueI32'](expr); break;
case Module['i64']: value = { 'low': Module['_BinaryenConstGetValueI64Low'](expr), 'high': Module['_BinaryenConstGetValueI64High'](expr) }; break;
case Module['f32']: value = Module['_BinaryenConstGetValueF32'](expr); break;
- case Module['f64']: value = Module['_BinaryenConstGetValueF64'](expr); break;
+ case Module['f64']: value = Module['_BinaryenConstGetValueF64'](expr); break;
+ case Module['v128']: {
+ preserveStack(function() {
+ var tempBuffer = stackAlloc(16);
+ Module['_BinaryenConstGetValueV128'](expr, tempBuffer);
+ value = new Array(16);
+ for (var i = 0 ; i < 16; i++) {
+ value[i] = HEAPU8[tempBuffer + i];
+ }
+ });
+ break;
+ }
default: throw Error('unexpected type: ' + type);
}
return {
@@ -2203,11 +2234,11 @@ Module['getExpressionInfo'] = function(expr) {
};
case Module['SIMDShuffleId']:
return preserveStack(function() {
- var ret = stackAlloc(16);
- Module['_BinaryenSIMDShuffleGetMask'](expr, ret);
- var mask = [];
+ var tempBuffer = stackAlloc(16);
+ Module['_BinaryenSIMDShuffleGetMask'](expr, tempBuffer);
+ var mask = new Array(16);
for (var i = 0 ; i < 16; i++) {
- mask[i] = HEAP8[ret + i];
+ mask[i] = HEAPU8[tempBuffer + i];
}
return {
'id': id,