encoder-unittest.cc revision 342c50ce1624b485728b9a4fc41d8bbf37eb46cf
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Copyright 2015 the V8 project authors. All rights reserved.
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Use of this source code is governed by a BSD-style license that can be
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// found in the LICENSE file.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "test/unittests/test-utils.h"
6f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
7f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#include "src/v8.h"
85739d2c168819394502e20cbe6071979b9c1038cbsalomon@google.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "src/wasm/ast-decoder.h"
10a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com#include "src/wasm/encoder.h"
11d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.com
128a4c1030ff4b8336b5ac5b0712691e2f65383440egdanielnamespace v8 {
13170f90b4576f291879371ecd6ae4bc2b1d85c64aegdanielnamespace internal {
14170f90b4576f291879371ecd6ae4bc2b1d85c64aegdanielnamespace wasm {
152db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
16f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.comclass EncoderTest : public TestWithZone {
17a2f4b15d4e861b8b29e20ec37743fd3fd4b05b03jvanverth@google.com protected:
185c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  void AddLocal(WasmFunctionBuilder* f, LocalType type) {
195c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com    uint16_t index = f->AddLocal(type);
20a2f4b15d4e861b8b29e20ec37743fd3fd4b05b03jvanverth@google.com    const std::vector<uint8_t>& out_index = UnsignedLEB128From(index);
215c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com    std::vector<uint8_t> code;
227510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    code.push_back(kExprGetLocal);
23dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com    for (size_t i = 0; i < out_index.size(); i++) {
242db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com      code.push_back(out_index.at(i));
252db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
262db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    uint32_t local_indices[] = {1};
272db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    f->EmitCode(&code[0], static_cast<uint32_t>(code.size()), local_indices, 1);
282db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  }
292db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
302db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  void CheckReadValue(uint8_t* leb_value, uint32_t expected_result,
312db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com                      int expected_length,
322db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com                      ReadUnsignedLEB128ErrorCode expected_error_code) {
332db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    int length;
3449f085dddff10473b6ebf832a974288300224e60bsalomon    uint32_t result;
352db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    ReadUnsignedLEB128ErrorCode error_code =
362db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com        ReadUnsignedLEB128Operand(leb_value, leb_value + 5, &length, &result);
372db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    CHECK_EQ(error_code, expected_error_code);
382db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    if (error_code == 0) {
3949f085dddff10473b6ebf832a974288300224e60bsalomon      CHECK_EQ(result, expected_result);
402db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com      CHECK_EQ(length, expected_length);
412db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    }
422db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  }
43f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com
449188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org  void CheckWriteValue(uint32_t input, int length, uint8_t* vals) {
45c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com    const std::vector<uint8_t> result = UnsignedLEB128From(input);
46c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com    CHECK_EQ(result.size(), length);
479188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org    for (int i = 0; i < length; i++) {
48948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com      CHECK_EQ(result.at(i), vals[i]);
49948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com    }
50948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  }
512db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com};
52948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com
53948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com
542db3ded335fdb6697623bece61cabc307a414770bsalomon@google.comTEST_F(EncoderTest, Function_Builder_Variable_Indexing) {
552db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  Zone zone;
562db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
57948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  uint16_t f_index = builder->AddFunction();
58948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  WasmFunctionBuilder* function = builder->FunctionAt(f_index);
59948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  uint16_t local_f32 = function->AddLocal(kAstF32);
602db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  uint16_t param_float32 = function->AddParam(kAstF32);
612db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  uint16_t local_i32 = function->AddLocal(kAstI32);
622db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  uint16_t local_f64 = function->AddLocal(kAstF64);
63948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  uint16_t local_i64 = function->AddLocal(kAstI64);
64948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  uint16_t param_int32 = function->AddParam(kAstI32);
655c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  uint16_t local_i32_2 = function->AddLocal(kAstI32);
665c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com
675c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  byte code[] = {kExprGetLocal, static_cast<uint8_t>(param_float32)};
685c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  uint32_t local_indices[] = {1};
695c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  function->EmitCode(code, sizeof(code), local_indices, 1);
705c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  code[1] = static_cast<uint8_t>(param_int32);
715c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  function->EmitCode(code, sizeof(code), local_indices, 1);
725c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  code[1] = static_cast<uint8_t>(local_i32);
735c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  function->EmitCode(code, sizeof(code), local_indices, 1);
745c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  code[1] = static_cast<uint8_t>(local_i32_2);
755c9b6faefff735110a59932793e81cf5b9dec51djvanverth@google.com  function->EmitCode(code, sizeof(code), local_indices, 1);
76948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  code[1] = static_cast<uint8_t>(local_i64);
77c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  function->EmitCode(code, sizeof(code), local_indices, 1);
78f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com  code[1] = static_cast<uint8_t>(local_f32);
79ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com  function->EmitCode(code, sizeof(code), local_indices, 1);
80c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  code[1] = static_cast<uint8_t>(local_f64);
8149f085dddff10473b6ebf832a974288300224e60bsalomon  function->EmitCode(code, sizeof(code), local_indices, 1);
822db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
83944bcf0acb78f8f9da01e991f1307629959e338absalomon  WasmFunctionEncoder* f = function->Build(&zone, builder);
84f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com  ZoneVector<uint8_t> buffer_vector(f->HeaderSize() + f->BodySize(), &zone);
85c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  byte* buffer = &buffer_vector[0];
86c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  byte* header = buffer;
87f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com  byte* body = buffer + f->HeaderSize();
882db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  f->Serialize(buffer, &header, &body);
892db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  for (size_t i = 0; i < 7; i++) {
902db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    CHECK_EQ(i, static_cast<size_t>(*(buffer + 2 * i + f->HeaderSize() + 1)));
912db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  }
922db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com}
9331ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com
94bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt
952c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.comTEST_F(EncoderTest, Function_Builder_Indexing_Variable_Width) {
962c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com  Zone zone;
97948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
98948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  uint16_t f_index = builder->AddFunction();
99948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  WasmFunctionBuilder* function = builder->FunctionAt(f_index);
1009ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com  for (size_t i = 0; i < 128; i++) {
1012db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    AddLocal(function, kAstF32);
1022db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  }
1032db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  AddLocal(function, kAstI32);
1042db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1052db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  WasmFunctionEncoder* f = function->Build(&zone, builder);
1062db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  ZoneVector<uint8_t> buffer_vector(f->HeaderSize() + f->BodySize(), &zone);
1072db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  byte* buffer = &buffer_vector[0];
1082db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  byte* header = buffer;
1092db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  byte* body = buffer + f->HeaderSize();
11049f085dddff10473b6ebf832a974288300224e60bsalomon  f->Serialize(buffer, &header, &body);
11149f085dddff10473b6ebf832a974288300224e60bsalomon  body = buffer + f->HeaderSize();
1122db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  for (size_t i = 0; i < 127; i++) {
1132db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    CHECK_EQ(kExprGetLocal, static_cast<size_t>(*(body + 2 * i)));
1142db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com    CHECK_EQ(i + 1, static_cast<size_t>(*(body + 2 * i + 1)));
1152db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  }
1162db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CHECK_EQ(kExprGetLocal, static_cast<size_t>(*(body + 2 * 127)));
1172db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CHECK_EQ(0x80, static_cast<size_t>(*(body + 2 * 127 + 1)));
1182db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CHECK_EQ(0x01, static_cast<size_t>(*(body + 2 * 127 + 2)));
1192db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CHECK_EQ(kExprGetLocal, static_cast<size_t>(*(body + 2 * 127 + 3)));
1202db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CHECK_EQ(0x00, static_cast<size_t>(*(body + 2 * 127 + 4)));
1212db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com}
1222db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1232db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com
1242db3ded335fdb6697623bece61cabc307a414770bsalomon@google.comTEST_F(EncoderTest, LEB_Functions) {
1252db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  byte leb_value[5] = {0, 0, 0, 0, 0};
126c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  CheckReadValue(leb_value, 0, 1, kNoError);
1272db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CheckWriteValue(0, 1, leb_value);
128948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  leb_value[0] = 23;
129948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  CheckReadValue(leb_value, 23, 1, kNoError);
130948787737b77555318fa2433e7ff941516fe950ejvanverth@google.com  CheckWriteValue(23, 1, leb_value);
131bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt  leb_value[0] = 0x80;
132bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt  leb_value[1] = 0x01;
1332db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CheckReadValue(leb_value, 128, 2, kNoError);
134c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  CheckWriteValue(128, 2, leb_value);
135c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  leb_value[0] = 0x80;
1362db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  leb_value[1] = 0x80;
137c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  leb_value[2] = 0x80;
1382db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  leb_value[3] = 0x80;
1392db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  leb_value[4] = 0x01;
1402db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  CheckReadValue(leb_value, 0x10000000, 5, kNoError);
141c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  CheckWriteValue(0x10000000, 5, leb_value);
142f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org  leb_value[0] = 0x80;
1432db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  leb_value[1] = 0x80;
144c1d2a58ec8510b226e080f5415a05723a686aab3bsalomon@google.com  leb_value[2] = 0x80;
1452db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  leb_value[3] = 0x80;
1462db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com  leb_value[4] = 0x80;
147f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com  CheckReadValue(leb_value, -1, -1, kInvalidLEB128);
148f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com}
1492db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com}  // namespace wasm
1502db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com}  // namespace internal
1512db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com}  // namespace v8
1522db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com