2015-12-11 12:26:16 +00:00
|
|
|
// Copyright 2015 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/unittests/test-utils.h"
|
|
|
|
|
2016-06-21 12:52:57 +00:00
|
|
|
#include "src/handles.h"
|
|
|
|
#include "src/objects-inl.h"
|
2015-12-11 12:26:16 +00:00
|
|
|
#include "src/wasm/module-decoder.h"
|
2016-12-14 17:45:59 +00:00
|
|
|
#include "src/wasm/wasm-limits.h"
|
2016-02-28 00:37:11 +00:00
|
|
|
#include "src/wasm/wasm-macro-gen.h"
|
2015-12-11 12:26:16 +00:00
|
|
|
#include "src/wasm/wasm-opcodes.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace wasm {
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define WASM_INIT_EXPR_I32V_1(val) WASM_I32V_1(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_I32V_2(val) WASM_I32V_2(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_I32V_3(val) WASM_I32V_3(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_I32V_4(val) WASM_I32V_4(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_I32V_5(val) WASM_I32V_5(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_F32(val) WASM_F32(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_I64(val) WASM_I64(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_F64(val) WASM_F64(val), kExprEnd
|
|
|
|
#define WASM_INIT_EXPR_GLOBAL(index) WASM_GET_GLOBAL(index), kExprEnd
|
|
|
|
|
2016-05-13 08:44:28 +00:00
|
|
|
#define SIZEOF_EMPTY_FUNCTION ((size_t)5)
|
2016-03-09 22:50:36 +00:00
|
|
|
#define EMPTY_BODY 0
|
2016-04-29 09:39:26 +00:00
|
|
|
#define SIZEOF_EMPTY_BODY ((size_t)1)
|
2016-03-09 22:50:36 +00:00
|
|
|
#define NOP_BODY 2, 0, kExprNop
|
2016-04-29 09:39:26 +00:00
|
|
|
#define SIZEOF_NOP_BODY ((size_t)3)
|
2016-03-10 12:36:42 +00:00
|
|
|
|
2016-04-29 09:39:26 +00:00
|
|
|
#define SIG_ENTRY_i_i SIG_ENTRY_x_x(kLocalI32, kLocalI32)
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define UNKNOWN_SECTION(size) 0, U32V_1(size + 5), 4, 'l', 'u', 'l', 'z'
|
2016-04-29 09:39:26 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define SECTION(name, size) k##name##SectionCode, U32V_1(size)
|
2016-04-29 09:39:26 +00:00
|
|
|
|
|
|
|
#define SIGNATURES_SECTION(count, ...) \
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1 + 3 * (count)), U32V_1(count), __VA_ARGS__
|
2016-04-29 09:39:26 +00:00
|
|
|
#define FUNCTION_SIGNATURES_SECTION(count, ...) \
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Function, 1 + (count)), U32V_1(count), __VA_ARGS__
|
2016-04-29 09:39:26 +00:00
|
|
|
|
|
|
|
#define FOO_STRING 3, 'f', 'o', 'o'
|
|
|
|
#define NO_LOCAL_NAMES 0
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define EMPTY_SIGNATURES_SECTION SECTION(Type, 1), 0
|
|
|
|
#define EMPTY_FUNCTION_SIGNATURES_SECTION SECTION(Function, 1), 0
|
|
|
|
#define EMPTY_FUNCTION_BODIES_SECTION SECTION(Code, 1), 0
|
2016-10-12 09:17:12 +00:00
|
|
|
#define SECTION_NAMES(size) SECTION(Unknown, size + 5), 4, 'n', 'a', 'm', 'e'
|
2016-09-27 20:46:10 +00:00
|
|
|
#define EMPTY_NAMES_SECTION SECTION_NAMES(1), 0
|
2016-04-29 09:39:26 +00:00
|
|
|
|
2016-05-25 16:12:09 +00:00
|
|
|
#define X1(...) __VA_ARGS__
|
|
|
|
#define X2(...) __VA_ARGS__, __VA_ARGS__
|
|
|
|
#define X3(...) __VA_ARGS__, __VA_ARGS__, __VA_ARGS__
|
|
|
|
#define X4(...) __VA_ARGS__, __VA_ARGS__, __VA_ARGS__, __VA_ARGS__
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define ONE_EMPTY_FUNCTION SECTION(Function, 1 + 1 * 1), 1, X1(0)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define TWO_EMPTY_FUNCTIONS SECTION(Function, 1 + 2 * 1), 2, X2(0)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define THREE_EMPTY_FUNCTIONS SECTION(Function, 1 + 3 * 1), 3, X3(0)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define FOUR_EMPTY_FUNCTIONS SECTION(Function, 1 + 4 * 1), 4, X4(0)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define ONE_EMPTY_BODY \
|
|
|
|
SECTION(Code, 1 + 1 * (1 + SIZEOF_EMPTY_BODY)) \
|
|
|
|
, 1, X1(SIZEOF_EMPTY_BODY, EMPTY_BODY)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define TWO_EMPTY_BODIES \
|
|
|
|
SECTION(Code, 1 + 2 * (1 + SIZEOF_EMPTY_BODY)) \
|
|
|
|
, 2, X2(SIZEOF_EMPTY_BODY, EMPTY_BODY)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define THREE_EMPTY_BODIES \
|
|
|
|
SECTION(Code, 1 + 3 * (1 + SIZEOF_EMPTY_BODY)) \
|
|
|
|
, 3, X3(SIZEOF_EMPTY_BODY, EMPTY_BODY)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define FOUR_EMPTY_BODIES \
|
|
|
|
SECTION(Code, 1 + 4 * (1 + SIZEOF_EMPTY_BODY)) \
|
|
|
|
, 4, X4(SIZEOF_EMPTY_BODY, EMPTY_BODY)
|
2016-05-25 16:12:09 +00:00
|
|
|
|
2016-04-29 09:39:26 +00:00
|
|
|
#define SIGNATURES_SECTION_VOID_VOID \
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1 + SIZEOF_SIG_ENTRY_v_v), 1, SIG_ENTRY_v_v
|
|
|
|
|
|
|
|
#define LINEAR_MEMORY_INDEX_0 0
|
2016-02-27 01:52:30 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define EXPECT_VERIFIES(data) \
|
|
|
|
do { \
|
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data)); \
|
|
|
|
EXPECT_TRUE(result.ok()); \
|
|
|
|
if (result.val) delete result.val; \
|
2015-12-11 12:26:16 +00:00
|
|
|
} while (false)
|
|
|
|
|
2016-02-28 00:37:11 +00:00
|
|
|
#define EXPECT_FAILURE_LEN(data, length) \
|
|
|
|
do { \
|
|
|
|
ModuleResult result = DecodeModule(data, data + length); \
|
|
|
|
EXPECT_FALSE(result.ok()); \
|
|
|
|
if (result.val) delete result.val; \
|
2015-12-11 12:26:16 +00:00
|
|
|
} while (false)
|
|
|
|
|
2016-02-28 00:37:11 +00:00
|
|
|
#define EXPECT_FAILURE(data) EXPECT_FAILURE_LEN(data, sizeof(data))
|
|
|
|
|
|
|
|
#define EXPECT_OFF_END_FAILURE(data, min, max) \
|
|
|
|
do { \
|
|
|
|
for (size_t length = min; length < max; length++) { \
|
|
|
|
EXPECT_FAILURE_LEN(data, length); \
|
|
|
|
} \
|
|
|
|
} while (false)
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-04-21 11:18:41 +00:00
|
|
|
#define EXPECT_OK(result) \
|
|
|
|
do { \
|
|
|
|
EXPECT_TRUE(result.ok()); \
|
|
|
|
if (!result.ok()) { \
|
|
|
|
if (result.val) delete result.val; \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} while (false)
|
|
|
|
|
2016-03-10 12:36:42 +00:00
|
|
|
static size_t SizeOfVarInt(size_t value) {
|
|
|
|
size_t size = 0;
|
|
|
|
do {
|
|
|
|
size++;
|
|
|
|
value = value >> 7;
|
|
|
|
} while (value > 0);
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
struct ValueTypePair {
|
2015-12-11 12:26:16 +00:00
|
|
|
uint8_t code;
|
2016-12-21 13:43:00 +00:00
|
|
|
ValueType type;
|
|
|
|
} kValueTypes[] = {{kLocalI32, kWasmI32},
|
|
|
|
{kLocalI64, kWasmI64},
|
|
|
|
{kLocalF32, kWasmF32},
|
|
|
|
{kLocalF64, kWasmF64}};
|
2015-12-11 12:26:16 +00:00
|
|
|
|
[wasm] Adding metrics for Asm/Wasm.
Collecting:
Time histograms for: instantiate, decode module, decode function, compile, compile function.
Memory histograms for: decode peak, instantiate peak, compile function peak, min mem pages, max mem pages, function bytes, module bytes.
Range histograms of: functions per module.
BUG= https://code.google.com/p/v8/issues/detail?id=4203
BUG= https://bugs.chromium.org/p/chromium/issues/detail?id=575167
TEST=None
R=ahaas@chromium.org,bmeurer@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1866873002
Cr-Commit-Position: refs/heads/master@{#35467}
2016-04-14 07:28:22 +00:00
|
|
|
class WasmModuleVerifyTest : public TestWithIsolateAndZone {
|
2016-02-28 00:37:11 +00:00
|
|
|
public:
|
|
|
|
ModuleResult DecodeModule(const byte* module_start, const byte* module_end) {
|
|
|
|
// Add the WASM magic and version number automatically.
|
|
|
|
size_t size = static_cast<size_t>(module_end - module_start);
|
|
|
|
byte header[] = {WASM_MODULE_HEADER};
|
|
|
|
size_t total = sizeof(header) + size;
|
|
|
|
auto temp = new byte[total];
|
|
|
|
memcpy(temp, header, sizeof(header));
|
|
|
|
memcpy(temp + sizeof(header), module_start, size);
|
[wasm] Use a Managed<WasmModule> to hold metadata about modules.
This CL refactors the handling of metadata associated with WebAssembly
modules to reduce the duplicate marshalling of data from the C++ world
to the JavaScript world. It does this by wrapping the C++ WasmModule*
object in a Foreign that is rooted from the on-heap WasmCompiledModule
(which is itself just a FixedArray). Upon serialization, the C++ object
is ignored and the original WASM wire bytes are serialized. Upon
deserialization, the C++ object is reconstituted by reparsing the bytes.
This is motivated by increasing complications in implementing the JS
API, in particular WebAssembly.Table, which must perform signature
canonicalization across instances.
Additionally, this CL implements the proper base + offset initialization
behavior for tables.
R=rossberg@chromium.org,bradnelson@chromium.org,mtrofin@chromium.org,yangguo@chromium.org
BUG=v8:5507, chromium:575167, chromium:657316
Review-Url: https://chromiumcodereview.appspot.com/2424623002
Cr-Commit-Position: refs/heads/master@{#40434}
2016-10-19 13:06:44 +00:00
|
|
|
ModuleResult result =
|
|
|
|
DecodeWasmModule(isolate(), temp, temp + total, false, kWasmOrigin);
|
2016-02-28 00:37:11 +00:00
|
|
|
delete[] temp;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
ModuleResult DecodeModuleNoHeader(const byte* module_start,
|
|
|
|
const byte* module_end) {
|
[wasm] Use a Managed<WasmModule> to hold metadata about modules.
This CL refactors the handling of metadata associated with WebAssembly
modules to reduce the duplicate marshalling of data from the C++ world
to the JavaScript world. It does this by wrapping the C++ WasmModule*
object in a Foreign that is rooted from the on-heap WasmCompiledModule
(which is itself just a FixedArray). Upon serialization, the C++ object
is ignored and the original WASM wire bytes are serialized. Upon
deserialization, the C++ object is reconstituted by reparsing the bytes.
This is motivated by increasing complications in implementing the JS
API, in particular WebAssembly.Table, which must perform signature
canonicalization across instances.
Additionally, this CL implements the proper base + offset initialization
behavior for tables.
R=rossberg@chromium.org,bradnelson@chromium.org,mtrofin@chromium.org,yangguo@chromium.org
BUG=v8:5507, chromium:575167, chromium:657316
Review-Url: https://chromiumcodereview.appspot.com/2424623002
Cr-Commit-Position: refs/heads/master@{#40434}
2016-10-19 13:06:44 +00:00
|
|
|
return DecodeWasmModule(isolate(), module_start, module_end, false,
|
2016-02-28 00:37:11 +00:00
|
|
|
kWasmOrigin);
|
|
|
|
}
|
|
|
|
};
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-02-28 00:37:11 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, WrongMagic) {
|
|
|
|
for (uint32_t x = 1; x; x <<= 1) {
|
2016-09-27 20:46:10 +00:00
|
|
|
const byte data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion)};
|
2016-02-28 00:37:11 +00:00
|
|
|
ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data));
|
|
|
|
EXPECT_FALSE(result.ok());
|
2015-12-17 11:38:28 +00:00
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
2016-02-28 00:37:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, WrongVersion) {
|
|
|
|
for (uint32_t x = 1; x; x <<= 1) {
|
2016-09-27 20:46:10 +00:00
|
|
|
const byte data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x)};
|
2016-02-28 00:37:11 +00:00
|
|
|
ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data));
|
|
|
|
EXPECT_FALSE(result.ok());
|
2015-12-17 11:38:28 +00:00
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-28 00:37:11 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, DecodeEmpty) {
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(nullptr, 0);
|
|
|
|
EXPECT_TRUE(result.ok());
|
|
|
|
if (result.val) delete result.val;
|
2016-02-28 00:37:11 +00:00
|
|
|
}
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, OneGlobal) {
|
2016-02-19 14:58:25 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Global, 6), // --
|
2015-12-11 12:26:16 +00:00
|
|
|
1,
|
2016-09-27 20:46:10 +00:00
|
|
|
kLocalI32, // local type
|
|
|
|
0, // immutable
|
|
|
|
WASM_INIT_EXPR_I32V_1(13) // init
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
{
|
|
|
|
// Should decode to exactly one global.
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, result.val->globals.size());
|
|
|
|
EXPECT_EQ(0u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(0u, result.val->data_segments.size());
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-05-24 16:32:03 +00:00
|
|
|
const WasmGlobal* global = &result.val->globals.back();
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
EXPECT_EQ(kWasmI32, global->type);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, global->offset);
|
2016-09-27 22:09:36 +00:00
|
|
|
EXPECT_FALSE(global->mutability);
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_EQ(WasmInitExpr::kI32Const, global->init.kind);
|
|
|
|
EXPECT_EQ(13, global->init.val.i32_const);
|
2015-12-17 11:38:28 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2016-02-28 00:37:11 +00:00
|
|
|
EXPECT_OFF_END_FAILURE(data, 1, sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2016-06-07 09:35:52 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, Global_invalid_type) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Global, 6), // --
|
2016-06-07 09:35:52 +00:00
|
|
|
1,
|
2016-09-27 20:46:10 +00:00
|
|
|
64, // invalid memory type
|
|
|
|
1, // mutable
|
|
|
|
WASM_INIT_EXPR_I32V_1(33), // init
|
2016-06-07 09:35:52 +00:00
|
|
|
};
|
|
|
|
|
2016-09-14 15:44:15 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
|
|
|
EXPECT_FALSE(result.ok());
|
|
|
|
if (result.val) delete result.val;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, Global_invalid_type2) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Global, 6), // --
|
2016-09-14 15:44:15 +00:00
|
|
|
1,
|
2016-09-27 20:46:10 +00:00
|
|
|
kLocalVoid, // invalid memory type
|
|
|
|
1, // mutable
|
|
|
|
WASM_INIT_EXPR_I32V_1(33), // init
|
2016-09-14 15:44:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-06-07 09:35:52 +00:00
|
|
|
EXPECT_FALSE(result.ok());
|
|
|
|
if (result.val) delete result.val;
|
|
|
|
}
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ZeroGlobals) {
|
2016-02-19 14:58:25 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Global, 1), // --
|
|
|
|
0, // declare 0 globals
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2015-12-17 11:38:28 +00:00
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2016-11-08 14:18:07 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ExportMutableGlobal) {
|
|
|
|
{
|
|
|
|
static const byte data[] = {
|
|
|
|
SECTION(Global, 6), // --
|
|
|
|
1,
|
|
|
|
kLocalI32, // local type
|
|
|
|
0, // immutable
|
|
|
|
WASM_INIT_EXPR_I32V_1(13), // init
|
|
|
|
SECTION(Export, 8), // --
|
|
|
|
1, // Export count
|
|
|
|
4, // name length
|
|
|
|
'n', // --
|
|
|
|
'a', // --
|
|
|
|
'm', // --
|
|
|
|
'e', // --
|
|
|
|
kExternalGlobal, // global
|
|
|
|
0, // global index
|
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
static const byte data[] = {
|
|
|
|
SECTION(Global, 6), // --
|
|
|
|
1, // --
|
|
|
|
kLocalI32, // local type
|
|
|
|
1, // mutable
|
|
|
|
WASM_INIT_EXPR_I32V_1(13), // init
|
|
|
|
SECTION(Export, 8), // --
|
|
|
|
1, // Export count
|
|
|
|
4, // name length
|
|
|
|
'n', // --
|
|
|
|
'a', // --
|
|
|
|
'm', // --
|
|
|
|
'e', // --
|
|
|
|
kExternalGlobal, // global
|
|
|
|
0, // global index
|
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
static void AppendUint32v(std::vector<byte>& buffer, uint32_t val) {
|
|
|
|
while (true) {
|
|
|
|
uint32_t next = val >> 7;
|
|
|
|
uint32_t out = val & 0x7f;
|
|
|
|
if (next) {
|
|
|
|
buffer.push_back(static_cast<byte>(0x80 | out));
|
|
|
|
val = next;
|
|
|
|
} else {
|
|
|
|
buffer.push_back(static_cast<byte>(out));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, NGlobals) {
|
2016-02-19 14:58:25 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
kLocalF32, // memory type
|
|
|
|
0, // immutable
|
|
|
|
WASM_INIT_EXPR_F32(7.7), // init
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
2016-02-28 00:37:11 +00:00
|
|
|
|
2016-12-14 17:45:59 +00:00
|
|
|
for (uint32_t i = 0; i < kV8MaxWasmGlobals; i = i * 13 + 1) {
|
2015-12-11 12:26:16 +00:00
|
|
|
std::vector<byte> buffer;
|
2016-04-29 09:39:26 +00:00
|
|
|
size_t size = SizeOfVarInt(i) + i * sizeof(data);
|
2016-09-27 20:46:10 +00:00
|
|
|
const byte globals[] = {kGlobalSectionCode, U32V_5(size)};
|
2016-03-10 12:36:42 +00:00
|
|
|
for (size_t g = 0; g != sizeof(globals); ++g) {
|
|
|
|
buffer.push_back(globals[g]);
|
|
|
|
}
|
|
|
|
AppendUint32v(buffer, i); // Number of globals.
|
2015-12-17 11:38:28 +00:00
|
|
|
for (uint32_t j = 0; j < i; j++) {
|
2016-02-28 00:37:11 +00:00
|
|
|
buffer.insert(buffer.end(), data, data + sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size());
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2015-12-17 11:38:28 +00:00
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, GlobalWithInvalidMemoryType) {
|
2016-09-27 20:46:10 +00:00
|
|
|
static const byte data[] = {SECTION(Global, 7),
|
|
|
|
33, // memory type
|
|
|
|
0, // exported
|
|
|
|
WASM_INIT_EXPR_I32V_1(1)};
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, TwoGlobals) {
|
2016-02-19 14:58:25 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Global, 21),
|
2015-12-11 12:26:16 +00:00
|
|
|
2,
|
2016-07-21 12:34:28 +00:00
|
|
|
kLocalF32, // type
|
2016-09-27 20:46:10 +00:00
|
|
|
0, // immutable
|
|
|
|
WASM_INIT_EXPR_F32(22.0),
|
2016-07-21 12:34:28 +00:00
|
|
|
kLocalF64, // type
|
2016-09-27 20:46:10 +00:00
|
|
|
1, // mutable
|
|
|
|
WASM_INIT_EXPR_F64(23.0),
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
{
|
|
|
|
// Should decode to exactly two globals.
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(2u, result.val->globals.size());
|
|
|
|
EXPECT_EQ(0u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(0u, result.val->data_segments.size());
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-05-24 16:32:03 +00:00
|
|
|
const WasmGlobal* g0 = &result.val->globals[0];
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
EXPECT_EQ(kWasmF32, g0->type);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, g0->offset);
|
2016-09-27 22:09:36 +00:00
|
|
|
EXPECT_FALSE(g0->mutability);
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_EQ(WasmInitExpr::kF32Const, g0->init.kind);
|
|
|
|
|
|
|
|
const WasmGlobal* g1 = &result.val->globals[1];
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
EXPECT_EQ(kWasmF64, g1->type);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(8u, g1->offset);
|
2016-09-27 22:09:36 +00:00
|
|
|
EXPECT_TRUE(g1->mutability);
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_EQ(WasmInitExpr::kF64Const, g1->init.kind);
|
2015-12-17 11:38:28 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2016-02-28 00:37:11 +00:00
|
|
|
EXPECT_OFF_END_FAILURE(data, 1, sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, OneSignature) {
|
2016-02-27 01:52:30 +00:00
|
|
|
{
|
2016-04-29 09:39:26 +00:00
|
|
|
static const byte data[] = {SIGNATURES_SECTION_VOID_VOID};
|
2016-02-27 01:52:30 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2016-09-27 20:46:10 +00:00
|
|
|
static const byte data[] = {SECTION(Type, 1 + SIZEOF_SIG_ENTRY_x_x), 1,
|
|
|
|
SIG_ENTRY_i_i};
|
2016-02-27 01:52:30 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, MultipleSignatures) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1 + SIZEOF_SIG_ENTRY_v_v + SIZEOF_SIG_ENTRY_x_x +
|
|
|
|
SIZEOF_SIG_ENTRY_x_xx), // --
|
2016-04-29 09:39:26 +00:00
|
|
|
3, // --
|
|
|
|
SIG_ENTRY_v_v, // void -> void
|
|
|
|
SIG_ENTRY_x_x(kLocalI32, kLocalF32), // f32 -> i32
|
|
|
|
SIG_ENTRY_x_xx(kLocalI32, kLocalF64, kLocalF64), // f64,f64 -> i32
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(3u, result.val->signatures.size());
|
2016-02-28 19:04:10 +00:00
|
|
|
if (result.val->signatures.size() == 3) {
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, result.val->signatures[0]->return_count());
|
|
|
|
EXPECT_EQ(1u, result.val->signatures[1]->return_count());
|
|
|
|
EXPECT_EQ(1u, result.val->signatures[2]->return_count());
|
2016-02-28 19:04:10 +00:00
|
|
|
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, result.val->signatures[0]->parameter_count());
|
|
|
|
EXPECT_EQ(1u, result.val->signatures[1]->parameter_count());
|
|
|
|
EXPECT_EQ(2u, result.val->signatures[2]->parameter_count());
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
2015-12-17 11:38:28 +00:00
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-02-28 00:37:11 +00:00
|
|
|
EXPECT_OFF_END_FAILURE(data, 1, sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2016-11-09 15:52:17 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, DataSegmentWithImmutableImportedGlobal) {
|
|
|
|
// Import 2 globals so that we can initialize data with a global index != 0.
|
|
|
|
const byte data[] = {
|
|
|
|
SECTION(Import, 15), // section header
|
|
|
|
2, // number of imports
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'm', // module name
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'f', // global name
|
|
|
|
kExternalGlobal, // import kind
|
|
|
|
kLocalI32, // type
|
|
|
|
0, // mutability
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'n', // module name
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'g', // global name
|
|
|
|
kExternalGlobal, // import kind
|
|
|
|
kLocalI32, // type
|
|
|
|
0, // mutability
|
|
|
|
SECTION(Memory, 4),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
kResizableMaximumFlag,
|
|
|
|
28,
|
|
|
|
28,
|
|
|
|
SECTION(Data, 9),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_GLOBAL(1), // dest addr
|
|
|
|
U32V_1(3), // source size
|
|
|
|
'a',
|
|
|
|
'b',
|
|
|
|
'c' // data bytes
|
|
|
|
};
|
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
|
|
|
EXPECT_OK(result);
|
|
|
|
WasmInitExpr expr = result.val->data_segments.back().dest_addr;
|
|
|
|
EXPECT_EQ(WasmInitExpr::kGlobalIndex, expr.kind);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, expr.val.global_index);
|
2016-11-09 15:52:17 +00:00
|
|
|
if (result.val) delete result.val;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, DataSegmentWithMutableImportedGlobal) {
|
|
|
|
// Only an immutable imported global can be used as an init_expr.
|
|
|
|
const byte data[] = {
|
|
|
|
SECTION(Import, 8), // section header
|
|
|
|
1, // number of imports
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'm', // module name
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'f', // global name
|
|
|
|
kExternalGlobal, // import kind
|
|
|
|
kLocalI32, // type
|
|
|
|
1, // mutability
|
|
|
|
SECTION(Memory, 4),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
kResizableMaximumFlag,
|
|
|
|
28,
|
|
|
|
28,
|
|
|
|
SECTION(Data, 9),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_GLOBAL(0), // dest addr
|
|
|
|
U32V_1(3), // source size
|
|
|
|
'a',
|
|
|
|
'b',
|
|
|
|
'c' // data bytes
|
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
TEST_F(WasmModuleVerifyTest, DataSegmentWithImmutableGlobal) {
|
|
|
|
// Only an immutable imported global can be used as an init_expr.
|
|
|
|
const byte data[] = {
|
|
|
|
SECTION(Memory, 4),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
kResizableMaximumFlag,
|
|
|
|
28,
|
|
|
|
28,
|
|
|
|
SECTION(Global, 8), // --
|
|
|
|
1,
|
|
|
|
kLocalI32, // local type
|
|
|
|
0, // immutable
|
|
|
|
WASM_INIT_EXPR_I32V_3(0x9bbaa), // init
|
|
|
|
SECTION(Data, 9),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_GLOBAL(0), // dest addr
|
|
|
|
U32V_1(3), // source size
|
|
|
|
'a',
|
|
|
|
'b',
|
|
|
|
'c' // data bytes
|
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, OneDataSegment) {
|
2016-09-27 20:46:10 +00:00
|
|
|
const byte kDataSegmentSourceOffset = 24;
|
2015-12-11 12:26:16 +00:00
|
|
|
const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Memory, 4),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
kResizableMaximumFlag,
|
2016-03-10 12:36:42 +00:00
|
|
|
28,
|
|
|
|
28,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Data, 11),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_I32V_3(0x9bbaa), // dest addr
|
|
|
|
U32V_1(3), // source size
|
2016-03-10 12:36:42 +00:00
|
|
|
'a',
|
|
|
|
'b',
|
|
|
|
'c' // data bytes
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
{
|
2016-01-20 15:19:58 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, result.val->globals.size());
|
|
|
|
EXPECT_EQ(0u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(1u, result.val->data_segments.size());
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-05-24 16:32:03 +00:00
|
|
|
const WasmDataSegment* segment = &result.val->data_segments.back();
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_EQ(WasmInitExpr::kI32Const, segment->dest_addr.kind);
|
|
|
|
EXPECT_EQ(0x9bbaa, segment->dest_addr.val.i32_const);
|
2016-03-09 19:43:02 +00:00
|
|
|
EXPECT_EQ(kDataSegmentSourceOffset, segment->source_offset);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(3u, segment->source_size);
|
2015-12-17 11:38:28 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_OFF_END_FAILURE(data, 14, sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, TwoDataSegments) {
|
2016-09-27 20:46:10 +00:00
|
|
|
const byte kDataSegment0SourceOffset = 24;
|
|
|
|
const byte kDataSegment1SourceOffset = kDataSegment0SourceOffset + 11;
|
2016-03-09 19:43:02 +00:00
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Memory, 4),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
kResizableMaximumFlag,
|
2016-03-10 12:36:42 +00:00
|
|
|
28,
|
|
|
|
28,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Data, 29),
|
|
|
|
ENTRY_COUNT(2), // segment count
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_I32V_3(0x7ffee), // #0: dest addr
|
|
|
|
U32V_1(4), // source size
|
2016-03-10 12:36:42 +00:00
|
|
|
1,
|
|
|
|
2,
|
|
|
|
3,
|
2016-09-27 20:46:10 +00:00
|
|
|
4, // data bytes
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_I32V_3(0x6ddcc), // #1: dest addr
|
|
|
|
U32V_1(10), // source size
|
2016-03-10 12:36:42 +00:00
|
|
|
1,
|
|
|
|
2,
|
|
|
|
3,
|
|
|
|
4,
|
|
|
|
5,
|
|
|
|
6,
|
|
|
|
7,
|
|
|
|
8,
|
|
|
|
9,
|
|
|
|
10 // data bytes
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
{
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, result.val->globals.size());
|
|
|
|
EXPECT_EQ(0u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(2u, result.val->data_segments.size());
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-05-24 16:32:03 +00:00
|
|
|
const WasmDataSegment* s0 = &result.val->data_segments[0];
|
|
|
|
const WasmDataSegment* s1 = &result.val->data_segments[1];
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_EQ(WasmInitExpr::kI32Const, s0->dest_addr.kind);
|
|
|
|
EXPECT_EQ(0x7ffee, s0->dest_addr.val.i32_const);
|
2016-03-09 19:43:02 +00:00
|
|
|
EXPECT_EQ(kDataSegment0SourceOffset, s0->source_offset);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(4u, s0->source_size);
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_EQ(WasmInitExpr::kI32Const, s1->dest_addr.kind);
|
|
|
|
EXPECT_EQ(0x6ddcc, s1->dest_addr.val.i32_const);
|
2016-03-09 19:43:02 +00:00
|
|
|
EXPECT_EQ(kDataSegment1SourceOffset, s1->source_offset);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(10u, s1->source_size);
|
2015-12-17 11:38:28 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_OFF_END_FAILURE(data, 14, sizeof(data));
|
|
|
|
}
|
|
|
|
|
2016-11-09 10:37:06 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, DataWithoutMemory) {
|
|
|
|
const byte data[] = {
|
|
|
|
SECTION(Data, 11),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_I32V_3(0x9bbaa), // dest addr
|
|
|
|
U32V_1(3), // source size
|
|
|
|
'a',
|
|
|
|
'b',
|
|
|
|
'c' // data bytes
|
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2016-11-07 12:25:49 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, MaxMaximumMemorySize) {
|
|
|
|
{
|
|
|
|
const byte data[] = {
|
|
|
|
SECTION(Memory, 6), ENTRY_COUNT(1), kResizableMaximumFlag, 0,
|
|
|
|
U32V_3(65536),
|
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
const byte data[] = {
|
|
|
|
SECTION(Memory, 6), ENTRY_COUNT(1), kResizableMaximumFlag, 0,
|
|
|
|
U32V_3(65537),
|
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, DataSegment_wrong_init_type) {
|
|
|
|
const byte data[] = {
|
|
|
|
SECTION(Memory, 4),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
kResizableMaximumFlag,
|
|
|
|
28,
|
|
|
|
28,
|
|
|
|
SECTION(Data, 11),
|
|
|
|
ENTRY_COUNT(1),
|
|
|
|
LINEAR_MEMORY_INDEX_0,
|
|
|
|
WASM_INIT_EXPR_F64(9.9), // dest addr
|
|
|
|
U32V_1(3), // source size
|
|
|
|
'a',
|
|
|
|
'b',
|
|
|
|
'c' // data bytes
|
|
|
|
};
|
|
|
|
|
|
|
|
EXPECT_FAILURE(data);
|
2016-09-23 15:56:42 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 17:58:07 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, OneIndirectFunction) {
|
2016-09-23 15:56:42 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
// sig#0 ---------------------------------------------------------------
|
2016-09-23 15:56:42 +00:00
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2016-09-27 20:46:10 +00:00
|
|
|
// funcs ---------------------------------------------------------------
|
2016-09-23 15:56:42 +00:00
|
|
|
ONE_EMPTY_FUNCTION,
|
2016-09-27 20:46:10 +00:00
|
|
|
// table declaration ---------------------------------------------------
|
|
|
|
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeForm, 0, 1};
|
2016-09-23 15:56:42 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
|
|
|
EXPECT_OK(result);
|
|
|
|
if (result.ok()) {
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, result.val->signatures.size());
|
|
|
|
EXPECT_EQ(1u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(1u, result.val->function_tables.size());
|
|
|
|
EXPECT_EQ(1u, result.val->function_tables[0].min_size);
|
2016-09-27 20:46:10 +00:00
|
|
|
}
|
|
|
|
if (result.val) delete result.val;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, OneIndirectFunction_one_entry) {
|
|
|
|
static const byte data[] = {
|
|
|
|
// sig#0 ---------------------------------------------------------------
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
|
|
|
// funcs ---------------------------------------------------------------
|
|
|
|
ONE_EMPTY_FUNCTION,
|
|
|
|
// table declaration ---------------------------------------------------
|
|
|
|
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeForm, 0, 1,
|
|
|
|
// elements ------------------------------------------------------------
|
|
|
|
SECTION(Element, 7),
|
|
|
|
1, // entry count
|
|
|
|
TABLE_INDEX(0), WASM_INIT_EXPR_I32V_1(0),
|
|
|
|
1, // elements count
|
|
|
|
FUNC_INDEX(0)};
|
|
|
|
|
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2015-12-11 12:26:16 +00:00
|
|
|
if (result.ok()) {
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, result.val->signatures.size());
|
|
|
|
EXPECT_EQ(1u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(1u, result.val->function_tables.size());
|
|
|
|
EXPECT_EQ(1u, result.val->function_tables[0].min_size);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
2015-12-17 11:38:28 +00:00
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) {
|
|
|
|
static const byte data[] = {
|
|
|
|
// sig#0 -------------------------------------------------------
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1 + SIZEOF_SIG_ENTRY_v_v + SIZEOF_SIG_ENTRY_v_x),
|
2016-04-29 09:39:26 +00:00
|
|
|
2, // --
|
|
|
|
SIG_ENTRY_v_v, // void -> void
|
|
|
|
SIG_ENTRY_v_x(kLocalI32), // void -> i32
|
2016-05-25 16:12:09 +00:00
|
|
|
// funcs ------------------------------------------------------
|
|
|
|
FOUR_EMPTY_FUNCTIONS,
|
2016-09-27 20:46:10 +00:00
|
|
|
// table declaration -------------------------------------------
|
|
|
|
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeForm, 0, 8,
|
|
|
|
// table elements ----------------------------------------------
|
|
|
|
SECTION(Element, 14),
|
|
|
|
1, // entry count
|
|
|
|
TABLE_INDEX(0), WASM_INIT_EXPR_I32V_1(0),
|
|
|
|
8, // elements count
|
|
|
|
FUNC_INDEX(0), // --
|
|
|
|
FUNC_INDEX(1), // --
|
|
|
|
FUNC_INDEX(2), // --
|
|
|
|
FUNC_INDEX(3), // --
|
|
|
|
FUNC_INDEX(0), // --
|
|
|
|
FUNC_INDEX(1), // --
|
|
|
|
FUNC_INDEX(2), // --
|
|
|
|
FUNC_INDEX(3), // --
|
2016-05-25 16:12:09 +00:00
|
|
|
FOUR_EMPTY_BODIES};
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2015-12-11 12:26:16 +00:00
|
|
|
if (result.ok()) {
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(2u, result.val->signatures.size());
|
|
|
|
EXPECT_EQ(4u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(1u, result.val->function_tables.size());
|
|
|
|
EXPECT_EQ(8u, result.val->function_tables[0].min_size);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
2015-12-17 11:38:28 +00:00
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, IndirectFunctionNoFunctions) {
|
|
|
|
static const byte data[] = {
|
|
|
|
// sig#0 -------------------------------------------------------
|
2016-04-29 09:39:26 +00:00
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2015-12-11 12:26:16 +00:00
|
|
|
// indirect table ----------------------------------------------
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Table, 4), ENTRY_COUNT(1), 1, 0, 0,
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, IndirectFunctionInvalidIndex) {
|
|
|
|
static const byte data[] = {
|
|
|
|
// sig#0 -------------------------------------------------------
|
2016-04-29 09:39:26 +00:00
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2015-12-11 12:26:16 +00:00
|
|
|
// functions ---------------------------------------------------
|
2016-05-25 16:12:09 +00:00
|
|
|
ONE_EMPTY_FUNCTION,
|
2015-12-11 12:26:16 +00:00
|
|
|
// indirect table ----------------------------------------------
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Table, 4), ENTRY_COUNT(1), 1, 1, 0,
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
class WasmSignatureDecodeTest : public TestWithZone {};
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, Ok_v_v) {
|
2016-04-29 09:39:26 +00:00
|
|
|
static const byte data[] = {SIG_ENTRY_v_v};
|
2016-09-20 16:07:25 +00:00
|
|
|
v8::internal::AccountingAllocator allocator;
|
2016-10-17 12:12:30 +00:00
|
|
|
Zone zone(&allocator, ZONE_NAME);
|
2015-12-11 12:26:16 +00:00
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(&zone, data, data + sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
EXPECT_TRUE(sig != nullptr);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, sig->parameter_count());
|
|
|
|
EXPECT_EQ(0u, sig->return_count());
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, Ok_t_v) {
|
2016-12-21 13:43:00 +00:00
|
|
|
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
|
|
|
|
ValueTypePair ret_type = kValueTypes[i];
|
2016-04-29 09:39:26 +00:00
|
|
|
const byte data[] = {SIG_ENTRY_x(ret_type.code)};
|
2015-12-11 12:26:16 +00:00
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
EXPECT_TRUE(sig != nullptr);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, sig->parameter_count());
|
|
|
|
EXPECT_EQ(1u, sig->return_count());
|
2015-12-11 12:26:16 +00:00
|
|
|
EXPECT_EQ(ret_type.type, sig->GetReturn());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, Ok_v_t) {
|
2016-12-21 13:43:00 +00:00
|
|
|
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
|
|
|
|
ValueTypePair param_type = kValueTypes[i];
|
2016-04-29 09:39:26 +00:00
|
|
|
const byte data[] = {SIG_ENTRY_v_x(param_type.code)};
|
2015-12-11 12:26:16 +00:00
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
EXPECT_TRUE(sig != nullptr);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, sig->parameter_count());
|
|
|
|
EXPECT_EQ(0u, sig->return_count());
|
2015-12-11 12:26:16 +00:00
|
|
|
EXPECT_EQ(param_type.type, sig->GetParam(0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, Ok_t_t) {
|
2016-12-21 13:43:00 +00:00
|
|
|
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
|
|
|
|
ValueTypePair ret_type = kValueTypes[i];
|
|
|
|
for (size_t j = 0; j < arraysize(kValueTypes); j++) {
|
|
|
|
ValueTypePair param_type = kValueTypes[j];
|
2016-04-29 09:39:26 +00:00
|
|
|
const byte data[] = {SIG_ENTRY_x_x(ret_type.code, param_type.code)};
|
2015-12-11 12:26:16 +00:00
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
EXPECT_TRUE(sig != nullptr);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, sig->parameter_count());
|
|
|
|
EXPECT_EQ(1u, sig->return_count());
|
2015-12-11 12:26:16 +00:00
|
|
|
EXPECT_EQ(param_type.type, sig->GetParam(0));
|
|
|
|
EXPECT_EQ(ret_type.type, sig->GetReturn());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, Ok_i_tt) {
|
2016-12-21 13:43:00 +00:00
|
|
|
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
|
|
|
|
ValueTypePair p0_type = kValueTypes[i];
|
|
|
|
for (size_t j = 0; j < arraysize(kValueTypes); j++) {
|
|
|
|
ValueTypePair p1_type = kValueTypes[j];
|
2016-04-29 09:39:26 +00:00
|
|
|
const byte data[] = {
|
|
|
|
SIG_ENTRY_x_xx(kLocalI32, p0_type.code, p1_type.code)};
|
2015-12-11 12:26:16 +00:00
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
EXPECT_TRUE(sig != nullptr);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(2u, sig->parameter_count());
|
|
|
|
EXPECT_EQ(1u, sig->return_count());
|
2015-12-11 12:26:16 +00:00
|
|
|
EXPECT_EQ(p0_type.type, sig->GetParam(0));
|
|
|
|
EXPECT_EQ(p1_type.type, sig->GetParam(1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-14 17:45:59 +00:00
|
|
|
TEST_F(WasmSignatureDecodeTest, TooManyParams) {
|
|
|
|
static const byte data[] = {kWasmFunctionTypeForm,
|
|
|
|
WASM_I32V_3(kV8MaxWasmFunctionParams + 1),
|
|
|
|
kLocalI32, 0};
|
|
|
|
FunctionSig* sig =
|
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
|
|
|
EXPECT_FALSE(sig != nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, TooManyReturns) {
|
|
|
|
bool prev = FLAG_wasm_mv_prototype;
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
FLAG_wasm_mv_prototype = i != 0;
|
|
|
|
const int max_return_count =
|
|
|
|
static_cast<int>(FLAG_wasm_mv_prototype ? kV8MaxWasmFunctionMultiReturns
|
|
|
|
: kV8MaxWasmFunctionReturns);
|
|
|
|
byte data[] = {kWasmFunctionTypeForm, 0, WASM_I32V_3(max_return_count + 1),
|
|
|
|
kLocalI32};
|
|
|
|
FunctionSig* sig =
|
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
|
|
|
EXPECT_EQ(nullptr, sig);
|
|
|
|
FLAG_wasm_mv_prototype = prev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
TEST_F(WasmSignatureDecodeTest, Fail_off_end) {
|
|
|
|
byte data[256];
|
|
|
|
for (int p = 0; p <= 255; p = p + 1 + p * 3) {
|
|
|
|
for (int i = 0; i <= p; i++) data[i] = kLocalI32;
|
|
|
|
data[0] = static_cast<byte>(p);
|
|
|
|
|
|
|
|
for (int i = 0; i < p + 1; i++) {
|
|
|
|
// Should fall off the end for all signatures.
|
|
|
|
FunctionSig* sig = DecodeWasmSignatureForTesting(zone(), data, data + i);
|
|
|
|
EXPECT_EQ(nullptr, sig);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, Fail_invalid_type) {
|
|
|
|
byte kInvalidType = 76;
|
2016-04-29 09:39:26 +00:00
|
|
|
for (size_t i = 0; i < SIZEOF_SIG_ENTRY_x_xx; i++) {
|
|
|
|
byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalI32)};
|
2015-12-11 12:26:16 +00:00
|
|
|
data[i] = kInvalidType;
|
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2015-12-11 12:26:16 +00:00
|
|
|
EXPECT_EQ(nullptr, sig);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-29 09:39:26 +00:00
|
|
|
TEST_F(WasmSignatureDecodeTest, Fail_invalid_ret_type1) {
|
|
|
|
static const byte data[] = {SIG_ENTRY_x_x(kLocalVoid, kLocalI32)};
|
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2016-04-29 09:39:26 +00:00
|
|
|
EXPECT_EQ(nullptr, sig);
|
|
|
|
}
|
2015-12-11 12:26:16 +00:00
|
|
|
|
2016-04-29 09:39:26 +00:00
|
|
|
TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type1) {
|
|
|
|
static const byte data[] = {SIG_ENTRY_x_x(kLocalI32, kLocalVoid)};
|
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2016-04-29 09:39:26 +00:00
|
|
|
EXPECT_EQ(nullptr, sig);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type2) {
|
|
|
|
static const byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalVoid)};
|
|
|
|
FunctionSig* sig =
|
2016-09-27 20:46:10 +00:00
|
|
|
DecodeWasmSignatureForTesting(zone(), data, data + sizeof(data));
|
2016-04-29 09:39:26 +00:00
|
|
|
EXPECT_EQ(nullptr, sig);
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
|
|
|
|
2017-03-28 14:27:42 +00:00
|
|
|
class WasmFunctionVerifyTest : public TestWithIsolateAndZone {
|
|
|
|
public:
|
|
|
|
WasmFunctionVerifyTest()
|
|
|
|
: instance(&module), env(&module, &instance, bytes) {}
|
|
|
|
virtual ~WasmFunctionVerifyTest() {}
|
|
|
|
|
|
|
|
ModuleBytesEnv* get_env() { return &env; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
WasmModule module;
|
|
|
|
WasmInstance instance;
|
|
|
|
Vector<const byte> bytes;
|
|
|
|
ModuleBytesEnv env;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(WasmFunctionVerifyTest);
|
|
|
|
};
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) {
|
2016-02-19 14:58:25 +00:00
|
|
|
static const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
SIG_ENTRY_v_v, // signature entry
|
|
|
|
4, // locals
|
|
|
|
3,
|
|
|
|
kLocalI32, // --
|
|
|
|
4,
|
|
|
|
kLocalI64, // --
|
|
|
|
5,
|
|
|
|
kLocalF32, // --
|
|
|
|
6,
|
|
|
|
kLocalF64, // --
|
2017-01-15 21:18:53 +00:00
|
|
|
kExprEnd // body
|
2015-12-11 12:26:16 +00:00
|
|
|
};
|
|
|
|
|
2017-03-28 14:27:42 +00:00
|
|
|
FunctionResult result = DecodeWasmFunction(isolate(), zone(), get_env(), data,
|
|
|
|
data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2015-12-11 12:26:16 +00:00
|
|
|
|
|
|
|
if (result.val && result.ok()) {
|
|
|
|
WasmFunction* function = result.val;
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, function->sig->parameter_count());
|
|
|
|
EXPECT_EQ(0u, function->sig->return_count());
|
|
|
|
EXPECT_EQ(0u, function->name_offset);
|
|
|
|
EXPECT_EQ(static_cast<uint32_t>(SIZEOF_SIG_ENTRY_v_v),
|
|
|
|
function->code_start_offset);
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_EQ(sizeof(data), function->code_end_offset);
|
2016-03-07 21:04:07 +00:00
|
|
|
// TODO(titzer): verify encoding of local declarations
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
2015-12-17 11:38:28 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2015-12-11 12:26:16 +00:00
|
|
|
}
|
2016-01-08 00:35:57 +00:00
|
|
|
|
2016-03-10 12:36:42 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, SectionWithoutNameLength) {
|
|
|
|
const byte data[] = {1};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, TheLoneliestOfValidModulesTheTrulyEmptyOne) {
|
2016-01-08 00:35:57 +00:00
|
|
|
const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
0, // unknown section code.
|
2016-03-10 12:36:42 +00:00
|
|
|
0, // Empty section name.
|
|
|
|
// No section name, no content, nothing but sadness.
|
2016-04-29 09:39:26 +00:00
|
|
|
0, // No section content.
|
2016-01-08 00:35:57 +00:00
|
|
|
};
|
2016-03-10 12:36:42 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
2016-01-08 00:35:57 +00:00
|
|
|
}
|
|
|
|
|
2016-03-10 12:36:42 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionEmpty) {
|
|
|
|
const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
UNKNOWN_SECTION(0),
|
2016-03-10 12:36:42 +00:00
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
2016-01-08 00:35:57 +00:00
|
|
|
}
|
|
|
|
|
2016-03-10 12:36:42 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, OnlyUnknownSectionNonEmpty) {
|
|
|
|
const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
UNKNOWN_SECTION(5),
|
2016-04-29 09:39:26 +00:00
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff,
|
|
|
|
0xff, // section data
|
2016-01-08 00:35:57 +00:00
|
|
|
};
|
2016-03-10 12:36:42 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
2016-01-08 00:35:57 +00:00
|
|
|
}
|
|
|
|
|
2016-03-10 12:36:42 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, SignatureFollowedByEmptyUnknownSection) {
|
|
|
|
const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2016-03-10 12:36:42 +00:00
|
|
|
// -----------------------------------------------------------
|
2016-09-27 20:46:10 +00:00
|
|
|
UNKNOWN_SECTION(0)};
|
2016-03-10 12:36:42 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, SignatureFollowedByUnknownSection) {
|
|
|
|
const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2016-03-10 12:36:42 +00:00
|
|
|
// -----------------------------------------------------------
|
2016-09-27 20:46:10 +00:00
|
|
|
UNKNOWN_SECTION(5), 0xff, 0xff, 0xff, 0xff, 0xff,
|
2016-03-10 12:36:42 +00:00
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
2016-01-08 00:35:57 +00:00
|
|
|
}
|
|
|
|
|
2016-03-03 16:52:10 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, UnknownSectionOverflow) {
|
2016-02-19 14:58:25 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
UNKNOWN_SECTION(9),
|
2016-04-29 09:39:26 +00:00
|
|
|
1,
|
|
|
|
2,
|
|
|
|
3,
|
|
|
|
4,
|
|
|
|
5,
|
|
|
|
6,
|
|
|
|
7,
|
|
|
|
8,
|
|
|
|
9,
|
|
|
|
10, // 10 byte section
|
2016-01-08 00:35:57 +00:00
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2016-03-03 16:52:10 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, UnknownSectionUnderflow) {
|
2016-02-19 14:58:25 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
UNKNOWN_SECTION(333),
|
2016-04-29 09:39:26 +00:00
|
|
|
1,
|
|
|
|
2,
|
|
|
|
3,
|
|
|
|
4, // 4 byte section
|
2016-01-08 00:35:57 +00:00
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2016-03-03 16:52:10 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, UnknownSectionSkipped) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
UNKNOWN_SECTION(1),
|
2016-04-29 09:39:26 +00:00
|
|
|
0, // one byte section
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Global, 6),
|
2016-03-03 16:52:10 +00:00
|
|
|
1,
|
2016-09-27 20:46:10 +00:00
|
|
|
kLocalI32, // memory type
|
|
|
|
0, // exported
|
|
|
|
WASM_INIT_EXPR_I32V_1(33), // init
|
2016-03-03 16:52:10 +00:00
|
|
|
};
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_OK(result);
|
2016-03-03 16:52:10 +00:00
|
|
|
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, result.val->globals.size());
|
|
|
|
EXPECT_EQ(0u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(0u, result.val->data_segments.size());
|
2016-03-03 16:52:10 +00:00
|
|
|
|
2016-05-24 16:32:03 +00:00
|
|
|
const WasmGlobal* global = &result.val->globals.back();
|
2016-03-03 16:52:10 +00:00
|
|
|
|
2016-12-21 13:43:00 +00:00
|
|
|
EXPECT_EQ(kWasmI32, global->type);
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(0u, global->offset);
|
2016-03-03 16:52:10 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
|
|
|
}
|
|
|
|
|
2016-02-19 14:58:25 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_empty) {
|
2016-09-27 20:46:10 +00:00
|
|
|
static const byte data[] = {SECTION(Type, 1), 0, SECTION(Import, 1), 0};
|
2016-02-19 14:58:25 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
2016-04-21 11:18:41 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_nosigs1) {
|
2016-09-27 20:46:10 +00:00
|
|
|
static const byte data[] = {SECTION(Import, 1), 0};
|
2016-04-21 11:18:41 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
2016-11-08 13:25:00 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_mutable_global) {
|
|
|
|
{
|
|
|
|
static const byte data[] = {
|
|
|
|
SECTION(Import, 8), // section header
|
|
|
|
1, // number of imports
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'm', // module name
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'f', // global name
|
|
|
|
kExternalGlobal, // import kind
|
|
|
|
kLocalI32, // type
|
|
|
|
0, // mutability
|
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
static const byte data[] = {
|
|
|
|
SECTION(Import, 8), // section header
|
|
|
|
1, // sig table
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'm', // module name
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'f', // global name
|
|
|
|
kExternalGlobal, // import kind
|
|
|
|
kLocalI32, // type
|
|
|
|
1, // mutability
|
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-17 13:35:20 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_mutability_malformed) {
|
|
|
|
static const byte data[] = {
|
|
|
|
SECTION(Import, 8),
|
|
|
|
1, // --
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'm', // module name
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'g', // global name
|
|
|
|
kExternalGlobal, // import kind
|
|
|
|
kLocalI32, // type
|
|
|
|
2, // invalid mutability
|
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2016-04-21 11:18:41 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_nosigs2) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Import, 6), 1, // sig table
|
|
|
|
NAME_LENGTH(1), 'm', // module name
|
|
|
|
NAME_LENGTH(1), 'f', // function name
|
|
|
|
kExternalFunction, // import kind
|
|
|
|
IMPORT_SIG_INDEX(0), // sig index
|
2016-04-21 11:18:41 +00:00
|
|
|
};
|
2016-02-19 14:58:25 +00:00
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_invalid_sig) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1), 0, // --
|
|
|
|
SECTION(Import, 6), 1, // --
|
|
|
|
NAME_LENGTH(1), 'm', // module name
|
|
|
|
NAME_LENGTH(1), 'f', // function name
|
|
|
|
kExternalFunction, // import kind
|
|
|
|
IMPORT_SIG_INDEX(0), // sig index
|
2016-02-19 14:58:25 +00:00
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_one_sig) {
|
|
|
|
static const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Import, 7),
|
|
|
|
1, // --
|
2016-03-10 12:36:42 +00:00
|
|
|
NAME_LENGTH(1),
|
|
|
|
'm', // module name
|
|
|
|
NAME_LENGTH(1),
|
2016-09-27 20:46:10 +00:00
|
|
|
'f', // function name
|
|
|
|
kExternalFunction, // import kind
|
|
|
|
IMPORT_SIG_INDEX(0), // sig index
|
2016-02-19 14:58:25 +00:00
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
2016-03-08 19:55:36 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_invalid_module) {
|
|
|
|
static const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
// signatures
|
2016-09-27 20:46:10 +00:00
|
|
|
SIGNATURES_SECTION_VOID_VOID, // --
|
|
|
|
SECTION(Import, 7), // --
|
|
|
|
1, // --
|
|
|
|
NO_NAME, // module name
|
|
|
|
NAME_LENGTH(1), // --
|
|
|
|
'f', // function name
|
|
|
|
kExternalFunction, // import kind
|
|
|
|
IMPORT_SIG_INDEX(0), // sig index
|
2016-03-08 19:55:36 +00:00
|
|
|
};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2016-02-19 14:58:25 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ImportTable_off_end) {
|
|
|
|
static const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Import, 6),
|
2016-03-10 12:36:42 +00:00
|
|
|
1,
|
|
|
|
NAME_LENGTH(1),
|
|
|
|
'm', // module name
|
|
|
|
NAME_LENGTH(1),
|
2016-09-27 20:46:10 +00:00
|
|
|
'f', // function name
|
|
|
|
kExternalFunction, // import kind
|
|
|
|
IMPORT_SIG_INDEX(0), // sig index
|
2016-02-19 14:58:25 +00:00
|
|
|
};
|
|
|
|
|
2016-03-10 12:36:42 +00:00
|
|
|
EXPECT_OFF_END_FAILURE(data, 16, sizeof(data));
|
2016-02-19 14:58:25 +00:00
|
|
|
}
|
|
|
|
|
2016-03-09 22:50:36 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTable_empty1) {
|
2016-09-27 20:46:10 +00:00
|
|
|
static const byte data[] = { // signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID, // --
|
|
|
|
ONE_EMPTY_FUNCTION, SECTION(Export, 1), // --
|
|
|
|
0, // --
|
2016-05-25 16:12:09 +00:00
|
|
|
ONE_EMPTY_BODY};
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-05-25 16:12:09 +00:00
|
|
|
EXPECT_OK(result);
|
|
|
|
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(0u, result.val->export_table.size());
|
2016-05-25 16:12:09 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2016-02-27 01:52:30 +00:00
|
|
|
}
|
|
|
|
|
2016-03-09 22:50:36 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTable_empty2) {
|
2016-04-29 09:39:26 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1), 0, SECTION(Export, 1), 0 // --
|
2016-04-29 09:39:26 +00:00
|
|
|
};
|
2016-09-27 20:46:10 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
2016-02-27 01:52:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions2) {
|
2016-09-27 20:46:10 +00:00
|
|
|
static const byte data[] = {SECTION(Export, 1), 0};
|
|
|
|
EXPECT_VERIFIES(data);
|
2016-02-27 01:52:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTableOne) {
|
2016-05-25 16:12:09 +00:00
|
|
|
static const byte data[] = {// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
|
|
|
ONE_EMPTY_FUNCTION,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Export, 4),
|
|
|
|
1, // exports
|
|
|
|
NO_NAME, // --
|
|
|
|
kExternalFunction, // --
|
|
|
|
FUNC_INDEX(0), // --
|
2016-05-25 16:12:09 +00:00
|
|
|
ONE_EMPTY_BODY};
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-05-25 16:12:09 +00:00
|
|
|
EXPECT_OK(result);
|
|
|
|
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(1u, result.val->export_table.size());
|
2016-05-25 16:12:09 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2016-02-27 01:52:30 +00:00
|
|
|
}
|
|
|
|
|
2016-09-06 09:50:12 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ExportNameWithInvalidStringLength) {
|
|
|
|
static const byte data[] = {// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
|
|
|
ONE_EMPTY_FUNCTION,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Export, 12),
|
|
|
|
1, // exports
|
|
|
|
NAME_LENGTH(84), // invalid string length
|
|
|
|
'e', // --
|
|
|
|
kExternalFunction, // --
|
|
|
|
FUNC_INDEX(0)};
|
2016-09-06 09:50:12 +00:00
|
|
|
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2016-02-27 01:52:30 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTableTwo) {
|
2016-05-25 16:12:09 +00:00
|
|
|
static const byte data[] = {// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
|
|
|
ONE_EMPTY_FUNCTION,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Export, 14),
|
|
|
|
2, // exports
|
2016-05-25 16:12:09 +00:00
|
|
|
NAME_LENGTH(4),
|
|
|
|
'n',
|
|
|
|
'a',
|
|
|
|
'm',
|
2016-09-27 20:46:10 +00:00
|
|
|
'e', // --
|
|
|
|
kExternalFunction,
|
2016-05-25 16:12:09 +00:00
|
|
|
FUNC_INDEX(0), // --
|
|
|
|
NAME_LENGTH(3),
|
|
|
|
'n',
|
|
|
|
'o',
|
2016-09-27 20:46:10 +00:00
|
|
|
'm', // --
|
|
|
|
kExternalFunction, // --
|
|
|
|
FUNC_INDEX(0), // --
|
2016-05-25 16:12:09 +00:00
|
|
|
ONE_EMPTY_BODY};
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-05-25 16:12:09 +00:00
|
|
|
EXPECT_OK(result);
|
|
|
|
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(1u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(2u, result.val->export_table.size());
|
2016-05-25 16:12:09 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2016-02-27 01:52:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTableThree) {
|
2016-05-25 16:12:09 +00:00
|
|
|
static const byte data[] = {// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
|
|
|
THREE_EMPTY_FUNCTIONS,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Export, 13),
|
|
|
|
3, // exports
|
|
|
|
NAME_LENGTH(1),
|
|
|
|
'a', // --
|
|
|
|
kExternalFunction,
|
2016-05-25 16:12:09 +00:00
|
|
|
FUNC_INDEX(0), // --
|
|
|
|
NAME_LENGTH(1),
|
2016-09-27 20:46:10 +00:00
|
|
|
'b', // --
|
|
|
|
kExternalFunction,
|
2016-05-25 16:12:09 +00:00
|
|
|
FUNC_INDEX(1), // --
|
|
|
|
NAME_LENGTH(1),
|
2016-09-23 17:58:07 +00:00
|
|
|
'c', // --
|
2016-09-27 20:46:10 +00:00
|
|
|
kExternalFunction,
|
|
|
|
FUNC_INDEX(2), // --
|
2016-05-25 16:12:09 +00:00
|
|
|
THREE_EMPTY_BODIES};
|
2016-09-27 20:46:10 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
2016-05-25 16:12:09 +00:00
|
|
|
EXPECT_OK(result);
|
|
|
|
|
2016-11-11 11:55:30 +00:00
|
|
|
EXPECT_EQ(3u, result.val->functions.size());
|
|
|
|
EXPECT_EQ(3u, result.val->export_table.size());
|
2016-05-25 16:12:09 +00:00
|
|
|
|
|
|
|
if (result.val) delete result.val;
|
2016-02-27 01:52:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTableThreeOne) {
|
|
|
|
for (int i = 0; i < 6; i++) {
|
2016-05-25 16:12:09 +00:00
|
|
|
const byte data[] = {// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
|
|
|
THREE_EMPTY_FUNCTIONS,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Export, 6),
|
|
|
|
1, // exports
|
2016-05-25 16:12:09 +00:00
|
|
|
NAME_LENGTH(2),
|
|
|
|
'e',
|
|
|
|
'x', // --
|
2016-09-27 20:46:10 +00:00
|
|
|
kExternalFunction,
|
|
|
|
FUNC_INDEX(i), // --
|
2016-05-25 16:12:09 +00:00
|
|
|
THREE_EMPTY_BODIES};
|
2016-02-27 01:52:30 +00:00
|
|
|
|
|
|
|
if (i < 3) {
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
} else {
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, ExportTableOne_off_end) {
|
|
|
|
static const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
// signatures
|
|
|
|
SIGNATURES_SECTION_VOID_VOID,
|
2016-05-25 16:12:09 +00:00
|
|
|
ONE_EMPTY_FUNCTION,
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Export, 1 + 6),
|
|
|
|
1, // exports
|
|
|
|
NO_NAME, // --
|
|
|
|
kExternalFunction,
|
2016-03-10 12:36:42 +00:00
|
|
|
FUNC_INDEX(0), // --
|
2016-02-27 01:52:30 +00:00
|
|
|
};
|
|
|
|
|
2016-11-10 12:50:51 +00:00
|
|
|
for (size_t length = 33; length < sizeof(data); length++) {
|
2016-02-27 01:52:30 +00:00
|
|
|
ModuleResult result = DecodeModule(data, data + length);
|
|
|
|
EXPECT_FALSE(result.ok());
|
|
|
|
if (result.val) delete result.val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-09 22:50:36 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, FunctionSignatures_empty) {
|
2016-04-21 11:18:41 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1), 0, // --
|
|
|
|
SECTION(Function, 1), 0 // --
|
|
|
|
}; // --
|
2016-03-09 22:50:36 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, FunctionSignatures_one) {
|
2016-04-21 11:18:41 +00:00
|
|
|
static const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
|
2016-04-21 11:18:41 +00:00
|
|
|
FUNCTION_SIGNATURES_SECTION(1, 0) // --
|
|
|
|
};
|
2016-03-09 22:50:36 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
2016-09-21 16:18:00 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, Regression_648070) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Type, 1), 0, // --
|
|
|
|
SECTION(Function, 5), // --
|
|
|
|
U32V_5(3500228624) // function count = 3500228624
|
|
|
|
}; // --
|
2016-09-21 16:18:00 +00:00
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2016-03-09 22:50:36 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, FunctionBodies_empty) {
|
2016-04-21 11:18:41 +00:00
|
|
|
static const byte data[] = {
|
|
|
|
EMPTY_SIGNATURES_SECTION, // --
|
|
|
|
EMPTY_FUNCTION_SIGNATURES_SECTION, // --
|
|
|
|
EMPTY_FUNCTION_BODIES_SECTION // --
|
|
|
|
};
|
2016-03-09 22:50:36 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, FunctionBodies_one_empty) {
|
2016-03-10 12:36:42 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
|
|
|
|
FUNCTION_SIGNATURES_SECTION(1, 0), // --
|
|
|
|
SECTION(Code, 1 + SIZEOF_EMPTY_BODY), 1, EMPTY_BODY // --
|
2016-04-21 11:18:41 +00:00
|
|
|
};
|
2016-03-09 22:50:36 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, FunctionBodies_one_nop) {
|
2016-03-10 12:36:42 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
|
|
|
|
FUNCTION_SIGNATURES_SECTION(1, 0), // --
|
|
|
|
SECTION(Code, 1 + SIZEOF_NOP_BODY), 1, NOP_BODY // --
|
2016-04-21 11:18:41 +00:00
|
|
|
};
|
2016-03-09 22:50:36 +00:00
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch1) {
|
2016-04-21 11:18:41 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
|
|
|
|
FUNCTION_SIGNATURES_SECTION(2, 0, 0), // --
|
|
|
|
SECTION(Code, 1 + SIZEOF_EMPTY_BODY), 1, // --
|
|
|
|
EMPTY_BODY // --
|
2016-04-21 11:18:41 +00:00
|
|
|
};
|
2016-03-09 22:50:36 +00:00
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, FunctionBodies_count_mismatch2) {
|
2016-04-21 11:18:41 +00:00
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
|
|
|
|
FUNCTION_SIGNATURES_SECTION(1, 0), // --
|
|
|
|
SECTION(Code, 1 + 2 * SIZEOF_NOP_BODY), // --
|
|
|
|
ENTRY_COUNT(2), // --
|
|
|
|
NOP_BODY, // --
|
|
|
|
NOP_BODY // --
|
2016-04-21 11:18:41 +00:00
|
|
|
};
|
2016-03-09 22:50:36 +00:00
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, Names_empty) {
|
|
|
|
static const byte data[] = {
|
|
|
|
EMPTY_SIGNATURES_SECTION, EMPTY_FUNCTION_SIGNATURES_SECTION,
|
|
|
|
EMPTY_FUNCTION_BODIES_SECTION, EMPTY_NAMES_SECTION};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, Names_one_empty) {
|
|
|
|
static const byte data[] = {
|
2016-04-29 09:39:26 +00:00
|
|
|
SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
|
2016-03-10 12:36:42 +00:00
|
|
|
FUNCTION_SIGNATURES_SECTION(1, 0), // --
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION(Code, 1 + SIZEOF_EMPTY_BODY),
|
|
|
|
ENTRY_COUNT(1),
|
2016-03-10 12:36:42 +00:00
|
|
|
EMPTY_BODY, // --
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION_NAMES(1 + 5),
|
|
|
|
ENTRY_COUNT(1),
|
2016-03-10 12:36:42 +00:00
|
|
|
FOO_STRING,
|
|
|
|
NO_LOCAL_NAMES // --
|
2016-03-09 22:50:36 +00:00
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, Names_two_empty) {
|
|
|
|
static const byte data[] = {
|
2016-09-27 20:46:10 +00:00
|
|
|
SIGNATURES_SECTION(1, SIG_ENTRY_v_v), // --
|
|
|
|
FUNCTION_SIGNATURES_SECTION(2, 0, 0), // --
|
|
|
|
SECTION(Code, 1 + 2 * SIZEOF_EMPTY_BODY), // --
|
|
|
|
ENTRY_COUNT(2),
|
2016-03-10 12:36:42 +00:00
|
|
|
EMPTY_BODY,
|
|
|
|
EMPTY_BODY, // --
|
2016-09-27 20:46:10 +00:00
|
|
|
SECTION_NAMES(1 + 10),
|
|
|
|
ENTRY_COUNT(2), // --
|
2016-03-10 12:36:42 +00:00
|
|
|
FOO_STRING,
|
|
|
|
NO_LOCAL_NAMES, // --
|
|
|
|
FOO_STRING,
|
|
|
|
NO_LOCAL_NAMES, // --
|
2016-03-09 22:50:36 +00:00
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
2017-02-02 08:38:34 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, Regression684855) {
|
|
|
|
static const byte data[] = {
|
|
|
|
SECTION_NAMES(12),
|
|
|
|
0xfb, // functions count
|
|
|
|
0x27, // |
|
|
|
|
0x00, // function name length
|
|
|
|
0xff, // local names count
|
|
|
|
0xff, // |
|
|
|
|
0xff, // |
|
|
|
|
0xff, // |
|
|
|
|
0xff, // |
|
|
|
|
0xff, // error: "varint too large"
|
|
|
|
0xff, // |
|
|
|
|
0x00, // --
|
|
|
|
0x00 // --
|
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
|
|
|
|
2016-09-27 20:46:10 +00:00
|
|
|
#define EXPECT_INIT_EXPR(Type, type, value, ...) \
|
|
|
|
{ \
|
|
|
|
static const byte data[] = {__VA_ARGS__, kExprEnd}; \
|
|
|
|
WasmInitExpr expr = \
|
|
|
|
DecodeWasmInitExprForTesting(data, data + sizeof(data)); \
|
|
|
|
EXPECT_EQ(WasmInitExpr::k##Type##Const, expr.kind); \
|
|
|
|
EXPECT_EQ(value, expr.val.type##_const); \
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, InitExpr_i32) {
|
|
|
|
EXPECT_INIT_EXPR(I32, i32, 33, WASM_I32V_1(33));
|
|
|
|
EXPECT_INIT_EXPR(I32, i32, -21, WASM_I32V_1(-21));
|
|
|
|
EXPECT_INIT_EXPR(I32, i32, 437, WASM_I32V_2(437));
|
|
|
|
EXPECT_INIT_EXPR(I32, i32, 77777, WASM_I32V_3(77777));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, InitExpr_f32) {
|
|
|
|
EXPECT_INIT_EXPR(F32, f32, static_cast<float>(13.1), WASM_F32(13.1));
|
|
|
|
EXPECT_INIT_EXPR(F32, f32, static_cast<float>(-21.1), WASM_F32(-21.1));
|
|
|
|
EXPECT_INIT_EXPR(F32, f32, static_cast<float>(437.2), WASM_F32(437.2));
|
|
|
|
EXPECT_INIT_EXPR(F32, f32, static_cast<float>(77777.3), WASM_F32(77777.3));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, InitExpr_i64) {
|
|
|
|
EXPECT_INIT_EXPR(I64, i64, 33, WASM_I64V_1(33));
|
|
|
|
EXPECT_INIT_EXPR(I64, i64, -21, WASM_I64V_2(-21));
|
|
|
|
EXPECT_INIT_EXPR(I64, i64, 437, WASM_I64V_5(437));
|
|
|
|
EXPECT_INIT_EXPR(I64, i64, 77777, WASM_I64V_7(77777));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, InitExpr_f64) {
|
|
|
|
EXPECT_INIT_EXPR(F64, f64, 83.22, WASM_F64(83.22));
|
|
|
|
EXPECT_INIT_EXPR(F64, f64, -771.3, WASM_F64(-771.3));
|
|
|
|
EXPECT_INIT_EXPR(F64, f64, 43703.0, WASM_F64(43703.0));
|
|
|
|
EXPECT_INIT_EXPR(F64, f64, 77999.1, WASM_F64(77999.1));
|
|
|
|
}
|
|
|
|
|
|
|
|
#define EXPECT_INIT_EXPR_FAIL(...) \
|
|
|
|
{ \
|
|
|
|
static const byte data[] = {__VA_ARGS__, kExprEnd}; \
|
|
|
|
WasmInitExpr expr = \
|
|
|
|
DecodeWasmInitExprForTesting(data, data + sizeof(data)); \
|
|
|
|
EXPECT_EQ(WasmInitExpr::kNone, expr.kind); \
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleVerifyTest, InitExpr_illegal) {
|
|
|
|
EXPECT_INIT_EXPR_FAIL(WASM_I32V_1(0), WASM_I32V_1(0));
|
|
|
|
EXPECT_INIT_EXPR_FAIL(WASM_GET_LOCAL(0));
|
|
|
|
EXPECT_INIT_EXPR_FAIL(WASM_SET_LOCAL(0, WASM_I32V_1(0)));
|
|
|
|
EXPECT_INIT_EXPR_FAIL(WASM_I32_ADD(WASM_I32V_1(0), WASM_I32V_1(0)));
|
|
|
|
EXPECT_INIT_EXPR_FAIL(WASM_IF_ELSE(WASM_ZERO, WASM_ZERO, WASM_ZERO));
|
|
|
|
}
|
|
|
|
|
2016-10-12 09:17:12 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, Multiple_Named_Sections) {
|
|
|
|
static const byte data[] = {
|
|
|
|
SECTION(Unknown, 4), 1, 'X', 17, 18, // --
|
|
|
|
SECTION(Unknown, 9), 3, 'f', 'o', 'o', 5, 6, 7, 8, 9, // --
|
|
|
|
SECTION(Unknown, 8), 5, 'o', 't', 'h', 'e', 'r', 7, 8, // --
|
|
|
|
};
|
|
|
|
EXPECT_VERIFIES(data);
|
|
|
|
}
|
2017-01-24 15:23:02 +00:00
|
|
|
|
2017-04-11 08:28:52 +00:00
|
|
|
TEST_F(WasmModuleVerifyTest, Section_Name_No_UTF8) {
|
|
|
|
static const byte data[] = {SECTION(Unknown, 4), 1, 0xff, 17, 18};
|
|
|
|
EXPECT_FAILURE(data);
|
|
|
|
}
|
|
|
|
|
2017-01-24 15:23:02 +00:00
|
|
|
class WasmModuleCustomSectionTest : public TestWithIsolateAndZone {
|
|
|
|
public:
|
|
|
|
void CheckSections(const byte* module_start, const byte* module_end,
|
|
|
|
CustomSectionOffset expected[], size_t num_expected) {
|
|
|
|
// Add the WASM magic and version number automatically.
|
|
|
|
size_t size = static_cast<size_t>(module_end - module_start);
|
|
|
|
byte header[] = {WASM_MODULE_HEADER};
|
|
|
|
size_t total = sizeof(header) + size;
|
|
|
|
auto temp = new byte[total];
|
|
|
|
memcpy(temp, header, sizeof(header));
|
|
|
|
memcpy(temp + sizeof(header), module_start, size);
|
|
|
|
std::vector<CustomSectionOffset> custom_sections =
|
|
|
|
DecodeCustomSections(module_start, module_end);
|
|
|
|
|
|
|
|
CHECK_EQ(num_expected, custom_sections.size());
|
|
|
|
|
|
|
|
for (size_t i = 0; i < num_expected; i++) {
|
|
|
|
EXPECT_EQ(expected[i].section_start, custom_sections[i].section_start);
|
|
|
|
EXPECT_EQ(expected[i].name_offset, custom_sections[i].name_offset);
|
|
|
|
EXPECT_EQ(expected[i].name_length, custom_sections[i].name_length);
|
|
|
|
EXPECT_EQ(expected[i].payload_offset, custom_sections[i].payload_offset);
|
|
|
|
EXPECT_EQ(expected[i].payload_length, custom_sections[i].payload_length);
|
|
|
|
EXPECT_EQ(expected[i].section_length, custom_sections[i].section_length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(WasmModuleCustomSectionTest, ThreeUnknownSections) {
|
|
|
|
static const byte data[] = {
|
|
|
|
U32_LE(kWasmMagic), // --
|
|
|
|
U32_LE(kWasmVersion), // --
|
|
|
|
SECTION(Unknown, 4), 1, 'X', 17, 18, // --
|
|
|
|
SECTION(Unknown, 9), 3, 'f', 'o', 'o', 5, 6, 7, 8, 9, // --
|
|
|
|
SECTION(Unknown, 8), 5, 'o', 't', 'h', 'e', 'r', 7, 8, // --
|
|
|
|
};
|
|
|
|
|
|
|
|
static CustomSectionOffset expected[] = {
|
|
|
|
// sec_start, nm_offset, nm_length, py_offset, py_length, sec_length
|
|
|
|
{10, 11, 1, 12, 2, 4}, // --
|
|
|
|
{16, 17, 3, 20, 5, 9}, // --
|
|
|
|
{27, 28, 5, 33, 2, 8}, // --
|
|
|
|
};
|
|
|
|
|
|
|
|
CheckSections(data, data + sizeof(data), expected, arraysize(expected));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WasmModuleCustomSectionTest, TwoKnownTwoUnknownSections) {
|
|
|
|
static const byte data[] = {
|
|
|
|
U32_LE(kWasmMagic), // --
|
|
|
|
U32_LE(kWasmVersion), // --
|
|
|
|
SIGNATURES_SECTION(2, SIG_ENTRY_v_v, SIG_ENTRY_v_v), // --
|
|
|
|
SECTION(Unknown, 4),
|
|
|
|
1,
|
|
|
|
'X',
|
|
|
|
17,
|
|
|
|
18, // --
|
|
|
|
ONE_EMPTY_FUNCTION,
|
|
|
|
SECTION(Unknown, 8),
|
|
|
|
5,
|
|
|
|
'o',
|
|
|
|
't',
|
|
|
|
'h',
|
|
|
|
'e',
|
|
|
|
'r',
|
|
|
|
7,
|
|
|
|
8, // --
|
|
|
|
};
|
|
|
|
|
|
|
|
static CustomSectionOffset expected[] = {
|
|
|
|
// sec_start, nm_offset, nm_length, py_offset, py_length, sec_length
|
|
|
|
{19, 20, 1, 21, 2, 4}, // --
|
|
|
|
{29, 30, 5, 35, 2, 8}, // --
|
|
|
|
};
|
|
|
|
|
|
|
|
CheckSections(data, data + sizeof(data), expected, arraysize(expected));
|
|
|
|
}
|
|
|
|
|
2015-12-11 12:26:16 +00:00
|
|
|
} // namespace wasm
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|