| Index: src/wasm/ast-decoder.cc
|
| diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc
|
| index 2943e3914ba050e8d5b7beb63a9e7dddc91fb590..cfee4f3cf14171df7815cc7a9465bf66c8d53a25 100644
|
| --- a/src/wasm/ast-decoder.cc
|
| +++ b/src/wasm/ast-decoder.cc
|
| @@ -112,28 +112,28 @@ class WasmDecoder : public Decoder {
|
| function_env_ = function_env;
|
| }
|
|
|
| - // Load an operand at [pc + 1].
|
| - template <typename V>
|
| - V Operand(const byte* pc) {
|
| - if ((limit_ - pc) < static_cast<int>(1 + sizeof(V))) {
|
| - const char* msg = "Expected operand following opcode";
|
| - switch (sizeof(V)) {
|
| - case 1:
|
| - msg = "Expected 1-byte operand following opcode";
|
| - break;
|
| - case 2:
|
| - msg = "Expected 2-byte operand following opcode";
|
| - break;
|
| - case 4:
|
| - msg = "Expected 4-byte operand following opcode";
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| + byte ByteOperand(const byte* pc, const char* msg = "missing 1-byte operand") {
|
| + if ((pc + sizeof(byte)) >= limit_) {
|
| error(pc, msg);
|
| - return -1;
|
| + return 0;
|
| + }
|
| + return pc[1];
|
| + }
|
| +
|
| + uint32_t Uint32Operand(const byte* pc) {
|
| + if ((pc + sizeof(uint32_t)) >= limit_) {
|
| + error(pc, "missing 4-byte operand");
|
| + return 0;
|
| + }
|
| + return read_u32(pc + 1);
|
| + }
|
| +
|
| + uint64_t Uint64Operand(const byte* pc) {
|
| + if ((pc + sizeof(uint64_t)) >= limit_) {
|
| + error(pc, "missing 8-byte operand");
|
| + return 0;
|
| }
|
| - return *reinterpret_cast<const V*>(pc + 1);
|
| + return read_u64(pc + 1);
|
| }
|
|
|
| LocalType LocalOperand(const byte* pc, uint32_t* index, int* length) {
|
| @@ -185,7 +185,7 @@ class WasmDecoder : public Decoder {
|
| }
|
|
|
| void MemoryAccessOperand(const byte* pc, int* length, uint32_t* offset) {
|
| - byte bitfield = Operand<uint8_t>(pc);
|
| + byte bitfield = ByteOperand(pc, "missing memory access operand");
|
| if (MemoryAccess::OffsetField::decode(bitfield)) {
|
| *offset = UnsignedLEB128Operand(pc + 1, length);
|
| (*length)++; // to account for the memory access byte
|
| @@ -431,7 +431,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| Leaf(kAstStmt);
|
| break;
|
| case kExprBlock: {
|
| - int length = Operand<uint8_t>(pc_);
|
| + int length = ByteOperand(pc_);
|
| if (length < 1) {
|
| Leaf(kAstStmt);
|
| } else {
|
| @@ -445,7 +445,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| break;
|
| }
|
| case kExprLoop: {
|
| - int length = Operand<uint8_t>(pc_);
|
| + int length = ByteOperand(pc_);
|
| if (length < 1) {
|
| Leaf(kAstStmt);
|
| } else {
|
| @@ -474,7 +474,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| Shift(kAstStmt, 3); // Result type is typeof(x) in {c ? x : y}.
|
| break;
|
| case kExprBr: {
|
| - uint32_t depth = Operand<uint8_t>(pc_);
|
| + uint32_t depth = ByteOperand(pc_);
|
| Shift(kAstEnd, 1);
|
| if (depth >= blocks_.size()) {
|
| error("improperly nested branch");
|
| @@ -483,7 +483,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| break;
|
| }
|
| case kExprBrIf: {
|
| - uint32_t depth = Operand<uint8_t>(pc_);
|
| + uint32_t depth = ByteOperand(pc_);
|
| Shift(kAstStmt, 2);
|
| if (depth >= blocks_.size()) {
|
| error("improperly nested conditional branch");
|
| @@ -496,8 +496,8 @@ class LR_WasmDecoder : public WasmDecoder {
|
| error("expected #tableswitch <cases> <table>, fell off end");
|
| break;
|
| }
|
| - uint16_t case_count = *reinterpret_cast<const uint16_t*>(pc_ + 1);
|
| - uint16_t table_count = *reinterpret_cast<const uint16_t*>(pc_ + 3);
|
| + uint16_t case_count = read_u16(pc_ + 1);
|
| + uint16_t table_count = read_u16(pc_ + 3);
|
| len = 5 + table_count * 2;
|
|
|
| if (table_count == 0) {
|
| @@ -514,8 +514,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
|
|
| // Verify table.
|
| for (int i = 0; i < table_count; i++) {
|
| - uint16_t target =
|
| - *reinterpret_cast<const uint16_t*>(pc_ + 5 + i * 2);
|
| + uint16_t target = read_u16(pc_ + 5 + i * 2);
|
| if (target >= 0x8000) {
|
| size_t depth = target - 0x8000;
|
| if (depth > blocks_.size()) {
|
| @@ -547,31 +546,31 @@ class LR_WasmDecoder : public WasmDecoder {
|
| break;
|
| }
|
| case kExprI8Const: {
|
| - int32_t value = Operand<int8_t>(pc_);
|
| + int32_t value = bit_cast<int8_t>(ByteOperand(pc_));
|
| Leaf(kAstI32, BUILD(Int32Constant, value));
|
| len = 2;
|
| break;
|
| }
|
| case kExprI32Const: {
|
| - int32_t value = Operand<int32_t>(pc_);
|
| + uint32_t value = Uint32Operand(pc_);
|
| Leaf(kAstI32, BUILD(Int32Constant, value));
|
| len = 5;
|
| break;
|
| }
|
| case kExprI64Const: {
|
| - int64_t value = Operand<int64_t>(pc_);
|
| + uint64_t value = Uint64Operand(pc_);
|
| Leaf(kAstI64, BUILD(Int64Constant, value));
|
| len = 9;
|
| break;
|
| }
|
| case kExprF32Const: {
|
| - float value = Operand<float>(pc_);
|
| + float value = bit_cast<float>(Uint32Operand(pc_));
|
| Leaf(kAstF32, BUILD(Float32Constant, value));
|
| len = 5;
|
| break;
|
| }
|
| case kExprF64Const: {
|
| - double value = Operand<double>(pc_);
|
| + double value = bit_cast<double>(Uint64Operand(pc_));
|
| Leaf(kAstF64, BUILD(Float64Constant, value));
|
| len = 9;
|
| break;
|
| @@ -877,7 +876,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| break;
|
| }
|
| case kExprBr: {
|
| - uint32_t depth = Operand<uint8_t>(p->pc());
|
| + uint32_t depth = ByteOperand(p->pc());
|
| if (depth >= blocks_.size()) {
|
| error("improperly nested branch");
|
| break;
|
| @@ -890,7 +889,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| if (p->index == 1) {
|
| TypeCheckLast(p, kAstI32);
|
| } else if (p->done()) {
|
| - uint32_t depth = Operand<uint8_t>(p->pc());
|
| + uint32_t depth = ByteOperand(p->pc());
|
| if (depth >= blocks_.size()) {
|
| error("improperly nested branch");
|
| break;
|
| @@ -911,8 +910,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| // Switch key finished.
|
| TypeCheckLast(p, kAstI32);
|
|
|
| - uint16_t table_count =
|
| - *reinterpret_cast<const uint16_t*>(p->pc() + 3);
|
| + uint16_t table_count = read_u16(p->pc() + 3);
|
|
|
| // Build the switch only if it has more than just a default target.
|
| bool build_switch = table_count > 1;
|
| @@ -920,7 +918,7 @@ class LR_WasmDecoder : public WasmDecoder {
|
| if (build_switch) sw = BUILD(Switch, table_count, p->last()->node);
|
|
|
| // Allocate environments for each case.
|
| - uint16_t case_count = *reinterpret_cast<const uint16_t*>(p->pc() + 1);
|
| + uint16_t case_count = read_u16(p->pc() + 1);
|
| SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(case_count);
|
| for (int i = 0; i < case_count; i++) case_envs[i] = UnreachableEnv();
|
|
|
| @@ -931,10 +929,8 @@ class LR_WasmDecoder : public WasmDecoder {
|
| ssa_env_ = copy;
|
|
|
| // Build the environments for each case based on the table.
|
| - const uint16_t* table =
|
| - reinterpret_cast<const uint16_t*>(p->pc() + 5);
|
| for (int i = 0; i < table_count; i++) {
|
| - uint16_t target = table[i];
|
| + uint16_t target = read_u16(p->pc() + 5 + i * 2);
|
| SsaEnv* env = copy;
|
| if (build_switch) {
|
| env = Split(env);
|
|
|