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 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 | 927 |
928 void BytecodeGenerator::VisitProperty(Property* expr) { | 928 void BytecodeGenerator::VisitProperty(Property* expr) { |
929 TemporaryRegisterScope temporary_register_scope(builder()); | 929 TemporaryRegisterScope temporary_register_scope(builder()); |
930 Register obj = temporary_register_scope.NewRegister(); | 930 Register obj = temporary_register_scope.NewRegister(); |
931 Visit(expr->obj()); | 931 Visit(expr->obj()); |
932 builder()->StoreAccumulatorInRegister(obj); | 932 builder()->StoreAccumulatorInRegister(obj); |
933 VisitPropertyLoad(obj, expr); | 933 VisitPropertyLoad(obj, expr); |
934 } | 934 } |
935 | 935 |
936 | 936 |
| 937 Register BytecodeGenerator::VisitArguments( |
| 938 ZoneList<Expression*>* args, TemporaryRegisterScope* register_scope) { |
| 939 // Visit arguments and place in a contiguous block of temporary registers. |
| 940 // Return the first temporary register corresponding to the first argument. |
| 941 DCHECK_GT(args->length(), 0); |
| 942 Register first_arg = register_scope->NewRegister(); |
| 943 Visit(args->at(0)); |
| 944 builder()->StoreAccumulatorInRegister(first_arg); |
| 945 for (int i = 1; i < static_cast<int>(args->length()); i++) { |
| 946 Register ith_arg = register_scope->NewRegister(); |
| 947 Visit(args->at(i)); |
| 948 builder()->StoreAccumulatorInRegister(ith_arg); |
| 949 DCHECK(ith_arg.index() - i == first_arg.index()); |
| 950 } |
| 951 |
| 952 return first_arg; |
| 953 } |
| 954 |
| 955 |
937 void BytecodeGenerator::VisitCall(Call* expr) { | 956 void BytecodeGenerator::VisitCall(Call* expr) { |
938 Expression* callee_expr = expr->expression(); | 957 Expression* callee_expr = expr->expression(); |
939 Call::CallType call_type = expr->GetCallType(isolate()); | 958 Call::CallType call_type = expr->GetCallType(isolate()); |
940 | 959 |
941 // Prepare the callee and the receiver to the function call. This depends on | 960 // Prepare the callee and the receiver to the function call. This depends on |
942 // the semantics of the underlying call type. | 961 // the semantics of the underlying call type. |
943 TemporaryRegisterScope temporary_register_scope(builder()); | 962 TemporaryRegisterScope temporary_register_scope(builder()); |
944 Register callee = temporary_register_scope.NewRegister(); | 963 Register callee = temporary_register_scope.NewRegister(); |
945 Register receiver = temporary_register_scope.NewRegister(); | 964 Register receiver = temporary_register_scope.NewRegister(); |
946 | 965 |
(...skipping 27 matching lines...) Expand all Loading... |
974 } | 993 } |
975 case Call::LOOKUP_SLOT_CALL: | 994 case Call::LOOKUP_SLOT_CALL: |
976 case Call::SUPER_CALL: | 995 case Call::SUPER_CALL: |
977 case Call::POSSIBLY_EVAL_CALL: | 996 case Call::POSSIBLY_EVAL_CALL: |
978 UNIMPLEMENTED(); | 997 UNIMPLEMENTED(); |
979 } | 998 } |
980 | 999 |
981 // Evaluate all arguments to the function call and store in sequential | 1000 // Evaluate all arguments to the function call and store in sequential |
982 // registers. | 1001 // registers. |
983 ZoneList<Expression*>* args = expr->arguments(); | 1002 ZoneList<Expression*>* args = expr->arguments(); |
984 for (int i = 0; i < args->length(); ++i) { | 1003 if (args->length() > 0) { |
985 Visit(args->at(i)); | 1004 Register first_arg = VisitArguments(args, &temporary_register_scope); |
986 Register arg = temporary_register_scope.NewRegister(); | 1005 CHECK_EQ(first_arg.index(), receiver.index() + 1); |
987 DCHECK(arg.index() - i == receiver.index() + 1); | |
988 builder()->StoreAccumulatorInRegister(arg); | |
989 } | 1006 } |
990 | 1007 |
991 // TODO(rmcilroy): Deal with possible direct eval here? | 1008 // TODO(rmcilroy): Deal with possible direct eval here? |
992 // TODO(rmcilroy): Use CallIC to allow call type feedback. | 1009 // TODO(rmcilroy): Use CallIC to allow call type feedback. |
993 builder()->Call(callee, receiver, args->length()); | 1010 builder()->Call(callee, receiver, args->length()); |
994 } | 1011 } |
995 | 1012 |
996 | 1013 |
997 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); } | 1014 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
| 1015 TemporaryRegisterScope temporary_register_scope(builder()); |
| 1016 Register constructor = temporary_register_scope.NewRegister(); |
| 1017 Visit(expr->expression()); |
| 1018 builder()->StoreAccumulatorInRegister(constructor); |
| 1019 ZoneList<Expression*>* args = expr->arguments(); |
| 1020 if (args->length() > 0) { |
| 1021 Register first_arg = VisitArguments(args, &temporary_register_scope); |
| 1022 builder()->New(constructor, first_arg, args->length()); |
| 1023 } else { |
| 1024 // The second argument here will be ignored as there are zero |
| 1025 // arguments. Using the constructor register avoids avoid |
| 1026 // allocating a temporary just to fill the operands. |
| 1027 builder()->New(constructor, constructor, 0); |
| 1028 } |
| 1029 } |
998 | 1030 |
999 | 1031 |
1000 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 1032 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
1001 if (expr->is_jsruntime()) { | 1033 if (expr->is_jsruntime()) { |
1002 UNIMPLEMENTED(); | 1034 UNIMPLEMENTED(); |
1003 } | 1035 } |
1004 | 1036 |
1005 // Evaluate all arguments to the runtime call. | 1037 // Evaluate all arguments to the runtime call. |
1006 ZoneList<Expression*>* args = expr->arguments(); | 1038 TemporaryRegisterScope temporary_register_scope(&builder_); |
1007 TemporaryRegisterScope temporary_register_scope(builder()); | |
1008 // Ensure we always have a valid first_arg register even if there are no | |
1009 // arguments to pass. | |
1010 Register first_arg = temporary_register_scope.NewRegister(); | |
1011 for (int i = 0; i < args->length(); ++i) { | |
1012 Register arg = | |
1013 (i == 0) ? first_arg : temporary_register_scope.NewRegister(); | |
1014 Visit(args->at(i)); | |
1015 DCHECK_EQ(arg.index() - i, first_arg.index()); | |
1016 builder()->StoreAccumulatorInRegister(arg); | |
1017 } | |
1018 | 1039 |
1019 // TODO(rmcilroy): support multiple return values. | 1040 // TODO(rmcilroy): support multiple return values. |
1020 DCHECK_LE(expr->function()->result_size, 1); | 1041 DCHECK_LE(expr->function()->result_size, 1); |
1021 Runtime::FunctionId function_id = expr->function()->function_id; | 1042 Runtime::FunctionId function_id = expr->function()->function_id; |
| 1043 ZoneList<Expression*>* args = expr->arguments(); |
| 1044 Register first_arg; |
| 1045 if (args->length() > 0) { |
| 1046 first_arg = VisitArguments(args, &temporary_register_scope); |
| 1047 } else { |
| 1048 // Allocation here is just to fullfil the requirement that there |
| 1049 // is a register operand for the start of the arguments though |
| 1050 // there are zero when this is generated. |
| 1051 first_arg = temporary_register_scope.NewRegister(); |
| 1052 } |
1022 builder()->CallRuntime(function_id, first_arg, args->length()); | 1053 builder()->CallRuntime(function_id, first_arg, args->length()); |
1023 } | 1054 } |
1024 | 1055 |
1025 | 1056 |
1026 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { | 1057 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { |
1027 Visit(expr->expression()); | 1058 Visit(expr->expression()); |
1028 builder()->LoadUndefined(); | 1059 builder()->LoadUndefined(); |
1029 } | 1060 } |
1030 | 1061 |
1031 | 1062 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 } | 1296 } |
1266 | 1297 |
1267 | 1298 |
1268 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1299 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
1269 return info()->feedback_vector()->GetIndex(slot); | 1300 return info()->feedback_vector()->GetIndex(slot); |
1270 } | 1301 } |
1271 | 1302 |
1272 } // namespace interpreter | 1303 } // namespace interpreter |
1273 } // namespace internal | 1304 } // namespace internal |
1274 } // namespace v8 | 1305 } // namespace v8 |
OLD | NEW |