From 854b13e38ea406abdf4d2588c3073dd1e548e2d1 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 10 Jun 2024 16:42:02 -0700 Subject: [PATCH 01/17] work --- src/wasm2js.h | 14 ++++++++------ test/wasm2js/tables.wast | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 test/wasm2js/tables.wast diff --git a/src/wasm2js.h b/src/wasm2js.h index 2084c04537c..045bf59feea 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -2236,16 +2236,18 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, visit(curr->right, EXPRESSION_RESULT)); } Ref visitTableGet(TableGet* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), + visit(curr->index, EXPRESSION_RESULT)); } Ref visitTableSet(TableSet* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + auto sub = ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), + visit(curr->index, EXPRESSION_RESULT)); + auto value = visit(curr->value, EXPRESSION_RESULT); + return ValueBuilder::makeBinary(sub, SET, value); } Ref visitTableSize(TableSize* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeDot(ValueBuilder::makeName(FUNCTION_TABLE), + ValueBuilder::makeName("length")); } Ref visitTableGrow(TableGrow* curr) { unimplemented(curr); diff --git a/test/wasm2js/tables.wast b/test/wasm2js/tables.wast new file mode 100644 index 00000000000..bab7646316f --- /dev/null +++ b/test/wasm2js/tables.wast @@ -0,0 +1,22 @@ +(module + (import "env" "table" (table $table 7 funcref)) + + (elem (i32.const 1) $table.get) + + (func $table.get (export "table.get") (result funcref) + (table.get $table + (i32.const 1) + ) + ) + + (func $table.set (export "table.set") + (table.set $table + (i32.const 1) + (ref.func $table.set) + ) + ) + + (func $table.size (export "table.size") (result i32) + (table.size $table) + ) +) From 421f4759b9c0440739a9ed142e249f00166846fc Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 10:05:06 -0700 Subject: [PATCH 02/17] work --- src/asmjs/shared-constants.cpp | 3 +++ src/asmjs/shared-constants.h | 3 +++ src/wasm2js.h | 23 ++++++++++++++++------- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index 57b9c4f8790..13d1fc89ded 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -62,6 +62,8 @@ IString ENV("env"); IString STACKTOP("STACKTOP"); IString STACK_MAX("STACK_MAX"); IString INSTRUMENT("instrument"); +IString NULL_("null"); +IString LENGTH("length"); IString MATH_IMUL("Math_imul"); IString MATH_ABS("Math_abs"); IString MATH_CEIL("Math_ceil"); @@ -83,6 +85,7 @@ IString WASM_ROTR32("__wasm_rotr_i32"); IString WASM_ROTR64("__wasm_rotr_i64"); IString WASM_MEMORY_GROW("__wasm_memory_grow"); IString WASM_MEMORY_SIZE("__wasm_memory_size"); +IString WASM_TABLE_GROW("__wasm_table_grow"); IString WASM_FETCH_HIGH_BITS("__wasm_fetch_high_bits"); IString INT64_TO_32_HIGH_BITS("i64toi32_i32$HIGH_BITS"); IString WASM_NEAREST_F32("__wasm_nearest_f32"); diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index e199b1361d3..fa5d807787e 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -65,6 +65,8 @@ extern IString ENV; extern IString STACKTOP; extern IString STACK_MAX; extern IString INSTRUMENT; +extern IString NULL_; +extern IString LENGTH; extern IString MATH_IMUL; extern IString MATH_ABS; extern IString MATH_CLZ32; @@ -86,6 +88,7 @@ extern IString WASM_ROTR32; extern IString WASM_ROTR64; extern IString WASM_MEMORY_GROW; extern IString WASM_MEMORY_SIZE; +extern IString WASM_TABLE_GROW; extern IString WASM_FETCH_HIGH_BITS; extern IString INT64_TO_32_HIGH_BITS; extern IString WASM_NEAREST_F32; diff --git a/src/wasm2js.h b/src/wasm2js.h index 045bf59feea..503f630847a 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -321,6 +321,7 @@ class Wasm2JSBuilder { void addFunctionImport(Ref ast, Function* import); void addGlobalImport(Ref ast, Global* import); void addTable(Ref ast, Module* wasm); + void addTableGrowFunc(Ref ast, Module* wasm, Table* table); void addStart(Ref ast, Module* wasm); void addExports(Ref ast, Module* wasm); void addGlobal(Ref ast, Global* global); @@ -672,12 +673,11 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) { if (!table->imported()) { TableUtils::FlatTable flat(*wasm, *table); if (flat.valid) { - Name null("null"); for (auto& name : flat.names) { if (name.is()) { name = fromName(name, NameScope::Top); } else { - name = null; + name = NULL_; } ValueBuilder::appendToArray(theArray, ValueBuilder::makeName(name)); } @@ -740,9 +740,16 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) { }); }); } + + if (table->max > table->initial) { + addTableGrowFunc(ast, wasm, table.get()); + } } } +void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { +} + void Wasm2JSBuilder::addStart(Ref ast, Module* wasm) { if (wasm->start.is()) { ast->push_back( @@ -2221,11 +2228,11 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, visit(curr->value, EXPRESSION_RESULT), visit(curr->size, EXPRESSION_RESULT)); } - Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName("null"); } + Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName(NULL_); } Ref visitRefIsNull(RefIsNull* curr) { return ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT), EQ, - ValueBuilder::makeName("null")); + ValueBuilder::makeName(NULL_)); } Ref visitRefFunc(RefFunc* curr) { return ValueBuilder::makeName(fromName(curr->func, NameScope::Top)); @@ -2247,11 +2254,13 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, } Ref visitTableSize(TableSize* curr) { return ValueBuilder::makeDot(ValueBuilder::makeName(FUNCTION_TABLE), - ValueBuilder::makeName("length")); + ValueBuilder::makeName(LENGTH)); } Ref visitTableGrow(TableGrow* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeCall( + WASM_TABLE_GROW, + makeJsCoercion(visit(curr->delta, EXPRESSION_RESULT), + wasmToJsType(curr->delta->type))); } Ref visitTableFill(TableFill* curr) { unimplemented(curr); From 45dfb55c3373174d817c1944a9b699340ff03fa0 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 10:16:40 -0700 Subject: [PATCH 03/17] work --- src/wasm2js.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/wasm2js.h b/src/wasm2js.h index 503f630847a..807a2af915f 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -748,6 +748,43 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) { } void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { + // TODO: support multiple tables + // TODO: check for attempts to grow beyond the declared max + + Ref tableGrowFunc = ValueBuilder::makeFunction(WASM_TABLE_GROW); + ValueBuilder::appendArgumentToFunction(tableGrowFunc, IString("delta")); + + auto getTableDotLength = [&]() { + return ValueBuilder::makeDot(ValueBuilder::makeName(FUNCTION_TABLE), + ValueBuilder::makeName(LENGTH)); + }; + + // Save the old size. + Ref oldSize = ValueBuilder::makeVar(); + tableGrowFunc[3]->push_back(oldSize); + ValueBuilder::appendToVar( + oldSize, + IString("oldSize"), + getTableDotLength())); + + // Compute the new size. + Ref newSize = ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("oldSize")), + PLUS, + ValueBuilder::makeName(IString("delta"))); + + // Grow/shrink. + Ref grow = ValueBuilder::makeBinary( + getTableDotLength(), + SET, + newSize); + tableGrowFunc[3]->push_back(grow); + + // Return the old size. + tableGrowFunc[3]->push_back( + ValueBuilder::makeReturn(ValueBuilder::makeName(IString("oldSize")))); + + ast->push_back(tableGrowFunc); } void Wasm2JSBuilder::addStart(Ref ast, Module* wasm) { From 0f1d998020f0801bf69849922842b75758b6d630 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 10:19:01 -0700 Subject: [PATCH 04/17] work --- src/asmjs/shared-constants.cpp | 1 - src/asmjs/shared-constants.h | 1 - src/wasm2js.h | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index 13d1fc89ded..6adc383d38f 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -62,7 +62,6 @@ IString ENV("env"); IString STACKTOP("STACKTOP"); IString STACK_MAX("STACK_MAX"); IString INSTRUMENT("instrument"); -IString NULL_("null"); IString LENGTH("length"); IString MATH_IMUL("Math_imul"); IString MATH_ABS("Math_abs"); diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index fa5d807787e..ec3c5faf84a 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -65,7 +65,6 @@ extern IString ENV; extern IString STACKTOP; extern IString STACK_MAX; extern IString INSTRUMENT; -extern IString NULL_; extern IString LENGTH; extern IString MATH_IMUL; extern IString MATH_ABS; diff --git a/src/wasm2js.h b/src/wasm2js.h index 807a2af915f..da35b44abfd 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -765,7 +765,7 @@ void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { ValueBuilder::appendToVar( oldSize, IString("oldSize"), - getTableDotLength())); + getTableDotLength()); // Compute the new size. Ref newSize = ValueBuilder::makeBinary( From 6ab13e0cea619e0fdaf0d3c576e930c8219bcc6c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 10:21:19 -0700 Subject: [PATCH 05/17] prep --- test/wasm2js/tables.wast | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/wasm2js/tables.wast b/test/wasm2js/tables.wast index bab7646316f..4d9bf3822b3 100644 --- a/test/wasm2js/tables.wast +++ b/test/wasm2js/tables.wast @@ -19,4 +19,11 @@ (func $table.size (export "table.size") (result i32) (table.size $table) ) + + (func $table.grow (export "table.grow") (result i32) + (table.grow $table + (ref.func $table.grow) + (i32.const 42) + ) + ) ) From eef7e4b3b52839b051ee4c9d6d89f3b82bf301f3 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 10:23:00 -0700 Subject: [PATCH 06/17] prep --- src/wasm2js.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wasm2js.h b/src/wasm2js.h index da35b44abfd..8a5c9c5d867 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -752,6 +752,7 @@ void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { // TODO: check for attempts to grow beyond the declared max Ref tableGrowFunc = ValueBuilder::makeFunction(WASM_TABLE_GROW); + ValueBuilder::appendArgumentToFunction(tableGrowFunc, IString("value")); ValueBuilder::appendArgumentToFunction(tableGrowFunc, IString("delta")); auto getTableDotLength = [&]() { @@ -780,6 +781,8 @@ void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { newSize); tableGrowFunc[3]->push_back(grow); + // Fill with the new value. TODO + // Return the old size. tableGrowFunc[3]->push_back( ValueBuilder::makeReturn(ValueBuilder::makeName(IString("oldSize")))); @@ -2296,6 +2299,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref visitTableGrow(TableGrow* curr) { return ValueBuilder::makeCall( WASM_TABLE_GROW, + visit(curr->value, EXPRESSION_RESULT), makeJsCoercion(visit(curr->delta, EXPRESSION_RESULT), wasmToJsType(curr->delta->type))); } From 0e98b3f97a58052f863f5e1c7615485c22e123e5 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:10:14 -0700 Subject: [PATCH 07/17] prep --- src/asmjs/shared-constants.cpp | 2 ++ src/asmjs/shared-constants.h | 2 ++ src/wasm2js.h | 44 +++++++++++++++++++++++++++++----- test/wasm2js/tables.wast | 17 +++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index 6adc383d38f..d32fb254a5a 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -85,6 +85,8 @@ IString WASM_ROTR64("__wasm_rotr_i64"); IString WASM_MEMORY_GROW("__wasm_memory_grow"); IString WASM_MEMORY_SIZE("__wasm_memory_size"); IString WASM_TABLE_GROW("__wasm_table_grow"); +IString WASM_TABLE_FILL("__wasm_table_fill"); +IString WASM_TABLE_COPY("__wasm_table_copy"); IString WASM_FETCH_HIGH_BITS("__wasm_fetch_high_bits"); IString INT64_TO_32_HIGH_BITS("i64toi32_i32$HIGH_BITS"); IString WASM_NEAREST_F32("__wasm_nearest_f32"); diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index ec3c5faf84a..54123e3f4d6 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -88,6 +88,8 @@ extern IString WASM_ROTR64; extern IString WASM_MEMORY_GROW; extern IString WASM_MEMORY_SIZE; extern IString WASM_TABLE_GROW; +extern IString WASM_TABLE_FILL; +extern IString WASM_TABLE_COPY; extern IString WASM_FETCH_HIGH_BITS; extern IString INT64_TO_32_HIGH_BITS; extern IString WASM_NEAREST_F32; diff --git a/src/wasm2js.h b/src/wasm2js.h index 8a5c9c5d867..5f90191e73e 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -322,6 +322,8 @@ class Wasm2JSBuilder { void addGlobalImport(Ref ast, Global* import); void addTable(Ref ast, Module* wasm); void addTableGrowFunc(Ref ast, Module* wasm, Table* table); + void addTableFillFunc(Ref ast, Module* wasm, Table* table); + void addTableCopyFunc(Ref ast, Module* wasm, Table* table); void addStart(Ref ast, Module* wasm); void addExports(Ref ast, Module* wasm); void addGlobal(Ref ast, Global* global); @@ -744,6 +746,8 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) { if (table->max > table->initial) { addTableGrowFunc(ast, wasm, table.get()); } + addTableFillFunc(ast, wasm, table.get()); + addTableCopyFunc(ast, wasm, table.get()); } } @@ -781,7 +785,20 @@ void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { newSize); tableGrowFunc[3]->push_back(grow); - // Fill with the new value. TODO + // Fill with the new value, if we grew. + Ref fill = ValueBuilder::makeCall( + WASM_TABLE_FILL, + ValueBuilder::makeName(IString("oldSize")), + ValueBuilder::makeName(IString("value")), + ValueBuilder::makeName(IString("delta")), + ); + Ref maybeFill = ValueBuilder::makeIf( + ValueBuilder::makeBinary(ValueBuilder::makeName(IString("newSize")), + GT, + ValueBuilder::makeName(IString("oldSize"))), + fill, + NULL)); + tableGrowFunc[3]->push_back(maybeFill); // Return the old size. tableGrowFunc[3]->push_back( @@ -2299,17 +2316,32 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref visitTableGrow(TableGrow* curr) { return ValueBuilder::makeCall( WASM_TABLE_GROW, - visit(curr->value, EXPRESSION_RESULT), + makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), + wasmToJsType(curr->value->type)), makeJsCoercion(visit(curr->delta, EXPRESSION_RESULT), wasmToJsType(curr->delta->type))); } Ref visitTableFill(TableFill* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeCall( + WASM_TABLE_FILL, + makeJsCoercion(visit(curr->dest, EXPRESSION_RESULT), + wasmToJsType(curr->dest->type)), + makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), + wasmToJsType(curr->value->type)), + makeJsCoercion(visit(curr->size, EXPRESSION_RESULT), + wasmToJsType(curr->size->type)) + ); } Ref visitTableCopy(TableCopy* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeCall( + WASM_TABLE_COPY, + makeJsCoercion(visit(curr->dest, EXPRESSION_RESULT), + wasmToJsType(curr->dest->type)), + makeJsCoercion(visit(curr->source, EXPRESSION_RESULT), + wasmToJsType(curr->source->type)), + makeJsCoercion(visit(curr->size, EXPRESSION_RESULT), + wasmToJsType(curr->size->type)) + ); } Ref visitTry(Try* curr) { unimplemented(curr); diff --git a/test/wasm2js/tables.wast b/test/wasm2js/tables.wast index 4d9bf3822b3..56e85e40d2f 100644 --- a/test/wasm2js/tables.wast +++ b/test/wasm2js/tables.wast @@ -26,4 +26,21 @@ (i32.const 42) ) ) + + (func $table.fill (export "table.fill") (param $dest i32) (param $value funcref) (param $size i32) + (table.fill $table + (local.get $dest) + (local.get $value) + (local.get $size) + ) + ) + + (func $table.copy (export "table.copy") (param $dest i32) (param $source i32) (param $size i32) + (table.copy $table $table + (local.get $dest) + (local.get $source) + (local.get $size) + ) + ) ) + From ebc01d40ced8fbe1ca43e5cf33475516b1c93ddc Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:22:08 -0700 Subject: [PATCH 08/17] prep --- src/wasm2js.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index 5f90191e73e..10c0f3c29b0 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -790,14 +790,14 @@ void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { WASM_TABLE_FILL, ValueBuilder::makeName(IString("oldSize")), ValueBuilder::makeName(IString("value")), - ValueBuilder::makeName(IString("delta")), + ValueBuilder::makeName(IString("delta")) ); Ref maybeFill = ValueBuilder::makeIf( ValueBuilder::makeBinary(ValueBuilder::makeName(IString("newSize")), GT, ValueBuilder::makeName(IString("oldSize"))), fill, - NULL)); + NULL); tableGrowFunc[3]->push_back(maybeFill); // Return the old size. @@ -807,6 +807,14 @@ void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { ast->push_back(tableGrowFunc); } +void Wasm2JSBuilder::addTableFillFunc(Ref ast, Module* wasm, Table* table) { + +// Ref ret = ValueBuilder::makeWhile(ValueBuilder::makeInt(1), body); +} + +void Wasm2JSBuilder::addTableCopyFunc(Ref ast, Module* wasm, Table* table) { +} + void Wasm2JSBuilder::addStart(Ref ast, Module* wasm) { if (wasm->start.is()) { ast->push_back( From 709990f0f42b4fcb8dcf1993d0162b507dadc402 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:33:28 -0700 Subject: [PATCH 09/17] prep --- src/wasm2js.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index 10c0f3c29b0..7b993ea72d2 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -808,8 +808,55 @@ void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { } void Wasm2JSBuilder::addTableFillFunc(Ref ast, Module* wasm, Table* table) { + Ref tableFillFunc = ValueBuilder::makeFunction(WASM_TABLE_FILL); + ValueBuilder::appendArgumentToFunction(tableFillFunc, IString("dest")); + ValueBuilder::appendArgumentToFunction(tableFillFunc, IString("value")); + ValueBuilder::appendArgumentToFunction(tableFillFunc, IString("size")); + + // Set up a variable to loop over. + Ref i = ValueBuilder::makeVar(); + tableFillFunc[3]->push_back(i); + ValueBuilder::appendToVar( + i, + IString("i"), + ValueBuilder::makeInt(0)); + + // Compute the index to write to in the table for the current loop iteration. + Ref index = ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("dest")), + PLUS, + ValueBuilder::makeName(IString("i")) + ); + + // Set the value for the current loop iteration. + Ref set = ValueBuilder::makeBinary( + ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), index), + SET, + ValueBuilder::makeName(IString("value"))); -// Ref ret = ValueBuilder::makeWhile(ValueBuilder::makeInt(1), body); + // Increment the variable. + Ref increment = ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("i")), + SET, + ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("i")), + PLUS, + ValueBuilder::makeInt(1))); + + // Loop body: set the value, and increment. + Ref body = ValueBuilder::makeBlock(); + block[1]->push_back(set); + block[1]->push_back(increment); + + // Loop until we reach the size. + Ref loopCondition = + ValueBuilder::makeBinary(ValueBuilder::makeName(IString("i")), + LT, + ValueBuilder::makeName(IString("size"))); + Ref loop = ValueBuilder::makeWhile(loopCondition, body); + tableFillFunc[3]->push_back(loop); + + ast->push_back(tableFillFunc); } void Wasm2JSBuilder::addTableCopyFunc(Ref ast, Module* wasm, Table* table) { From bb61473f2725200334f57d9fd9dad3f4d1f891a7 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:34:04 -0700 Subject: [PATCH 10/17] prep --- src/wasm2js.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index 7b993ea72d2..cfc9442b0fb 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -845,8 +845,8 @@ void Wasm2JSBuilder::addTableFillFunc(Ref ast, Module* wasm, Table* table) { // Loop body: set the value, and increment. Ref body = ValueBuilder::makeBlock(); - block[1]->push_back(set); - block[1]->push_back(increment); + body[1]->push_back(set); + body[1]->push_back(increment); // Loop until we reach the size. Ref loopCondition = From 670ee9b958e3c8b220857a97d355708112845135 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:36:05 -0700 Subject: [PATCH 11/17] prep --- src/wasm2js.h | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/wasm2js.h b/src/wasm2js.h index cfc9442b0fb..265432298fc 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -860,6 +860,60 @@ void Wasm2JSBuilder::addTableFillFunc(Ref ast, Module* wasm, Table* table) { } void Wasm2JSBuilder::addTableCopyFunc(Ref ast, Module* wasm, Table* table) { + Ref tableCopyFunc = ValueBuilder::makeFunction(WASM_TABLE_COPY); + ValueBuilder::appendArgumentToFunction(tableCopyFunc, IString("dest")); + ValueBuilder::appendArgumentToFunction(tableCopyFunc, IString("source")); + ValueBuilder::appendArgumentToFunction(tableCopyFunc, IString("size")); + + // Set up a variable to loop over. + Ref i = ValueBuilder::makeVar(); + tableCopyFunc[3]->push_back(i); + ValueBuilder::appendToVar( + i, + IString("i"), + ValueBuilder::makeInt(0)); + + // Compute the table indexes to use for the current loop iteration. + Ref destIndex = ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("dest")), + PLUS, + ValueBuilder::makeName(IString("i")) + ); + Ref sourceIndex = ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("source")), + PLUS, + ValueBuilder::makeName(IString("i")) + ); + + // Set the value for the current loop iteration. + Ref set = ValueBuilder::makeBinary( + ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), destIndex), + SET, + ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), sourceIndex)); + + // Increment the variable. + Ref increment = ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("i")), + SET, + ValueBuilder::makeBinary( + ValueBuilder::makeName(IString("i")), + PLUS, + ValueBuilder::makeInt(1))); + + // Loop body: set the value, and increment. + Ref body = ValueBuilder::makeBlock(); + body[1]->push_back(set); + body[1]->push_back(increment); + + // Loop until we reach the size. + Ref loopCondition = + ValueBuilder::makeBinary(ValueBuilder::makeName(IString("i")), + LT, + ValueBuilder::makeName(IString("size"))); + Ref loop = ValueBuilder::makeWhile(loopCondition, body); + tableCopyFunc[3]->push_back(loop); + + ast->push_back(tableCopyFunc); } void Wasm2JSBuilder::addStart(Ref ast, Module* wasm) { From 9ea29ea419ad810f7b02a85027b17af58fa1aa35 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:37:28 -0700 Subject: [PATCH 12/17] work --- test/wasm2js/dynamicLibrary.2asm.js | 16 +++++ test/wasm2js/dynamicLibrary.2asm.js.opt | 16 +++++ test/wasm2js/emscripten.2asm.js | 25 +++++++ test/wasm2js/emscripten.2asm.js.opt | 25 +++++++ test/wasm2js/func-ptr-offset.2asm.js | 25 +++++++ test/wasm2js/func-ptr-offset.2asm.js.opt | 25 +++++++ test/wasm2js/func_ptrs.2asm.js | 32 +++++++++ test/wasm2js/indirect-select.2asm.js | 25 +++++++ test/wasm2js/indirect-select.2asm.js.opt | 25 +++++++ test/wasm2js/left-to-right.2asm.js | 16 +++++ test/wasm2js/ordering.2asm.js | 25 +++++++ test/wasm2js/ordering.2asm.js.opt | 25 +++++++ test/wasm2js/tables.2asm.js | 89 ++++++++++++++++++++++++ test/wasm2js/tables.2asm.js.opt | 89 ++++++++++++++++++++++++ 14 files changed, 458 insertions(+) create mode 100644 test/wasm2js/tables.2asm.js create mode 100644 test/wasm2js/tables.2asm.js.opt diff --git a/test/wasm2js/dynamicLibrary.2asm.js b/test/wasm2js/dynamicLibrary.2asm.js index bb6f4dcaff6..af453dcf27d 100644 --- a/test/wasm2js/dynamicLibrary.2asm.js +++ b/test/wasm2js/dynamicLibrary.2asm.js @@ -76,6 +76,22 @@ function asmFunc(imports) { var FUNCTION_TABLE = Table(new Array(10)); FUNCTION_TABLE[import$tableBase + 0] = foo; FUNCTION_TABLE[import$tableBase + 1] = bar; + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/dynamicLibrary.2asm.js.opt b/test/wasm2js/dynamicLibrary.2asm.js.opt index 543f755f37d..8197dc3b641 100644 --- a/test/wasm2js/dynamicLibrary.2asm.js.opt +++ b/test/wasm2js/dynamicLibrary.2asm.js.opt @@ -68,6 +68,22 @@ function asmFunc(imports) { var FUNCTION_TABLE = Table(new Array(10)); FUNCTION_TABLE[import$tableBase + 0] = foo; FUNCTION_TABLE[import$tableBase + 1] = foo; + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/emscripten.2asm.js b/test/wasm2js/emscripten.2asm.js index 8ba8564ceea..8d12785d2c0 100644 --- a/test/wasm2js/emscripten.2asm.js +++ b/test/wasm2js/emscripten.2asm.js @@ -216,6 +216,31 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = tabled; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/emscripten.2asm.js.opt b/test/wasm2js/emscripten.2asm.js.opt index caef2389639..f63e4bade1a 100644 --- a/test/wasm2js/emscripten.2asm.js.opt +++ b/test/wasm2js/emscripten.2asm.js.opt @@ -211,6 +211,31 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = internal; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/func-ptr-offset.2asm.js b/test/wasm2js/func-ptr-offset.2asm.js index dcac8386ef4..be9e34aa316 100644 --- a/test/wasm2js/func-ptr-offset.2asm.js +++ b/test/wasm2js/func-ptr-offset.2asm.js @@ -28,6 +28,31 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [null, t1, t2, t3]; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "call": $0 }; diff --git a/test/wasm2js/func-ptr-offset.2asm.js.opt b/test/wasm2js/func-ptr-offset.2asm.js.opt index e5ad86908db..05363d76d77 100644 --- a/test/wasm2js/func-ptr-offset.2asm.js.opt +++ b/test/wasm2js/func-ptr-offset.2asm.js.opt @@ -28,6 +28,31 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [null, t1, t2, t3]; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "call": $0 }; diff --git a/test/wasm2js/func_ptrs.2asm.js b/test/wasm2js/func_ptrs.2asm.js index 3e5c82e78c6..0f3d13f58ef 100644 --- a/test/wasm2js/func_ptrs.2asm.js +++ b/test/wasm2js/func_ptrs.2asm.js @@ -90,6 +90,22 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [t1, t2, t3, u1, u2, t1, t3]; + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "callt": $0, "callu": $1 @@ -126,6 +142,22 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [t1, t2]; + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "callt": $0 }; diff --git a/test/wasm2js/indirect-select.2asm.js b/test/wasm2js/indirect-select.2asm.js index b1725927481..7519df6c64b 100644 --- a/test/wasm2js/indirect-select.2asm.js +++ b/test/wasm2js/indirect-select.2asm.js @@ -23,6 +23,31 @@ function asmFunc(imports) { return FUNCTION_TABLE[(x ? 0 : 1) | 0]() | 0 | 0; } + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "foo_true": foo_true, "foo_false": foo_false diff --git a/test/wasm2js/indirect-select.2asm.js.opt b/test/wasm2js/indirect-select.2asm.js.opt index 2d1792a53d9..b4eaaebd4b2 100644 --- a/test/wasm2js/indirect-select.2asm.js.opt +++ b/test/wasm2js/indirect-select.2asm.js.opt @@ -23,6 +23,31 @@ function asmFunc(imports) { return FUNCTION_TABLE[!$0 | 0]() | 0; } + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "foo_true": foo_true, "foo_false": foo_false diff --git a/test/wasm2js/left-to-right.2asm.js b/test/wasm2js/left-to-right.2asm.js index 6553cbc11d5..64dddaf93e5 100644 --- a/test/wasm2js/left-to-right.2asm.js +++ b/test/wasm2js/left-to-right.2asm.js @@ -2082,6 +2082,22 @@ function asmFunc(imports) { bufferView = HEAPU8; var FUNCTION_TABLE = [i32_t0, i32_t1, i64_t0, i64_t1, f32_t0, f32_t1, f64_t0, f64_t1]; + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/ordering.2asm.js b/test/wasm2js/ordering.2asm.js index 672e8d8aa79..cbf3398b761 100644 --- a/test/wasm2js/ordering.2asm.js +++ b/test/wasm2js/ordering.2asm.js @@ -47,6 +47,31 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = baz; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "main": main }; diff --git a/test/wasm2js/ordering.2asm.js.opt b/test/wasm2js/ordering.2asm.js.opt index 912fdbacd4e..5c29f9b4d79 100644 --- a/test/wasm2js/ordering.2asm.js.opt +++ b/test/wasm2js/ordering.2asm.js.opt @@ -38,6 +38,31 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = baz; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + return { "main": main }; diff --git a/test/wasm2js/tables.2asm.js b/test/wasm2js/tables.2asm.js new file mode 100644 index 00000000000..37ca1b3d50d --- /dev/null +++ b/test/wasm2js/tables.2asm.js @@ -0,0 +1,89 @@ +import * as env from 'env'; + +function asmFunc(imports) { + var env = imports.env; + var FUNCTION_TABLE = env.table; + var Math_imul = Math.imul; + var Math_fround = Math.fround; + var Math_abs = Math.abs; + var Math_clz32 = Math.clz32; + var Math_min = Math.min; + var Math_max = Math.max; + var Math_floor = Math.floor; + var Math_ceil = Math.ceil; + var Math_trunc = Math.trunc; + var Math_sqrt = Math.sqrt; + function table_get() { + return FUNCTION_TABLE[1]; + } + + function table_set() { + FUNCTION_TABLE[1] = table_set; + } + + function table_size() { + return FUNCTION_TABLE.length | 0; + } + + function table_grow() { + return __wasm_table_grow(table_grow, 42 | 0) | 0; + } + + function table_fill(dest, value, size) { + dest = dest | 0; + size = size | 0; + __wasm_table_fill(dest | 0, value, size | 0); + } + + function table_copy(dest, source, size) { + dest = dest | 0; + source = source | 0; + size = size | 0; + __wasm_table_copy(dest | 0, source | 0, size | 0); + } + + FUNCTION_TABLE[1] = table_get; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + + return { + "table_get": table_get, + "table_set": table_set, + "table_size": table_size, + "table_grow": table_grow, + "table_fill": table_fill, + "table_copy": table_copy + }; +} + +var retasmFunc = asmFunc({ + "env": env, +}); +export var table_get = retasmFunc.table_get; +export var table_set = retasmFunc.table_set; +export var table_size = retasmFunc.table_size; +export var table_grow = retasmFunc.table_grow; +export var table_fill = retasmFunc.table_fill; +export var table_copy = retasmFunc.table_copy; diff --git a/test/wasm2js/tables.2asm.js.opt b/test/wasm2js/tables.2asm.js.opt new file mode 100644 index 00000000000..a27a74698f6 --- /dev/null +++ b/test/wasm2js/tables.2asm.js.opt @@ -0,0 +1,89 @@ +import * as env from 'env'; + +function asmFunc(imports) { + var env = imports.env; + var FUNCTION_TABLE = env.table; + var Math_imul = Math.imul; + var Math_fround = Math.fround; + var Math_abs = Math.abs; + var Math_clz32 = Math.clz32; + var Math_min = Math.min; + var Math_max = Math.max; + var Math_floor = Math.floor; + var Math_ceil = Math.ceil; + var Math_trunc = Math.trunc; + var Math_sqrt = Math.sqrt; + function table_get() { + return FUNCTION_TABLE[1]; + } + + function table_set() { + FUNCTION_TABLE[1] = table_set; + } + + function table_size() { + return FUNCTION_TABLE.length | 0; + } + + function table_grow() { + return __wasm_table_grow(table_grow, 42) | 0; + } + + function table_fill($0, $1, $2) { + $0 = $0 | 0; + $2 = $2 | 0; + __wasm_table_fill($0 | 0, $1, $2 | 0); + } + + function table_copy($0, $1, $2) { + $0 = $0 | 0; + $1 = $1 | 0; + $2 = $2 | 0; + __wasm_table_copy($0 | 0, $1 | 0, $2 | 0); + } + + FUNCTION_TABLE[1] = table_get; + function __wasm_table_grow(value, delta) { + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = value; + i = i + 1; + }; + } + + function __wasm_table_copy(dest, source, size) { + var i = 0; + while (i < size) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + i = i + 1; + }; + } + + return { + "table_get": table_get, + "table_set": table_set, + "table_size": table_size, + "table_grow": table_grow, + "table_fill": table_fill, + "table_copy": table_copy + }; +} + +var retasmFunc = asmFunc({ + "env": env, +}); +export var table_get = retasmFunc.table_get; +export var table_set = retasmFunc.table_set; +export var table_size = retasmFunc.table_size; +export var table_grow = retasmFunc.table_grow; +export var table_fill = retasmFunc.table_fill; +export var table_copy = retasmFunc.table_copy; From d92ac973aa9e425acf70dd09b8134c058f2ba051 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:52:26 -0700 Subject: [PATCH 13/17] work --- src/abi/js.h | 3 + src/asmjs/shared-constants.cpp | 6 +- src/asmjs/shared-constants.h | 3 - src/wasm2js.h | 244 +++++++-------------------------- 4 files changed, 52 insertions(+), 204 deletions(-) diff --git a/src/abi/js.h b/src/abi/js.h index e121e9b2864..6c6a3912ed4 100644 --- a/src/abi/js.h +++ b/src/abi/js.h @@ -36,6 +36,9 @@ extern IString SCRATCH_STORE_F64; extern IString MEMORY_INIT; extern IString MEMORY_FILL; extern IString MEMORY_COPY; +extern IString TABLE_GROW; +extern IString TABLE_FILL; +extern IString TABLE_COPY; extern IString DATA_DROP; extern IString ATOMIC_WAIT_I32; extern IString ATOMIC_RMW_I64; diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index d32fb254a5a..bd924f17943 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -84,9 +84,6 @@ IString WASM_ROTR32("__wasm_rotr_i32"); IString WASM_ROTR64("__wasm_rotr_i64"); IString WASM_MEMORY_GROW("__wasm_memory_grow"); IString WASM_MEMORY_SIZE("__wasm_memory_size"); -IString WASM_TABLE_GROW("__wasm_table_grow"); -IString WASM_TABLE_FILL("__wasm_table_fill"); -IString WASM_TABLE_COPY("__wasm_table_copy"); IString WASM_FETCH_HIGH_BITS("__wasm_fetch_high_bits"); IString INT64_TO_32_HIGH_BITS("i64toi32_i32$HIGH_BITS"); IString WASM_NEAREST_F32("__wasm_nearest_f32"); @@ -115,6 +112,9 @@ IString SCRATCH_STORE_F64("wasm2js_scratch_store_f64"); IString MEMORY_INIT("wasm2js_memory_init"); IString MEMORY_FILL("wasm2js_memory_fill"); IString MEMORY_COPY("wasm2js_memory_copy"); +IString TABLE_GROW("wasm2js_table_grow"); +IString TABLE_FILL("wasm2js_table_fill"); +IString TABLE_COPY("wasm2js_table_copy"); IString DATA_DROP("wasm2js_data_drop"); IString ATOMIC_WAIT_I32("wasm2js_atomic_wait_i32"); IString ATOMIC_RMW_I64("wasm2js_atomic_rmw_i64"); diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index 54123e3f4d6..d48da560ec2 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -87,9 +87,6 @@ extern IString WASM_ROTR32; extern IString WASM_ROTR64; extern IString WASM_MEMORY_GROW; extern IString WASM_MEMORY_SIZE; -extern IString WASM_TABLE_GROW; -extern IString WASM_TABLE_FILL; -extern IString WASM_TABLE_COPY; extern IString WASM_FETCH_HIGH_BITS; extern IString INT64_TO_32_HIGH_BITS; extern IString WASM_NEAREST_F32; diff --git a/src/wasm2js.h b/src/wasm2js.h index 265432298fc..dd4e61a51b3 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -321,9 +321,6 @@ class Wasm2JSBuilder { void addFunctionImport(Ref ast, Function* import); void addGlobalImport(Ref ast, Global* import); void addTable(Ref ast, Module* wasm); - void addTableGrowFunc(Ref ast, Module* wasm, Table* table); - void addTableFillFunc(Ref ast, Module* wasm, Table* table); - void addTableCopyFunc(Ref ast, Module* wasm, Table* table); void addStart(Ref ast, Module* wasm); void addExports(Ref ast, Module* wasm); void addGlobal(Ref ast, Global* global); @@ -742,180 +739,9 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) { }); }); } - - if (table->max > table->initial) { - addTableGrowFunc(ast, wasm, table.get()); - } - addTableFillFunc(ast, wasm, table.get()); - addTableCopyFunc(ast, wasm, table.get()); } } -void Wasm2JSBuilder::addTableGrowFunc(Ref ast, Module* wasm, Table* table) { - // TODO: support multiple tables - // TODO: check for attempts to grow beyond the declared max - - Ref tableGrowFunc = ValueBuilder::makeFunction(WASM_TABLE_GROW); - ValueBuilder::appendArgumentToFunction(tableGrowFunc, IString("value")); - ValueBuilder::appendArgumentToFunction(tableGrowFunc, IString("delta")); - - auto getTableDotLength = [&]() { - return ValueBuilder::makeDot(ValueBuilder::makeName(FUNCTION_TABLE), - ValueBuilder::makeName(LENGTH)); - }; - - // Save the old size. - Ref oldSize = ValueBuilder::makeVar(); - tableGrowFunc[3]->push_back(oldSize); - ValueBuilder::appendToVar( - oldSize, - IString("oldSize"), - getTableDotLength()); - - // Compute the new size. - Ref newSize = ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("oldSize")), - PLUS, - ValueBuilder::makeName(IString("delta"))); - - // Grow/shrink. - Ref grow = ValueBuilder::makeBinary( - getTableDotLength(), - SET, - newSize); - tableGrowFunc[3]->push_back(grow); - - // Fill with the new value, if we grew. - Ref fill = ValueBuilder::makeCall( - WASM_TABLE_FILL, - ValueBuilder::makeName(IString("oldSize")), - ValueBuilder::makeName(IString("value")), - ValueBuilder::makeName(IString("delta")) - ); - Ref maybeFill = ValueBuilder::makeIf( - ValueBuilder::makeBinary(ValueBuilder::makeName(IString("newSize")), - GT, - ValueBuilder::makeName(IString("oldSize"))), - fill, - NULL); - tableGrowFunc[3]->push_back(maybeFill); - - // Return the old size. - tableGrowFunc[3]->push_back( - ValueBuilder::makeReturn(ValueBuilder::makeName(IString("oldSize")))); - - ast->push_back(tableGrowFunc); -} - -void Wasm2JSBuilder::addTableFillFunc(Ref ast, Module* wasm, Table* table) { - Ref tableFillFunc = ValueBuilder::makeFunction(WASM_TABLE_FILL); - ValueBuilder::appendArgumentToFunction(tableFillFunc, IString("dest")); - ValueBuilder::appendArgumentToFunction(tableFillFunc, IString("value")); - ValueBuilder::appendArgumentToFunction(tableFillFunc, IString("size")); - - // Set up a variable to loop over. - Ref i = ValueBuilder::makeVar(); - tableFillFunc[3]->push_back(i); - ValueBuilder::appendToVar( - i, - IString("i"), - ValueBuilder::makeInt(0)); - - // Compute the index to write to in the table for the current loop iteration. - Ref index = ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("dest")), - PLUS, - ValueBuilder::makeName(IString("i")) - ); - - // Set the value for the current loop iteration. - Ref set = ValueBuilder::makeBinary( - ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), index), - SET, - ValueBuilder::makeName(IString("value"))); - - // Increment the variable. - Ref increment = ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("i")), - SET, - ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("i")), - PLUS, - ValueBuilder::makeInt(1))); - - // Loop body: set the value, and increment. - Ref body = ValueBuilder::makeBlock(); - body[1]->push_back(set); - body[1]->push_back(increment); - - // Loop until we reach the size. - Ref loopCondition = - ValueBuilder::makeBinary(ValueBuilder::makeName(IString("i")), - LT, - ValueBuilder::makeName(IString("size"))); - Ref loop = ValueBuilder::makeWhile(loopCondition, body); - tableFillFunc[3]->push_back(loop); - - ast->push_back(tableFillFunc); -} - -void Wasm2JSBuilder::addTableCopyFunc(Ref ast, Module* wasm, Table* table) { - Ref tableCopyFunc = ValueBuilder::makeFunction(WASM_TABLE_COPY); - ValueBuilder::appendArgumentToFunction(tableCopyFunc, IString("dest")); - ValueBuilder::appendArgumentToFunction(tableCopyFunc, IString("source")); - ValueBuilder::appendArgumentToFunction(tableCopyFunc, IString("size")); - - // Set up a variable to loop over. - Ref i = ValueBuilder::makeVar(); - tableCopyFunc[3]->push_back(i); - ValueBuilder::appendToVar( - i, - IString("i"), - ValueBuilder::makeInt(0)); - - // Compute the table indexes to use for the current loop iteration. - Ref destIndex = ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("dest")), - PLUS, - ValueBuilder::makeName(IString("i")) - ); - Ref sourceIndex = ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("source")), - PLUS, - ValueBuilder::makeName(IString("i")) - ); - - // Set the value for the current loop iteration. - Ref set = ValueBuilder::makeBinary( - ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), destIndex), - SET, - ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), sourceIndex)); - - // Increment the variable. - Ref increment = ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("i")), - SET, - ValueBuilder::makeBinary( - ValueBuilder::makeName(IString("i")), - PLUS, - ValueBuilder::makeInt(1))); - - // Loop body: set the value, and increment. - Ref body = ValueBuilder::makeBlock(); - body[1]->push_back(set); - body[1]->push_back(increment); - - // Loop until we reach the size. - Ref loopCondition = - ValueBuilder::makeBinary(ValueBuilder::makeName(IString("i")), - LT, - ValueBuilder::makeName(IString("size"))); - Ref loop = ValueBuilder::makeWhile(loopCondition, body); - tableCopyFunc[3]->push_back(loop); - - ast->push_back(tableCopyFunc); -} - void Wasm2JSBuilder::addStart(Ref ast, Module* wasm) { if (wasm->start.is()) { ast->push_back( @@ -2423,34 +2249,26 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, ValueBuilder::makeName(LENGTH)); } Ref visitTableGrow(TableGrow* curr) { - return ValueBuilder::makeCall( - WASM_TABLE_GROW, - makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), - wasmToJsType(curr->value->type)), - makeJsCoercion(visit(curr->delta, EXPRESSION_RESULT), - wasmToJsType(curr->delta->type))); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_GROW); + // Also ensure fill, as grow calls fill internally. + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL); + return ValueBuilder::makeCall(ABI::wasm2js::TABLE_GROW, + visit(curr->value, EXPRESSION_RESULT), + visit(curr->delta, EXPRESSION_RESULT)); } Ref visitTableFill(TableFill* curr) { - return ValueBuilder::makeCall( - WASM_TABLE_FILL, - makeJsCoercion(visit(curr->dest, EXPRESSION_RESULT), - wasmToJsType(curr->dest->type)), - makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), - wasmToJsType(curr->value->type)), - makeJsCoercion(visit(curr->size, EXPRESSION_RESULT), - wasmToJsType(curr->size->type)) - ); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL); + return ValueBuilder::makeCall(ABI::wasm2js::TABLE_FILL, + visit(curr->dest, EXPRESSION_RESULT), + visit(curr->value, EXPRESSION_RESULT), + visit(curr->size, EXPRESSION_RESULT)); } Ref visitTableCopy(TableCopy* curr) { - return ValueBuilder::makeCall( - WASM_TABLE_COPY, - makeJsCoercion(visit(curr->dest, EXPRESSION_RESULT), - wasmToJsType(curr->dest->type)), - makeJsCoercion(visit(curr->source, EXPRESSION_RESULT), - wasmToJsType(curr->source->type)), - makeJsCoercion(visit(curr->size, EXPRESSION_RESULT), - wasmToJsType(curr->size->type)) - ); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_COPY); + return ValueBuilder::makeCall(ABI::wasm2js::TABLE_COPY, + visit(curr->dest, EXPRESSION_RESULT), + visit(curr->source, EXPRESSION_RESULT), + visit(curr->size, EXPRESSION_RESULT)); } Ref visitTry(Try* curr) { unimplemented(curr); @@ -3217,6 +3035,36 @@ void Wasm2JSGlue::emitSpecialSupport() { function wasm2js_memory_copy(dest, source, size) { // TODO: traps on invalid things bufferView.copyWithin(dest, source, source + size); + } + )"; + } else if (import->base == ABI::wasm2js::TABLE_GROW) { + out << R"( + function wasm2js_table_grow(value, delta) { + // TODO: traps on invalid things + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + )"; + } else if (import->base == ABI::wasm2js::TABLE_FILL) { + out << R"( + function __wasm_table_fill(dest, value, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = value; + } + } + )"; + } else if (import->base == ABI::wasm2js::TABLE_COPY) { + out << R"( + function __wasm_table_copy(dest, source, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + } } )"; } else if (import->base == ABI::wasm2js::DATA_DROP) { From d8f6f81ad3e2e62fe14b8f33985357524b6bcc08 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 11:54:13 -0700 Subject: [PATCH 14/17] work --- test/wasm2js/dynamicLibrary.2asm.js | 16 ------------ test/wasm2js/dynamicLibrary.2asm.js.opt | 16 ------------ test/wasm2js/emscripten.2asm.js | 25 ------------------ test/wasm2js/emscripten.2asm.js.opt | 25 ------------------ test/wasm2js/func-ptr-offset.2asm.js | 25 ------------------ test/wasm2js/func-ptr-offset.2asm.js.opt | 25 ------------------ test/wasm2js/func_ptrs.2asm.js | 32 ------------------------ test/wasm2js/indirect-select.2asm.js | 25 ------------------ test/wasm2js/indirect-select.2asm.js.opt | 25 ------------------ test/wasm2js/left-to-right.2asm.js | 16 ------------ test/wasm2js/ordering.2asm.js | 25 ------------------ test/wasm2js/ordering.2asm.js.opt | 25 ------------------ test/wasm2js/tables.2asm.js | 31 +++-------------------- test/wasm2js/tables.2asm.js.opt | 31 +++-------------------- 14 files changed, 6 insertions(+), 336 deletions(-) diff --git a/test/wasm2js/dynamicLibrary.2asm.js b/test/wasm2js/dynamicLibrary.2asm.js index af453dcf27d..bb6f4dcaff6 100644 --- a/test/wasm2js/dynamicLibrary.2asm.js +++ b/test/wasm2js/dynamicLibrary.2asm.js @@ -76,22 +76,6 @@ function asmFunc(imports) { var FUNCTION_TABLE = Table(new Array(10)); FUNCTION_TABLE[import$tableBase + 0] = foo; FUNCTION_TABLE[import$tableBase + 1] = bar; - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/dynamicLibrary.2asm.js.opt b/test/wasm2js/dynamicLibrary.2asm.js.opt index 8197dc3b641..543f755f37d 100644 --- a/test/wasm2js/dynamicLibrary.2asm.js.opt +++ b/test/wasm2js/dynamicLibrary.2asm.js.opt @@ -68,22 +68,6 @@ function asmFunc(imports) { var FUNCTION_TABLE = Table(new Array(10)); FUNCTION_TABLE[import$tableBase + 0] = foo; FUNCTION_TABLE[import$tableBase + 1] = foo; - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/emscripten.2asm.js b/test/wasm2js/emscripten.2asm.js index 8d12785d2c0..8ba8564ceea 100644 --- a/test/wasm2js/emscripten.2asm.js +++ b/test/wasm2js/emscripten.2asm.js @@ -216,31 +216,6 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = tabled; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/emscripten.2asm.js.opt b/test/wasm2js/emscripten.2asm.js.opt index f63e4bade1a..caef2389639 100644 --- a/test/wasm2js/emscripten.2asm.js.opt +++ b/test/wasm2js/emscripten.2asm.js.opt @@ -211,31 +211,6 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = internal; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/func-ptr-offset.2asm.js b/test/wasm2js/func-ptr-offset.2asm.js index be9e34aa316..dcac8386ef4 100644 --- a/test/wasm2js/func-ptr-offset.2asm.js +++ b/test/wasm2js/func-ptr-offset.2asm.js @@ -28,31 +28,6 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [null, t1, t2, t3]; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "call": $0 }; diff --git a/test/wasm2js/func-ptr-offset.2asm.js.opt b/test/wasm2js/func-ptr-offset.2asm.js.opt index 05363d76d77..e5ad86908db 100644 --- a/test/wasm2js/func-ptr-offset.2asm.js.opt +++ b/test/wasm2js/func-ptr-offset.2asm.js.opt @@ -28,31 +28,6 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [null, t1, t2, t3]; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "call": $0 }; diff --git a/test/wasm2js/func_ptrs.2asm.js b/test/wasm2js/func_ptrs.2asm.js index 0f3d13f58ef..3e5c82e78c6 100644 --- a/test/wasm2js/func_ptrs.2asm.js +++ b/test/wasm2js/func_ptrs.2asm.js @@ -90,22 +90,6 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [t1, t2, t3, u1, u2, t1, t3]; - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "callt": $0, "callu": $1 @@ -142,22 +126,6 @@ function asmFunc(imports) { } var FUNCTION_TABLE = [t1, t2]; - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "callt": $0 }; diff --git a/test/wasm2js/indirect-select.2asm.js b/test/wasm2js/indirect-select.2asm.js index 7519df6c64b..b1725927481 100644 --- a/test/wasm2js/indirect-select.2asm.js +++ b/test/wasm2js/indirect-select.2asm.js @@ -23,31 +23,6 @@ function asmFunc(imports) { return FUNCTION_TABLE[(x ? 0 : 1) | 0]() | 0 | 0; } - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "foo_true": foo_true, "foo_false": foo_false diff --git a/test/wasm2js/indirect-select.2asm.js.opt b/test/wasm2js/indirect-select.2asm.js.opt index b4eaaebd4b2..2d1792a53d9 100644 --- a/test/wasm2js/indirect-select.2asm.js.opt +++ b/test/wasm2js/indirect-select.2asm.js.opt @@ -23,31 +23,6 @@ function asmFunc(imports) { return FUNCTION_TABLE[!$0 | 0]() | 0; } - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "foo_true": foo_true, "foo_false": foo_false diff --git a/test/wasm2js/left-to-right.2asm.js b/test/wasm2js/left-to-right.2asm.js index 64dddaf93e5..6553cbc11d5 100644 --- a/test/wasm2js/left-to-right.2asm.js +++ b/test/wasm2js/left-to-right.2asm.js @@ -2082,22 +2082,6 @@ function asmFunc(imports) { bufferView = HEAPU8; var FUNCTION_TABLE = [i32_t0, i32_t1, i64_t0, i64_t1, f32_t0, f32_t1, f64_t0, f64_t1]; - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; } diff --git a/test/wasm2js/ordering.2asm.js b/test/wasm2js/ordering.2asm.js index cbf3398b761..672e8d8aa79 100644 --- a/test/wasm2js/ordering.2asm.js +++ b/test/wasm2js/ordering.2asm.js @@ -47,31 +47,6 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = baz; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "main": main }; diff --git a/test/wasm2js/ordering.2asm.js.opt b/test/wasm2js/ordering.2asm.js.opt index 5c29f9b4d79..912fdbacd4e 100644 --- a/test/wasm2js/ordering.2asm.js.opt +++ b/test/wasm2js/ordering.2asm.js.opt @@ -38,31 +38,6 @@ function asmFunc(imports) { FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = baz; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "main": main }; diff --git a/test/wasm2js/tables.2asm.js b/test/wasm2js/tables.2asm.js index 37ca1b3d50d..1b5afb7f076 100644 --- a/test/wasm2js/tables.2asm.js +++ b/test/wasm2js/tables.2asm.js @@ -26,48 +26,23 @@ function asmFunc(imports) { } function table_grow() { - return __wasm_table_grow(table_grow, 42 | 0) | 0; + return wasm2js_table_grow(table_grow, 42) | 0; } function table_fill(dest, value, size) { dest = dest | 0; size = size | 0; - __wasm_table_fill(dest | 0, value, size | 0); + wasm2js_table_fill(dest, value, size); } function table_copy(dest, source, size) { dest = dest | 0; source = source | 0; size = size | 0; - __wasm_table_copy(dest | 0, source | 0, size | 0); + wasm2js_table_copy(dest, source, size); } FUNCTION_TABLE[1] = table_get; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "table_get": table_get, "table_set": table_set, diff --git a/test/wasm2js/tables.2asm.js.opt b/test/wasm2js/tables.2asm.js.opt index a27a74698f6..92a55fda4f4 100644 --- a/test/wasm2js/tables.2asm.js.opt +++ b/test/wasm2js/tables.2asm.js.opt @@ -26,48 +26,23 @@ function asmFunc(imports) { } function table_grow() { - return __wasm_table_grow(table_grow, 42) | 0; + return wasm2js_table_grow(table_grow, 42) | 0; } function table_fill($0, $1, $2) { $0 = $0 | 0; $2 = $2 | 0; - __wasm_table_fill($0 | 0, $1, $2 | 0); + wasm2js_table_fill($0, $1, $2); } function table_copy($0, $1, $2) { $0 = $0 | 0; $1 = $1 | 0; $2 = $2 | 0; - __wasm_table_copy($0 | 0, $1 | 0, $2 | 0); + wasm2js_table_copy($0, $1, $2); } FUNCTION_TABLE[1] = table_get; - function __wasm_table_grow(value, delta) { - var oldSize = FUNCTION_TABLE.length; - FUNCTION_TABLE.length = oldSize + delta; - if (newSize > oldSize) { - __wasm_table_fill(oldSize, value, delta) - } - return oldSize; - } - - function __wasm_table_fill(dest, value, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = value; - i = i + 1; - }; - } - - function __wasm_table_copy(dest, source, size) { - var i = 0; - while (i < size) { - FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; - i = i + 1; - }; - } - return { "table_get": table_get, "table_set": table_set, From 948803dc290f7cb721fb215ec66977c05059066b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 12:50:07 -0700 Subject: [PATCH 15/17] work --- src/abi/js.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/abi/js.h b/src/abi/js.h index 6c6a3912ed4..e8c5f6fe963 100644 --- a/src/abi/js.h +++ b/src/abi/js.h @@ -74,6 +74,10 @@ inline void ensureHelpers(Module* wasm, IString specific = IString()) { MEMORY_INIT, {Type::i32, Type::i32, Type::i32, Type::i32}, Type::none); ensureImport(MEMORY_FILL, {Type::i32, Type::i32, Type::i32}, Type::none); ensureImport(MEMORY_COPY, {Type::i32, Type::i32, Type::i32}, Type::none); + auto funcref = Type(HeapType::func, Nullable); + ensureImport(TABLE_GROW, {funcref, Type::i32}, Type::none); + ensureImport(TABLE_FILL, {Type::i32, funcref, Type::i32}, Type::none); + ensureImport(TABLE_COPY, {Type::i32, Type::i32, Type::i32}, Type::none); ensureImport(DATA_DROP, {Type::i32}, Type::none); ensureImport(ATOMIC_WAIT_I32, {Type::i32, Type::i32, Type::i32, Type::i32, Type::i32}, @@ -91,7 +95,8 @@ inline bool isHelper(IString name) { name == SCRATCH_LOAD_F32 || name == SCRATCH_STORE_F32 || name == SCRATCH_LOAD_F64 || name == SCRATCH_STORE_F64 || name == ATOMIC_WAIT_I32 || name == MEMORY_INIT || - name == MEMORY_FILL || name == MEMORY_COPY || name == DATA_DROP || + name == MEMORY_FILL || name == MEMORY_COPY || name == TABLE_GROW || + name == TABLE_FILL || name == TABLE_COPY || name == DATA_DROP || name == ATOMIC_RMW_I64 || name == GET_STASHED_BITS || name == TRAP; } From 468d83005df0ee90cd938f3dab515088faf139f1 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 13:06:03 -0700 Subject: [PATCH 16/17] work --- src/abi/js.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/abi/js.h b/src/abi/js.h index e8c5f6fe963..b8f56f14d64 100644 --- a/src/abi/js.h +++ b/src/abi/js.h @@ -74,10 +74,6 @@ inline void ensureHelpers(Module* wasm, IString specific = IString()) { MEMORY_INIT, {Type::i32, Type::i32, Type::i32, Type::i32}, Type::none); ensureImport(MEMORY_FILL, {Type::i32, Type::i32, Type::i32}, Type::none); ensureImport(MEMORY_COPY, {Type::i32, Type::i32, Type::i32}, Type::none); - auto funcref = Type(HeapType::func, Nullable); - ensureImport(TABLE_GROW, {funcref, Type::i32}, Type::none); - ensureImport(TABLE_FILL, {Type::i32, funcref, Type::i32}, Type::none); - ensureImport(TABLE_COPY, {Type::i32, Type::i32, Type::i32}, Type::none); ensureImport(DATA_DROP, {Type::i32}, Type::none); ensureImport(ATOMIC_WAIT_I32, {Type::i32, Type::i32, Type::i32, Type::i32, Type::i32}, @@ -88,6 +84,13 @@ inline void ensureHelpers(Module* wasm, IString specific = IString()) { Type::i32); ensureImport(GET_STASHED_BITS, {}, Type::i32); ensureImport(TRAP, {}, Type::none); + + if (wasm->features.hasReferenceTypes()) { + auto funcref = Type(HeapType::func, Nullable); + ensureImport(TABLE_GROW, {funcref, Type::i32}, Type::none); + ensureImport(TABLE_FILL, {Type::i32, funcref, Type::i32}, Type::none); + ensureImport(TABLE_COPY, {Type::i32, Type::i32, Type::i32}, Type::none); + } } inline bool isHelper(IString name) { From 75133c4a8d79f2e938d28057e7b2dc1b23ed9fb3 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 13:12:08 -0700 Subject: [PATCH 17/17] fix --- test/wasm2js/tables.2asm.js | 25 +++++++++++++++++++++++++ test/wasm2js/tables.2asm.js.opt | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/test/wasm2js/tables.2asm.js b/test/wasm2js/tables.2asm.js index 1b5afb7f076..a7dd8fdd55e 100644 --- a/test/wasm2js/tables.2asm.js +++ b/test/wasm2js/tables.2asm.js @@ -1,5 +1,30 @@ import * as env from 'env'; + + function wasm2js_table_grow(value, delta) { + // TODO: traps on invalid things + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = value; + } + } + + function __wasm_table_copy(dest, source, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + } + } + function asmFunc(imports) { var env = imports.env; var FUNCTION_TABLE = env.table; diff --git a/test/wasm2js/tables.2asm.js.opt b/test/wasm2js/tables.2asm.js.opt index 92a55fda4f4..f15b0cb1172 100644 --- a/test/wasm2js/tables.2asm.js.opt +++ b/test/wasm2js/tables.2asm.js.opt @@ -1,5 +1,30 @@ import * as env from 'env'; + + function wasm2js_table_grow(value, delta) { + // TODO: traps on invalid things + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = value; + } + } + + function __wasm_table_copy(dest, source, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + } + } + function asmFunc(imports) { var env = imports.env; var FUNCTION_TABLE = env.table;