From 21e14cce23582fcd622b97d643a4e9b2f10a0583 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 16 Jun 2020 12:23:25 -0700 Subject: [PATCH] [lld][WebAssembly] Allow ctors functions that return values Some projects use the constructor attribute on functions that also return values. In this case we just ignore them. The error was reported in the libgpg-error project that marks gpg_err_init with the `__constructor__` attribute. Differential Revision: https://reviews.llvm.org/D81962 --- lld/test/wasm/ctor_return_value.s | 46 +++++++++++++++++++++++++++++++++++++++ lld/wasm/Writer.cpp | 7 ++++-- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 lld/test/wasm/ctor_return_value.s diff --git a/lld/test/wasm/ctor_return_value.s b/lld/test/wasm/ctor_return_value.s new file mode 100644 index 0000000..8fa28ea --- /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 index 8cfab83..0434a4c 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -913,6 +913,9 @@ void Writer::createCallCtorsFunction() { 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"); } @@ -977,8 +980,8 @@ void Writer::calculateInitFunctions() { 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}); } -- 2.7.4