Index: src/wasm/ast-decoder.cc |
diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc |
index 798f9d393a5bf10dba8e1c5b5ebb944e1d0f171e..9d01e665708a6e3618d0261ca04c9fc867cb0011 100644 |
--- a/src/wasm/ast-decoder.cc |
+++ b/src/wasm/ast-decoder.cc |
@@ -386,8 +386,12 @@ class WasmDecoder : public Decoder { |
FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE) |
FOREACH_SIMPLE_MEM_OPCODE(DECLARE_OPCODE_CASE) |
FOREACH_ASMJS_COMPAT_OPCODE(DECLARE_OPCODE_CASE) |
- FOREACH_SIMD_OPCODE(DECLARE_OPCODE_CASE) |
+ FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
#undef DECLARE_OPCODE_CASE |
+#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
+ FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
+#undef DECLARE_OPCODE_CASE |
+ return 1; |
default: |
UNREACHABLE(); |
return 0; |
@@ -456,7 +460,10 @@ class WasmDecoder : public Decoder { |
ReturnArityOperand operand(this, pc); |
return 1 + operand.length; |
} |
- |
+#define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
+ FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE) { return 2; } |
+ FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) { return 3; } |
+#undef DECLARE_OPCODE_CASE |
default: |
return 1; |
} |
@@ -1271,7 +1278,7 @@ class WasmFullDecoder : public WasmDecoder { |
len++; |
byte simd_index = *(pc_ + 1); |
opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); |
- DecodeSimdOpcode(opcode); |
+ len += DecodeSimdOpcode(opcode); |
break; |
} |
default: |
@@ -1396,15 +1403,35 @@ class WasmFullDecoder : public WasmDecoder { |
return 1 + operand.length; |
} |
- void DecodeSimdOpcode(WasmOpcode opcode) { |
- FunctionSig* sig = WasmOpcodes::Signature(opcode); |
- compiler::NodeVector inputs(sig->parameter_count(), zone_); |
- for (size_t i = sig->parameter_count(); i > 0; i--) { |
- Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); |
- inputs[i - 1] = val.node; |
+ unsigned DecodeSimdOpcode(WasmOpcode opcode) { |
+ unsigned len = 0; |
+ switch (opcode) { |
+ case kExprI32x4ExtractLane: { |
+ uint8_t lane = this->checked_read_u8(pc_, 2, "lane number"); |
+ if (lane >= 0 && lane <= 3) { |
+ error(pc_, pc_ + 2, "invalid extract lane value "); |
+ } |
+ TFNode* input = Pop(0, LocalType::kSimd128).node; |
+ TFNode* node = BUILD(SimdExtractLane, opcode, lane, input); |
+ Push(LocalType::kWord32, node); |
+ len++; |
+ break; |
+ } |
+ default: { |
+ FunctionSig* sig = WasmOpcodes::Signature(opcode); |
+ if (sig == nullptr) { |
+ error(pc_, pc_, "invalid simd opcode"); |
titzer
2016/09/05 12:49:50
You'll have to break here, or you'll crash on the
aseemgarg
2016/09/06 02:49:15
Done.
|
+ } |
+ compiler::NodeVector inputs(sig->parameter_count(), zone_); |
+ for (size_t i = sig->parameter_count(); i > 0; i--) { |
+ Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); |
+ inputs[i - 1] = val.node; |
+ } |
+ TFNode* node = BUILD(SimdOp, opcode, inputs); |
+ Push(GetReturnType(sig), node); |
+ } |
} |
- TFNode* node = BUILD(SimdOp, opcode, inputs); |
- Push(GetReturnType(sig), node); |
+ return len; |
} |
void DispatchToTargets(Control* next_block, const Value& val) { |