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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include <stack> | 7 #include <stack> |
8 | 8 |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 | 917 |
918 void BytecodeGenerator::VisitProperty(Property* expr) { | 918 void BytecodeGenerator::VisitProperty(Property* expr) { |
919 TemporaryRegisterScope temporary_register_scope(builder()); | 919 TemporaryRegisterScope temporary_register_scope(builder()); |
920 Register obj = temporary_register_scope.NewRegister(); | 920 Register obj = temporary_register_scope.NewRegister(); |
921 Visit(expr->obj()); | 921 Visit(expr->obj()); |
922 builder()->StoreAccumulatorInRegister(obj); | 922 builder()->StoreAccumulatorInRegister(obj); |
923 VisitPropertyLoad(obj, expr); | 923 VisitPropertyLoad(obj, expr); |
924 } | 924 } |
925 | 925 |
926 | 926 |
| 927 Register BytecodeGenerator::VisitArguments( |
| 928 ZoneList<Expression*>* args, TemporaryRegisterScope* register_scope) { |
| 929 // Visit arguments and place in a contiguous block of temporary registers. |
| 930 // Return the first temporary register corresponding to the first argument. |
| 931 DCHECK_GT(args->length(), 0); |
| 932 Register first_arg = register_scope->NewRegister(); |
| 933 Visit(args->at(0)); |
| 934 builder()->StoreAccumulatorInRegister(first_arg); |
| 935 for (int i = 1; i < static_cast<int>(args->length()); i++) { |
| 936 Register ith_arg = register_scope->NewRegister(); |
| 937 Visit(args->at(i)); |
| 938 builder()->StoreAccumulatorInRegister(ith_arg); |
| 939 DCHECK(ith_arg.index() - i == first_arg.index()); |
| 940 } |
| 941 |
| 942 return first_arg; |
| 943 } |
| 944 |
| 945 |
927 void BytecodeGenerator::VisitCall(Call* expr) { | 946 void BytecodeGenerator::VisitCall(Call* expr) { |
928 Expression* callee_expr = expr->expression(); | 947 Expression* callee_expr = expr->expression(); |
929 Call::CallType call_type = expr->GetCallType(isolate()); | 948 Call::CallType call_type = expr->GetCallType(isolate()); |
930 | 949 |
931 // Prepare the callee and the receiver to the function call. This depends on | 950 // Prepare the callee and the receiver to the function call. This depends on |
932 // the semantics of the underlying call type. | 951 // the semantics of the underlying call type. |
933 TemporaryRegisterScope temporary_register_scope(builder()); | 952 TemporaryRegisterScope temporary_register_scope(builder()); |
934 Register callee = temporary_register_scope.NewRegister(); | 953 Register callee = temporary_register_scope.NewRegister(); |
935 Register receiver = temporary_register_scope.NewRegister(); | 954 Register receiver = temporary_register_scope.NewRegister(); |
936 | 955 |
(...skipping 27 matching lines...) Expand all Loading... |
964 } | 983 } |
965 case Call::LOOKUP_SLOT_CALL: | 984 case Call::LOOKUP_SLOT_CALL: |
966 case Call::SUPER_CALL: | 985 case Call::SUPER_CALL: |
967 case Call::POSSIBLY_EVAL_CALL: | 986 case Call::POSSIBLY_EVAL_CALL: |
968 UNIMPLEMENTED(); | 987 UNIMPLEMENTED(); |
969 } | 988 } |
970 | 989 |
971 // Evaluate all arguments to the function call and store in sequential | 990 // Evaluate all arguments to the function call and store in sequential |
972 // registers. | 991 // registers. |
973 ZoneList<Expression*>* args = expr->arguments(); | 992 ZoneList<Expression*>* args = expr->arguments(); |
974 for (int i = 0; i < args->length(); ++i) { | 993 if (args->length() > 0) { |
975 Visit(args->at(i)); | 994 Register first_arg = VisitArguments(args, &temporary_register_scope); |
976 Register arg = temporary_register_scope.NewRegister(); | 995 CHECK_EQ(first_arg.index(), receiver.index() + 1); |
977 DCHECK(arg.index() - i == receiver.index() + 1); | |
978 builder()->StoreAccumulatorInRegister(arg); | |
979 } | 996 } |
980 | 997 |
981 // TODO(rmcilroy): Deal with possible direct eval here? | 998 // TODO(rmcilroy): Deal with possible direct eval here? |
982 // TODO(rmcilroy): Use CallIC to allow call type feedback. | 999 // TODO(rmcilroy): Use CallIC to allow call type feedback. |
983 builder()->Call(callee, receiver, args->length()); | 1000 builder()->Call(callee, receiver, args->length()); |
984 } | 1001 } |
985 | 1002 |
986 | 1003 |
987 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); } | 1004 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
| 1005 TemporaryRegisterScope temporary_register_scope(builder()); |
| 1006 Register constructor = temporary_register_scope.NewRegister(); |
| 1007 Visit(expr->expression()); |
| 1008 builder()->StoreAccumulatorInRegister(constructor); |
| 1009 ZoneList<Expression*>* args = expr->arguments(); |
| 1010 if (args->length() > 0) { |
| 1011 Register first_arg = VisitArguments(args, &temporary_register_scope); |
| 1012 builder()->New(constructor, first_arg, args->length()); |
| 1013 } else { |
| 1014 // The second argument here will be ignored as there are zero |
| 1015 // arguments. Using the constructor register avoids avoid |
| 1016 // allocating a temporary just to fill the operands. |
| 1017 builder()->New(constructor, constructor, 0); |
| 1018 } |
| 1019 } |
988 | 1020 |
989 | 1021 |
990 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 1022 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
991 if (expr->is_jsruntime()) { | 1023 if (expr->is_jsruntime()) { |
992 UNIMPLEMENTED(); | 1024 UNIMPLEMENTED(); |
993 } | 1025 } |
994 | 1026 |
995 // Evaluate all arguments to the runtime call. | 1027 // Evaluate all arguments to the runtime call. |
996 ZoneList<Expression*>* args = expr->arguments(); | 1028 TemporaryRegisterScope temporary_register_scope(&builder_); |
997 TemporaryRegisterScope temporary_register_scope(builder()); | |
998 // Ensure we always have a valid first_arg register even if there are no | |
999 // arguments to pass. | |
1000 Register first_arg = temporary_register_scope.NewRegister(); | |
1001 for (int i = 0; i < args->length(); ++i) { | |
1002 Register arg = | |
1003 (i == 0) ? first_arg : temporary_register_scope.NewRegister(); | |
1004 Visit(args->at(i)); | |
1005 DCHECK_EQ(arg.index() - i, first_arg.index()); | |
1006 builder()->StoreAccumulatorInRegister(arg); | |
1007 } | |
1008 | 1029 |
1009 // TODO(rmcilroy): support multiple return values. | 1030 // TODO(rmcilroy): support multiple return values. |
1010 DCHECK_LE(expr->function()->result_size, 1); | 1031 DCHECK_LE(expr->function()->result_size, 1); |
1011 Runtime::FunctionId function_id = expr->function()->function_id; | 1032 Runtime::FunctionId function_id = expr->function()->function_id; |
| 1033 ZoneList<Expression*>* args = expr->arguments(); |
| 1034 Register first_arg; |
| 1035 if (args->length() > 0) { |
| 1036 first_arg = VisitArguments(args, &temporary_register_scope); |
| 1037 } else { |
| 1038 // Allocation here is just to fullfil the requirement that there |
| 1039 // is a register operand for the start of the arguments though |
| 1040 // there are zero when this is generated. |
| 1041 first_arg = temporary_register_scope.NewRegister(); |
| 1042 } |
1012 builder()->CallRuntime(function_id, first_arg, args->length()); | 1043 builder()->CallRuntime(function_id, first_arg, args->length()); |
1013 } | 1044 } |
1014 | 1045 |
1015 | 1046 |
1016 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { | 1047 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { |
1017 Visit(expr->expression()); | 1048 Visit(expr->expression()); |
1018 builder()->LoadUndefined(); | 1049 builder()->LoadUndefined(); |
1019 } | 1050 } |
1020 | 1051 |
1021 | 1052 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 } | 1235 } |
1205 | 1236 |
1206 | 1237 |
1207 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1238 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
1208 return info()->feedback_vector()->GetIndex(slot); | 1239 return info()->feedback_vector()->GetIndex(slot); |
1209 } | 1240 } |
1210 | 1241 |
1211 } // namespace interpreter | 1242 } // namespace interpreter |
1212 } // namespace internal | 1243 } // namespace internal |
1213 } // namespace v8 | 1244 } // namespace v8 |
OLD | NEW |