| 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 |