From dacc6e57048dc9af133c98ea3c843f8b912c9980 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 26 Aug 2024 10:15:00 -0700 Subject: Support more reference constants in wast scripts (#6865) Spec tests use constants like `ref.array` and `ref.eq` to assert that exported function return references of the correct types. Support more such constants in the wast parser. Also fix a bug where the interpretation of `array.new_data` for arrays of packed fields was not properly truncating the packed data. Move the function for reading fields from memory from literal.cpp to wasm-interpreter.h, where the function for truncating packed data lives. Other bugs prevent us from enabling any more spec tests as a result of this change, but we can get farther through several of them before failing. Update the comments about the failures accordingly. --- src/literal.h | 1 - src/parser/wast-parser.cpp | 28 ++++++++++++++++++++++++++++ src/wasm-interpreter.h | 24 +++++++++++++++++++++--- src/wasm/literal.cpp | 18 ------------------ 4 files changed, 49 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/literal.h b/src/literal.h index 882a99027..df9a16d9a 100644 --- a/src/literal.h +++ b/src/literal.h @@ -211,7 +211,6 @@ public: } static Literal makeFromMemory(void* p, Type type); - static Literal makeFromMemory(void* p, const Field& field); static Literal makeSignedMin(Type type) { switch (type.getBasic()) { diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index 00269a577..5eaf352b7 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -217,6 +217,34 @@ Result result(Lexer& in) { return RefResult{HeapType::func}; } + if (in.takeSExprStart("ref.struct")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.struct"); + } + return RefResult{HeapType::struct_}; + } + + if (in.takeSExprStart("ref.array")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.array"); + } + return RefResult{HeapType::array}; + } + + if (in.takeSExprStart("ref.eq")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.eq"); + } + return RefResult{HeapType::eq}; + } + + if (in.takeSExprStart("ref.i31")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.i31"); + } + return RefResult{HeapType::i31}; + } + if (in.takeSExprStart("ref.i31_shared")) { if (!in.takeRParen()) { return in.err("expected end of ref.i31_shared"); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 81b755f9f..77349fd33 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -2196,7 +2196,7 @@ public: WASM_UNREACHABLE("unimp"); } -private: +protected: // Truncate the value if we need to. The storage is just a list of Literals, // so we can't just write the value like we would to a C struct field and // expect it to truncate for us. Instead, we truncate so the stored value is @@ -2231,6 +2231,24 @@ private: } return value; } + + Literal makeFromMemory(void* p, Field field) { + switch (field.packedType) { + case Field::not_packed: + return Literal::makeFromMemory(p, field.type); + case Field::i8: { + int8_t i; + memcpy(&i, p, sizeof(i)); + return truncateForPacking(Literal(int32_t(i)), field); + } + case Field::i16: { + int16_t i; + memcpy(&i, p, sizeof(i)); + return truncateForPacking(Literal(int32_t(i)), field); + } + } + WASM_UNREACHABLE("unexpected type"); + } }; // Execute a suspected constant expression (precompute and C-API). @@ -3972,7 +3990,7 @@ public: contents.reserve(size); for (Index i = offset; i < end; i += elemBytes) { auto addr = (void*)&seg.data[i]; - contents.push_back(Literal::makeFromMemory(addr, element)); + contents.push_back(this->makeFromMemory(addr, element)); } return self()->makeGCData(contents, curr->type); } @@ -4052,7 +4070,7 @@ public: } for (size_t i = 0; i < sizeVal; i++) { void* addr = (void*)&seg->data[offsetVal + i * elemSize]; - data->values[indexVal + i] = Literal::makeFromMemory(addr, elem); + data->values[indexVal + i] = this->makeFromMemory(addr, elem); } return {}; } diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 65c2b4e62..6a4614a90 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -294,24 +294,6 @@ Literal Literal::makeFromMemory(void* p, Type type) { } } -Literal Literal::makeFromMemory(void* p, const Field& field) { - switch (field.packedType) { - case Field::not_packed: - return makeFromMemory(p, field.type); - case Field::i8: { - int8_t i; - memcpy(&i, p, sizeof(i)); - return Literal(int32_t(i)); - } - case Field::i16: { - int16_t i; - memcpy(&i, p, sizeof(i)); - return Literal(int32_t(i)); - } - } - WASM_UNREACHABLE("unexpected type"); -} - Literal Literal::standardizeNaN(const Literal& input) { if (!std::isnan(input.getFloat())) { return input; -- cgit v1.2.3