| 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 |