uint32_t Index;
SignatureForm Form = wasm::WASM_TYPE_FUNC;
std::vector<ValueType> ParamTypes;
- ValueType ReturnType;
+ std::vector<ValueType> ReturnTypes;
};
struct SymbolInfo {
Sig.Params.push_back(wasm::ValType(ParamType));
}
uint32_t ReturnCount = readVaruint32(Ctx);
- if (ReturnCount) {
- if (ReturnCount != 1) {
- return make_error<GenericBinaryError>(
- "Multiple return types not supported", object_error::parse_failed);
- }
- Sig.Returns.push_back(wasm::ValType(readUint8(Ctx)));
+ while (ReturnCount--) {
+ uint32_t ReturnType = readUint8(Ctx);
+ Sig.Returns.push_back(wasm::ValType(ReturnType));
}
Signatures.push_back(std::move(Sig));
}
encodeULEB128(Sig.ParamTypes.size(), OS);
for (auto ParamType : Sig.ParamTypes)
writeUint8(OS, ParamType);
- if (Sig.ReturnType == wasm::WASM_TYPE_NORESULT) {
- encodeULEB128(0, OS);
- } else {
- encodeULEB128(1, OS);
- writeUint8(OS, Sig.ReturnType);
- }
+ encodeULEB128(Sig.ReturnTypes.size(), OS);
+ for (auto ReturnType : Sig.ReturnTypes)
+ writeUint8(OS, ReturnType);
}
}
void MappingTraits<WasmYAML::Signature>::mapping(
IO &IO, WasmYAML::Signature &Signature) {
IO.mapRequired("Index", Signature.Index);
- IO.mapRequired("ReturnType", Signature.ReturnType);
IO.mapRequired("ParamTypes", Signature.ParamTypes);
+ IO.mapRequired("ReturnTypes", Signature.ReturnTypes);
}
void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) {
ECase(V128);
ECase(FUNCREF);
ECase(FUNC);
- ECase(NORESULT);
#undef ECase
}
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+multivalue | FileCheck %s
+; RUN: llc < %s --filetype=obj -mattr=+multivalue | obj2yaml | FileCheck %s --check-prefix OBJ
; Test that the multivalue returns, function types, and block types
; work as expected.
; CHECK-NEXT: .int8 43
; CHECK-NEXT: .int8 10
; CHECK-NEXT: .ascii "multivalue"
+
+; OBJ-LABEL: - Type: TYPE
+; OBJ-NEXT: Signatures:
+; OBJ-NEXT: - Index: 0
+; OBJ-NEXT: ParamTypes:
+; OBJ-NEXT: - I32
+; OBJ-NEXT: - I32
+; OBJ-NEXT: ReturnTypes:
+; OBJ-NEXT: - I32
+; OBJ-NEXT: - I32
+; OBJ-NEXT: - Index: 1
+; OBJ-NEXT: ParamTypes:
+; OBJ-NEXT: - I32
+; OBJ-NEXT: ReturnTypes:
+; OBJ-NEXT: - I32
+; OBJ-NEXT: - I64
; return-called functions include the proper return types
; YAML-LABEL: - Index: 8
-; YAML-NEXT: ReturnType: I32
; YAML-NEXT: ParamTypes:
; YAML-NEXT: - I32
; YAML-NEXT: - F32
; YAML-NEXT: - I64
; YAML-NEXT: - F64
+; YAML-NEXT: ReturnTypes:
+; YAML-NEXT: - I32
define i32 @unique_caller(i32 (i32, float, i64, double)** %p) {
%f = load i32 (i32, float, i64, double)*, i32 (i32, float, i64, double)** %p
%v = tail call i32 %f(i32 0, float 0., i64 0, double 0.)
; CHECK-NEXT: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes: []
; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes: []
+; CHECK-NEXT: ReturnTypes: []
; CHECK-NEXT: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
; CHECK-NEXT: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: ReturnType: I32
-; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ParamTypes: []
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - I32
; CHECK-NEXT: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
# BIN-NEXT: - Type: TYPE
# BIN-NEXT: Signatures:
# BIN-NEXT: - Index: 0
-# BIN-NEXT: ReturnType: I32
# BIN-NEXT: ParamTypes: []
+# BIN-NEXT: ReturnTypes:
+# BIN-NEXT: - I32
# BIN-NEXT: - Type: IMPORT
# BIN-NEXT: Imports:
# BIN-NEXT: - Module: env
; CHECK-NEXT: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - I32
; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes: []
; CHECK: - Type: EVENT
; CHECK-NEXT: Events:
; CHECK-NEXT: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes: []
; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
; CHECK-NEXT: - I32
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - I32
; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK: - Module: env
; CHECK-NEXT: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes: []
; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
; CHECK-NEXT: - I32
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - I32
; CHECK-NEXT: - Type: IMPORT
# CHECK-NEXT: - Type: TYPE
# CHECK-NEXT: Signatures:
# CHECK-NEXT: - Index: 0
-# CHECK-NEXT: ReturnType: I32
# CHECK-NEXT: ParamTypes: []
+# CHECK-NEXT: ReturnTypes:
+# CHECK-NEXT: - I32
# CHECK-NEXT: - Type: IMPORT
# CHECK-NEXT: Imports:
# CHECK-NEXT: - Module: env
# BIN-NEXT: - Type: TYPE
# BIN-NEXT: Signatures:
# BIN-NEXT: - Index: 0
-# BIN-NEXT: ReturnType: I32
# BIN-NEXT: ParamTypes:
# BIN-NEXT: - I32
+# BIN-NEXT: ReturnTypes:
+# BIN-NEXT: - I32
# BIN-NEXT: - Index: 1
-# BIN-NEXT: ReturnType: F64
# BIN-NEXT: ParamTypes:
# BIN-NEXT: - F64
+# BIN-NEXT: ReturnTypes:
+# BIN-NEXT: - F64
# BIN-NEXT: - Type: IMPORT
# BIN-NEXT: Imports:
# BIN-NEXT: - Module: env
# BIN-NEXT: Flags: [ BINDING_LOCAL ]
# BIN-NEXT: Function: 0
# BIN-NEXT: ...
-
; CHECK-LABEL: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ReturnTypes: []
; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - I32
; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: ReturnType: I64
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - I64
; CHECK-NEXT: - Index: 3
-; CHECK-NEXT: ReturnType: F32
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - F32
; CHECK-NEXT: - Index: 4
-; CHECK-NEXT: ReturnType: F64
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - F64
; CHECK-NEXT: - Index: 5
-; CHECK-NEXT: ReturnType: V128
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - V128
; CHECK-NEXT: - Index: 6
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes: []
; CHECK-NEXT: - Index: 7
-; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
; CHECK-NEXT: - I32
; CHECK-NEXT: - I32
+; CHECK-NEXT: ReturnTypes: []
; should be no additional types
-; CHECK-NOT: ReturnType
+; CHECK-NOT: ReturnTypes
; CHECK: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: ReturnTypes:
+; CHECK-NEXT: - I32
; CHECK-NEXT: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: IMPORT
Imports:
- Module: foo
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: NORESULT
ParamTypes: []
+ ReturnTypes: []
- Type: IMPORT
Imports:
- Module: env
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: F32
ParamTypes:
- I32
+ ReturnTypes:
+ - F32
- Index: 1
- ReturnType: NORESULT
ParamTypes:
- I32
- I64
+ ReturnTypes: []
- Type: FUNCTION
FunctionTypes:
- 0
# CHECK: - Type: TYPE
# CHECK: Signatures:
# CHECK: - Index: 0
-# CHECK: ReturnType: F32
# CHECK: ParamTypes:
# CHECK: - I32
+# CHECK: ReturnTypes:
+# CHECK: - F32
# CHECK: - Index: 1
-# CHECK: ReturnType: NORESULT
# CHECK: ParamTypes:
# CHECK: - I32
# CHECK: - I64
+# CHECK: ReturnTypes: []
# CHECK: - Type: CODE
# CHECK: Relocations:
# CHECK: - Type: R_WASM_TABLE_INDEX_SLEB
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Index: 1
- ReturnType: NORESULT
ParamTypes:
- I32
+ ReturnTypes: []
- Type: FUNCTION
FunctionTypes: [ 0 ]
- Type: EVENT
# CHECK-NEXT: - Type: TYPE
# CHECK-NEXT: Signatures:
# CHECK-NEXT: - Index: 0
-# CHECK-NEXT: ReturnType: I32
# CHECK-NEXT: ParamTypes:
# CHECK-NEXT: - I32
+# CHECK-NEXT: ReturnTypes:
+# CHECK-NEXT: - I32
# CHECK-NEXT: - Index: 1
-# CHECK-NEXT: ReturnType: NORESULT
# CHECK-NEXT: ParamTypes:
# CHECK-NEXT: - I32
+# CHECK-NEXT: ReturnTypes: []
# CHECK-NEXT: - Type: FUNCTION
# CHECK-NEXT: FunctionTypes: [ 0 ]
# CHECK-NEXT: - Type: EVENT
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: NORESULT
ParamTypes:
+ ReturnTypes: []
- Type: FUNCTION
FunctionTypes: [ 0, 0 ]
- Type: GLOBAL
Opcode: I64_CONST
Value: 64
- Type: EXPORT
- Exports:
+ Exports:
- Name: function_export
Kind: FUNCTION
Index: 1
# CHECK: Version: 0x00000001
# CHECK: Sections:
# CHECK: - Type: EXPORT
-# CHECK: Exports:
+# CHECK: Exports:
# CHECK: - Name: function_export
# CHECK: Kind: FUNCTION
# CHECK: Index: 1
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: NORESULT
ParamTypes:
+ ReturnTypes: []
- Index: 1
- ReturnType: NORESULT
ParamTypes:
- I32
+ ReturnTypes: []
- Type: FUNCTION
FunctionTypes: [ 1, 0 ]
- Type: CODE
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: IMPORT
Imports:
- Module: foo
# CHECK: Version: 0x00000001
# CHECK: Sections:
# CHECK: - Type: IMPORT
-# CHECK: Imports:
+# CHECK: Imports:
# CHECK: - Module: foo
# CHECK: Field: imported_memory
# CHECK: Kind: MEMORY
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: IMPORT
Imports:
- Module: foo
# CHECK: Version: 0x00000001
# CHECK: Sections:
# CHECK: - Type: IMPORT
-# CHECK: Imports:
+# CHECK: Imports:
# CHECK: - Module: foo
# CHECK: Field: imported_function
# CHECK: Kind: FUNCTION
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: NORESULT
ParamTypes: []
+ ReturnTypes: []
- Type: CODE
Functions:
- Index: 0
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: IMPORT
Imports:
- Module: foo
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: IMPORT
Imports:
- Module: foo
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: NORESULT
- ParamTypes:
+ ParamTypes: []
+ ReturnTypes: []
- Type: FUNCTION
FunctionTypes: [ 0, 0, 0 ]
- Type: START
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- F32
- F32
+ ReturnTypes:
+ - I32
- Index: 1
- ReturnType: I64
ParamTypes:
- F64
- F64
+ ReturnTypes:
+ - I64
...
# CHECK: --- !WASM
# CHECK: FileHeader:
# CHECK: - Type: TYPE
# CHECK: Signatures:
# CHECK: - Index: 0
-# CHECK: ReturnType: I32
# CHECK: ParamTypes:
# CHECK: - F32
# CHECK: - F32
+# CHECK: ReturnTypes:
+# CHECK: - I32
# CHECK: - Index: 1
-# CHECK: ReturnType: I64
# CHECK: ParamTypes:
# CHECK: - F64
# CHECK: - F64
+# CHECK: ReturnTypes:
+# CHECK: - I64
# CHECK: ...
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
- ParamTypes:
+ ParamTypes: []
+ ReturnTypes:
+ - I32
- Type: FUNCTION
FunctionTypes: [ 0, 0 ]
- Type: GLOBAL
- Globals:
+ Globals:
- Index: 0
Type: I32
Mutable: false
Opcode: I32_CONST
Value: 1
- Type: EXPORT
- Exports:
+ Exports:
- Name: function_export
Kind: FUNCTION
Index: 1
# CHECK: Version: 0x00000001
# CHECK: Sections:
# CHECK: - Type: EXPORT
-# CHECK: Exports:
+# CHECK: Exports:
# CHECK: - Name: function_export
# CHECK: Kind: FUNCTION
# CHECK: Index: 1
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: FUNCTION
FunctionTypes: [ 0 ]
- Type: GLOBAL
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: IMPORT
Imports:
- Module: env
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes:
- I32
+ ReturnTypes:
+ - I32
- Type: IMPORT
Imports:
- Module: env
- Type: TYPE
Signatures:
- Index: 0
- ReturnType: I32
ParamTypes: []
+ ReturnTypes:
+ - I32
- Index: 1
- ReturnType: NORESULT
ParamTypes: []
+ ReturnTypes: []
- Type: IMPORT
Imports:
- Module: env
for (const auto &FunctionSig : Obj.types()) {
WasmYAML::Signature Sig;
Sig.Index = Index++;
- Sig.ReturnType = wasm::WASM_TYPE_NORESULT;
- assert(FunctionSig.Returns.size() <= 1 &&
- "Functions with multiple returns are not supported");
- if (FunctionSig.Returns.size())
- Sig.ReturnType = static_cast<uint32_t>(FunctionSig.Returns[0]);
for (const auto &ParamType : FunctionSig.Params)
Sig.ParamTypes.emplace_back(static_cast<uint32_t>(ParamType));
+ for (const auto &ReturnType : FunctionSig.Returns)
+ Sig.ReturnTypes.emplace_back(static_cast<uint32_t>(ReturnType));
TypeSec->Signatures.push_back(Sig);
}
S = std::move(TypeSec);