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 |