diff --git a/lld/test/wasm/ctor_return_value.s b/lld/test/wasm/ctor_return_value.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/ctor_return_value.s @@ -0,0 +1,46 @@ +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s +# RUN: wasm-ld %t.o -o %t.wasm +# RUN: obj2yaml %t.wasm | FileCheck %s + + .globl myctor +myctor: + .functype myctor () -> (i32) + i32.const 1 + + end_function + + .globl _start +_start: + .functype _start () -> () + call __wasm_call_ctors + end_function + + .section .init_array.100,"",@ + .p2align 2 + .int32 myctor + .int32 myctor + .int32 myctor + +.type __wasm_call_ctors,@function + +# CHECK: - Type: CODE +# CHECK-NEXT: Functions: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 10011A10011A10011A0B +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 41010B +# CHECK-NEXT: - Index: 2 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 1080808080000B +# CHECK-NEXT: - Type: CUSTOM +# CHECK-NEXT: Name: name +# CHECK-NEXT: FunctionNames: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Name: __wasm_call_ctors +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Name: myctor +# CHECK-NEXT: - Index: 2 +# CHECK-NEXT: Name: _start +# CHECK-NEXT: ... diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -909,6 +909,9 @@ for (const WasmInitEntry &f : initFunctions) { writeU8(os, WASM_OPCODE_CALL, "CALL"); writeUleb128(os, f.sym->getFunctionIndex(), "function index"); + for (size_t i = 0; i < f.sym->signature->Returns.size(); i++) { + writeU8(os, WASM_OPCODE_DROP, "DROP"); + } } writeU8(os, WASM_OPCODE_END, "END"); } @@ -973,8 +976,8 @@ if (sym->isDiscarded()) continue; assert(sym->isLive()); - if (*sym->signature != WasmSignature{{}, {}}) - error("invalid signature for init func: " + toString(*sym)); + if (sym->signature->Params.size() != 0) + error("constructor functions cannot take arguments: " + toString(*sym)); LLVM_DEBUG(dbgs() << "initFunctions: " << toString(*sym) << "\n"); initFunctions.emplace_back(WasmInitEntry{sym, f.Priority}); }