|
| 1 | +// Copyright 2020 the V8 project authors. All rights reserved. |
| 2 | +// Use of this source code is governed by a BSD-style license that can be |
| 3 | +// found in the LICENSE file. |
| 4 | + |
| 5 | +#include <stdint.h> |
| 6 | + |
| 7 | +#include "src/utils/utils.h" |
| 8 | +#include "src/utils/vector.h" |
| 9 | +#include "src/wasm/module-decoder.h" |
| 10 | +#include "src/wasm/struct-types.h" |
| 11 | +#include "src/wasm/wasm-engine.h" |
| 12 | +#include "src/wasm/wasm-module-builder.h" |
| 13 | +#include "src/wasm/wasm-module.h" |
| 14 | +#include "src/wasm/wasm-objects-inl.h" |
| 15 | +#include "src/wasm/wasm-opcodes.h" |
| 16 | +#include "test/cctest/cctest.h" |
| 17 | +#include "test/cctest/compiler/value-helper.h" |
| 18 | +#include "test/cctest/wasm/wasm-run-utils.h" |
| 19 | +#include "test/common/wasm/test-signatures.h" |
| 20 | +#include "test/common/wasm/wasm-macro-gen.h" |
| 21 | +#include "test/common/wasm/wasm-module-runner.h" |
| 22 | + |
| 23 | +namespace v8 { |
| 24 | +namespace internal { |
| 25 | +namespace wasm { |
| 26 | +namespace test_gc { |
| 27 | + |
| 28 | +WASM_EXEC_TEST(BasicStruct) { |
| 29 | + // TODO(7748): Implement support in other tiers. |
| 30 | + if (execution_tier == ExecutionTier::kLiftoff) return; |
| 31 | + if (execution_tier == ExecutionTier::kInterpreter) return; |
| 32 | + TestSignatures sigs; |
| 33 | + EXPERIMENTAL_FLAG_SCOPE(gc); |
| 34 | + EXPERIMENTAL_FLAG_SCOPE(anyref); |
| 35 | + v8::internal::AccountingAllocator allocator; |
| 36 | + Zone zone(&allocator, ZONE_NAME); |
| 37 | + |
| 38 | + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 39 | + StructType::Builder type_builder(&zone, 2); |
| 40 | + type_builder.AddField(kWasmI32); |
| 41 | + type_builder.AddField(kWasmI32); |
| 42 | + int32_t type_index = builder->AddStructType(type_builder.Build()); |
| 43 | + ValueType kRefTypes[] = {ValueType(ValueType::kRef, type_index)}; |
| 44 | + FunctionSig sig_q_v(1, 0, kRefTypes); |
| 45 | + |
| 46 | + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 47 | + f->builder()->AddExport(CStrVector("f"), f); |
| 48 | + byte f_code[] = {WASM_STRUCT_GET(type_index, 0, |
| 49 | + WASM_STRUCT_NEW(type_index, WASM_I32V(42), |
| 50 | + WASM_I32V(64))), |
| 51 | + kExprEnd}; |
| 52 | + f->EmitCode(f_code, sizeof(f_code)); |
| 53 | + |
| 54 | + WasmFunctionBuilder* g = builder->AddFunction(sigs.i_v()); |
| 55 | + g->builder()->AddExport(CStrVector("g"), g); |
| 56 | + byte g_code[] = {WASM_STRUCT_GET(type_index, 1, |
| 57 | + WASM_STRUCT_NEW(type_index, WASM_I32V(42), |
| 58 | + WASM_I32V(64))), |
| 59 | + kExprEnd}; |
| 60 | + g->EmitCode(g_code, sizeof(g_code)); |
| 61 | + |
| 62 | + WasmFunctionBuilder* h = builder->AddFunction(&sig_q_v); |
| 63 | + h->builder()->AddExport(CStrVector("h"), h); |
| 64 | + byte h_code[] = {WASM_STRUCT_NEW(type_index, WASM_I32V(42), WASM_I32V(64)), |
| 65 | + kExprEnd}; |
| 66 | + h->EmitCode(h_code, sizeof(h_code)); |
| 67 | + |
| 68 | + ZoneBuffer buffer(&zone); |
| 69 | + builder->WriteTo(&buffer); |
| 70 | + |
| 71 | + Isolate* isolate = CcTest::InitIsolateOnce(); |
| 72 | + HandleScope scope(isolate); |
| 73 | + testing::SetupIsolateForWasmModule(isolate); |
| 74 | + ErrorThrower thrower(isolate, "Test"); |
| 75 | + Handle<WasmInstanceObject> instance = |
| 76 | + testing::CompileAndInstantiateForTesting( |
| 77 | + isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end())) |
| 78 | + .ToHandleChecked(); |
| 79 | + |
| 80 | + CHECK_EQ(42, testing::CallWasmFunctionForTesting(isolate, instance, &thrower, |
| 81 | + "f", 0, nullptr)); |
| 82 | + CHECK_EQ(64, testing::CallWasmFunctionForTesting(isolate, instance, &thrower, |
| 83 | + "g", 0, nullptr)); |
| 84 | + |
| 85 | + // TODO(7748): This uses the JavaScript interface to retrieve the plain |
| 86 | + // WasmStruct. Once the JS interaction story is settled, this may well |
| 87 | + // need to be changed. |
| 88 | + Handle<WasmExportedFunction> h_export = |
| 89 | + testing::GetExportedFunction(isolate, instance, "h").ToHandleChecked(); |
| 90 | + Handle<Object> undefined = isolate->factory()->undefined_value(); |
| 91 | + Handle<Object> ref_result = |
| 92 | + Execution::Call(isolate, h_export, undefined, 0, nullptr) |
| 93 | + .ToHandleChecked(); |
| 94 | + CHECK(ref_result->IsWasmStruct()); |
| 95 | +} |
| 96 | + |
| 97 | +} // namespace test_gc |
| 98 | +} // namespace wasm |
| 99 | +} // namespace internal |
| 100 | +} // namespace v8 |
0 commit comments