From dfd028c16202e825ba9b0f1a9101d45901a8aa0d Mon Sep 17 00:00:00 2001 From: Manos Koukoutos Date: Mon, 21 Sep 2020 13:51:42 +0000 Subject: [PATCH] [wasm-gc] Fix empty structs bug Drive-by: add const modifier to some StructType fields Bug: v8:7748 Change-Id: Ic0b4bb51ed01502f19d082c669683f69b85e76e7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2419015 Commit-Queue: Manos Koukoutos Reviewed-by: Jakob Kummerow Cr-Commit-Position: refs/heads/master@{#70029} --- src/wasm/struct-types.h | 17 +++++++++-------- test/cctest/wasm/test-gc.cc | 17 +++++++++++++++-- test/unittests/wasm/module-decoder-unittest.cc | 11 +++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/wasm/struct-types.h b/src/wasm/struct-types.h index e6e174dd7d..33af7de6bd 100644 --- a/src/wasm/struct-types.h +++ b/src/wasm/struct-types.h @@ -62,10 +62,11 @@ class StructType : public ZoneObject { return field_offsets_[index - 1]; } uint32_t total_fields_size() const { - return field_offsets_[field_count() - 1]; + return field_count() == 0 ? 0 : field_offsets_[field_count() - 1]; } void InitializeOffsets() { + if (field_count() == 0) return; uint32_t offset = field(0).element_size_bytes(); for (uint32_t i = 1; i < field_count(); i++) { uint32_t field_size = field(i).element_size_bytes(); @@ -102,17 +103,17 @@ class StructType : public ZoneObject { private: const uint32_t field_count_; - Zone* zone_; + Zone* const zone_; uint32_t cursor_; - ValueType* buffer_; - bool* mutabilities_; + ValueType* const buffer_; + bool* const mutabilities_; }; private: - uint32_t field_count_; - uint32_t* field_offsets_; - const ValueType* reps_; - const bool* mutabilities_; + const uint32_t field_count_; + uint32_t* const field_offsets_; + const ValueType* const reps_; + const bool* const mutabilities_; }; class ArrayType : public ZoneObject { diff --git a/test/cctest/wasm/test-gc.cc b/test/cctest/wasm/test-gc.cc index c90286507f..dc4822a104 100644 --- a/test/cctest/wasm/test-gc.cc +++ b/test/cctest/wasm/test-gc.cc @@ -181,9 +181,12 @@ TEST(WasmBasicStruct) { WasmGCTester tester; const byte type_index = tester.DefineStruct({F(kWasmI32, true), F(kWasmI32, true)}); - ValueType kRefTypes[] = {ref(type_index)}; + const byte empty_struct_index = tester.DefineStruct({}); + ValueType kRefType = ref(type_index); + ValueType kEmptyStructType = ref(empty_struct_index); ValueType kOptRefType = optref(type_index); - FunctionSig sig_q_v(1, 0, kRefTypes); + FunctionSig sig_q_v(1, 0, &kRefType); + FunctionSig sig_qe_v(1, 0, &kEmptyStructType); // Test struct.new and struct.get. const byte kGet1 = tester.DefineFunction( @@ -210,6 +213,13 @@ TEST(WasmBasicStruct) { WASM_RTT_CANON(type_index)), kExprEnd}); + // Test struct.new, returning reference to an empty struct. + const byte kGetEmptyStruct = tester.DefineFunction( + &sig_qe_v, {}, + {WASM_STRUCT_NEW_WITH_RTT(empty_struct_index, + WASM_RTT_CANON(empty_struct_index)), + kExprEnd}); + // Test struct.set, struct refs types in locals. const byte j_local_index = 0; const byte j_field_index = 0; @@ -230,6 +240,9 @@ TEST(WasmBasicStruct) { tester.CheckResult(kGet1, 42); tester.CheckResult(kGet2, 64); CHECK(tester.GetResultObject(kGetStruct).ToHandleChecked()->IsWasmStruct()); + CHECK(tester.GetResultObject(kGetEmptyStruct) + .ToHandleChecked() + ->IsWasmStruct()); tester.CheckResult(kSet, -99); } diff --git a/test/unittests/wasm/module-decoder-unittest.cc b/test/unittests/wasm/module-decoder-unittest.cc index 8025ffb038..5120a2a865 100644 --- a/test/unittests/wasm/module-decoder-unittest.cc +++ b/test/unittests/wasm/module-decoder-unittest.cc @@ -834,6 +834,17 @@ TEST_F(WasmModuleVerifyTest, RttSubGlobalTypeError) { "(rtt 2 i31)"); } +TEST_F(WasmModuleVerifyTest, EmptyStruct) { + WASM_FEATURE_SCOPE(reftypes); + WASM_FEATURE_SCOPE(typed_funcref); + WASM_FEATURE_SCOPE(gc); + static const byte empty_struct[] = {SECTION(Type, ENTRY_COUNT(1), // -- + kWasmStructTypeCode, // -- + U32V_1(0))}; // field count + + EXPECT_VERIFIES(empty_struct); +} + TEST_F(WasmModuleVerifyTest, InvalidStructTypeDef) { WASM_FEATURE_SCOPE(reftypes); WASM_FEATURE_SCOPE(typed_funcref);