2019-07-08 11:55:29 +00:00
|
|
|
// Copyright 2019 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "test/wasm-api-tests/wasm-api-test.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace wasm {
|
|
|
|
|
|
|
|
using ::wasm::GlobalType;
|
|
|
|
|
|
|
|
TEST_F(WasmCapiTest, Globals) {
|
|
|
|
const bool kMutable = true;
|
|
|
|
const bool kImmutable = false;
|
|
|
|
|
|
|
|
// Define imported and exported globals in the module.
|
2021-06-17 15:43:55 +00:00
|
|
|
const uint32_t cfi_index = builder()->AddGlobalImport(
|
|
|
|
base::CStrVector("const f32"), kWasmF32, kImmutable);
|
|
|
|
const uint32_t cii_index = builder()->AddGlobalImport(
|
|
|
|
base::CStrVector("const i64"), kWasmI64, kImmutable);
|
|
|
|
const uint32_t vfi_index = builder()->AddGlobalImport(
|
|
|
|
base::CStrVector("var f32"), kWasmF32, kMutable);
|
|
|
|
const uint32_t vii_index = builder()->AddGlobalImport(
|
|
|
|
base::CStrVector("var i64"), kWasmI64, kMutable);
|
2019-07-08 11:55:29 +00:00
|
|
|
const int kNumImported = 4;
|
|
|
|
|
|
|
|
const uint32_t cfe_index =
|
2021-06-17 15:43:55 +00:00
|
|
|
kNumImported +
|
|
|
|
builder()->AddExportedGlobal(kWasmF32, kImmutable, WasmInitExpr(5.f),
|
|
|
|
base::CStrVector("const f32"));
|
2019-07-08 11:55:29 +00:00
|
|
|
const uint32_t cie_index =
|
2021-06-17 15:43:55 +00:00
|
|
|
kNumImported + builder()->AddExportedGlobal(
|
|
|
|
kWasmI64, kImmutable, WasmInitExpr(int64_t{6}),
|
|
|
|
base::CStrVector("const i64"));
|
2019-07-08 11:55:29 +00:00
|
|
|
const uint32_t vfe_index =
|
|
|
|
kNumImported + builder()->AddExportedGlobal(kWasmF32, kMutable,
|
|
|
|
WasmInitExpr(7.f),
|
2021-06-17 15:43:55 +00:00
|
|
|
base::CStrVector("var f32"));
|
2019-07-08 11:55:29 +00:00
|
|
|
const uint32_t vie_index =
|
|
|
|
kNumImported + builder()->AddExportedGlobal(kWasmI64, kMutable,
|
|
|
|
WasmInitExpr(int64_t{8}),
|
2021-06-17 15:43:55 +00:00
|
|
|
base::CStrVector("var i64"));
|
2019-07-08 11:55:29 +00:00
|
|
|
|
|
|
|
// Define functions for inspecting globals.
|
|
|
|
ValueType f32_type[] = {kWasmF32};
|
|
|
|
ValueType i64_type[] = {kWasmI64};
|
|
|
|
FunctionSig return_f32(1, 0, f32_type);
|
|
|
|
FunctionSig return_i64(1, 0, i64_type);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gcfi[] = {WASM_GLOBAL_GET(cfi_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get const f32 import"), gcfi,
|
|
|
|
sizeof(gcfi), &return_f32);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gcii[] = {WASM_GLOBAL_GET(cii_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get const i64 import"), gcii,
|
|
|
|
sizeof(gcii), &return_i64);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gvfi[] = {WASM_GLOBAL_GET(vfi_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get var f32 import"), gvfi,
|
|
|
|
sizeof(gvfi), &return_f32);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gvii[] = {WASM_GLOBAL_GET(vii_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get var i64 import"), gvii,
|
|
|
|
sizeof(gvii), &return_i64);
|
2019-07-08 11:55:29 +00:00
|
|
|
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gcfe[] = {WASM_GLOBAL_GET(cfe_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get const f32 export"), gcfe,
|
|
|
|
sizeof(gcfe), &return_f32);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gcie[] = {WASM_GLOBAL_GET(cie_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get const i64 export"), gcie,
|
|
|
|
sizeof(gcie), &return_i64);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gvfe[] = {WASM_GLOBAL_GET(vfe_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get var f32 export"), gvfe,
|
|
|
|
sizeof(gvfe), &return_f32);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte gvie[] = {WASM_GLOBAL_GET(vie_index)};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("get var i64 export"), gvie,
|
|
|
|
sizeof(gvie), &return_i64);
|
2019-07-08 11:55:29 +00:00
|
|
|
|
|
|
|
// Define functions for manipulating globals.
|
|
|
|
FunctionSig param_f32(0, 1, f32_type);
|
|
|
|
FunctionSig param_i64(0, 1, i64_type);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte svfi[] = {WASM_GLOBAL_SET(vfi_index, WASM_LOCAL_GET(0))};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("set var f32 import"), svfi,
|
|
|
|
sizeof(svfi), ¶m_f32);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte svii[] = {WASM_GLOBAL_SET(vii_index, WASM_LOCAL_GET(0))};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("set var i64 import"), svii,
|
|
|
|
sizeof(svii), ¶m_i64);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte svfe[] = {WASM_GLOBAL_SET(vfe_index, WASM_LOCAL_GET(0))};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("set var f32 export"), svfe,
|
|
|
|
sizeof(svfe), ¶m_f32);
|
2020-12-17 16:56:08 +00:00
|
|
|
byte svie[] = {WASM_GLOBAL_SET(vie_index, WASM_LOCAL_GET(0))};
|
2021-06-17 15:43:55 +00:00
|
|
|
AddExportedFunction(base::CStrVector("set var i64 export"), svie,
|
|
|
|
sizeof(svie), ¶m_i64);
|
2019-07-08 11:55:29 +00:00
|
|
|
|
|
|
|
// Create imported globals.
|
2019-08-19 14:35:47 +00:00
|
|
|
own<GlobalType> const_f32_type =
|
2019-07-08 11:55:29 +00:00
|
|
|
GlobalType::make(ValType::make(::wasm::F32), ::wasm::CONST);
|
2019-08-19 14:35:47 +00:00
|
|
|
own<GlobalType> const_i64_type =
|
2019-07-08 11:55:29 +00:00
|
|
|
GlobalType::make(ValType::make(::wasm::I64), ::wasm::CONST);
|
2019-08-19 14:35:47 +00:00
|
|
|
own<GlobalType> var_f32_type =
|
2019-07-08 11:55:29 +00:00
|
|
|
GlobalType::make(ValType::make(::wasm::F32), ::wasm::VAR);
|
2019-08-19 14:35:47 +00:00
|
|
|
own<GlobalType> var_i64_type =
|
2019-07-08 11:55:29 +00:00
|
|
|
GlobalType::make(ValType::make(::wasm::I64), ::wasm::VAR);
|
2019-08-19 14:35:47 +00:00
|
|
|
own<Global> const_f32_import =
|
2019-07-08 11:55:29 +00:00
|
|
|
Global::make(store(), const_f32_type.get(), Val::f32(1));
|
2019-08-19 14:35:47 +00:00
|
|
|
own<Global> const_i64_import =
|
2019-07-08 11:55:29 +00:00
|
|
|
Global::make(store(), const_i64_type.get(), Val::i64(2));
|
2019-08-19 14:35:47 +00:00
|
|
|
own<Global> var_f32_import =
|
2019-07-08 11:55:29 +00:00
|
|
|
Global::make(store(), var_f32_type.get(), Val::f32(3));
|
2019-08-19 14:35:47 +00:00
|
|
|
own<Global> var_i64_import =
|
2019-07-08 11:55:29 +00:00
|
|
|
Global::make(store(), var_i64_type.get(), Val::i64(4));
|
|
|
|
Extern* imports[] = {const_f32_import.get(), const_i64_import.get(),
|
|
|
|
var_f32_import.get(), var_i64_import.get()};
|
|
|
|
|
|
|
|
Instantiate(imports);
|
|
|
|
|
|
|
|
// Extract exports.
|
|
|
|
size_t i = 0;
|
|
|
|
Global* const_f32_export = GetExportedGlobal(i++);
|
|
|
|
Global* const_i64_export = GetExportedGlobal(i++);
|
|
|
|
Global* var_f32_export = GetExportedGlobal(i++);
|
|
|
|
Global* var_i64_export = GetExportedGlobal(i++);
|
|
|
|
Func* get_const_f32_import = GetExportedFunction(i++);
|
|
|
|
Func* get_const_i64_import = GetExportedFunction(i++);
|
|
|
|
Func* get_var_f32_import = GetExportedFunction(i++);
|
|
|
|
Func* get_var_i64_import = GetExportedFunction(i++);
|
|
|
|
Func* get_const_f32_export = GetExportedFunction(i++);
|
|
|
|
Func* get_const_i64_export = GetExportedFunction(i++);
|
|
|
|
Func* get_var_f32_export = GetExportedFunction(i++);
|
|
|
|
Func* get_var_i64_export = GetExportedFunction(i++);
|
|
|
|
Func* set_var_f32_import = GetExportedFunction(i++);
|
|
|
|
Func* set_var_i64_import = GetExportedFunction(i++);
|
|
|
|
Func* set_var_f32_export = GetExportedFunction(i++);
|
|
|
|
Func* set_var_i64_export = GetExportedFunction(i++);
|
|
|
|
|
2019-08-06 13:56:56 +00:00
|
|
|
// Try cloning.
|
|
|
|
EXPECT_TRUE(var_f32_import->copy()->same(var_f32_import.get()));
|
|
|
|
|
2019-07-08 11:55:29 +00:00
|
|
|
// Check initial values.
|
|
|
|
EXPECT_EQ(1.f, const_f32_import->get().f32());
|
|
|
|
EXPECT_EQ(2, const_i64_import->get().i64());
|
|
|
|
EXPECT_EQ(3.f, var_f32_import->get().f32());
|
|
|
|
EXPECT_EQ(4, var_i64_import->get().i64());
|
|
|
|
EXPECT_EQ(5.f, const_f32_export->get().f32());
|
|
|
|
EXPECT_EQ(6, const_i64_export->get().i64());
|
|
|
|
EXPECT_EQ(7.f, var_f32_export->get().f32());
|
|
|
|
EXPECT_EQ(8, var_i64_export->get().i64());
|
|
|
|
Val result[1];
|
|
|
|
get_const_f32_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(1.f, result[0].f32());
|
|
|
|
get_const_i64_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(2, result[0].i64());
|
|
|
|
get_var_f32_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(3.f, result[0].f32());
|
|
|
|
get_var_i64_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(4, result[0].i64());
|
|
|
|
get_const_f32_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(5.f, result[0].f32());
|
|
|
|
get_const_i64_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(6, result[0].i64());
|
|
|
|
get_var_f32_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(7.f, result[0].f32());
|
|
|
|
get_var_i64_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(8, result[0].i64());
|
|
|
|
|
|
|
|
// Modify variables through the API and check again.
|
|
|
|
var_f32_import->set(Val::f32(33));
|
|
|
|
var_i64_import->set(Val::i64(34));
|
|
|
|
var_f32_export->set(Val::f32(35));
|
|
|
|
var_i64_export->set(Val::i64(36));
|
|
|
|
|
|
|
|
EXPECT_EQ(33.f, var_f32_import->get().f32());
|
|
|
|
EXPECT_EQ(34, var_i64_import->get().i64());
|
|
|
|
EXPECT_EQ(35.f, var_f32_export->get().f32());
|
|
|
|
EXPECT_EQ(36, var_i64_export->get().i64());
|
|
|
|
|
|
|
|
get_var_f32_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(33.f, result[0].f32());
|
|
|
|
get_var_i64_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(34, result[0].i64());
|
|
|
|
get_var_f32_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(35.f, result[0].f32());
|
|
|
|
get_var_i64_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(36, result[0].i64());
|
|
|
|
|
|
|
|
// Modify variables through calls and check again.
|
|
|
|
Val args[1];
|
|
|
|
args[0] = Val::f32(73);
|
|
|
|
set_var_f32_import->call(args, nullptr);
|
|
|
|
args[0] = Val::i64(74);
|
|
|
|
set_var_i64_import->call(args, nullptr);
|
|
|
|
args[0] = Val::f32(75);
|
|
|
|
set_var_f32_export->call(args, nullptr);
|
|
|
|
args[0] = Val::i64(76);
|
|
|
|
set_var_i64_export->call(args, nullptr);
|
|
|
|
|
|
|
|
EXPECT_EQ(73.f, var_f32_import->get().f32());
|
|
|
|
EXPECT_EQ(74, var_i64_import->get().i64());
|
|
|
|
EXPECT_EQ(75.f, var_f32_export->get().f32());
|
|
|
|
EXPECT_EQ(76, var_i64_export->get().i64());
|
|
|
|
|
|
|
|
get_var_f32_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(73.f, result[0].f32());
|
|
|
|
get_var_i64_import->call(nullptr, result);
|
|
|
|
EXPECT_EQ(74, result[0].i64());
|
|
|
|
get_var_f32_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(75.f, result[0].f32());
|
|
|
|
get_var_i64_export->call(nullptr, result);
|
|
|
|
EXPECT_EQ(76, result[0].i64());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace wasm
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|