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 | |
946 void BytecodeGenerator::VisitCall(Call* expr) { | 927 void BytecodeGenerator::VisitCall(Call* expr) { |
947 Expression* callee_expr = expr->expression(); | 928 Expression* callee_expr = expr->expression(); |
948 Call::CallType call_type = expr->GetCallType(isolate()); | 929 Call::CallType call_type = expr->GetCallType(isolate()); |
949 | 930 |
950 // Prepare the callee and the receiver to the function call. This depends on | 931 // Prepare the callee and the receiver to the function call. This depends on |
951 // the semantics of the underlying call type. | 932 // the semantics of the underlying call type. |
952 TemporaryRegisterScope temporary_register_scope(builder()); | 933 TemporaryRegisterScope temporary_register_scope(builder()); |
953 Register callee = temporary_register_scope.NewRegister(); | 934 Register callee = temporary_register_scope.NewRegister(); |
954 Register receiver = temporary_register_scope.NewRegister(); | 935 Register receiver = temporary_register_scope.NewRegister(); |
955 | 936 |
(...skipping 27 matching lines...) Expand all Loading... |
983 } | 964 } |
984 case Call::LOOKUP_SLOT_CALL: | 965 case Call::LOOKUP_SLOT_CALL: |
985 case Call::SUPER_CALL: | 966 case Call::SUPER_CALL: |
986 case Call::POSSIBLY_EVAL_CALL: | 967 case Call::POSSIBLY_EVAL_CALL: |
987 UNIMPLEMENTED(); | 968 UNIMPLEMENTED(); |
988 } | 969 } |
989 | 970 |
990 // Evaluate all arguments to the function call and store in sequential | 971 // Evaluate all arguments to the function call and store in sequential |
991 // registers. | 972 // registers. |
992 ZoneList<Expression*>* args = expr->arguments(); | 973 ZoneList<Expression*>* args = expr->arguments(); |
993 if (args->length() > 0) { | 974 for (int i = 0; i < args->length(); ++i) { |
994 Register first_arg = VisitArguments(args, &temporary_register_scope); | 975 Visit(args->at(i)); |
995 CHECK_EQ(first_arg.index(), receiver.index() + 1); | 976 Register arg = temporary_register_scope.NewRegister(); |
| 977 DCHECK(arg.index() - i == receiver.index() + 1); |
| 978 builder()->StoreAccumulatorInRegister(arg); |
996 } | 979 } |
997 | 980 |
998 // TODO(rmcilroy): Deal with possible direct eval here? | 981 // TODO(rmcilroy): Deal with possible direct eval here? |
999 // TODO(rmcilroy): Use CallIC to allow call type feedback. | 982 // TODO(rmcilroy): Use CallIC to allow call type feedback. |
1000 builder()->Call(callee, receiver, args->length()); | 983 builder()->Call(callee, receiver, args->length()); |
1001 } | 984 } |
1002 | 985 |
1003 | 986 |
1004 void BytecodeGenerator::VisitCallNew(CallNew* expr) { | 987 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); } |
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 } | |
1020 | 988 |
1021 | 989 |
1022 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 990 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
1023 if (expr->is_jsruntime()) { | 991 if (expr->is_jsruntime()) { |
1024 UNIMPLEMENTED(); | 992 UNIMPLEMENTED(); |
1025 } | 993 } |
1026 | 994 |
1027 // Evaluate all arguments to the runtime call. | 995 // Evaluate all arguments to the runtime call. |
1028 TemporaryRegisterScope temporary_register_scope(&builder_); | 996 ZoneList<Expression*>* args = expr->arguments(); |
| 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 } |
1029 | 1008 |
1030 // TODO(rmcilroy): support multiple return values. | 1009 // TODO(rmcilroy): support multiple return values. |
1031 DCHECK_LE(expr->function()->result_size, 1); | 1010 DCHECK_LE(expr->function()->result_size, 1); |
1032 Runtime::FunctionId function_id = expr->function()->function_id; | 1011 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 } | |
1043 builder()->CallRuntime(function_id, first_arg, args->length()); | 1012 builder()->CallRuntime(function_id, first_arg, args->length()); |
1044 } | 1013 } |
1045 | 1014 |
1046 | 1015 |
1047 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { | 1016 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { |
1048 Visit(expr->expression()); | 1017 Visit(expr->expression()); |
1049 builder()->LoadUndefined(); | 1018 builder()->LoadUndefined(); |
1050 } | 1019 } |
1051 | 1020 |
1052 | 1021 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 } | 1255 } |
1287 | 1256 |
1288 | 1257 |
1289 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1258 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
1290 return info()->feedback_vector()->GetIndex(slot); | 1259 return info()->feedback_vector()->GetIndex(slot); |
1291 } | 1260 } |
1292 | 1261 |
1293 } // namespace interpreter | 1262 } // namespace interpreter |
1294 } // namespace internal | 1263 } // namespace internal |
1295 } // namespace v8 | 1264 } // namespace v8 |
OLD | NEW |