OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/signature.h" | 5 #include "src/signature.h" |
6 | 6 |
7 #include "src/bit-vector.h" | 7 #include "src/bit-vector.h" |
8 #include "src/flags.h" | 8 #include "src/flags.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/zone-containers.h" | 10 #include "src/zone-containers.h" |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 while (true) { // decoding loop. | 714 while (true) { // decoding loop. |
715 unsigned len = 1; | 715 unsigned len = 1; |
716 WasmOpcode opcode = static_cast<WasmOpcode>(*pc_); | 716 WasmOpcode opcode = static_cast<WasmOpcode>(*pc_); |
717 if (!WasmOpcodes::IsPrefixOpcode(opcode)) { | 717 if (!WasmOpcodes::IsPrefixOpcode(opcode)) { |
718 TRACE(" @%-8d #%02x:%-20s|", startrel(pc_), opcode, | 718 TRACE(" @%-8d #%02x:%-20s|", startrel(pc_), opcode, |
719 WasmOpcodes::ShortOpcodeName(opcode)); | 719 WasmOpcodes::ShortOpcodeName(opcode)); |
720 } | 720 } |
721 | 721 |
722 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 722 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
723 if (sig) { | 723 if (sig) { |
724 // Fast case of a simple operator. | 724 BuildSimpleOperator(opcode, sig); |
725 TFNode* node; | |
726 switch (sig->parameter_count()) { | |
727 case 1: { | |
728 Value val = Pop(0, sig->GetParam(0)); | |
729 node = BUILD(Unop, opcode, val.node, position()); | |
730 break; | |
731 } | |
732 case 2: { | |
733 Value rval = Pop(1, sig->GetParam(1)); | |
734 Value lval = Pop(0, sig->GetParam(0)); | |
735 node = BUILD(Binop, opcode, lval.node, rval.node, position()); | |
736 break; | |
737 } | |
738 default: | |
739 UNREACHABLE(); | |
740 node = nullptr; | |
741 break; | |
742 } | |
743 Push(GetReturnType(sig), node); | |
744 } else { | 725 } else { |
745 // Complex bytecode. | 726 // Complex bytecode. |
746 switch (opcode) { | 727 switch (opcode) { |
747 case kExprNop: | 728 case kExprNop: |
748 Push(kAstStmt, nullptr); | 729 Push(kAstStmt, nullptr); |
749 break; | 730 break; |
750 case kExprBlock: { | 731 case kExprBlock: { |
751 // The break environment is the outer environment. | 732 // The break environment is the outer environment. |
752 SsaEnv* break_env = ssa_env_; | 733 SsaEnv* break_env = ssa_env_; |
753 PushBlock(break_env); | 734 PushBlock(break_env); |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 break; | 1210 break; |
1230 case kExprI64StoreMem: | 1211 case kExprI64StoreMem: |
1231 len = DecodeStoreMem(kAstI64, MachineType::Int64()); | 1212 len = DecodeStoreMem(kAstI64, MachineType::Int64()); |
1232 break; | 1213 break; |
1233 case kExprF32StoreMem: | 1214 case kExprF32StoreMem: |
1234 len = DecodeStoreMem(kAstF32, MachineType::Float32()); | 1215 len = DecodeStoreMem(kAstF32, MachineType::Float32()); |
1235 break; | 1216 break; |
1236 case kExprF64StoreMem: | 1217 case kExprF64StoreMem: |
1237 len = DecodeStoreMem(kAstF64, MachineType::Float64()); | 1218 len = DecodeStoreMem(kAstF64, MachineType::Float64()); |
1238 break; | 1219 break; |
1239 | 1220 case kExprGrowMemory: |
| 1221 if (module_->origin != kAsmJsOrigin) { |
| 1222 Value val = Pop(0, kAstI32); |
| 1223 Push(kAstI32, BUILD(GrowMemory, val.node)); |
| 1224 } else { |
| 1225 error("grow_memory is not supported for asmjs modules"); |
| 1226 } |
| 1227 break; |
1240 case kExprMemorySize: | 1228 case kExprMemorySize: |
1241 Push(kAstI32, BUILD(MemSize, 0)); | 1229 Push(kAstI32, BUILD(MemSize, 0)); |
1242 break; | 1230 break; |
1243 case kExprCallFunction: { | 1231 case kExprCallFunction: { |
1244 CallFunctionOperand operand(this, pc_); | 1232 CallFunctionOperand operand(this, pc_); |
1245 if (Validate(pc_, operand)) { | 1233 if (Validate(pc_, operand)) { |
1246 TFNode** buffer = PopArgs(operand.sig); | 1234 TFNode** buffer = PopArgs(operand.sig); |
1247 TFNode* call = | 1235 TFNode* call = |
1248 BUILD(CallDirect, operand.index, buffer, position()); | 1236 BUILD(CallDirect, operand.index, buffer, position()); |
1249 Push(GetReturnType(operand.sig), call); | 1237 Push(GetReturnType(operand.sig), call); |
(...skipping 29 matching lines...) Expand all Loading... |
1279 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); | 1267 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); |
1280 len++; | 1268 len++; |
1281 byte simd_index = *(pc_ + 1); | 1269 byte simd_index = *(pc_ + 1); |
1282 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); | 1270 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); |
1283 TRACE(" @%-4d #%02x #%02x:%-20s|", startrel(pc_), kSimdPrefix, | 1271 TRACE(" @%-4d #%02x #%02x:%-20s|", startrel(pc_), kSimdPrefix, |
1284 simd_index, WasmOpcodes::ShortOpcodeName(opcode)); | 1272 simd_index, WasmOpcodes::ShortOpcodeName(opcode)); |
1285 len += DecodeSimdOpcode(opcode); | 1273 len += DecodeSimdOpcode(opcode); |
1286 break; | 1274 break; |
1287 } | 1275 } |
1288 default: | 1276 default: |
1289 error("Invalid opcode"); | 1277 // Deal with special asmjs opcodes. |
1290 return; | 1278 if (module_->origin == kAsmJsOrigin) { |
| 1279 sig = WasmOpcodes::AsmjsSignature(opcode); |
| 1280 if (sig) { |
| 1281 BuildSimpleOperator(opcode, sig); |
| 1282 } |
| 1283 } else { |
| 1284 error("Invalid opcode"); |
| 1285 return; |
| 1286 } |
1291 } | 1287 } |
1292 } // end complex bytecode | 1288 } // end complex bytecode |
1293 | 1289 |
1294 #if DEBUG | 1290 #if DEBUG |
1295 if (FLAG_trace_wasm_decoder) { | 1291 if (FLAG_trace_wasm_decoder) { |
1296 for (size_t i = 0; i < stack_.size(); ++i) { | 1292 for (size_t i = 0; i < stack_.size(); ++i) { |
1297 Value& val = stack_[i]; | 1293 Value& val = stack_[i]; |
1298 WasmOpcode opcode = static_cast<WasmOpcode>(*val.pc); | 1294 WasmOpcode opcode = static_cast<WasmOpcode>(*val.pc); |
1299 if (WasmOpcodes::IsPrefixOpcode(opcode)) { | 1295 if (WasmOpcodes::IsPrefixOpcode(opcode)) { |
1300 opcode = static_cast<WasmOpcode>(opcode << 8 | *(val.pc + 1)); | 1296 opcode = static_cast<WasmOpcode>(opcode << 8 | *(val.pc + 1)); |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 pc += length; | 1903 pc += length; |
1908 } | 1904 } |
1909 return ok() ? assigned : nullptr; | 1905 return ok() ? assigned : nullptr; |
1910 } | 1906 } |
1911 | 1907 |
1912 inline wasm::WasmCodePosition position() { | 1908 inline wasm::WasmCodePosition position() { |
1913 int offset = static_cast<int>(pc_ - start_); | 1909 int offset = static_cast<int>(pc_ - start_); |
1914 DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen | 1910 DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen |
1915 return offset; | 1911 return offset; |
1916 } | 1912 } |
| 1913 |
| 1914 inline void BuildSimpleOperator(WasmOpcode opcode, FunctionSig* sig) { |
| 1915 TFNode* node; |
| 1916 switch (sig->parameter_count()) { |
| 1917 case 1: { |
| 1918 Value val = Pop(0, sig->GetParam(0)); |
| 1919 node = BUILD(Unop, opcode, val.node, position()); |
| 1920 break; |
| 1921 } |
| 1922 case 2: { |
| 1923 Value rval = Pop(1, sig->GetParam(1)); |
| 1924 Value lval = Pop(0, sig->GetParam(0)); |
| 1925 node = BUILD(Binop, opcode, lval.node, rval.node, position()); |
| 1926 break; |
| 1927 } |
| 1928 default: |
| 1929 UNREACHABLE(); |
| 1930 node = nullptr; |
| 1931 break; |
| 1932 } |
| 1933 Push(GetReturnType(sig), node); |
| 1934 } |
1917 }; | 1935 }; |
1918 | 1936 |
1919 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, | 1937 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, |
1920 const byte* end) { | 1938 const byte* end) { |
1921 base::AccountingAllocator allocator; | 1939 base::AccountingAllocator allocator; |
1922 Zone tmp(&allocator); | 1940 Zone tmp(&allocator); |
1923 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1941 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1924 WasmFullDecoder decoder(&tmp, nullptr, body); | 1942 WasmFullDecoder decoder(&tmp, nullptr, body); |
1925 return decoder.DecodeLocalDecls(decls); | 1943 return decoder.DecodeLocalDecls(decls); |
1926 } | 1944 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2102 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2120 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
2103 const byte* start, const byte* end) { | 2121 const byte* start, const byte* end) { |
2104 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 2122 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
2105 WasmFullDecoder decoder(zone, nullptr, body); | 2123 WasmFullDecoder decoder(zone, nullptr, body); |
2106 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 2124 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
2107 } | 2125 } |
2108 | 2126 |
2109 } // namespace wasm | 2127 } // namespace wasm |
2110 } // namespace internal | 2128 } // namespace internal |
2111 } // namespace v8 | 2129 } // namespace v8 |
OLD | NEW |