diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 8e8c295f2ca..18378fe8e02 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1796,7 +1796,16 @@ BinaryenExpressionRef BinaryenArrayNewData(BinaryenModuleRef module, .makeArrayNewData( HeapType(type), name, (Expression*)offset, (Expression*)size)); } - +BinaryenExpressionRef BinaryenArrayNewElem(BinaryenModuleRef module, + BinaryenHeapType type, + const char* name, + BinaryenExpressionRef offset, + BinaryenExpressionRef size) { + return static_cast( + Builder(*(Module*)module) + .makeArrayNewElem( + HeapType(type), name, (Expression*)offset, (Expression*)size)); +} BinaryenExpressionRef BinaryenArrayNewFixed(BinaryenModuleRef module, BinaryenHeapType type, BinaryenExpressionRef* values, @@ -1843,6 +1852,43 @@ BinaryenExpressionRef BinaryenArrayCopy(BinaryenModuleRef module, (Expression*)srcIndex, (Expression*)length)); } +BinaryenExpressionRef BinaryenArrayFill(BinaryenModuleRef module, + BinaryenExpressionRef ref, + BinaryenExpressionRef index, + BinaryenExpressionRef value, + BinaryenExpressionRef size) { + return static_cast(Builder(*(Module*)module) + .makeArrayFill((Expression*)ref, + (Expression*)index, + (Expression*)value, + (Expression*)size)); +} +BinaryenExpressionRef BinaryenArrayInitData(BinaryenModuleRef module, + const char* name, + BinaryenExpressionRef ref, + BinaryenExpressionRef index, + BinaryenExpressionRef offset, + BinaryenExpressionRef size) { + return static_cast(Builder(*(Module*)module) + .makeArrayInitData(name, + (Expression*)ref, + (Expression*)index, + (Expression*)offset, + (Expression*)size)); +} +BinaryenExpressionRef BinaryenArrayInitElem(BinaryenModuleRef module, + const char* seg, + BinaryenExpressionRef ref, + BinaryenExpressionRef index, + BinaryenExpressionRef offset, + BinaryenExpressionRef size) { + return static_cast(Builder(*(Module*)module) + .makeArrayInitElem(seg, + (Expression*)ref, + (Expression*)index, + (Expression*)offset, + (Expression*)size)); +} BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module, BinaryenOp op, BinaryenExpressionRef ptr, @@ -4276,6 +4322,76 @@ BinaryenArrayNewFixedRemoveValueAt(BinaryenExpressionRef expr, assert(expression->is()); return static_cast(expression)->values.removeAt(index); } +// ArrayNewData +const char* BinaryenArrayNewDataGetSegment(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->segment.str.data(); +} +void BinaryenArrayNewDataSetSegment(BinaryenExpressionRef expr, + const char* segment) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->segment = Name(segment); +} +BinaryenExpressionRef +BinaryenArrayNewDataGetOffset(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->offset; +} +void BinaryenArrayNewDataSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} +BinaryenExpressionRef BinaryenArrayNewDataGetSize(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->size; +} +void BinaryenArrayNewDataSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->size = size; +} +// ArrayNewElem +const char* BinaryenArrayNewElemGetSegment(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->segment.str.data(); +} +void BinaryenArrayNewElemSetSegment(BinaryenExpressionRef expr, + const char* segment) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->segment = Name(segment); +} +BinaryenExpressionRef +BinaryenArrayNewElemGetOffset(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->offset; +} +void BinaryenArrayNewElemSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} +BinaryenExpressionRef BinaryenArrayNewElemGetSize(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->size; +} +void BinaryenArrayNewElemSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->size = size; +} // ArrayGet BinaryenExpressionRef BinaryenArrayGetGetRef(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; @@ -4361,6 +4477,55 @@ void BinaryenArrayLenSetRef(BinaryenExpressionRef expr, assert(refExpr); static_cast(expression)->ref = (Expression*)refExpr; } +// ArrayFill +BinaryenExpressionRef BinaryenArrayFillGetRef(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->ref; +} +void BinaryenArrayFillSetRef(BinaryenExpressionRef expr, + BinaryenExpressionRef refExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(refExpr); + static_cast(expression)->ref = (Expression*)refExpr; +} +BinaryenExpressionRef BinaryenArrayFillGetIndex(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->index; +} +void BinaryenArrayFillSetIndex(BinaryenExpressionRef expr, + BinaryenExpressionRef indexExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(indexExpr); + static_cast(expression)->index = (Expression*)indexExpr; +} +BinaryenExpressionRef BinaryenArrayFillGetValue(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->value; +} +void BinaryenArrayFillSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(valueExpr); + static_cast(expression)->value = (Expression*)valueExpr; +} +BinaryenExpressionRef BinaryenArrayFillGetSize(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->size; +} +void BinaryenArrayFillSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + assert(sizeExpr); + static_cast(expression)->size = (Expression*)sizeExpr; +} // ArrayCopy BinaryenExpressionRef BinaryenArrayCopyGetDestRef(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; @@ -4423,6 +4588,122 @@ void BinaryenArrayCopySetLength(BinaryenExpressionRef expr, assert(lengthExpr); static_cast(expression)->length = (Expression*)lengthExpr; } +// ArrayInitData +const char* BinaryenArrayInitDataGetSegment(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->segment.str.data(); +} +void BinaryenArrayInitDataSetSegment(BinaryenExpressionRef expr, + const char* segment) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->segment = Name(segment); +} +BinaryenExpressionRef BinaryenArrayInitDataGetRef(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->ref; +} +void BinaryenArrayInitDataSetRef(BinaryenExpressionRef expr, + BinaryenExpressionRef ref) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->ref = ref; +} +BinaryenExpressionRef +BinaryenArrayInitDataGetIndex(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->index; +} +void BinaryenArrayInitDataSetIndex(BinaryenExpressionRef expr, + BinaryenExpressionRef index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->index = index; +} +BinaryenExpressionRef +BinaryenArrayInitDataGetOffset(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->offset; +} +void BinaryenArrayInitDataSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} +BinaryenExpressionRef BinaryenArrayInitDataGetSize(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->size; +} +void BinaryenArrayInitDataSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->size = size; +} +// ArrayInitElem +const char* BinaryenArrayInitElemGetSegment(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->segment.str.data(); +} +void BinaryenArrayInitElemSetSegment(BinaryenExpressionRef expr, + const char* segment) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->segment = Name(segment); +} +BinaryenExpressionRef BinaryenArrayInitElemGetRef(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->ref; +} +void BinaryenArrayInitElemSetRef(BinaryenExpressionRef expr, + BinaryenExpressionRef ref) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->ref = ref; +} +BinaryenExpressionRef +BinaryenArrayInitElemGetIndex(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->index; +} +void BinaryenArrayInitElemSetIndex(BinaryenExpressionRef expr, + BinaryenExpressionRef index) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->index = index; +} +BinaryenExpressionRef +BinaryenArrayInitElemGetOffset(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->offset; +} +void BinaryenArrayInitElemSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->offset = offset; +} +BinaryenExpressionRef BinaryenArrayInitElemGetSize(BinaryenExpressionRef expr) { + auto* expression = (Expression*)expr; + assert(expression->is()); + return static_cast(expression)->size; +} +void BinaryenArrayInitElemSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size) { + auto* expression = (Expression*)expr; + assert(expression->is()); + static_cast(expression)->size = size; +} // StringNew BinaryenOp BinaryenStringNewGetOp(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 65a2f12f451..67948d8b79c 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -1050,7 +1050,6 @@ BINARYEN_API BinaryenExpressionRef BinaryenArrayNew(BinaryenModuleRef module, BinaryenHeapType type, BinaryenExpressionRef size, BinaryenExpressionRef init); - BINARYEN_API BinaryenExpressionRef BinaryenArrayNewData(BinaryenModuleRef module, BinaryenHeapType type, @@ -1058,6 +1057,12 @@ BinaryenArrayNewData(BinaryenModuleRef module, BinaryenExpressionRef offset, BinaryenExpressionRef size); BINARYEN_API BinaryenExpressionRef +BinaryenArrayNewElem(BinaryenModuleRef module, + BinaryenHeapType type, + const char* seg, + BinaryenExpressionRef offset, + BinaryenExpressionRef size); +BINARYEN_API BinaryenExpressionRef BinaryenArrayNewFixed(BinaryenModuleRef module, BinaryenHeapType type, BinaryenExpressionRef* values, @@ -1082,11 +1087,31 @@ BinaryenArrayCopy(BinaryenModuleRef module, BinaryenExpressionRef srcIndex, BinaryenExpressionRef length); BINARYEN_API BinaryenExpressionRef +BinaryenArrayFill(BinaryenModuleRef module, + BinaryenExpressionRef ref, + BinaryenExpressionRef index, + BinaryenExpressionRef value, + BinaryenExpressionRef size); +BINARYEN_API BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module, BinaryenOp op, BinaryenExpressionRef ref, BinaryenExpressionRef start, BinaryenExpressionRef end); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitData(BinaryenModuleRef module, + const char* name, + BinaryenExpressionRef ref, + BinaryenExpressionRef index, + BinaryenExpressionRef offset, + BinaryenExpressionRef size); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitElem(BinaryenModuleRef module, + const char* seg, + BinaryenExpressionRef ref, + BinaryenExpressionRef index, + BinaryenExpressionRef offset, + BinaryenExpressionRef size); BINARYEN_API BinaryenExpressionRef BinaryenStringConst(BinaryenModuleRef module, const char* name); BINARYEN_API BinaryenExpressionRef BinaryenStringMeasure( @@ -2444,6 +2469,36 @@ BinaryenArrayNewFixedInsertValueAt(BinaryenExpressionRef expr, BINARYEN_API BinaryenExpressionRef BinaryenArrayNewFixedRemoveValueAt( BinaryenExpressionRef expr, BinaryenIndex index); +// ArrayNewData + +BINARYEN_API const char* +BinaryenArrayNewDataGetSegment(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayNewDataSetSegment(BinaryenExpressionRef expr, + const char* segment); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayNewDataGetOffset(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayNewDataSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayNewDataGetSize(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayNewDataSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size); + +// ArrayNewElem + +BINARYEN_API const char* +BinaryenArrayNewElemGetSegment(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayNewElemSetSegment(BinaryenExpressionRef expr, + const char* segment); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayNewElemGetOffset(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayNewElemSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayNewElemGetSize(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayNewElemSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size); + // ArrayGet BINARYEN_API BinaryenExpressionRef @@ -2480,6 +2535,25 @@ BinaryenArrayLenGetRef(BinaryenExpressionRef expr); BINARYEN_API void BinaryenArrayLenSetRef(BinaryenExpressionRef expr, BinaryenExpressionRef refExpr); +// ArrayFill + +BINARYEN_API BinaryenExpressionRef +BinaryenArrayFillGetRef(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayFillSetRef(BinaryenExpressionRef expr, + BinaryenExpressionRef refExpr); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayFillGetIndex(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayFillSetIndex(BinaryenExpressionRef expr, + BinaryenExpressionRef indexExpr); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayFillGetValue(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayFillSetValue(BinaryenExpressionRef expr, + BinaryenExpressionRef valueExpr); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayFillGetSize(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayFillSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef sizeExpr); + // ArrayCopy BINARYEN_API BinaryenExpressionRef @@ -2506,6 +2580,52 @@ BinaryenArrayCopyGetLength(BinaryenExpressionRef expr); BINARYEN_API void BinaryenArrayCopySetLength(BinaryenExpressionRef expr, BinaryenExpressionRef lengthExpr); +// ArrayInitData + +BINARYEN_API const char* +BinaryenArrayInitDataGetSegment(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitDataSetSegment(BinaryenExpressionRef expr, + const char* segment); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitDataGetRef(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitDataSetRef(BinaryenExpressionRef expr, + BinaryenExpressionRef ref); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitDataGetIndex(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitDataSetIndex(BinaryenExpressionRef expr, + BinaryenExpressionRef index); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitDataGetOffset(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitDataSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitDataGetSize(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitDataSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size); + +// ArrayInitElem + +BINARYEN_API const char* +BinaryenArrayInitElemGetSegment(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitElemSetSegment(BinaryenExpressionRef expr, + const char* segment); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitElemGetRef(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitElemSetRef(BinaryenExpressionRef expr, + BinaryenExpressionRef ref); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitElemGetIndex(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitElemSetIndex(BinaryenExpressionRef expr, + BinaryenExpressionRef index); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitElemGetOffset(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitElemSetOffset(BinaryenExpressionRef expr, + BinaryenExpressionRef offset); +BINARYEN_API BinaryenExpressionRef +BinaryenArrayInitElemGetSize(BinaryenExpressionRef expr); +BINARYEN_API void BinaryenArrayInitElemSetSize(BinaryenExpressionRef expr, + BinaryenExpressionRef size); + // StringNew BINARYEN_API BinaryenOp BinaryenStringNewGetOp(BinaryenExpressionRef expr); diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 6d886d26b1d..5521cc6cca8 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -40,12 +40,22 @@ function initializeConstants() { ['i31ref', 'I31ref'], ['structref', 'Structref'], ['stringref', 'Stringref'], + ['nullref', 'Nullref'], + ['nullexternref', 'NullExternref'], + ['nullfuncref', 'NullFuncref'], ['unreachable', 'Unreachable'], ['auto', 'Auto'] ].forEach(entry => { Module[entry[0]] = Module['_BinaryenType' + entry[1]](); }); + [ ['notPacked', 'NotPacked'], + ['i8', 'Int8'], + ['i16', 'Int16'] + ].forEach(entry => { + Module[entry[0]] = Module['_BinaryenPackedType' + entry[1]](); + }); + // Expression ids Module['ExpressionIds'] = {}; [ 'Invalid', @@ -113,10 +123,15 @@ function initializeConstants() { 'StructSet', 'ArrayNew', 'ArrayNewFixed', + 'ArrayNewData', + 'ArrayNewElem', 'ArrayGet', 'ArraySet', 'ArrayLen', + 'ArrayFill', 'ArrayCopy', + 'ArrayInitData', + 'ArrayInitElem', 'RefAs', 'StringNew', 'StringConst', @@ -705,54 +720,54 @@ function wrapModule(module, self = {}) { self['global'] = { 'get'(name, type) { - return Module['_BinaryenGlobalGet'](module, strToStack(name), type); + return preserveStack(() => Module['_BinaryenGlobalGet'](module, strToStack(name), type)); }, 'set'(name, value) { - return Module['_BinaryenGlobalSet'](module, strToStack(name), value); + return preserveStack(() => Module['_BinaryenGlobalSet'](module, strToStack(name), value)); } } self['table'] = { 'get'(name, index, type) { - return Module['_BinaryenTableGet'](module, strToStack(name), index, type); + return preserveStack(() => Module['_BinaryenTableGet'](module, strToStack(name), index, type)); }, 'set'(name, index, value) { - return Module['_BinaryenTableSet'](module, strToStack(name), index, value); + return preserveStack(() => Module['_BinaryenTableSet'](module, strToStack(name), index, value)); }, 'size'(name) { - return Module['_BinaryenTableSize'](module, strToStack(name)); + return preserveStack(() => Module['_BinaryenTableSize'](module, strToStack(name))); }, 'grow'(name, value, delta) { - return Module['_BinaryenTableGrow'](module, strToStack(name), value, delta); + return preserveStack(() => Module['_BinaryenTableGrow'](module, strToStack(name), value, delta)); } } self['memory'] = { // memory64 defaults to undefined/false. 'size'(name, memory64) { - return Module['_BinaryenMemorySize'](module, strToStack(name), memory64); + return preserveStack(() => Module['_BinaryenMemorySize'](module, strToStack(name), memory64)); }, 'grow'(value, name, memory64) { - return Module['_BinaryenMemoryGrow'](module, value, strToStack(name), memory64); + return preserveStack(() => Module['_BinaryenMemoryGrow'](module, value, strToStack(name), memory64)); }, 'init'(segment, dest, offset, size, name) { return preserveStack(() => Module['_BinaryenMemoryInit'](module, strToStack(segment), dest, offset, size, strToStack(name))); }, 'copy'(dest, source, size, destMemory, sourceMemory) { - return Module['_BinaryenMemoryCopy'](module, dest, source, size, strToStack(destMemory), strToStack(sourceMemory)); + return preserveStack(() => Module['_BinaryenMemoryCopy'](module, dest, source, size, strToStack(destMemory), strToStack(sourceMemory))); }, 'fill'(dest, value, size, name) { - return Module['_BinaryenMemoryFill'](module, dest, value, size, strToStack(name)); + return preserveStack(() => Module['_BinaryenMemoryFill'](module, dest, value, size, strToStack(name))); }, 'atomic': { 'notify'(ptr, notifyCount, name) { - return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicNotify'](module, ptr, notifyCount, strToStack(name))); }, 'wait32'(ptr, expected, timeout, name) { - return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32'], strToStack(name))); }, 'wait64'(ptr, expected, timeout, name) { - return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64'], strToStack(name))); } } } @@ -765,28 +780,28 @@ function wrapModule(module, self = {}) { self['i32'] = { 'load'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 4, true, offset, align, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 4, true, offset, align, Module['i32'], ptr, strToStack(name))); }, 'load8_s'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 1, true, offset, align, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 1, true, offset, align, Module['i32'], ptr, strToStack(name))); }, 'load8_u'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 1, false, offset, align, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 1, false, offset, align, Module['i32'], ptr, strToStack(name))); }, 'load16_s'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 2, true, offset, align, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 2, true, offset, align, Module['i32'], ptr, strToStack(name))); }, 'load16_u'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 2, false, offset, align, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 2, false, offset, align, Module['i32'], ptr, strToStack(name))); }, 'store'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i32'], strToStack(name))); }, 'store8'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 1, offset, align, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 1, offset, align, ptr, value, Module['i32'], strToStack(name))); }, 'store16'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 2, offset, align, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 2, offset, align, ptr, value, Module['i32'], strToStack(name))); }, 'const'(x) { return preserveStack(() => { @@ -928,90 +943,111 @@ function wrapModule(module, self = {}) { }, 'atomic': { 'load'(offset, ptr, name) { - return Module['_BinaryenAtomicLoad'](module, 4, offset, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicLoad'](module, 4, offset, Module['i32'], ptr, strToStack(name))); }, 'load8_u'(offset, ptr, name) { - return Module['_BinaryenAtomicLoad'](module, 1, offset, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicLoad'](module, 1, offset, Module['i32'], ptr, strToStack(name))); }, 'load16_u'(offset, ptr, name) { - return Module['_BinaryenAtomicLoad'](module, 2, offset, Module['i32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicLoad'](module, 2, offset, Module['i32'], ptr, strToStack(name))); }, 'store'(offset, ptr, value, name) { - return Module['_BinaryenAtomicStore'](module, 4, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicStore'](module, 4, offset, ptr, value, Module['i32'], strToStack(name))); }, 'store8'(offset, ptr, value, name) { - return Module['_BinaryenAtomicStore'](module, 1, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicStore'](module, 1, offset, ptr, value, Module['i32'], strToStack(name))); }, 'store16'(offset, ptr, value, name) { - return Module['_BinaryenAtomicStore'](module, 2, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicStore'](module, 2, offset, ptr, value, Module['i32'], strToStack(name))); }, 'rmw': { 'add'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 4, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 4, offset, ptr, value, Module['i32'], strToStack(name))); }, 'sub'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 4, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 4, offset, ptr, value, Module['i32'], strToStack(name))); }, 'and'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 4, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 4, offset, ptr, value, Module['i32'], strToStack(name))); }, 'or'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 4, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 4, offset, ptr, value, Module['i32'], strToStack(name))); }, 'xor'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 4, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 4, offset, ptr, value, Module['i32'], strToStack(name))); }, 'xchg'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 4, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 4, offset, ptr, value, Module['i32'], strToStack(name))); }, 'cmpxchg'(offset, ptr, expected, replacement, name) { - return Module['_BinaryenAtomicCmpxchg'](module, 4, offset, ptr, expected, replacement, Module['i32'], strToStack(name)) + return preserveStack(() => + Module['_BinaryenAtomicCmpxchg'](module, 4, offset, ptr, expected, replacement, Module['i32'], strToStack(name))); }, }, 'rmw8_u': { 'add'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 1, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 1, offset, ptr, value, Module['i32'], strToStack(name))); }, 'sub'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 1, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 1, offset, ptr, value, Module['i32'], strToStack(name))); }, 'and'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 1, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 1, offset, ptr, value, Module['i32'], strToStack(name))); }, 'or'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 1, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 1, offset, ptr, value, Module['i32'], strToStack(name))); }, 'xor'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 1, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 1, offset, ptr, value, Module['i32'], strToStack(name))); }, 'xchg'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 1, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 1, offset, ptr, value, Module['i32'], strToStack(name))); }, 'cmpxchg'(offset, ptr, expected, replacement, name) { - return Module['_BinaryenAtomicCmpxchg'](module, 1, offset, ptr, expected, replacement, Module['i32'], strToStack(name)) + return preserveStack(() => + Module['_BinaryenAtomicCmpxchg'](module, 1, offset, ptr, expected, replacement, Module['i32'], strToStack(name))); }, }, 'rmw16_u': { 'add'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 2, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 2, offset, ptr, value, Module['i32'], strToStack(name))); }, 'sub'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 2, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 2, offset, ptr, value, Module['i32'], strToStack(name))); }, 'and'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 2, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 2, offset, ptr, value, Module['i32'], strToStack(name))); }, 'or'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 2, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 2, offset, ptr, value, Module['i32'], strToStack(name))); }, 'xor'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 2, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 2, offset, ptr, value, Module['i32'], strToStack(name))); }, 'xchg'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 2, offset, ptr, value, Module['i32'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 2, offset, ptr, value, Module['i32'], strToStack(name))); }, 'cmpxchg'(offset, ptr, expected, replacement, name) { - return Module['_BinaryenAtomicCmpxchg'](module, 2, offset, ptr, expected, replacement, Module['i32'], strToStack(name)) + return preserveStack(() => + Module['_BinaryenAtomicCmpxchg'](module, 2, offset, ptr, expected, replacement, Module['i32'], strToStack(name))); }, }, }, @@ -1022,37 +1058,37 @@ function wrapModule(module, self = {}) { self['i64'] = { 'load'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 8, true, offset, align, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 8, true, offset, align, Module['i64'], ptr, strToStack(name))); }, 'load8_s'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 1, true, offset, align, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 1, true, offset, align, Module['i64'], ptr, strToStack(name))); }, 'load8_u'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 1, false, offset, align, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 1, false, offset, align, Module['i64'], ptr, strToStack(name))); }, 'load16_s'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 2, true, offset, align, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 2, true, offset, align, Module['i64'], ptr, strToStack(name))); }, 'load16_u'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 2, false, offset, align, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 2, false, offset, align, Module['i64'], ptr, strToStack(name))); }, 'load32_s'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 4, true, offset, align, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 4, true, offset, align, Module['i64'], ptr, strToStack(name))); }, 'load32_u'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 4, false, offset, align, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 4, false, offset, align, Module['i64'], ptr, strToStack(name))); }, 'store'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 8, offset, align, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 8, offset, align, ptr, value, Module['i64'], strToStack(name))); }, 'store8'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 1, offset, align, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 1, offset, align, ptr, value, Module['i64'], strToStack(name))); }, 'store16'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 2, offset, align, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 2, offset, align, ptr, value, Module['i64'], strToStack(name))); }, 'store32'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i64'], strToStack(name))); }, 'const'(x, y) { return preserveStack(() => { @@ -1200,119 +1236,147 @@ function wrapModule(module, self = {}) { }, 'atomic': { 'load'(offset, ptr, name) { - return Module['_BinaryenAtomicLoad'](module, 8, offset, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicLoad'](module, 8, offset, Module['i64'], ptr, strToStack(name))); }, 'load8_u'(offset, ptr, name) { - return Module['_BinaryenAtomicLoad'](module, 1, offset, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicLoad'](module, 1, offset, Module['i64'], ptr, strToStack(name))); }, 'load16_u'(offset, ptr, name) { - return Module['_BinaryenAtomicLoad'](module, 2, offset, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicLoad'](module, 2, offset, Module['i64'], ptr, strToStack(name))); }, 'load32_u'(offset, ptr, name) { - return Module['_BinaryenAtomicLoad'](module, 4, offset, Module['i64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicLoad'](module, 4, offset, Module['i64'], ptr, strToStack(name))); }, 'store'(offset, ptr, value, name) { - return Module['_BinaryenAtomicStore'](module, 8, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicStore'](module, 8, offset, ptr, value, Module['i64'], strToStack(name))); }, 'store8'(offset, ptr, value, name) { - return Module['_BinaryenAtomicStore'](module, 1, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicStore'](module, 1, offset, ptr, value, Module['i64'], strToStack(name))); }, 'store16'(offset, ptr, value, name) { - return Module['_BinaryenAtomicStore'](module, 2, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicStore'](module, 2, offset, ptr, value, Module['i64'], strToStack(name))); }, 'store32'(offset, ptr, value, name) { - return Module['_BinaryenAtomicStore'](module, 4, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenAtomicStore'](module, 4, offset, ptr, value, Module['i64'], strToStack(name))); }, 'rmw': { 'add'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 8, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 8, offset, ptr, value, Module['i64'], strToStack(name))); }, 'sub'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 8, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 8, offset, ptr, value, Module['i64'], strToStack(name))); }, 'and'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 8, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 8, offset, ptr, value, Module['i64'], strToStack(name))); }, 'or'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 8, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 8, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xor'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 8, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 8, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xchg'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 8, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 8, offset, ptr, value, Module['i64'], strToStack(name))); }, 'cmpxchg'(offset, ptr, expected, replacement, name) { - return Module['_BinaryenAtomicCmpxchg'](module, 8, offset, ptr, expected, replacement, Module['i64'], strToStack(name)) + return preserveStack(() => + Module['_BinaryenAtomicCmpxchg'](module, 8, offset, ptr, expected, replacement, Module['i64'], strToStack(name))); }, }, 'rmw8_u': { 'add'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 1, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 1, offset, ptr, value, Module['i64'], strToStack(name))); }, 'sub'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 1, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 1, offset, ptr, value, Module['i64'], strToStack(name))); }, 'and'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 1, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 1, offset, ptr, value, Module['i64'], strToStack(name))); }, 'or'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 1, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 1, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xor'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 1, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 1, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xchg'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 1, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 1, offset, ptr, value, Module['i64'], strToStack(name))); }, 'cmpxchg'(offset, ptr, expected, replacement, name) { - return Module['_BinaryenAtomicCmpxchg'](module, 1, offset, ptr, expected, replacement, Module['i64'], strToStack(name)) + return preserveStack(() => + Module['_BinaryenAtomicCmpxchg'](module, 1, offset, ptr, expected, replacement, Module['i64'], strToStack(name))); }, }, 'rmw16_u': { 'add'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 2, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 2, offset, ptr, value, Module['i64'], strToStack(name))); }, 'sub'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 2, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 2, offset, ptr, value, Module['i64'], strToStack(name))); }, 'and'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 2, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 2, offset, ptr, value, Module['i64'], strToStack(name))); }, 'or'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 2, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 2, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xor'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 2, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 2, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xchg'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 2, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 2, offset, ptr, value, Module['i64'], strToStack(name))); }, 'cmpxchg'(offset, ptr, expected, replacement, name) { - return Module['_BinaryenAtomicCmpxchg'](module, 2, offset, ptr, expected, replacement, Module['i64'], strToStack(name)) + return preserveStack(() => + Module['_BinaryenAtomicCmpxchg'](module, 2, offset, ptr, expected, replacement, Module['i64'], strToStack(name))); }, }, 'rmw32_u': { 'add'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 4, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAdd'], 4, offset, ptr, value, Module['i64'], strToStack(name))); }, 'sub'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 4, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWSub'], 4, offset, ptr, value, Module['i64'], strToStack(name))); }, 'and'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 4, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWAnd'], 4, offset, ptr, value, Module['i64'], strToStack(name))); }, 'or'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 4, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWOr'], 4, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xor'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 4, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXor'], 4, offset, ptr, value, Module['i64'], strToStack(name))); }, 'xchg'(offset, ptr, value, name) { - return Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 4, offset, ptr, value, Module['i64'], strToStack(name)); + return preserveStack(() => + Module['_BinaryenAtomicRMW'](module, Module['AtomicRMWXchg'], 4, offset, ptr, value, Module['i64'], strToStack(name))); }, 'cmpxchg'(offset, ptr, expected, replacement, name) { - return Module['_BinaryenAtomicCmpxchg'](module, 4, offset, ptr, expected, replacement, Module['i64'], strToStack(name)) + return preserveStack(() => + Module['_BinaryenAtomicCmpxchg'](module, 4, offset, ptr, expected, replacement, Module['i64'], strToStack(name))); }, }, }, @@ -1323,10 +1387,10 @@ function wrapModule(module, self = {}) { self['f32'] = { 'load'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 4, true, offset, align, Module['f32'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 4, true, offset, align, Module['f32'], ptr, strToStack(name))); }, 'store'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['f32'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['f32'], strToStack(name))); }, 'const'(x) { return preserveStack(() => { @@ -1431,10 +1495,10 @@ function wrapModule(module, self = {}) { self['f64'] = { 'load'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 8, true, offset, align, Module['f64'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 8, true, offset, align, Module['f64'], ptr, strToStack(name))); }, 'store'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 8, offset, align, ptr, value, Module['f64'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 8, offset, align, ptr, value, Module['f64'], strToStack(name))); }, 'const'(x) { return preserveStack(() => { @@ -1539,70 +1603,78 @@ function wrapModule(module, self = {}) { self['v128'] = { 'load'(offset, align, ptr, name) { - return Module['_BinaryenLoad'](module, 16, false, offset, align, Module['v128'], ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenLoad'](module, 16, false, offset, align, Module['v128'], ptr, strToStack(name))); }, 'load8_splat'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load8SplatVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load8SplatVec128'], offset, align, ptr, strToStack(name))); }, 'load16_splat'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load16SplatVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load16SplatVec128'], offset, align, ptr, strToStack(name))); }, 'load32_splat'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load32SplatVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load32SplatVec128'], offset, align, ptr, strToStack(name))); }, 'load64_splat'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load64SplatVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load64SplatVec128'], offset, align, ptr, strToStack(name))); }, 'load8x8_s'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load8x8SVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load8x8SVec128'], offset, align, ptr, strToStack(name))); }, 'load8x8_u'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load8x8UVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load8x8UVec128'], offset, align, ptr, strToStack(name))); }, 'load16x4_s'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load16x4SVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load16x4SVec128'], offset, align, ptr, strToStack(name))); }, 'load16x4_u'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load16x4UVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load16x4UVec128'], offset, align, ptr, strToStack(name))); }, 'load32x2_s'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load32x2SVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load32x2SVec128'], offset, align, ptr, strToStack(name))); }, 'load32x2_u'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load32x2UVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load32x2UVec128'], offset, align, ptr, strToStack(name))); }, 'load32_zero'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load32ZeroVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load32ZeroVec128'], offset, align, ptr, strToStack(name))); }, 'load64_zero'(offset, align, ptr, name) { - return Module['_BinaryenSIMDLoad'](module, Module['Load64ZeroVec128'], offset, align, ptr, strToStack(name)); + return preserveStack(() => Module['_BinaryenSIMDLoad'](module, Module['Load64ZeroVec128'], offset, align, ptr, strToStack(name))); }, 'load8_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load8LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load8LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'load16_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load16LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load16LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'load32_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load32LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load32LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'load64_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load64LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Load64LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'store8_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store8LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store8LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'store16_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store16LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store16LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'store32_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store32LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store32LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'store64_lane'(offset, align, index, ptr, vec, name) { - return Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store64LaneVec128'], offset, align, index, ptr, vec, strToStack(name)); + return preserveStack(() => + Module['_BinaryenSIMDLoadStoreLane'](module, Module['Store64LaneVec128'], offset, align, index, ptr, vec, strToStack(name))); }, 'store'(offset, align, ptr, value, name) { - return Module['_BinaryenStore'](module, 16, offset, align, ptr, value, Module['v128'], strToStack(name)); + return preserveStack(() => Module['_BinaryenStore'](module, 16, offset, align, ptr, value, Module['v128'], strToStack(name))); }, 'const'(i8s) { return preserveStack(() => { @@ -2333,6 +2405,12 @@ function wrapModule(module, self = {}) { }, 'eq'(left, right) { return Module['_BinaryenRefEq'](module, left, right); + }, + 'test'(value, castType) { + return Module['_BinaryenRefTest'](module, value, castType); + }, + 'cast'(value, castType) { + return Module['_BinaryenRefCast'](module, value, castType); } }; @@ -2366,7 +2444,7 @@ function wrapModule(module, self = {}) { return preserveStack(() => Module['_BinaryenThrow'](module, strToStack(tag), i32sToStack(operands), operands.length)); }; self['rethrow'] = function(target) { - return Module['_BinaryenRethrow'](module, strToStack(target)); + return preserveStack(() => Module['_BinaryenRethrow'](module, strToStack(target))); }; self['tuple'] = { @@ -2387,13 +2465,90 @@ function wrapModule(module, self = {}) { } }; - // TODO: any.convert_extern - // TODO: extern.convert_any - // TODO: ref.test - // TODO: ref.cast - // TODO: br_on_* - // TODO: struct.* - // TODO: array.* + self['any'] = { + 'convert_extern'() { + return Module['_BinaryenRefAsAnyConvertExtern'](); + } + }; + + self['extern'] = { + 'convert_any'() { + return Module['_BinaryenRefAsExternConvertAny'](); + } + }; + + self['br_on_null'] = function(name, value) { + return preserveStack(() => Module['_BinaryenBrOn'](module, Module['BrOnNull'], strToStack(name), value, Module['unreachable'])); + }; + + self['br_on_non_null'] = function(name, value) { + return preserveStack(() => Module['_BinaryenBrOn'](module, Module['BrOnNonNull'], strToStack(name), value, Module['unreachable'])); + }; + + self['br_on_cast'] = function(name, value, castType) { + return preserveStack(() => Module['_BinaryenBrOn'](module, Module['BrOnCast'], strToStack(name), value, castType)); + }; + + self['br_on_cast_fail'] = function(name, value, castType) { + return preserveStack(() => Module['_BinaryenBrOn'](module, Module['BrOnCastFail'], strToStack(name), value, castType)); + }; + + self['struct'] = { + 'new'(operands, type) { + return preserveStack(() => Module['_BinaryenStructNew'](module, i32sToStack(operands), operands.length, type)); + }, + 'new_default'(type) { + // Passing in null for |operands| (and 0 for |numOperands|) implies this is + // struct.new_default. + return Module['_BinaryenStructNew'](module, 0, 0, type); + }, + 'get'(index, ref, type, isSigned) { + return Module['_BinaryenStructGet'](module, index, ref, type, isSigned); + }, + 'set'(index, ref, value) { + return Module['_BinaryenStructSet'](module, index, ref, value); + } + }; + + self['array'] = { + 'new'(type, size, init) { + return Module['_BinaryenArrayNew'](module, type, size, init); + }, + 'new_default'(type, size) { + return Module['_BinaryenArrayNew'](module, type, size, 0); + }, + 'new_fixed'(type, values) { + return preserveStack(() => Module['_BinaryenArrayNewFixed'](module, type, i32sToStack(values), values.length)); + }, + 'new_data'(type, name, offset, size) { + return preserveStack(() => Module['_BinaryenArrayNewData'](module, type, strToStack(name), offset, size)); + }, + 'new_elem'(type, name, offset, size) { + return preserveStack(() => Module['_BinaryenArrayNewElem'](module, type, strToStack(name), offset, size)); + }, + 'get'(ref, index, type, isSigned) { + return Module['_BinaryenArrayGet'](module, ref, index, type, isSigned); + }, + 'set'(ref, index, value) { + return Module['_BinaryenArraySet'](module, ref, index, value); + }, + 'len'(ref) { + return Module['_BinaryenArrayLen'](module, ref); + }, + 'fill'(ref, index, value, size) { + return Module['_BinaryenArrayFill'](module, ref, index, value, size); + }, + 'copy'(destRef, destIndex, srcRef, srcIndex, length) { + return Module['_BinaryenArrayCopy'](module, destRef, destIndex, srcRef, srcIndex, length); + }, + 'init_data'(name, ref, index, offset, size) { + return preserveStack(() => Module['_BinaryenArrayInitData'](module, strToStack(name), ref, index, offset, size)); + }, + 'init_elem'(name, ref, index, offset, size) { + return preserveStack(() => Module['_BinaryenArrayInitElem'](module, strToStack(name), ref, index, offset, size)); + } + }; + // TODO: string.* // 'Module' operations @@ -2556,40 +2711,44 @@ function wrapModule(module, self = {}) { return Boolean(Module['_BinaryenHasMemory'](module)); }; self['getMemoryInfo'] = function(name) { - var memoryInfo = { - 'module': UTF8ToString(Module['_BinaryenMemoryImportGetModule'](module, strToStack(name))), - 'base': UTF8ToString(Module['_BinaryenMemoryImportGetBase'](module, strToStack(name))), - 'initial': Module['_BinaryenMemoryGetInitial'](module, strToStack(name)), - 'shared': Boolean(Module['_BinaryenMemoryIsShared'](module, strToStack(name))), - 'is64': Boolean(Module['_BinaryenMemoryIs64'](module, strToStack(name))), - }; - if (Module['_BinaryenMemoryHasMax'](module, strToStack(name))) { - memoryInfo['max'] = Module['_BinaryenMemoryGetMax'](module, strToStack(name)); - } - return memoryInfo; + return preserveStack(() => { + var memoryInfo = { + 'module': UTF8ToString(Module['_BinaryenMemoryImportGetModule'](module, strToStack(name))), + 'base': UTF8ToString(Module['_BinaryenMemoryImportGetBase'](module, strToStack(name))), + 'initial': Module['_BinaryenMemoryGetInitial'](module, strToStack(name)), + 'shared': Boolean(Module['_BinaryenMemoryIsShared'](module, strToStack(name))), + 'is64': Boolean(Module['_BinaryenMemoryIs64'](module, strToStack(name))), + }; + if (Module['_BinaryenMemoryHasMax'](module, strToStack(name))) { + memoryInfo['max'] = Module['_BinaryenMemoryGetMax'](module, strToStack(name)); + } + return memoryInfo; + }); }; self['getNumMemorySegments'] = function() { return Module['_BinaryenGetNumMemorySegments'](module); }; self['getMemorySegmentInfo'] = function(name) { - const passive = Boolean(Module['_BinaryenGetMemorySegmentPassive'](module, strToStack(name))); - let offset = null; - if (!passive) { - offset = Module['_BinaryenGetMemorySegmentByteOffset'](module, strToStack(name)); - } - return { - 'offset': offset, - 'data': (function(){ - const size = Module['_BinaryenGetMemorySegmentByteLength'](module, strToStack(name)); - const ptr = _malloc(size); - Module['_BinaryenCopyMemorySegmentData'](module, strToStack(name), ptr); - const res = new Uint8Array(size); - res.set(HEAP8.subarray(ptr, ptr + size)); - _free(ptr); - return res.buffer; - })(), - 'passive': passive - }; + return preserveStack(() => { + const passive = Boolean(Module['_BinaryenGetMemorySegmentPassive'](module, strToStack(name))); + let offset = null; + if (!passive) { + offset = Module['_BinaryenGetMemorySegmentByteOffset'](module, strToStack(name)); + } + return { + 'offset': offset, + 'data': (function(){ + const size = Module['_BinaryenGetMemorySegmentByteLength'](module, strToStack(name)); + const ptr = _malloc(size); + Module['_BinaryenCopyMemorySegmentData'](module, strToStack(name), ptr); + const res = new Uint8Array(size); + res.set(HEAP8.subarray(ptr, ptr + size)); + _free(ptr); + return res.buffer; + })(), + 'passive': passive + }; + }); }; self['setStart'] = function(start) { return Module['_BinaryenSetStart'](module, start); @@ -2603,6 +2762,16 @@ function wrapModule(module, self = {}) { self['setFeatures'] = function(features) { Module['_BinaryenModuleSetFeatures'](module, features); }; + self['setTypeName'] = function(heapType, name) { + return preserveStack(() => + Module['_BinaryenModuleSetTypeName'](module, heapType, strToStack(name)) + ); + }; + self['setFieldName'] = function(heapType, index, name) { + return preserveStack(() => + Module['_BinaryenModuleSetFieldName'](module, heapType, index, strToStack(name)) + ); + }; self['addCustomSection'] = function(name, contents) { return preserveStack(() => Module['_BinaryenAddCustomSection'](module, strToStack(name), i8sToStack(contents), contents.length) @@ -2724,6 +2893,92 @@ function wrapModule(module, self = {}) { } Module['wrapModule'] = wrapModule; +// 'TypeBuilder' interface +/** @constructor */ +Module['TypeBuilder'] = function(size) { + const builder = Module['_TypeBuilderCreate'](size); + this['ptr'] = builder; + + this['grow'] = function(count) { + Module['_TypeBuilderGrow'](builder, count); + }; + this['getSize'] = function() { + return Module['_TypeBuilderGetSize'](builder); + }; + this['setSignatureType'] = function(index, paramTypes, resultTypes) { + Module['_TypeBuilderSetSignatureType'](builder, index, paramTypes, resultTypes); + }; + this['setStructType'] = function(index, fields = []) { + // fields are assumed to be { type: type ref, packedType: type ref, mutable: bool } + preserveStack(() => { + const numFields = fields.length; + const types = new Array(numFields); + const packedTypes = new Array(numFields); + const mutables = new Array(numFields); + for (let i = 0; i < numFields; i++) { + const { ['type']: type, ['packedType']: packedType, ['mutable']: mutable } = fields[i]; + types[i] = type; + packedTypes[i] = packedType; + mutables[i] = mutable; + } + Module['_TypeBuilderSetStructType'](builder, + index, + i32sToStack(types), i32sToStack(packedTypes), + i8sToStack(mutables), + numFields + ); + }); + }; + this['setArrayType'] = function(index, elementType, elementPackedType, elementMutable) { + Module['_TypeBuilderSetArrayType'](builder, + index, elementType, elementPackedType, elementMutable + ); + }; + this['getTempHeapType'] = function(index) { + return Module['_TypeBuilderGetTempHeapType'](builder, index); + }; + this['getTempTupleType'] = function(types) { + return preserveStack(() => { + return Module['_TypeBuilderGetTempTupleType'](builder, i32sToStack(types), types.length); + }); + }; + this['getTempRefType'] = function(heapType, nullable) { + return Module['_TypeBuilderGetTempRefType'](builder, heapType, nullable); + }; + this['setSubType'] = function(index, superType) { + Module['_TypeBuilderSetSubType'](builder, index, superType); + }; + this['setOpen'] = function(index) { + Module['_TypeBuilderSetOpen'](builder, index); + }; + this['createRecGroup'] = function(index, length) { + Module['_TypeBuilderCreateRecGroup'](builder, index, length); + }; + this['buildAndDispose'] = function() { + return preserveStack(() => { + const numTypes = this['getSize'](); + const array = stackAlloc(numTypes << 2); + if (!Module['_TypeBuilderBuildAndDispose'](builder, array, 0, 0)) + throw new TypeError('TypeBuilder.buildAndDispose failed'); + const types = new Array(numTypes); + for (let i = 0; i < numTypes; i++) { + types[i] = HEAPU32[(array >>> 2) + i]; + } + return types; + }); + }; +} + +// Gets the type from a heap type generated by TypeBuilder +Module['getTypeFromHeapType'] = function(heapType, nullable) { + return Module['_BinaryenTypeFromHeapType'](heapType, nullable); +}; + +// Gets the heap type of a type +Module['getHeapType'] = function(type) { + return Module['_BinaryenTypeGetHeapType'](type); +}; + // 'Relooper' interface /** @constructor */ Module['Relooper'] = function(module) { @@ -2803,7 +3058,7 @@ Module['getExpressionType'] = function(expr) { Module['getExpressionInfo'] = function(expr) { const id = Module['_BinaryenExpressionGetId'](expr); const type = Module['_BinaryenExpressionGetType'](expr); - switch (id) { + switch (id) { // TODO: GC instructions case Module['BlockId']: return { 'id': id, @@ -4693,6 +4948,406 @@ Module['RefEq'] = makeExpressionWrapper({ } }); +Module['RefTest'] = makeExpressionWrapper({ + 'getRef'(expr) { + return Module['_BinaryenRefTestGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenRefTestSetRef'](expr, ref); + }, + 'getCastType'(expr) { + return Module['_BinaryenRefTestGetCastType'](expr); + }, + 'setCastType'(expr, castType) { + Module['_BinaryenRefTestSetCastType'](expr, castType); + } +}); + +Module['RefCast'] = makeExpressionWrapper({ + 'getRef'(expr) { + return Module['_BinaryenRefCastGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenRefCastSetRef'](expr, ref); + } +}); + +// TODO: any.convert_extern +// TODO: extern.convert_any + +Module['BrOn'] = makeExpressionWrapper({ + 'getOp'(expr) { + return Module['_BinaryenBrOnGetOp'](expr); + }, + 'setOp'(expr, op) { + Module['_BinaryenBrOnSetOp'](expr, op); + }, + 'getName'(expr) { + return UTF8ToString(Module['_BinaryenBrOnGetName'](expr)); + }, + 'setName'(expr, name) { + preserveStack(() => Module['_BinaryenBrOnSetName'](expr, strToStack(name))); + }, + 'getRef'(expr) { + return Module['_BinaryenBrOnGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenBrOnSetRef'](expr, ref); + }, + 'getCastType'(expr) { + return Module['_BinaryenBrOnGetCastType'](expr); + }, + 'setCastType'(expr, castType) { + Module['_BinaryenBrOnSetCastType'](expr, castType); + } +}); + +Module['StructNew'] = makeExpressionWrapper({ + 'getNumOperands'(expr) { + return Module['_BinaryenStructNewGetNumOperands'](expr); + }, + 'getOperands'(expr) { + return getAllNested(expr, Module['_BinaryenStructNewGetNumOperands'], Module['_BinaryenStructNewGetOperandAt']); + }, + 'setOperands'(expr, operands) { + setAllNested( + expr, + operands, + Module['_BinaryenStructNewGetNumOperands'], + Module['_BinaryenStructNewSetOperandAt'], + Module['_BinaryenStructNewAppendOperand'], + Module['_BinaryenStructNewRemoveOperandAt'] + ); + }, + 'getOperandAt'(expr, index) { + return Module['_BinaryenStructNewGetOperandAt'](expr, index); + }, + 'setOperandAt'(expr, index, operandExpr) { + Module['_BinaryenStructNewSetOperandAt'](expr, index, operandExpr); + }, + 'appendOperand'(expr, operandExpr) { + return Module['_BinaryenStructNewAppendOperand'](expr, operandExpr); + }, + 'insertOperandAt'(expr, index, operandExpr) { + Module['_BinaryenStructNewInsertOperandAt'](expr, index, operandExpr); + }, + 'removeOperandAt'(expr, index) { + return Module['_BinaryenStructNewRemoveOperandAt'](expr, index); + } +}); + +Module['StructGet'] = makeExpressionWrapper({ + 'getIndex'(expr) { + return Module['_BinaryenStructGetGetIndex'](expr); + }, + 'setIndex'(expr, index) { + Module['_BinaryenStructGetSetIndex'](expr, index); + }, + 'getRef'(expr) { + return Module['_BinaryenStructGetGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenStructGetSetRef'](expr, ref); + }, + 'isSigned'(expr) { + return Boolean(Module['_BinaryenStructGetIsSigned'](expr)); + }, + 'setSigned'(expr, signed) { + Module['_BinaryenStructGetSetSigned'](expr, signed); + } +}); + +Module['StructSet'] = makeExpressionWrapper({ + 'getIndex'(expr) { + return Module['_BinaryenStructSetGetIndex'](expr); + }, + 'setIndex'(expr, index) { + Module['_BinaryenStructSetSetIndex'](expr, index); + }, + 'getRef'(expr) { + return Module['_BinaryenStructSetGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenStructSetSetRef'](expr, ref); + }, + 'getValue'(expr) { + return Module['_BinaryenStructSetGetValue'](expr); + }, + 'setValue'(expr, value) { + Module['_BinaryenStructSetSetValue'](expr, value); + } +}); + +Module['ArrayNew'] = makeExpressionWrapper({ + 'getInit'(expr) { + return Module['_BinaryenArrayNewGetInit'](expr); + }, + 'setInit'(expr, init) { + Module['_BinaryenArrayNewSetInit'](expr, init); + }, + 'getSize'(expr) { + return Module['_BinaryenArrayNewGetSize'](expr); + }, + 'setSize'(expr, size) { + Module['_BinaryenArrayNewSetSize'](expr, size); + } +}); + +Module['ArrayNewFixed'] = makeExpressionWrapper({ + 'getNumValues'(expr) { + return Module['_BinaryenArrayNewFixedGetNumValues'](expr); + }, + 'getValues'(expr) { + return getAllNested(expr, + Module['_BinaryenArrayNewFixedGetNumValues'], + Module['_BinaryenArrayNewFixedGetValueAt']); + }, + 'setValues'(expr, values) { + setAllNested( + expr, + values, + Module['_BinaryenArrayNewFixedGetNumValues'], + Module['_BinaryenArrayNewFixedSetValueAt'], + Module['_BinaryenArrayNewFixedAppendValue'], + Module['_BinaryenArrayNewFixedRemoveValueAt'] + ); + }, + 'getValueAt'(expr, index) { + return Module['_BinaryenArrayNewFixedGetValueAt'](expr, index); + }, + 'setValueAt'(expr, index, valueExpr) { + Module['_BinaryenArrayNewFixedSetValueAt'](expr, index, valueExpr); + }, + 'appendValue'(expr, valueExpr) { + return Module['_BinaryenArrayNewFixedAppendValue'](expr, valueExpr); + }, + 'insertValueAt'(expr, index, valueExpr) { + Module['_BinaryenArrayNewFixedInsertValueAt'](expr, index, valueExpr); + }, + 'removeValueAt'(expr, index) { + return Module['_BinaryenArrayNewFixedRemoveValueAt'](expr, index); + } +}); + +Module['ArrayNewData'] = makeExpressionWrapper({ + 'getSegment'(expr) { + return UTF8ToString(Module['_BinaryenArrayNewDataGetSegment'](expr)); + }, + 'setSegment'(expr, segment) { + preserveStack(() => Module['_BinaryenArrayNewDataSetSegment'](expr, strToStack(segment))); + }, + 'getOffset'(expr) { + return Module['_BinaryenArrayNewDataGetOffset'](expr); + }, + 'setOffset'(expr, offset) { + Module['_BinaryenArrayNewDataSetOffset'](expr, offset); + }, + 'getSize'(expr) { + return Module['_BinaryenArrayNewDataGetSize'](expr); + }, + 'setSize'(expr, size) { + Module['_BinaryenArrayNewDataSetSize'](expr, size); + } +}); + +Module['ArrayNewElem'] = makeExpressionWrapper({ + 'getSegment'(expr) { + return UTF8ToString(Module['_BinaryenArrayNewElemGetSegment'](expr)); + }, + 'setSegment'(expr, segment) { + preserveStack(() => Module['_BinaryenArrayNewElemSetSegment'](expr, strToStack(segment))); + }, + 'getOffset'(expr) { + return Module['_BinaryenArrayNewElemGetOffset'](expr); + }, + 'setOffset'(expr, offset) { + Module['_BinaryenArrayNewElemSetOffset'](expr, offset); + }, + 'getSize'(expr) { + return Module['_BinaryenArrayNewElemGetSize'](expr); + }, + 'setSize'(expr, size) { + Module['_BinaryenArrayNewElemSetSize'](expr, size); + } +}); + +Module['ArrayGet'] = makeExpressionWrapper({ + 'getRef'(expr) { + return Module['_BinaryenArrayGetGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenArrayGetSetRef'](expr, ref); + }, + 'getIndex'(expr) { + return Module['_BinaryenArrayGetGetIndex'](expr); + }, + 'setIndex'(expr, index) { + Module['_BinaryenArrayGetSetIndex'](expr, index); + }, + 'isSigned'(expr) { + return Boolean(Module['_BinaryenArrayGetIsSigned'](expr)); + }, + 'setSigned'(expr, signed) { + Module['_BinaryenArrayGetSetSigned'](expr, signed); + } +}); + +Module['ArraySet'] = makeExpressionWrapper({ + 'getRef'(expr) { + return Module['_BinaryenArraySetGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenArraySetSetRef'](expr, ref); + }, + 'getIndex'(expr) { + return Module['_BinaryenArraySetGetIndex'](expr); + }, + 'setIndex'(expr, index) { + Module['_BinaryenArraySetSetIndex'](expr, index); + }, + 'getValue'(expr) { + return Module['_BinaryenArraySetGetValue'](expr); + }, + 'setValue'(expr, value) { + Module['_BinaryenArraySetSetValue'](expr, value); + } +}); + +Module['ArrayLen'] = makeExpressionWrapper({ + 'getRef'(expr) { + return Module['_BinaryenArrayLenGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenArrayLenSetRef'](expr, ref); + } +}); + +Module['ArrayFill'] = makeExpressionWrapper({ + 'getRef'(expr) { + return Module['_BinaryenArrayFillGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenArrayFillSetRef'](expr, ref); + }, + 'getIndex'(expr) { + return Module['_BinaryenArrayFillGetIndex'](expr); + }, + 'setIndex'(expr, index) { + Module['_BinaryenArrayFillSetIndex'](expr, index); + }, + 'getValue'(expr) { + return Module['_BinaryenArrayFillGetValue'](expr); + }, + 'setValue'(expr, value) { + Module['_BinaryenArrayFillSetValue'](expr, value); + }, + 'getSize'(expr) { + return Module['_BinaryenArrayFillGetSize'](expr); + }, + 'setSize'(expr, size) { + Module['_BinaryenArrayFillSetSize'](expr, size); + } +}); + +Module['ArrayCopy'] = makeExpressionWrapper({ + 'getDestRef'(expr) { + return Module['_BinaryenArrayCopyGetDestRef'](expr); + }, + 'setDestRef'(expr, ref) { + Module['_BinaryenArrayCopySetDestRef'](expr, ref); + }, + 'getDestIndex'(expr) { + return Module['_BinaryenArrayCopyGetDestIndex'](expr); + }, + 'setDestIndex'(expr, index) { + Module['_BinaryenArrayCopySetDestIndex'](expr, index); + }, + 'getSrcRef'(expr) { + return Module['_BinaryenArrayCopyGetSrcRef'](expr); + }, + 'setSrcRef'(expr, ref) { + Module['_BinaryenArrayCopySetSrcRef'](expr, ref); + }, + 'getSrcIndex'(expr) { + return Module['_BinaryenArrayCopyGetSrcIndex'](expr); + }, + 'setSrcIndex'(expr, index) { + Module['_BinaryenArrayCopySetSrcIndex'](expr, index); + }, + 'getLength'(expr) { + return Module['_BinaryenArrayCopyGetLength'](expr); + }, + 'setLength'(expr, length) { + Module['_BinaryenArrayCopySetLength'](expr, length); + } +}); + +Module['ArrayInitData'] = makeExpressionWrapper({ + 'getSegment'(expr) { + return UTF8ToString(Module['_BinaryenArrayInitDataGetSegment'](expr)); + }, + 'setSegment'(expr, segment) { + preserveStack(() => Module['_BinaryenArrayInitDataSetSegment'](expr, strToStack(segment))); + }, + 'getRef'(expr) { + return Module['_BinaryenArrayInitDataGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenArrayInitDataSetRef'](expr, ref); + }, + 'getIndex'(expr) { + return Module['_BinaryenArrayInitDataGetIndex'](expr); + }, + 'setIndex'(expr, index) { + Module['_BinaryenArrayInitDataSetIndex'](expr, index); + }, + 'getOffset'(expr) { + return Module['_BinaryenArrayInitDataGetOffset'](expr); + }, + 'setOffset'(expr, offset) { + Module['_BinaryenArrayInitDataSetOffset'](expr, offset); + }, + 'getSize'(expr) { + return Module['_BinaryenArrayInitDataGetSize'](expr); + }, + 'setSize'(expr, size) { + Module['_BinaryenArrayInitDataSetSize'](expr, size); + } +}); + +Module['ArrayInitElem'] = makeExpressionWrapper({ + 'getSegment'(expr) { + return UTF8ToString(Module['_BinaryenArrayInitElemGetSegment'](expr)); + }, + 'setSegment'(expr, segment) { + preserveStack(() => Module['_BinaryenArrayInitElemSetSegment'](expr, strToStack(segment))); + }, + 'getRef'(expr) { + return Module['_BinaryenArrayInitElemGetRef'](expr); + }, + 'setRef'(expr, ref) { + Module['_BinaryenArrayInitElemSetRef'](expr, ref); + }, + 'getIndex'(expr) { + return Module['_BinaryenArrayInitElemGetIndex'](expr); + }, + 'setIndex'(expr, index) { + Module['_BinaryenArrayInitElemSetIndex'](expr, index); + }, + 'getOffset'(expr) { + return Module['_BinaryenArrayInitElemGetOffset'](expr); + }, + 'setOffset'(expr, offset) { + Module['_BinaryenArrayInitElemSetOffset'](expr, offset); + }, + 'getSize'(expr) { + return Module['_BinaryenArrayInitElemGetSize'](expr); + }, + 'setSize'(expr, size) { + Module['_BinaryenArrayInitElemSetSize'](expr, size); + } +}); + Module['Try'] = makeExpressionWrapper({ 'getName'(expr) { const name = Module['_BinaryenTryGetName'](expr); diff --git a/test/binaryen.js/expressions.js b/test/binaryen.js/expressions.js index 0d1c9669084..544f2b97806 100644 --- a/test/binaryen.js/expressions.js +++ b/test/binaryen.js/expressions.js @@ -1531,6 +1531,759 @@ console.log("# RefEq"); module.dispose(); })(); +console.log("# RefTest"); +(function testRefTest() { + const module = new binaryen.Module(); + + var ref = module.local.get(0, binaryen.anyref); + var castType = binaryen.anyref; + const theRefTest = binaryen.RefTest(module.ref.test(ref, castType)); + assert(theRefTest instanceof binaryen.RefTest); + assert(theRefTest instanceof binaryen.Expression); + assert(theRefTest.ref === ref); + assert(theRefTest.castType === castType); + assert(theRefTest.type === binaryen.i32); + + theRefTest.ref = ref = module.local.get(2, binaryen.externref); + assert(theRefTest.ref === ref); + theRefTest.castType = castType = binaryen.externref; + assert(theRefTest.castType === castType); + theRefTest.type = binaryen.f64; + theRefTest.finalize(); + assert(theRefTest.type === binaryen.i32); + + console.log(theRefTest.toText()); + assert( + theRefTest.toText() + == + "(ref.test externref\n (local.get $2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# RefCast"); +(function testRefCast() { + const module = new binaryen.Module(); + + var ref = module.local.get(0, binaryen.anyref); + var type = binaryen.anyref; + const theRefCast = binaryen.RefCast(module.ref.cast(ref, type)); + assert(theRefCast instanceof binaryen.RefCast); + assert(theRefCast instanceof binaryen.Expression); + assert(theRefCast.ref === ref); + assert(theRefCast.type === type); + + theRefCast.ref = ref = module.local.get(2, binaryen.externref); + assert(theRefCast.ref === ref); + theRefCast.type = type = binaryen.externref; + theRefCast.finalize(); + assert(theRefCast.type === type); + + console.log(theRefCast.toText()); + assert( + theRefCast.toText() + == + "(ref.cast externref\n (local.get $2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# BrOn"); +(function testBrOn() { + const module = new binaryen.Module(); + + var name = "br"; + var ref = module.local.get(0, binaryen.externref); + var op = binaryen.Operations.BrOnNull; + var castType = binaryen.unreachable; + const theBrOn = binaryen.BrOn(module.br_on_null(name, ref)); + assert(theBrOn instanceof binaryen.BrOn); + assert(theBrOn instanceof binaryen.Expression); + assert(theBrOn.name === name); + assert(theBrOn.ref === ref); + assert(theBrOn.op === op); + assert(theBrOn.castType === castType); + + // TODO: What should theBrOn.type be equal to? + + theBrOn.name = name = "br2"; + assert(theBrOn.name === name); + theBrOn.ref = ref = module.local.get(1, binaryen.anyref); + assert(theBrOn.ref === ref); + theBrOn.op = op = binaryen.Operations.BrOnCast; + assert(theBrOn.op === op); + theBrOn.castType = castType = binaryen.i31ref; + assert(theBrOn.castType === castType); + theBrOn.finalize(); + + console.log(theBrOn.toText()); + assert( + theBrOn.toText() + == + "(br_on_cast $br2 anyref i31ref\n (local.get $1)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# StructNew"); +(function testStructNew() { + const builder = new binaryen.TypeBuilder(2); + builder.setStructType(0, [ + { type: binaryen.i32, packedType: binaryen.notPacked, mutable: true }, + ]); + builder.setStructType(1, [ + { type: binaryen.i32, packedType: binaryen.i16, mutable: true }, + { type: binaryen.i64, packedType: binaryen.notPacked, mutable: true } + ]); + var [ + struct0Type, + struct1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var operands = [ + module.i32.const(1), + module.i32.const(2) + ]; + var type = struct0Type; + const theStructNew = binaryen.StructNew(module.struct.new(operands, type)); + assert(theStructNew instanceof binaryen.StructNew); + assert(theStructNew instanceof binaryen.Expression); + assertDeepEqual(theStructNew.operands, operands); + assertDeepEqual(theStructNew.getOperands(), operands); + assert(theStructNew.type === type); + + theStructNew.operands = operands = [ + module.i32.const(3), // set + module.i32.const(4), // set + module.i32.const(5) // append + ]; + assertDeepEqual(theStructNew.operands, operands); + operands = [ + module.i32.const(6) // set + // remove + // remove + ]; + theStructNew.setOperands(operands); + assertDeepEqual(theStructNew.operands, operands); + theStructNew.insertOperandAt(0, module.i32.const(7)); + theStructNew.type = type = struct1Type; + theStructNew.finalize(); + assert(theStructNew.type === type); + + console.log(theStructNew.toText()); + assert( + theStructNew.toText() + == + "(struct.new $struct.0\n (i32.const 7)\n (i32.const 6)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# StructGet"); +(function testStructGet() { + const builder = new binaryen.TypeBuilder(2); + builder.setStructType(0, [ + { type: binaryen.i32, packedType: binaryen.notPacked, mutable: true }, + ]); + builder.setStructType(1, [ + { type: binaryen.i32, packedType: binaryen.i16, mutable: true }, + { type: binaryen.i64, packedType: binaryen.notPacked, mutable: true } + ]); + var [ + struct0Type, + struct1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var index = 0; + var ref = module.local.get(0, struct0Type); + var type = binaryen.i32; + var signed = false; + const theStructGet = binaryen.StructGet(module.struct.get(index, ref, type, signed)); + assert(theStructGet instanceof binaryen.StructGet); + assert(theStructGet instanceof binaryen.Expression); + assert(theStructGet.index === index); + assert(theStructGet.ref === ref); + assert(theStructGet.signed === signed); + assert(theStructGet.type === type); + + theStructGet.index = index = 1; + assert(theStructGet.index === index); + theStructGet.ref = ref = module.local.get(1, struct1Type); + assert(theStructGet.ref === ref); + theStructGet.signed = signed = true; + assert(theStructGet.signed === signed); + theStructGet.type = type = binaryen.i64; + theStructGet.finalize(); + assert(theStructGet.type === type); + + console.log(theStructGet.toText()); + assert( + theStructGet.toText() + == + "(struct.get $struct.0 1\n (local.get $1)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# StructSet"); +(function testStructSet() { + const builder = new binaryen.TypeBuilder(2); + builder.setStructType(0, [ + { type: binaryen.i32, packedType: binaryen.notPacked, mutable: true }, + ]); + builder.setStructType(1, [ + { type: binaryen.i32, packedType: binaryen.i16, mutable: true }, + { type: binaryen.i64, packedType: binaryen.notPacked, mutable: true } + ]); + var [ + struct0Type, + struct1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var index = 0; + var ref = module.local.get(0, struct0Type); + var value = module.local.get(1, binaryen.i32); + const theStructSet = binaryen.StructSet(module.struct.set(index, ref, value)); + assert(theStructSet instanceof binaryen.StructSet); + assert(theStructSet instanceof binaryen.Expression); + assert(theStructSet.index === index); + assert(theStructSet.ref === ref); + assert(theStructSet.value === value); + assert(theStructSet.type === binaryen.none); + + theStructSet.index = index = 1; + assert(theStructSet.index === index); + theStructSet.ref = ref = module.local.get(2, struct1Type); + assert(theStructSet.ref === ref); + theStructSet.value = value = module.local.get(3, binaryen.i64); + assert(theStructSet.value === value); + theStructSet.type = binaryen.f64; + theStructSet.finalize(); + assert(theStructSet.type === binaryen.none); + + console.log(theStructSet.toText()); + assert( + theStructSet.toText() + == + "(struct.set $struct.0 1\n (local.get $2)\n (local.get $3)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayNew"); +(function testArrayNew() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i32, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var type = array0Type; + var size = module.i32.const(2); + var init = module.i32.const(1); + const theArrayNew = binaryen.ArrayNew(module.array.new(type, size, init)); + assert(theArrayNew instanceof binaryen.ArrayNew); + assert(theArrayNew instanceof binaryen.Expression); + assert(theArrayNew.size === size); + assert(theArrayNew.init === init); + assert(theArrayNew.type === type); + + theArrayNew.size = size = module.i32.const(4); + assert(theArrayNew.size === size); + theArrayNew.init = init = module.i32.const(3); + assert(theArrayNew.init === init); + theArrayNew.type = type = array1Type; + theArrayNew.finalize(); + assert(theArrayNew.type === type); + + console.log(theArrayNew.toText()); + assert( + theArrayNew.toText() + == + "(array.new $array.0\n (i32.const 3)\n (i32.const 4)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayNewFixed"); +(function testArrayNewFixed() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i32, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var type = array0Type; + var values = [ + module.i32.const(1), + module.i32.const(2) + ]; + const theArrayNewFixed = binaryen.ArrayNewFixed(module.array.new_fixed(type, values)); + assert(theArrayNewFixed instanceof binaryen.ArrayNewFixed); + assert(theArrayNewFixed instanceof binaryen.Expression); + assertDeepEqual(theArrayNewFixed.values, values); + assertDeepEqual(theArrayNewFixed.getValues(), values); + assert(theArrayNewFixed.type === type); + + theArrayNewFixed.values = values = [ + module.i32.const(3), // set + module.i32.const(4), // set + module.i32.const(5) // append + ]; + assertDeepEqual(theArrayNewFixed.values, values); + values = [ + module.i32.const(6) // set + // remove + // remove + ]; + theArrayNewFixed.setValues(values); + assertDeepEqual(theArrayNewFixed.values, values); + theArrayNewFixed.insertValueAt(0, module.i32.const(7)); + theArrayNewFixed.type = type = array1Type; + theArrayNewFixed.finalize(); + assert(theArrayNewFixed.type === type); + + console.log(theArrayNewFixed.toText()); + assert( + theArrayNewFixed.toText() + == + "(array.new_fixed $array.0 2\n (i32.const 7)\n (i32.const 6)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayNewData"); +(function testArrayNewData() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i32, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var type = array0Type; + var segment = "0"; + var offset = module.i32.const(1); + var size = module.i32.const(2); + const theArrayNewData = binaryen.ArrayNewData(module.array.new_data(type, segment, offset, size)); + assert(theArrayNewData instanceof binaryen.ArrayNewData); + assert(theArrayNewData instanceof binaryen.Expression); + assert(theArrayNewData.segment === segment); + assert(theArrayNewData.offset === offset); + assert(theArrayNewData.size === size); + assert(theArrayNewData.type === type); + + theArrayNewData.segment = segment = "3"; + assert(theArrayNewData.segment === segment); + theArrayNewData.offset = offset = module.i32.const(4); + assert(theArrayNewData.offset === offset); + theArrayNewData.size = size = module.i32.const(5); + assert(theArrayNewData.size === size); + theArrayNewData.type = type = array1Type; + theArrayNewData.finalize(); + assert(theArrayNewData.type === type); + + console.log(theArrayNewData.toText()); + assert( + theArrayNewData.toText() + == + "(array.new_data $array.0 $3\n (i32.const 4)\n (i32.const 5)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayNewElem"); +(function testArrayNewElem() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i32, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var type = array0Type; + var segment = "0"; + var offset = module.i32.const(1); + var size = module.i32.const(2); + const theArrayNewElem = binaryen.ArrayNewElem(module.array.new_elem(type, segment, offset, size)); + assert(theArrayNewElem instanceof binaryen.ArrayNewElem); + assert(theArrayNewElem instanceof binaryen.Expression); + assert(theArrayNewElem.segment === segment); + assert(theArrayNewElem.offset === offset); + assert(theArrayNewElem.size === size); + assert(theArrayNewElem.type === type); + + theArrayNewElem.segment = segment = "3"; + assert(theArrayNewElem.segment === segment); + theArrayNewElem.offset = offset = module.i32.const(4); + assert(theArrayNewElem.offset === offset); + theArrayNewElem.size = size = module.i32.const(5); + assert(theArrayNewElem.size === size); + theArrayNewElem.type = type = array1Type; + theArrayNewElem.finalize(); + assert(theArrayNewElem.type === type); + + console.log(theArrayNewElem.toText()); + assert( + theArrayNewElem.toText() + == + "(array.new_elem $array.0 $3\n (i32.const 4)\n (i32.const 5)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayGet"); +(function testArrayGet() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i64, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var ref = module.local.get(0, array0Type); + var index = module.i32.const(0); + var type = binaryen.i32; + var signed = false; + const theArrayGet = binaryen.ArrayGet(module.array.get(ref, index, type, signed)); + assert(theArrayGet instanceof binaryen.ArrayGet); + assert(theArrayGet instanceof binaryen.Expression); + assert(theArrayGet.ref === ref); + assert(theArrayGet.index === index); + assert(theArrayGet.signed === signed); + assert(theArrayGet.type === type); + + theArrayGet.ref = ref = module.local.get(1, array1Type); + assert(theArrayGet.ref === ref); + theArrayGet.index = index = module.i32.const(1); + assert(theArrayGet.index === index); + theArrayGet.signed = signed = true; + assert(theArrayGet.signed === signed); + theArrayGet.type = type = binaryen.i64; + theArrayGet.finalize(); + assert(theArrayGet.type === type); + + console.log(theArrayGet.toText()); + assert( + theArrayGet.toText() + == + "(array.get $array.0\n (local.get $1)\n (i32.const 1)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArraySet"); +(function testArraySet() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i64, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var ref = module.local.get(0, array0Type); + var index = module.i32.const(0); + var value = module.local.get(1, binaryen.i32); + const theArraySet = binaryen.ArraySet(module.array.set(ref, index, value)); + assert(theArraySet instanceof binaryen.ArraySet); + assert(theArraySet instanceof binaryen.Expression); + assert(theArraySet.ref === ref); + assert(theArraySet.index === index); + assert(theArraySet.value === value); + assert(theArraySet.type === binaryen.none); + + theArraySet.ref = ref = module.local.get(2, array1Type); + assert(theArraySet.ref === ref); + theArraySet.index = index = module.i32.const(1); + assert(theArraySet.index === index); + theArraySet.value = value = module.local.get(3, binaryen.i64); + assert(theArraySet.value === value); + theArraySet.type = binaryen.i64; + theArraySet.finalize(); + assert(theArraySet.type === binaryen.none); + + console.log(theArraySet.toText()); + assert( + theArraySet.toText() + == + "(array.set $array.0\n (local.get $2)\n (i32.const 1)\n (local.get $3)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayLen"); +(function testArrayLen() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i64, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var ref = module.local.get(0, array0Type); + const theArrayLen = binaryen.ArrayLen(module.array.len(ref)); + assert(theArrayLen instanceof binaryen.ArrayLen); + assert(theArrayLen instanceof binaryen.Expression); + assert(theArrayLen.ref === ref); + assert(theArrayLen.type === binaryen.i32); + + theArrayLen.ref = ref = module.local.get(1, array1Type); + assert(theArrayLen.ref === ref); + theArrayLen.type = binaryen.i64; + theArrayLen.finalize(); + assert(theArrayLen.type === binaryen.i32); + + console.log(theArrayLen.toText()); + assert( + theArrayLen.toText() + == + "(array.len\n (local.get $1)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayFill"); +(function testArrayFill() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i64, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var ref = module.local.get(0, array0Type); + var index = module.i32.const(0); + var value = module.local.get(1, binaryen.i32); + var size = module.i32.const(1); + const theArrayFill = binaryen.ArrayFill(module.array.fill(ref, index, value, size)); + assert(theArrayFill instanceof binaryen.ArrayFill); + assert(theArrayFill instanceof binaryen.Expression); + assert(theArrayFill.ref === ref); + assert(theArrayFill.index === index); + assert(theArrayFill.value === value); + assert(theArrayFill.size === size); + assert(theArrayFill.type === binaryen.none); + + theArrayFill.ref = ref = module.local.get(2, array1Type); + assert(theArrayFill.ref === ref); + theArrayFill.index = index = module.i32.const(2); + assert(theArrayFill.index === index); + theArrayFill.value = value = module.local.get(3, binaryen.i64); + assert(theArrayFill.value = value); + theArrayFill.size = size = module.i32.const(3); + assert(theArrayFill.size === size); + theArrayFill.type = binaryen.i64; + theArrayFill.finalize(); + assert(theArrayFill.type === binaryen.none); + + console.log(theArrayFill.toText()); + assert( + theArrayFill.toText() + == + "(array.fill $array.0\n (local.get $2)\n (i32.const 2)\n (local.get $3)\n (i32.const 3)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayCopy"); +(function testArrayCopy() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i64, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var destRef = module.local.get(0, array0Type); + var destIndex = module.i32.const(0); + var srcRef = module.local.get(1, array0Type); + var srcIndex = module.i32.const(1); + var length = module.i32.const(1); + const theArrayCopy = binaryen.ArrayCopy(module.array.copy(destRef, destIndex, srcRef, srcIndex, length)); + assert(theArrayCopy instanceof binaryen.ArrayCopy); + assert(theArrayCopy instanceof binaryen.Expression); + assert(theArrayCopy.destRef === destRef); + assert(theArrayCopy.destIndex === destIndex); + assert(theArrayCopy.srcRef === srcRef); + assert(theArrayCopy.srcIndex === srcIndex); + assert(theArrayCopy.length === length); + assert(theArrayCopy.type === binaryen.none); + + theArrayCopy.destRef = destRef = module.local.get(2, array1Type); + assert(theArrayCopy.destRef === destRef); + theArrayCopy.destIndex = destIndex = module.i32.const(2); + assert(theArrayCopy.destIndex === destIndex); + theArrayCopy.srcRef = srcRef = module.local.get(3, array1Type); + assert(theArrayCopy.srcRef === srcRef); + theArrayCopy.srcIndex = srcIndex = module.i32.const(3); + assert(theArrayCopy.srcIndex === srcIndex); + theArrayCopy.length = length = module.i32.const(2); + assert(theArrayCopy.length === length); + theArrayCopy.type = binaryen.i64; + theArrayCopy.finalize(); + assert(theArrayCopy.type === binaryen.none); + + console.log(theArrayCopy.toText()); + assert( + theArrayCopy.toText() + == + "(array.copy $array.0 $array.0\n (local.get $2)\n (i32.const 2)\n (local.get $3)\n (i32.const 3)\n (i32.const 2)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayInitData"); +(function testArrayInitData() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i32, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var segment = "0"; + var ref = module.local.get(0, array0Type); + var index = module.i32.const(0); + var offset = module.i32.const(1); + var size = module.i32.const(2); + const theArrayInitData = binaryen.ArrayInitData(module.array.init_data(segment, ref, index, offset, size)); + assert(theArrayInitData instanceof binaryen.ArrayInitData); + assert(theArrayInitData instanceof binaryen.Expression); + assert(theArrayInitData.segment === segment); + assert(theArrayInitData.ref === ref); + assert(theArrayInitData.index === index); + assert(theArrayInitData.offset === offset); + assert(theArrayInitData.size === size); + assert(theArrayInitData.type === binaryen.none); + + theArrayInitData.segment = segment = "1"; + assert(theArrayInitData.segment === segment); + theArrayInitData.ref = ref = module.local.get(1, array1Type); + assert(theArrayInitData.ref === ref); + theArrayInitData.index = index = module.i32.const(3); + assert(theArrayInitData.index === index); + theArrayInitData.offset = offset = module.i32.const(4); + assert(theArrayInitData.offset === offset); + theArrayInitData.size = size = module.i32.const(5); + assert(theArrayInitData.size === size); + theArrayInitData.type = binaryen.i64; + theArrayInitData.finalize(); + assert(theArrayInitData.type === binaryen.none); + + console.log(theArrayInitData.toText()); + assert( + theArrayInitData.toText() + == + "(array.init_data $array.0 $1\n (local.get $1)\n (i32.const 3)\n (i32.const 4)\n (i32.const 5)\n)\n" + ); + + module.dispose(); +})(); + +console.log("# ArrayInitElem"); +(function testArrayInitElem() { + const builder = new binaryen.TypeBuilder(2); + builder.setArrayType(0, binaryen.i32, binaryen.i16, true); + builder.setArrayType(1, binaryen.i32, binaryen.notPacked, true); + var [ + array0Type, + array1Type + ] = builder.buildAndDispose(); + + const module = new binaryen.Module(); + + var segment = "0"; + var ref = module.local.get(0, array0Type); + var index = module.i32.const(0); + var offset = module.i32.const(1); + var size = module.i32.const(2); + const theArrayInitElem = binaryen.ArrayInitElem(module.array.init_elem(segment, ref, index, offset, size)); + assert(theArrayInitElem instanceof binaryen.ArrayInitElem); + assert(theArrayInitElem instanceof binaryen.Expression); + assert(theArrayInitElem.segment === segment); + assert(theArrayInitElem.ref === ref); + assert(theArrayInitElem.index === index); + assert(theArrayInitElem.offset === offset); + assert(theArrayInitElem.size === size); + assert(theArrayInitElem.type === binaryen.none); + + theArrayInitElem.segment = segment = "1"; + assert(theArrayInitElem.segment === segment); + theArrayInitElem.ref = ref = module.local.get(1, array1Type); + assert(theArrayInitElem.ref === ref); + theArrayInitElem.index = index = module.i32.const(3); + assert(theArrayInitElem.index === index); + theArrayInitElem.offset = offset = module.i32.const(4); + assert(theArrayInitElem.offset === offset); + theArrayInitElem.size = size = module.i32.const(5); + assert(theArrayInitElem.size === size); + theArrayInitElem.type = binaryen.i64; + theArrayInitElem.finalize(); + assert(theArrayInitElem.type === binaryen.none); + + console.log(theArrayInitElem.toText()); + assert( + theArrayInitElem.toText() + == + "(array.init_elem $array.0 $1\n (local.get $1)\n (i32.const 3)\n (i32.const 4)\n (i32.const 5)\n)\n" + ); + + module.dispose(); +})(); + console.log("# Try"); (function testTry() { const module = new binaryen.Module(); diff --git a/test/binaryen.js/expressions.js.txt b/test/binaryen.js/expressions.js.txt index 5d6c37c6bc6..47d7cf43fb4 100644 --- a/test/binaryen.js/expressions.js.txt +++ b/test/binaryen.js/expressions.js.txt @@ -239,6 +239,113 @@ (local.get $3) ) +# RefTest +(ref.test externref + (local.get $2) +) + +# RefCast +(ref.cast externref + (local.get $2) +) + +# BrOn +(br_on_cast $br2 anyref i31ref + (local.get $1) +) + +# StructNew +(struct.new $struct.0 + (i32.const 7) + (i32.const 6) +) + +# StructGet +(struct.get $struct.0 1 + (local.get $1) +) + +# StructSet +(struct.set $struct.0 1 + (local.get $2) + (local.get $3) +) + +# ArrayNew +(array.new $array.0 + (i32.const 3) + (i32.const 4) +) + +# ArrayNewFixed +(array.new_fixed $array.0 2 + (i32.const 7) + (i32.const 6) +) + +# ArrayNewData +(array.new_data $array.0 $3 + (i32.const 4) + (i32.const 5) +) + +# ArrayNewElem +(array.new_elem $array.0 $3 + (i32.const 4) + (i32.const 5) +) + +# ArrayGet +(array.get $array.0 + (local.get $1) + (i32.const 1) +) + +# ArraySet +(array.set $array.0 + (local.get $2) + (i32.const 1) + (local.get $3) +) + +# ArrayLen +(array.len + (local.get $1) +) + +# ArrayFill +(array.fill $array.0 + (local.get $2) + (i32.const 2) + (local.get $3) + (i32.const 3) +) + +# ArrayCopy +(array.copy $array.0 $array.0 + (local.get $2) + (i32.const 2) + (local.get $3) + (i32.const 3) + (i32.const 2) +) + +# ArrayInitData +(array.init_data $array.0 $1 + (local.get $1) + (i32.const 3) + (i32.const 4) + (i32.const 5) +) + +# ArrayInitElem +(array.init_elem $array.0 $1 + (local.get $1) + (i32.const 3) + (i32.const 4) + (i32.const 5) +) + # Try (try (result i32) (do diff --git a/test/binaryen.js/gc.js b/test/binaryen.js/gc.js new file mode 100644 index 00000000000..0f12184b4c4 --- /dev/null +++ b/test/binaryen.js/gc.js @@ -0,0 +1,178 @@ +var builder = new binaryen.TypeBuilder(4); +builder.setSignatureType(0, binaryen.createType([binaryen.i32]), binaryen.none); +builder.setStructType(1, [ + { type: binaryen.i32, packedType: binaryen.i16, mutable: true }, + { type: binaryen.f64, packedType: binaryen.notPacked, mutable: true } +]); +builder.setArrayType(2, binaryen.i32, binaryen.i8, true); +builder.setArrayType(3, binaryen.funcref, binaryen.notPacked, true); +var [ + signatureHeapType, + structHeapType, + arrayHeapType, + funcArrayHeapType +] = builder.buildAndDispose(); + +var signatureType = binaryen.getTypeFromHeapType(signatureHeapType, true); +var structType = binaryen.getTypeFromHeapType(structHeapType, true); +var arrayType = binaryen.getTypeFromHeapType(arrayHeapType, true); +var funcArrayType = binaryen.getTypeFromHeapType(funcArrayHeapType, true); + +var module = new binaryen.Module(); +module.setFeatures(binaryen.Features.ReferenceTypes | binaryen.Features.BulkMemory | binaryen.Features.GC); + +module.addFunction("add", binaryen.createType([binaryen.i32, binaryen.i32]), binaryen.i32, [], + module.i32.add( + module.local.get("0", binaryen.i32), + module.local.get("1", binaryen.i32) + ) +); + +module.setMemory(1, -1, null, [ + { offset: module.i32.const(0), data: [4, 3, 2, 1] } +]); + +module.addTable("0", 1, -1); +module.addActiveElementSegment("0", "0", ["add"]); + +module.addGlobal("struct-global", + structType, + true, + module.struct.new_default( + binaryen.getHeapType(structType) + ) +); + +module.addGlobal("array-global", + arrayType, + true, + module.array.new_default( + binaryen.getHeapType(arrayType), + module.i32.const(4) + ) +); + +module.addGlobal("funcArray-global", + funcArrayType, + true, + module.array.new_default( + binaryen.getHeapType(funcArrayType), + module.i32.const(4) + ) +); + +var valueList = [ + // ref + + // struct + module.struct.new( + [ + module.i32.const(1), + module.f64.const(2.3) + ], + binaryen.getHeapType(structType) + ), + module.struct.new_default( + binaryen.getHeapType(structType) + ), + module.struct.get( + 0, + module.global.get("struct-global", structType), + binaryen.i32, + true + ), + module.struct.set( + 1, + module.global.get("struct-global", structType), + module.f64.const(1.23) + ), + + // array + module.array.new( + binaryen.getHeapType(arrayType), + module.i32.const(1), + module.i32.const(0) + ), + module.array.new_default( + binaryen.getHeapType(arrayType), + module.i32.const(1) + ), + module.array.new_fixed( + binaryen.getHeapType(arrayType), + [ + module.i32.const(1), + module.i32.const(2), + module.i32.const(3) + ] + ), + module.array.new_data( + binaryen.getHeapType(arrayType), + "0", + module.i32.const(0), + module.i32.const(4) + ), + module.array.new_elem( + binaryen.getHeapType(funcArrayType), + "0", + module.i32.const(0), + module.i32.const(1) + ), + module.array.get( + module.global.get("array-global", arrayType), + module.i32.const(0), + binaryen.i32, + true + ), + module.array.set( + module.global.get("array-global", arrayType), + module.i32.const(1), + module.i32.const(2) + ), + module.array.len( + module.global.get("array-global", arrayType) + ), + module.array.fill( + module.global.get("array-global", arrayType), + module.i32.const(0), + module.i32.const(1), + module.i32.const(2) + ), + module.array.copy( + module.global.get("array-global", arrayType), + module.i32.const(0), + module.global.get("array-global", arrayType), + module.i32.const(1), + module.i32.const(2) + ), + module.array.init_data( + "0", + module.global.get("array-global", arrayType), + module.i32.const(0), + module.i32.const(1), + module.i32.const(2) + ), + module.array.init_elem( + "0", + module.global.get("funcArray-global", funcArrayType), + module.i32.const(0), + module.i32.const(1), + module.i32.const(2) + ) +]; +module.addFunction("main", binaryen.none, binaryen.none, [], + module.block( + null, + valueList.map(value => { + var type = binaryen.getExpressionType(value); + if (type === binaryen.none || type === binaryen.unreachable) + return value; + else + return module.drop(value); + }), + binaryen.none + ) +); + +assert(module.validate()); + +console.log(module.emitText()); diff --git a/test/binaryen.js/gc.js.txt b/test/binaryen.js/gc.js.txt new file mode 100644 index 00000000000..7b557c7c743 --- /dev/null +++ b/test/binaryen.js/gc.js.txt @@ -0,0 +1,116 @@ +(module + (type $0 (array (mut i8))) + (type $1 (struct (field (mut i16)) (field (mut f64)))) + (type $2 (array (mut funcref))) + (type $3 (func (param i32 i32) (result i32))) + (type $4 (func)) + (global $struct-global (mut (ref null $1)) (struct.new_default $1)) + (global $array-global (mut (ref null $0)) (array.new_default $0 + (i32.const 4) + )) + (global $funcArray-global (mut (ref null $2)) (array.new_default $2 + (i32.const 4) + )) + (memory $0 1) + (data $0 (i32.const 0) "\04\03\02\01") + (table $0 1 funcref) + (elem $0 (i32.const 0) $add) + (func $add (type $3) (param $0 i32) (param $1 i32) (result i32) + (i32.add + (local.get $0) + (local.get $1) + ) + ) + (func $main (type $4) + (drop + (struct.new $1 + (i32.const 1) + (f64.const 2.3) + ) + ) + (drop + (struct.new_default $1) + ) + (drop + (struct.get_s $1 0 + (global.get $struct-global) + ) + ) + (struct.set $1 1 + (global.get $struct-global) + (f64.const 1.23) + ) + (drop + (array.new $0 + (i32.const 0) + (i32.const 1) + ) + ) + (drop + (array.new_default $0 + (i32.const 1) + ) + ) + (drop + (array.new_fixed $0 3 + (i32.const 1) + (i32.const 2) + (i32.const 3) + ) + ) + (drop + (array.new_data $0 $0 + (i32.const 0) + (i32.const 4) + ) + ) + (drop + (array.new_elem $2 $0 + (i32.const 0) + (i32.const 1) + ) + ) + (drop + (array.get_s $0 + (global.get $array-global) + (i32.const 0) + ) + ) + (array.set $0 + (global.get $array-global) + (i32.const 1) + (i32.const 2) + ) + (drop + (array.len + (global.get $array-global) + ) + ) + (array.fill $0 + (global.get $array-global) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + (array.copy $0 $0 + (global.get $array-global) + (i32.const 0) + (global.get $array-global) + (i32.const 1) + (i32.const 2) + ) + (array.init_data $0 $0 + (global.get $array-global) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + (array.init_elem $2 $0 + (global.get $funcArray-global) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + ) +) + diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index c97de45a366..85937929d7e 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -518,25 +518,29 @@ void test_core() { BinaryenType v128 = BinaryenTypeVec128(); BinaryenType i8Array; BinaryenType i16Array; + BinaryenType funcArray; BinaryenType i32Struct; { - TypeBuilderRef tb = TypeBuilderCreate(3); + TypeBuilderRef tb = TypeBuilderCreate(4); TypeBuilderSetArrayType( tb, 0, BinaryenTypeInt32(), BinaryenPackedTypeInt8(), true); TypeBuilderSetArrayType( tb, 1, BinaryenTypeInt32(), BinaryenPackedTypeInt16(), true); + TypeBuilderSetArrayType( + tb, 2, BinaryenTypeFuncref(), BinaryenPackedTypeNotPacked(), true); TypeBuilderSetStructType( tb, - 2, + 3, (BinaryenType[]){BinaryenTypeInt32()}, (BinaryenPackedType[]){BinaryenPackedTypeNotPacked()}, (bool[]){true}, 1); - BinaryenHeapType builtHeapTypes[3]; + BinaryenHeapType builtHeapTypes[4]; TypeBuilderBuildAndDispose(tb, (BinaryenHeapType*)&builtHeapTypes, 0, 0); i8Array = BinaryenTypeFromHeapType(builtHeapTypes[0], true); i16Array = BinaryenTypeFromHeapType(builtHeapTypes[1], true); - i32Struct = BinaryenTypeFromHeapType(builtHeapTypes[2], true); + funcArray = BinaryenTypeFromHeapType(builtHeapTypes[2], true); + i32Struct = BinaryenTypeFromHeapType(builtHeapTypes[3], true); } // Memory. Add it before creating any memory-using instructions. @@ -1170,12 +1174,30 @@ void test_core() { makeInt32(module, 42)), BinaryenArrayLen(module, BinaryenGlobalGet(module, "i8Array-global", i8Array)), + BinaryenArrayFill(module, + BinaryenGlobalGet(module, "i8Array-global", i8Array), + makeInt32(module, 0), + makeInt32(module, 1), + makeInt32(module, 2)), BinaryenArrayCopy(module, BinaryenGlobalGet(module, "i8Array-global", i8Array), makeInt32(module, 0), BinaryenGlobalGet(module, "i8Array-global", i8Array), makeInt32(module, 1), makeInt32(module, 2)), + BinaryenArrayInitData(module, + "0", + BinaryenGlobalGet(module, "i8Array-global", i8Array), + makeInt32(module, 0), + makeInt32(module, 1), + makeInt32(module, 2)), + BinaryenArrayInitElem( + module, + "0", + BinaryenGlobalGet(module, "funcArray-global", funcArray), + makeInt32(module, 0), + makeInt32(module, 1), + makeInt32(module, 2)), // Strings BinaryenStringNew(module, BinaryenStringNewLossyUTF8Array(), @@ -1302,6 +1324,15 @@ void test_core() { true, BinaryenArrayNew( module, BinaryenTypeGetHeapType(i16Array), makeInt32(module, 0), 0)); + BinaryenAddGlobal( + module, + "funcArray-global", + funcArray, + true, + BinaryenArrayNew(module, + BinaryenTypeGetHeapType(funcArray), + makeInt32(module, 0), + BinaryenRefNull(module, BinaryenTypeNullFuncref()))); BinaryenAddGlobal( module, "i32Struct-global", diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 78f1c73552f..1961547c5a1 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -67,17 +67,22 @@ BinaryenFeatureAll: 4194303 (type $0 (array (mut i8))) (type $1 (struct (field (mut i32)))) (type $2 (func (param i32 i64 f32 f64) (result i32))) - (type $3 (array (mut i16))) - (type $4 (func (param i32))) - (type $5 (func (param i32 f64) (result f32))) - (type $6 (func)) - (import "module" "base" (func $an-imported (type $5) (param i32 f64) (result f32))) + (type $3 (array (mut funcref))) + (type $4 (array (mut i16))) + (type $5 (func (param i32))) + (type $6 (func (param i32 f64) (result f32))) + (type $7 (func)) + (import "module" "base" (func $an-imported (type $6) (param i32 f64) (result f32))) (global $a-global i32 (i32.const 7)) (global $a-mutable-global (mut f32) (f32.const 7.5)) (global $i8Array-global (mut (ref null $0)) (array.new_default $0 (i32.const 0) )) - (global $i16Array-global (mut (ref null $3)) (array.new_default $3 + (global $i16Array-global (mut (ref null $4)) (array.new_default $4 + (i32.const 0) + )) + (global $funcArray-global (mut (ref null $3)) (array.new $3 + (ref.null nofunc) (i32.const 0) )) (global $i32Struct-global (mut (ref null $1)) (struct.new_default $1)) @@ -91,7 +96,7 @@ BinaryenFeatureAll: 4194303 (table $0 1 1 funcref) (elem $0 (table $0) (i32.const 0) func $"kitchen()sinker") (elem $passive func $"kitchen()sinker") - (tag $a-tag (type $4) (param i32)) + (tag $a-tag (type $5) (param i32)) (export "mem" (memory $0)) (export "kitchen_sinker" (func $"kitchen()sinker")) (start $starter) @@ -2327,6 +2332,12 @@ BinaryenFeatureAll: 4194303 (global.get $i8Array-global) ) ) + (array.fill $0 + (global.get $i8Array-global) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) (array.copy $0 $0 (global.get $i8Array-global) (i32.const 0) @@ -2334,6 +2345,18 @@ BinaryenFeatureAll: 4194303 (i32.const 1) (i32.const 2) ) + (array.init_data $0 $0 + (global.get $i8Array-global) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + (array.init_elem $3 $0 + (global.get $funcArray-global) + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) (drop (string.new_lossy_utf8_array (global.get $i8Array-global) @@ -2419,7 +2442,7 @@ BinaryenFeatureAll: 4194303 (i32.const 42) ) ) - (func $starter (type $6) + (func $starter (type $7) (nop) ) )