| 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 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 #if DEBUG | 25 #if DEBUG |
| 26 #define TRACE(...) \ | 26 #define TRACE(...) \ |
| 27 do { \ | 27 do { \ |
| 28 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ | 28 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ |
| 29 } while (false) | 29 } while (false) |
| 30 #else | 30 #else |
| 31 #define TRACE(...) | 31 #define TRACE(...) |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 #define CHECK_PROTOTYPE_OPCODE(flag) \ |
| 35 if (!FLAG_##flag) { \ |
| 36 error("Invalid opcode (enable with --" #flag ")"); \ |
| 37 break; \ |
| 38 } |
| 39 |
| 34 // An SsaEnv environment carries the current local variable renaming | 40 // An SsaEnv environment carries the current local variable renaming |
| 35 // as well as the current effect and control dependency in the TF graph. | 41 // as well as the current effect and control dependency in the TF graph. |
| 36 // It maintains a control state that tracks whether the environment | 42 // It maintains a control state that tracks whether the environment |
| 37 // is reachable, has reached a control end, or has been merged. | 43 // is reachable, has reached a control end, or has been merged. |
| 38 struct SsaEnv { | 44 struct SsaEnv { |
| 39 enum State { kControlEnd, kUnreachable, kReached, kMerged }; | 45 enum State { kControlEnd, kUnreachable, kReached, kMerged }; |
| 40 | 46 |
| 41 State state; | 47 State state; |
| 42 TFNode* control; | 48 TFNode* control; |
| 43 TFNode* effect; | 49 TFNode* effect; |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 Push(kAstStmt, nullptr); | 670 Push(kAstStmt, nullptr); |
| 665 break; | 671 break; |
| 666 case kExprBlock: { | 672 case kExprBlock: { |
| 667 // The break environment is the outer environment. | 673 // The break environment is the outer environment. |
| 668 SsaEnv* break_env = ssa_env_; | 674 SsaEnv* break_env = ssa_env_; |
| 669 PushBlock(break_env); | 675 PushBlock(break_env); |
| 670 SetEnv("block:start", Steal(break_env)); | 676 SetEnv("block:start", Steal(break_env)); |
| 671 break; | 677 break; |
| 672 } | 678 } |
| 673 case kExprThrow: { | 679 case kExprThrow: { |
| 674 if (!FLAG_wasm_eh_prototype) { | 680 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 675 error("Invalid opcode"); | 681 Pop(0, kAstI32); |
| 676 return; | |
| 677 } | |
| 678 | |
| 679 // TODO(jpp): validate the poped value. | |
| 680 Pop(); | |
| 681 | 682 |
| 682 // TODO(jpp): start exception propagation. | 683 // TODO(jpp): start exception propagation. |
| 683 break; | 684 break; |
| 684 } | 685 } |
| 685 case kExprTryCatch: { | 686 case kExprTryCatch: { |
| 686 if (!FLAG_wasm_eh_prototype) { | 687 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 687 error("Invalid opcode"); | |
| 688 return; | |
| 689 } | |
| 690 | |
| 691 SsaEnv* outer_env = ssa_env_; | 688 SsaEnv* outer_env = ssa_env_; |
| 692 SsaEnv* try_env = Steal(outer_env); | 689 SsaEnv* try_env = Steal(outer_env); |
| 693 SsaEnv* catch_env = Split(try_env); | 690 SsaEnv* catch_env = Split(try_env); |
| 694 PushTry(outer_env, catch_env, nullptr); | 691 PushTry(outer_env, catch_env, nullptr); |
| 695 SetEnv("try_catch:start", try_env); | 692 SetEnv("try_catch:start", try_env); |
| 696 break; | 693 break; |
| 697 } | 694 } |
| 698 case kExprTryCatchFinally: { | 695 case kExprTryCatchFinally: { |
| 699 if (!FLAG_wasm_eh_prototype) { | 696 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 700 error("Invalid opcode"); | |
| 701 return; | |
| 702 } | |
| 703 | |
| 704 SsaEnv* outer_env = ssa_env_; | 697 SsaEnv* outer_env = ssa_env_; |
| 705 SsaEnv* try_env = Steal(outer_env); | 698 SsaEnv* try_env = Steal(outer_env); |
| 706 SsaEnv* catch_env = Split(try_env); | 699 SsaEnv* catch_env = Split(try_env); |
| 707 SsaEnv* finally_env = Split(try_env); | 700 SsaEnv* finally_env = Split(try_env); |
| 708 PushTry(finally_env, catch_env, outer_env); | 701 PushTry(finally_env, catch_env, outer_env); |
| 709 SetEnv("try_catch_finally:start", try_env); | 702 SetEnv("try_catch_finally:start", try_env); |
| 710 break; | 703 break; |
| 711 } | 704 } |
| 712 case kExprTryFinally: { | 705 case kExprTryFinally: { |
| 713 if (!FLAG_wasm_eh_prototype) { | 706 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 714 error("Invalid opcode"); | |
| 715 return; | |
| 716 } | |
| 717 | |
| 718 SsaEnv* outer_env = ssa_env_; | 707 SsaEnv* outer_env = ssa_env_; |
| 719 SsaEnv* try_env = Steal(outer_env); | 708 SsaEnv* try_env = Steal(outer_env); |
| 720 SsaEnv* finally_env = Split(outer_env); | 709 SsaEnv* finally_env = Split(outer_env); |
| 721 PushTry(finally_env, nullptr, outer_env); | 710 PushTry(finally_env, nullptr, outer_env); |
| 722 SetEnv("try_finally:start", try_env); | 711 SetEnv("try_finally:start", try_env); |
| 723 break; | 712 break; |
| 724 } | 713 } |
| 725 case kExprCatch: { | 714 case kExprCatch: { |
| 726 if (!FLAG_wasm_eh_prototype) { | 715 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 727 error("Invalid opcode"); | |
| 728 return; | |
| 729 } | |
| 730 | |
| 731 LocalIndexOperand operand(this, pc_); | 716 LocalIndexOperand operand(this, pc_); |
| 732 len = 1 + operand.length; | 717 len = 1 + operand.length; |
| 733 | 718 |
| 734 if (control_.empty()) { | 719 if (control_.empty()) { |
| 735 error(pc_, "catch does not match a any try"); | 720 error(pc_, "catch does not match a any try"); |
| 736 break; | 721 break; |
| 737 } | 722 } |
| 738 | 723 |
| 739 Control* c = &control_.back(); | 724 Control* c = &control_.back(); |
| 740 if (!c->has_catch()) { | 725 if (!c->has_catch()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 759 if (ssa_env_->locals) { | 744 if (ssa_env_->locals) { |
| 760 ssa_env_->locals[operand.index] = nullptr; | 745 ssa_env_->locals[operand.index] = nullptr; |
| 761 } | 746 } |
| 762 } | 747 } |
| 763 | 748 |
| 764 PopUpTo(c->stack_depth); | 749 PopUpTo(c->stack_depth); |
| 765 | 750 |
| 766 break; | 751 break; |
| 767 } | 752 } |
| 768 case kExprFinally: { | 753 case kExprFinally: { |
| 769 if (!FLAG_wasm_eh_prototype) { | 754 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 770 error("Invalid opcode"); | |
| 771 return; | |
| 772 } | |
| 773 | |
| 774 if (control_.empty()) { | 755 if (control_.empty()) { |
| 775 error(pc_, "finally does not match a any try"); | 756 error(pc_, "finally does not match a any try"); |
| 776 break; | 757 break; |
| 777 } | 758 } |
| 778 | 759 |
| 779 Control* c = &control_.back(); | 760 Control* c = &control_.back(); |
| 780 if (c->has_catch() && c->catch_env != nullptr) { | 761 if (c->has_catch() && c->catch_env != nullptr) { |
| 781 error(pc_, "missing catch for try with catch and finally"); | 762 error(pc_, "missing catch for try with catch and finally"); |
| 782 break; | 763 break; |
| 783 } | 764 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 if (c->false_env != nullptr) { | 859 if (c->false_env != nullptr) { |
| 879 // End the true branch of a one-armed if. | 860 // End the true branch of a one-armed if. |
| 880 Goto(c->false_env, c->end_env); | 861 Goto(c->false_env, c->end_env); |
| 881 val = {val.pc, nullptr, kAstStmt}; | 862 val = {val.pc, nullptr, kAstStmt}; |
| 882 name = "if:merge"; | 863 name = "if:merge"; |
| 883 } else { | 864 } else { |
| 884 // End the false branch of a two-armed if. | 865 // End the false branch of a two-armed if. |
| 885 name = "if_else:merge"; | 866 name = "if_else:merge"; |
| 886 } | 867 } |
| 887 } else if (c->is_try()) { | 868 } else if (c->is_try()) { |
| 888 DCHECK(FLAG_wasm_eh_prototype); | |
| 889 | |
| 890 name = "try:end"; | 869 name = "try:end"; |
| 891 | 870 |
| 892 // try blocks do not yield a value. | 871 // try blocks do not yield a value. |
| 893 val = {val.pc, nullptr, kAstStmt}; | 872 val = {val.pc, nullptr, kAstStmt}; |
| 894 | 873 |
| 895 // validate that catch/finally were seen. | 874 // validate that catch/finally were seen. |
| 896 if (c->catch_env != nullptr) { | 875 if (c->catch_env != nullptr) { |
| 897 error(pc_, "missing catch in try with catch"); | 876 error(pc_, "missing catch in try with catch"); |
| 898 break; | 877 break; |
| 899 } | 878 } |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 if (Validate(pc_, operand)) { | 1173 if (Validate(pc_, operand)) { |
| 1195 TFNode** buffer = PopArgs(operand.sig); | 1174 TFNode** buffer = PopArgs(operand.sig); |
| 1196 TFNode* call = | 1175 TFNode* call = |
| 1197 BUILD(CallImport, operand.index, buffer, position()); | 1176 BUILD(CallImport, operand.index, buffer, position()); |
| 1198 Push(GetReturnType(operand.sig), call); | 1177 Push(GetReturnType(operand.sig), call); |
| 1199 } | 1178 } |
| 1200 len = 1 + operand.length; | 1179 len = 1 + operand.length; |
| 1201 break; | 1180 break; |
| 1202 } | 1181 } |
| 1203 case kSimdPrefix: { | 1182 case kSimdPrefix: { |
| 1204 if (!FLAG_wasm_simd_prototype) { | 1183 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); |
| 1205 error("Invalid opcode"); | |
| 1206 return; | |
| 1207 } | |
| 1208 len++; | 1184 len++; |
| 1209 byte simd_index = *(pc_ + 1); | 1185 byte simd_index = *(pc_ + 1); |
| 1210 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); | 1186 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); |
| 1211 DecodeSimdOpcode(opcode); | 1187 DecodeSimdOpcode(opcode); |
| 1212 break; | 1188 break; |
| 1213 } | 1189 } |
| 1214 default: | 1190 default: |
| 1215 error("Invalid opcode"); | 1191 error("Invalid opcode"); |
| 1216 return; | 1192 return; |
| 1217 } | 1193 } |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1849 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
| 1874 const byte* start, const byte* end) { | 1850 const byte* start, const byte* end) { |
| 1875 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1851 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
| 1876 WasmFullDecoder decoder(zone, nullptr, body); | 1852 WasmFullDecoder decoder(zone, nullptr, body); |
| 1877 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 1853 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
| 1878 } | 1854 } |
| 1879 | 1855 |
| 1880 } // namespace wasm | 1856 } // namespace wasm |
| 1881 } // namespace internal | 1857 } // namespace internal |
| 1882 } // namespace v8 | 1858 } // namespace v8 |
| OLD | NEW |