diff options
-rwxr-xr-x | scripts/test/generate_lld_tests.py | 8 | ||||
-rw-r--r-- | scripts/test/lld.py | 12 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 21 | ||||
-rw-r--r-- | test/lld/em_asm64.cpp | 8 | ||||
-rw-r--r-- | test/lld/em_asm64.wat | 68 | ||||
-rw-r--r-- | test/lld/em_asm64.wat.out | 99 |
6 files changed, 206 insertions, 10 deletions
diff --git a/scripts/test/generate_lld_tests.py b/scripts/test/generate_lld_tests.py index 94c511ef4..00d5ae026 100755 --- a/scripts/test/generate_lld_tests.py +++ b/scripts/test/generate_lld_tests.py @@ -48,10 +48,10 @@ def generate_wat_files(llvm_bin, emscripten_root): wasm_path = os.path.join(lld_path, wasm_file) wat_path = os.path.join(lld_path, wat_file) is_shared = 'shared' in src_file + is_64 = '64' in src_file compile_cmd = [ os.path.join(llvm_bin, 'clang'), src_path, '-o', obj_path, - '--target=wasm32-emscripten', '-mllvm', '-enable-emscripten-sjlj', '-c', '-nostdinc', @@ -81,6 +81,12 @@ def generate_wat_files(llvm_bin, emscripten_root): else: link_cmd.append('--entry=main') + if is_64: + compile_cmd.append('--target=wasm64-emscripten') + link_cmd.append('-mwasm64') + else: + compile_cmd.append('--target=wasm32-emscripten') + try: support.run_command(compile_cmd) support.run_command(link_cmd) diff --git a/scripts/test/lld.py b/scripts/test/lld.py index 328339287..1c632b957 100644 --- a/scripts/test/lld.py +++ b/scripts/test/lld.py @@ -49,7 +49,10 @@ def run_test(input_path): else: continue - cmd = shared.WASM_EMSCRIPTEN_FINALIZE + [input_path, '-S'] + args + cmd = shared.WASM_EMSCRIPTEN_FINALIZE + args + if '64' in input_path: + cmd += ['--enable-memory64', '--bigint'] + cmd += [input_path, '-S'] cmd += args_for_finalize(os.path.basename(input_path)) actual = support.run_command(cmd) @@ -94,9 +97,12 @@ def update_lld_tests(): out_path = input_path + ext if ext != '.out' and not os.path.exists(out_path): continue - cmd = shared.WASM_EMSCRIPTEN_FINALIZE + [input_path, '-S'] + \ - ext_args + cmd = shared.WASM_EMSCRIPTEN_FINALIZE + ext_args + if '64' in input_path: + cmd += ['--enable-memory64', '--bigint'] + cmd += [input_path, '-S'] cmd += args_for_finalize(os.path.basename(input_path)) actual = support.run_command(cmd) + with open(out_path, 'w') as o: o.write(actual) diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index f8dc16a32..fe9aeffeb 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -177,7 +177,7 @@ const char* stringAtAddr(Module& wasm, std::string codeForConstAddr(Module& wasm, std::vector<Address> const& segmentOffsets, - int32_t address) { + int64_t address) { const char* str = stringAtAddr(wasm, segmentOffsets, address); if (!str) { Fatal() << "unable to find data for ASM/EM_JS const at: " << address; @@ -232,7 +232,7 @@ struct AsmConstWalker : public LinearExecutionWalker<AsmConstWalker> { void process(); private: - void createAsmConst(uint32_t id, std::string code, Signature sig, Name name); + void createAsmConst(uint64_t id, std::string code, Signature sig, Name name); Signature asmConstSig(Signature baseSig); Name nameForImportWithSig(Signature sig, Proxying proxy); void addImports(); @@ -291,7 +291,7 @@ void AsmConstWalker::visitCall(Call* curr) { } if (auto* bin = arg->dynCast<Binary>()) { - if (bin->op == AddInt32) { + if (bin->op == AddInt32 || bin->op == AddInt64) { // In the dynamic linking case the address of the string constant // is the result of adding its offset to __memory_base. // In this case are only looking for the offset from __memory_base @@ -301,12 +301,21 @@ void AsmConstWalker::visitCall(Call* curr) { } } + if (auto* unary = arg->dynCast<Unary>()) { + if (unary->op == WrapInt64) { + // This cast may be inserted around the string constant in the + // Memory64Lowering pass. + arg = unary->value; + continue; + } + } + Fatal() << "Unexpected arg0 type (" << getExpressionName(arg) << ") in call to: " << importName; } auto* value = arg->cast<Const>(); - int32_t address = value->value.geti32(); + int64_t address = value->value.getInteger(); auto code = codeForConstAddr(wasm, segmentOffsets, address); createAsmConst(address, code, sig, importName); } @@ -328,7 +337,7 @@ void AsmConstWalker::process() { addImports(); } -void AsmConstWalker::createAsmConst(uint32_t id, +void AsmConstWalker::createAsmConst(uint64_t id, std::string code, Signature sig, Name name) { @@ -388,7 +397,7 @@ struct EmJsWalker : public PostWalker<EmJsWalker> { Fatal() << "Unexpected generated __em_js__ function body: " << curr->name; } auto* addrConst = consts.list[0]; - int32_t address = addrConst->value.geti32(); + int64_t address = addrConst->value.getInteger(); auto code = codeForConstAddr(wasm, segmentOffsets, address); codeByName[funcName] = code; } diff --git a/test/lld/em_asm64.cpp b/test/lld/em_asm64.cpp new file mode 100644 index 000000000..ed89783f8 --- /dev/null +++ b/test/lld/em_asm64.cpp @@ -0,0 +1,8 @@ +#include <emscripten/em_asm.h> + +int main() { + EM_ASM({ Module.print("Hello world"); }); + int x = EM_ASM_INT({ return $0 + $1; }, 13, 27); + EM_ASM_({ Module.print("Got " + $0); }, x); + return 0; +} diff --git a/test/lld/em_asm64.wat b/test/lld/em_asm64.wat new file mode 100644 index 000000000..2c41c31b7 --- /dev/null +++ b/test/lld/em_asm64.wat @@ -0,0 +1,68 @@ +(module + (type $none_=>_none (func)) + (type $none_=>_i32 (func (result i32))) + (type $i32_i64_=>_i32 (func (param i32 i64) (result i32))) + (type $i64_i64_i64_=>_i32 (func (param i64 i64 i64) (result i32))) + (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i64 i64 i64) (result i32))) + (memory $0 i64 2) + (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00") + (table $0 1 1 funcref) + (global $__stack_pointer (mut i64) (i64.const 66208)) + (export "memory" (memory $0)) + (export "__wasm_call_ctors" (func $__wasm_call_ctors)) + (export "main" (func $main)) + (func $__wasm_call_ctors + ) + (func $__original_main (result i32) + (local $0 i64) + (global.set $__stack_pointer + (local.tee $0 + (i64.sub + (global.get $__stack_pointer) + (i64.const 32) + ) + ) + ) + (drop + (call $emscripten_asm_const_int + (i64.const 568) + (i64.const 601) + (i64.const 0) + ) + ) + (i64.store offset=16 + (local.get $0) + (i64.const 115964117005) + ) + (i32.store + (local.get $0) + (call $emscripten_asm_const_int + (i64.const 602) + (i64.const 622) + (i64.add + (local.get $0) + (i64.const 16) + ) + ) + ) + (drop + (call $emscripten_asm_const_int + (i64.const 625) + (i64.const 656) + (local.get $0) + ) + ) + (global.set $__stack_pointer + (i64.add + (local.get $0) + (i64.const 32) + ) + ) + (i32.const 0) + ) + (func $main (param $0 i32) (param $1 i64) (result i32) + (call $__original_main) + ) + ;; custom section "producers", size 112 +) + diff --git a/test/lld/em_asm64.wat.out b/test/lld/em_asm64.wat.out new file mode 100644 index 000000000..727dc7267 --- /dev/null +++ b/test/lld/em_asm64.wat.out @@ -0,0 +1,99 @@ +(module + (type $none_=>_none (func)) + (type $none_=>_i32 (func (result i32))) + (type $i32_i64_=>_i32 (func (param i32 i64) (result i32))) + (type $i64_i64_i64_=>_i32 (func (param i64 i64 i64) (result i32))) + (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i64 i64 i64) (result i32))) + (memory $0 i64 2) + (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00") + (table $0 1 1 funcref) + (global $__stack_pointer (mut i64) (i64.const 66208)) + (export "memory" (memory $0)) + (export "__wasm_call_ctors" (func $__wasm_call_ctors)) + (export "main" (func $main)) + (func $__wasm_call_ctors + (nop) + ) + (func $__original_main (result i32) + (local $0 i64) + (global.set $__stack_pointer + (local.tee $0 + (i64.sub + (global.get $__stack_pointer) + (i64.const 32) + ) + ) + ) + (drop + (call $emscripten_asm_const_int + (i64.const 568) + (i64.const 601) + (i64.const 0) + ) + ) + (i64.store offset=16 + (local.get $0) + (i64.const 115964117005) + ) + (i32.store + (local.get $0) + (call $emscripten_asm_const_int + (i64.const 602) + (i64.const 622) + (i64.add + (local.get $0) + (i64.const 16) + ) + ) + ) + (drop + (call $emscripten_asm_const_int + (i64.const 625) + (i64.const 656) + (local.get $0) + ) + ) + (global.set $__stack_pointer + (i64.add + (local.get $0) + (i64.const 32) + ) + ) + (i32.const 0) + ) + (func $main (param $0 i32) (param $1 i64) (result i32) + (call $__original_main) + ) +) +(; +--BEGIN METADATA -- +{ + "asmConsts": { + "568": ["{ Module.print(\"Hello world\"); }", ["ijj"], [""]], + "602": ["{ return $0 + $1; }", ["ijj"], [""]], + "625": ["{ Module.print(\"Got \" + $0); }", ["ijj"], [""]] + }, + "tableSize": 1, + "initializers": [ + "__wasm_call_ctors" + ], + "declares": [ + "emscripten_asm_const_int" + ], + "externs": [ + ], + "exports": [ + "__wasm_call_ctors", + "main" + ], + "namedGlobals": { + }, + "invokeFuncs": [ + ], + "mainReadsParams": 0, + "features": [ + "--enable-memory64" + ] +} +-- END METADATA -- +;) |