Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1419003002: [Interpreter] Unify global and unallocated variable access. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix unallocated variable error Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/control-flow-builders.h" 8 #include "src/interpreter/control-flow-builders.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 case ObjectLiteral::Property::CONSTANT: 706 case ObjectLiteral::Property::CONSTANT:
707 UNREACHABLE(); 707 UNREACHABLE();
708 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 708 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
709 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 709 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
710 // Fall through. 710 // Fall through.
711 case ObjectLiteral::Property::COMPUTED: { 711 case ObjectLiteral::Property::COMPUTED: {
712 // It is safe to use [[Put]] here because the boilerplate already 712 // It is safe to use [[Put]] here because the boilerplate already
713 // contains computed properties with an uninitialized value. 713 // contains computed properties with an uninitialized value.
714 if (literal_key->value()->IsInternalizedString()) { 714 if (literal_key->value()->IsInternalizedString()) {
715 if (property->emit_store()) { 715 if (property->emit_store()) {
716 Register name = inner_temporary_register_scope.NewRegister(); 716 size_t name_index =
717 builder() 717 builder()->GetConstantPoolEntry(literal_key->AsPropertyName());
718 ->LoadLiteral(literal_key->AsPropertyName())
719 .StoreAccumulatorInRegister(name);
720 VisitForAccumulatorValue(property->value()); 718 VisitForAccumulatorValue(property->value());
721 builder()->StoreNamedProperty(literal, name, 719 builder()->StoreNamedProperty(literal, name_index,
722 feedback_index(property->GetSlot(0)), 720 feedback_index(property->GetSlot(0)),
723 language_mode()); 721 language_mode());
724 } else { 722 } else {
725 VisitForEffect(property->value()); 723 VisitForEffect(property->value());
726 } 724 }
727 } else { 725 } else {
728 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3); 726 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3);
729 Register key = 727 Register key =
730 inner_temporary_register_scope.NextConsecutiveRegister(); 728 inner_temporary_register_scope.NextConsecutiveRegister();
731 Register value = 729 Register value =
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 } 930 }
933 case VariableLocation::PARAMETER: { 931 case VariableLocation::PARAMETER: {
934 // The parameter indices are shifted by 1 (receiver is variable 932 // The parameter indices are shifted by 1 (receiver is variable
935 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 933 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
936 Register source = builder()->Parameter(variable->index() + 1); 934 Register source = builder()->Parameter(variable->index() + 1);
937 execution_result()->SetResultInRegister(source); 935 execution_result()->SetResultInRegister(source);
938 break; 936 break;
939 } 937 }
940 case VariableLocation::GLOBAL: 938 case VariableLocation::GLOBAL:
941 case VariableLocation::UNALLOCATED: { 939 case VariableLocation::UNALLOCATED: {
942 TemporaryRegisterScope temporary_register_scope(builder()); 940 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
943 Register obj = temporary_register_scope.NewRegister(); 941 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode());
944 builder()->LoadContextSlot(execution_context()->reg(),
945 Context::GLOBAL_OBJECT_INDEX);
946 builder()->StoreAccumulatorInRegister(obj);
947 builder()->LoadLiteral(variable->name());
948 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode());
949 execution_result()->SetResultInAccumulator(); 942 execution_result()->SetResultInAccumulator();
950 break; 943 break;
951 } 944 }
952 case VariableLocation::CONTEXT: { 945 case VariableLocation::CONTEXT: {
953 ContextScope* context = execution_context()->Previous(variable->scope()); 946 ContextScope* context = execution_context()->Previous(variable->scope());
954 if (context) { 947 if (context) {
955 builder()->LoadContextSlot(context->reg(), variable->index()); 948 builder()->LoadContextSlot(context->reg(), variable->index());
956 execution_result()->SetResultInAccumulator(); 949 execution_result()->SetResultInAccumulator();
957 } else { 950 } else {
958 UNIMPLEMENTED(); 951 UNIMPLEMENTED();
(...skipping 21 matching lines...) Expand all
980 case VariableLocation::PARAMETER: { 973 case VariableLocation::PARAMETER: {
981 // The parameter indices are shifted by 1 (receiver is variable 974 // The parameter indices are shifted by 1 (receiver is variable
982 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 975 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
983 Register destination(builder()->Parameter(variable->index() + 1)); 976 Register destination(builder()->Parameter(variable->index() + 1));
984 builder()->StoreAccumulatorInRegister(destination); 977 builder()->StoreAccumulatorInRegister(destination);
985 RecordStoreToRegister(destination); 978 RecordStoreToRegister(destination);
986 break; 979 break;
987 } 980 }
988 case VariableLocation::GLOBAL: 981 case VariableLocation::GLOBAL:
989 case VariableLocation::UNALLOCATED: { 982 case VariableLocation::UNALLOCATED: {
990 Register value = execution_result()->NewRegister(); 983 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
991 Register obj = execution_result()->NewRegister(); 984 builder()->StoreGlobal(name_index, feedback_index(slot), language_mode());
992 Register name = execution_result()->NewRegister();
993
994 // TODO(rmcilroy): Investigate whether we can avoid having to stash the
995 // value in a register.
996 builder()->StoreAccumulatorInRegister(value);
997 builder()->LoadContextSlot(execution_context()->reg(),
998 Context::GLOBAL_OBJECT_INDEX);
999 builder()->StoreAccumulatorInRegister(obj);
1000 builder()->LoadLiteral(variable->name());
1001 builder()->StoreAccumulatorInRegister(name);
1002 builder()->LoadAccumulatorWithRegister(value);
1003 builder()->StoreNamedProperty(obj, name, feedback_index(slot),
1004 language_mode());
1005 break; 985 break;
1006 } 986 }
1007 case VariableLocation::CONTEXT: { 987 case VariableLocation::CONTEXT: {
1008 // TODO(rmcilroy): support const mode initialization. 988 // TODO(rmcilroy): support const mode initialization.
1009 ContextScope* context = execution_context()->Previous(variable->scope()); 989 ContextScope* context = execution_context()->Previous(variable->scope());
1010 if (context) { 990 if (context) {
1011 builder()->StoreContextSlot(context->reg(), variable->index()); 991 builder()->StoreContextSlot(context->reg(), variable->index());
1012 } else { 992 } else {
1013 UNIMPLEMENTED(); 993 UNIMPLEMENTED();
1014 } 994 }
1015 break; 995 break;
1016 } 996 }
1017 case VariableLocation::LOOKUP: 997 case VariableLocation::LOOKUP:
1018 UNIMPLEMENTED(); 998 UNIMPLEMENTED();
1019 } 999 }
1020 } 1000 }
1021 1001
1022 1002
1023 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 1003 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
1024 DCHECK(expr->target()->IsValidReferenceExpression()); 1004 DCHECK(expr->target()->IsValidReferenceExpression());
1025 Register object, key; 1005 Register object, key;
1006 size_t name_index = kMaxUInt32;
1026 1007
1027 // Left-hand side can only be a property, a global or a variable slot. 1008 // Left-hand side can only be a property, a global or a variable slot.
1028 Property* property = expr->target()->AsProperty(); 1009 Property* property = expr->target()->AsProperty();
1029 LhsKind assign_type = Property::GetAssignType(property); 1010 LhsKind assign_type = Property::GetAssignType(property);
1030 1011
1031 // Evaluate LHS expression. 1012 // Evaluate LHS expression.
1032 switch (assign_type) { 1013 switch (assign_type) {
1033 case VARIABLE: 1014 case VARIABLE:
1034 // Nothing to do to evaluate variable assignment LHS. 1015 // Nothing to do to evaluate variable assignment LHS.
1035 break; 1016 break;
1036 case NAMED_PROPERTY: { 1017 case NAMED_PROPERTY: {
1037 object = VisitForRegisterValue(property->obj()); 1018 object = VisitForRegisterValue(property->obj());
1038 key = execution_result()->NewRegister(); 1019 name_index = builder()->GetConstantPoolEntry(
1039 builder()->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()); 1020 property->key()->AsLiteral()->AsPropertyName());
1040 builder()->StoreAccumulatorInRegister(key);
1041 break; 1021 break;
1042 } 1022 }
1043 case KEYED_PROPERTY: { 1023 case KEYED_PROPERTY: {
1044 object = VisitForRegisterValue(property->obj()); 1024 object = VisitForRegisterValue(property->obj());
1045 key = VisitForRegisterValue(property->key()); 1025 key = VisitForRegisterValue(property->key());
1046 break; 1026 break;
1047 } 1027 }
1048 case NAMED_SUPER_PROPERTY: 1028 case NAMED_SUPER_PROPERTY:
1049 case KEYED_SUPER_PROPERTY: 1029 case KEYED_SUPER_PROPERTY:
1050 UNIMPLEMENTED(); 1030 UNIMPLEMENTED();
(...skipping 11 matching lines...) Expand all
1062 FeedbackVectorSlot slot = expr->AssignmentSlot(); 1042 FeedbackVectorSlot slot = expr->AssignmentSlot();
1063 switch (assign_type) { 1043 switch (assign_type) {
1064 case VARIABLE: { 1044 case VARIABLE: {
1065 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. 1045 // TODO(oth): The VisitVariableAssignment() call is hard to reason about.
1066 // Is the value in the accumulator safe? Yes, but scary. 1046 // Is the value in the accumulator safe? Yes, but scary.
1067 Variable* variable = expr->target()->AsVariableProxy()->var(); 1047 Variable* variable = expr->target()->AsVariableProxy()->var();
1068 VisitVariableAssignment(variable, slot); 1048 VisitVariableAssignment(variable, slot);
1069 break; 1049 break;
1070 } 1050 }
1071 case NAMED_PROPERTY: 1051 case NAMED_PROPERTY:
1072 builder()->StoreNamedProperty(object, key, feedback_index(slot), 1052 builder()->StoreNamedProperty(object, name_index, feedback_index(slot),
1073 language_mode()); 1053 language_mode());
1074 break; 1054 break;
1075 case KEYED_PROPERTY: 1055 case KEYED_PROPERTY:
1076 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 1056 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
1077 language_mode()); 1057 language_mode());
1078 break; 1058 break;
1079 case NAMED_SUPER_PROPERTY: 1059 case NAMED_SUPER_PROPERTY:
1080 case KEYED_SUPER_PROPERTY: 1060 case KEYED_SUPER_PROPERTY:
1081 UNIMPLEMENTED(); 1061 UNIMPLEMENTED();
1082 } 1062 }
(...skipping 10 matching lines...) Expand all
1093 } 1073 }
1094 1074
1095 1075
1096 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { 1076 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
1097 LhsKind property_kind = Property::GetAssignType(expr); 1077 LhsKind property_kind = Property::GetAssignType(expr);
1098 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); 1078 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
1099 switch (property_kind) { 1079 switch (property_kind) {
1100 case VARIABLE: 1080 case VARIABLE:
1101 UNREACHABLE(); 1081 UNREACHABLE();
1102 case NAMED_PROPERTY: { 1082 case NAMED_PROPERTY: {
1103 builder()->LoadLiteral(expr->key()->AsLiteral()->AsPropertyName()); 1083 size_t name_index = builder()->GetConstantPoolEntry(
1104 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode()); 1084 expr->key()->AsLiteral()->AsPropertyName());
1085 builder()->LoadNamedProperty(obj, name_index, feedback_index(slot),
1086 language_mode());
1105 break; 1087 break;
1106 } 1088 }
1107 case KEYED_PROPERTY: { 1089 case KEYED_PROPERTY: {
1108 VisitForAccumulatorValue(expr->key()); 1090 VisitForAccumulatorValue(expr->key());
1109 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); 1091 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode());
1110 break; 1092 break;
1111 } 1093 }
1112 case NAMED_SUPER_PROPERTY: 1094 case NAMED_SUPER_PROPERTY:
1113 case KEYED_SUPER_PROPERTY: 1095 case KEYED_SUPER_PROPERTY:
1114 UNIMPLEMENTED(); 1096 UNIMPLEMENTED();
1115 } 1097 }
1116 execution_result()->SetResultInAccumulator(); 1098 execution_result()->SetResultInAccumulator();
1117 } 1099 }
1118 1100
1119 1101
1102 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj,
1103 Property* expr) {
1104 AccumulatorResultScope result_scope(this);
1105 VisitPropertyLoad(obj, expr);
1106 }
1107
1108
1120 void BytecodeGenerator::VisitProperty(Property* expr) { 1109 void BytecodeGenerator::VisitProperty(Property* expr) {
1121 Register obj = VisitForRegisterValue(expr->obj()); 1110 Register obj = VisitForRegisterValue(expr->obj());
1122 VisitPropertyLoad(obj, expr); 1111 VisitPropertyLoad(obj, expr);
1123 } 1112 }
1124 1113
1125 1114
1126 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { 1115 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
1127 // Visit arguments and place in a contiguous block of temporary 1116 // Visit arguments and place in a contiguous block of temporary
1128 // registers. Return the first temporary register corresponding to 1117 // registers. Return the first temporary register corresponding to
1129 // the first argument. 1118 // the first argument.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 ZoneList<Expression*>* args = expr->arguments(); 1155 ZoneList<Expression*>* args = expr->arguments();
1167 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1); 1156 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1);
1168 Register receiver = execution_result()->NextConsecutiveRegister(); 1157 Register receiver = execution_result()->NextConsecutiveRegister();
1169 1158
1170 switch (call_type) { 1159 switch (call_type) {
1171 case Call::PROPERTY_CALL: { 1160 case Call::PROPERTY_CALL: {
1172 Property* property = callee_expr->AsProperty(); 1161 Property* property = callee_expr->AsProperty();
1173 if (property->IsSuperAccess()) { 1162 if (property->IsSuperAccess()) {
1174 UNIMPLEMENTED(); 1163 UNIMPLEMENTED();
1175 } 1164 }
1165
1176 VisitForAccumulatorValue(property->obj()); 1166 VisitForAccumulatorValue(property->obj());
1177 builder()->StoreAccumulatorInRegister(receiver); 1167 builder()->StoreAccumulatorInRegister(receiver);
1178 // Need a result scope here to keep our consecutive 1168 VisitPropertyLoadForAccumulator(receiver, property);
1179 // temporaries.
1180 AccumulatorResultScope accumulator_execution_result(this);
1181 // Perform a property load of the callee.
1182 VisitPropertyLoad(receiver, property);
1183 builder()->StoreAccumulatorInRegister(callee); 1169 builder()->StoreAccumulatorInRegister(callee);
1184 break; 1170 break;
1185 } 1171 }
1186 case Call::GLOBAL_CALL: { 1172 case Call::GLOBAL_CALL: {
1187 // Receiver is undefined for global calls. 1173 // Receiver is undefined for global calls.
1188 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1174 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1189 // Load callee as a global variable. 1175 // Load callee as a global variable.
1190 VariableProxy* proxy = callee_expr->AsVariableProxy(); 1176 VariableProxy* proxy = callee_expr->AsVariableProxy();
1191 // Result scope for VisitVariableLoad to avoid using our temporaries 1177 // Result scope for VisitVariableLoad to avoid using our temporaries
1192 // and double setting the result in our result_scope() and. 1178 // and double setting the result in our result_scope() and.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 1252
1267 1253
1268 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { 1254 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
1269 VisitForEffect(expr->expression()); 1255 VisitForEffect(expr->expression());
1270 builder()->LoadUndefined(); 1256 builder()->LoadUndefined();
1271 execution_result()->SetResultInAccumulator(); 1257 execution_result()->SetResultInAccumulator();
1272 } 1258 }
1273 1259
1274 1260
1275 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) { 1261 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
1262 // TODO(rmcilroy): Set TypeofMode to INSIDE_TYPEOF for any loadICs performed
1263 // while visiting the expression.
1276 VisitForAccumulatorValue(expr->expression()); 1264 VisitForAccumulatorValue(expr->expression());
1277 builder()->TypeOf(); 1265 builder()->TypeOf();
1278 execution_result()->SetResultInAccumulator(); 1266 execution_result()->SetResultInAccumulator();
1279 } 1267 }
1280 1268
1281 1269
1282 void BytecodeGenerator::VisitNot(UnaryOperation* expr) { 1270 void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
1283 VisitForAccumulatorValue(expr->expression()); 1271 VisitForAccumulatorValue(expr->expression());
1284 builder()->LogicalNot(); 1272 builder()->LogicalNot();
1285 execution_result()->SetResultInAccumulator(); 1273 execution_result()->SetResultInAccumulator();
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 UNIMPLEMENTED(); 1370 UNIMPLEMENTED();
1383 } 1371 }
1384 1372
1385 1373
1386 void BytecodeGenerator::VisitSuperPropertyReference( 1374 void BytecodeGenerator::VisitSuperPropertyReference(
1387 SuperPropertyReference* expr) { 1375 SuperPropertyReference* expr) {
1388 UNIMPLEMENTED(); 1376 UNIMPLEMENTED();
1389 } 1377 }
1390 1378
1391 1379
1380 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
1381 VisitForEffect(binop->left());
1382 Visit(binop->right());
1383 }
1384
1385
1386 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
1387 Expression* left = binop->left();
1388 Expression* right = binop->right();
1389
1390 // Short-circuit evaluation- If it is known that left is always true,
1391 // no need to visit right
1392 if (left->ToBooleanIsTrue()) {
1393 VisitForAccumulatorValue(left);
1394 } else {
1395 BytecodeLabel end_label;
1396 VisitForAccumulatorValue(left);
1397 builder()->JumpIfToBooleanTrue(&end_label);
1398 VisitForAccumulatorValue(right);
1399 builder()->Bind(&end_label);
1400 }
1401 execution_result()->SetResultInAccumulator();
1402 }
1403
1404
1405 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
1406 Expression* left = binop->left();
1407 Expression* right = binop->right();
1408
1409 // Short-circuit evaluation- If it is known that left is always false,
1410 // no need to visit right
1411 if (left->ToBooleanIsFalse()) {
1412 VisitForAccumulatorValue(left);
1413 } else {
1414 BytecodeLabel end_label;
1415 VisitForAccumulatorValue(left);
1416 builder()->JumpIfToBooleanFalse(&end_label);
1417 VisitForAccumulatorValue(right);
1418 builder()->Bind(&end_label);
1419 }
1420 execution_result()->SetResultInAccumulator();
1421 }
1422
1423
1392 void BytecodeGenerator::VisitNewLocalFunctionContext() { 1424 void BytecodeGenerator::VisitNewLocalFunctionContext() {
1425 AccumulatorResultScope accumulator_execution_result(this);
1393 Scope* scope = this->scope(); 1426 Scope* scope = this->scope();
1394 1427
1395 // Allocate a new local context. 1428 // Allocate a new local context.
1396 if (scope->is_script_scope()) { 1429 if (scope->is_script_scope()) {
1397 TemporaryRegisterScope temporary_register_scope(builder()); 1430 TemporaryRegisterScope temporary_register_scope(builder());
1398 Register closure = temporary_register_scope.NewRegister(); 1431 Register closure = temporary_register_scope.NewRegister();
1399 Register scope_info = temporary_register_scope.NewRegister(); 1432 Register scope_info = temporary_register_scope.NewRegister();
1400 DCHECK(Register::AreContiguous(closure, scope_info)); 1433 DCHECK(Register::AreContiguous(closure, scope_info));
1401 builder() 1434 builder()
1402 ->LoadAccumulatorWithRegister(Register::function_closure()) 1435 ->LoadAccumulatorWithRegister(Register::function_closure())
1403 .StoreAccumulatorInRegister(closure) 1436 .StoreAccumulatorInRegister(closure)
1404 .LoadLiteral(scope->GetScopeInfo(isolate())) 1437 .LoadLiteral(scope->GetScopeInfo(isolate()))
1405 .StoreAccumulatorInRegister(scope_info) 1438 .StoreAccumulatorInRegister(scope_info)
1406 .CallRuntime(Runtime::kNewScriptContext, closure, 2); 1439 .CallRuntime(Runtime::kNewScriptContext, closure, 2);
1407 } else { 1440 } else {
1408 builder()->CallRuntime(Runtime::kNewFunctionContext, 1441 builder()->CallRuntime(Runtime::kNewFunctionContext,
1409 Register::function_closure(), 1); 1442 Register::function_closure(), 1);
1410 } 1443 }
1444 execution_result()->SetResultInAccumulator();
1411 } 1445 }
1412 1446
1413 1447
1414 void BytecodeGenerator::VisitBuildLocalActivationContext() { 1448 void BytecodeGenerator::VisitBuildLocalActivationContext() {
1415 Scope* scope = this->scope(); 1449 Scope* scope = this->scope();
1416 1450
1417 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 1451 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
1418 UNIMPLEMENTED(); 1452 UNIMPLEMENTED();
1419 } 1453 }
1420 1454
1421 // Copy parameters into context if necessary. 1455 // Copy parameters into context if necessary.
1422 int num_parameters = scope->num_parameters(); 1456 int num_parameters = scope->num_parameters();
1423 for (int i = 0; i < num_parameters; i++) { 1457 for (int i = 0; i < num_parameters; i++) {
1424 Variable* variable = scope->parameter(i); 1458 Variable* variable = scope->parameter(i);
1425 if (!variable->IsContextSlot()) continue; 1459 if (!variable->IsContextSlot()) continue;
1426 1460
1427 // The parameter indices are shifted by 1 (receiver is variable 1461 // The parameter indices are shifted by 1 (receiver is variable
1428 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 1462 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
1429 Register parameter(builder()->Parameter(i + 1)); 1463 Register parameter(builder()->Parameter(i + 1));
1430 // Context variable (at bottom of the context chain). 1464 // Context variable (at bottom of the context chain).
1431 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 1465 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
1432 builder()->LoadAccumulatorWithRegister(parameter) 1466 builder()->LoadAccumulatorWithRegister(parameter)
1433 .StoreContextSlot(execution_context()->reg(), variable->index()); 1467 .StoreContextSlot(execution_context()->reg(), variable->index());
1434 } 1468 }
1435 } 1469 }
1436 1470
1437 1471
1438 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { 1472 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
1473 AccumulatorResultScope accumulator_execution_result(this);
1439 DCHECK(scope->is_block_scope()); 1474 DCHECK(scope->is_block_scope());
1440 1475
1441 // Allocate a new local block context. 1476 // Allocate a new local block context.
1442 TemporaryRegisterScope temporary_register_scope(builder()); 1477 TemporaryRegisterScope temporary_register_scope(builder());
1443 Register scope_info = temporary_register_scope.NewRegister(); 1478 Register scope_info = temporary_register_scope.NewRegister();
1444 Register closure = temporary_register_scope.NewRegister(); 1479 Register closure = temporary_register_scope.NewRegister();
1445 DCHECK(Register::AreContiguous(scope_info, closure)); 1480 DCHECK(Register::AreContiguous(scope_info, closure));
1446 builder() 1481 builder()
1447 ->LoadLiteral(scope->GetScopeInfo(isolate())) 1482 ->LoadLiteral(scope->GetScopeInfo(isolate()))
1448 .StoreAccumulatorInRegister(scope_info); 1483 .StoreAccumulatorInRegister(scope_info);
1449 VisitFunctionClosureForContext(); 1484 VisitFunctionClosureForContext();
1450 builder() 1485 builder()
1451 ->StoreAccumulatorInRegister(closure) 1486 ->StoreAccumulatorInRegister(closure)
1452 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2); 1487 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2);
1453 }
1454
1455
1456 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
1457 VisitForEffect(binop->left());
1458 Visit(binop->right());
1459 }
1460
1461
1462 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
1463 Expression* left = binop->left();
1464 Expression* right = binop->right();
1465
1466 // Short-circuit evaluation- If it is known that left is always true,
1467 // no need to visit right
1468 if (left->ToBooleanIsTrue()) {
1469 VisitForAccumulatorValue(left);
1470 } else {
1471 BytecodeLabel end_label;
1472 VisitForAccumulatorValue(left);
1473 builder()->JumpIfToBooleanTrue(&end_label);
1474 VisitForAccumulatorValue(right);
1475 builder()->Bind(&end_label);
1476 }
1477 execution_result()->SetResultInAccumulator(); 1488 execution_result()->SetResultInAccumulator();
1478 } 1489 }
1479 1490
1480
1481 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
1482 Expression* left = binop->left();
1483 Expression* right = binop->right();
1484
1485 // Short-circuit evaluation- If it is known that left is always false,
1486 // no need to visit right
1487 if (left->ToBooleanIsFalse()) {
1488 VisitForAccumulatorValue(left);
1489 } else {
1490 BytecodeLabel end_label;
1491 VisitForAccumulatorValue(left);
1492 builder()->JumpIfToBooleanFalse(&end_label);
1493 VisitForAccumulatorValue(right);
1494 builder()->Bind(&end_label);
1495 }
1496 execution_result()->SetResultInAccumulator();
1497 }
1498
1499 1491
1500 void BytecodeGenerator::VisitObjectLiteralAccessor( 1492 void BytecodeGenerator::VisitObjectLiteralAccessor(
1501 Register home_object, ObjectLiteralProperty* property, Register value_out) { 1493 Register home_object, ObjectLiteralProperty* property, Register value_out) {
1502 // TODO(rmcilroy): Replace value_out with VisitForRegister(); 1494 // TODO(rmcilroy): Replace value_out with VisitForRegister();
1503 if (property == nullptr) { 1495 if (property == nullptr) {
1504 builder()->LoadNull().StoreAccumulatorInRegister(value_out); 1496 builder()->LoadNull().StoreAccumulatorInRegister(value_out);
1505 } else { 1497 } else {
1506 VisitForAccumulatorValue(property->value()); 1498 VisitForAccumulatorValue(property->value());
1507 builder()->StoreAccumulatorInRegister(value_out); 1499 builder()->StoreAccumulatorInRegister(value_out);
1508 VisitSetHomeObject(value_out, home_object, property); 1500 VisitSetHomeObject(value_out, home_object, property);
1509 } 1501 }
1510 } 1502 }
1511 1503
1512 1504
1513 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, 1505 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
1514 ObjectLiteralProperty* property, 1506 ObjectLiteralProperty* property,
1515 int slot_number) { 1507 int slot_number) {
1516 Expression* expr = property->value(); 1508 Expression* expr = property->value();
1517 if (!FunctionLiteral::NeedsHomeObject(expr)) return; 1509 if (!FunctionLiteral::NeedsHomeObject(expr)) return;
1518 1510
1519 // TODO(rmcilroy): Remove UNIMPLEMENTED once we have tests for setting the
1520 // home object.
1521 UNIMPLEMENTED(); 1511 UNIMPLEMENTED();
1522
1523 TemporaryRegisterScope temporary_register_scope(builder());
1524 Register name = temporary_register_scope.NewRegister();
1525 isolate()->factory()->home_object_symbol();
1526 builder()
1527 ->LoadLiteral(isolate()->factory()->home_object_symbol())
1528 .StoreAccumulatorInRegister(name)
1529 .StoreNamedProperty(home_object, name,
1530 feedback_index(property->GetSlot(slot_number)),
1531 language_mode());
1532 } 1512 }
1533 1513
1534 1514
1535 void BytecodeGenerator::VisitFunctionClosureForContext() { 1515 void BytecodeGenerator::VisitFunctionClosureForContext() {
1516 AccumulatorResultScope accumulator_execution_result(this);
1536 Scope* closure_scope = execution_context()->scope()->ClosureScope(); 1517 Scope* closure_scope = execution_context()->scope()->ClosureScope();
1537 if (closure_scope->is_script_scope() || 1518 if (closure_scope->is_script_scope() ||
1538 closure_scope->is_module_scope()) { 1519 closure_scope->is_module_scope()) {
1539 // Contexts nested in the native context have a canonical empty function as 1520 // Contexts nested in the native context have a canonical empty function as
1540 // their closure, not the anonymous closure containing the global code. 1521 // their closure, not the anonymous closure containing the global code.
1541 // Pass a SMI sentinel and let the runtime look up the empty function. 1522 // Pass a SMI sentinel and let the runtime look up the empty function.
1542 builder()->LoadLiteral(Smi::FromInt(0)); 1523 builder()->LoadLiteral(Smi::FromInt(0));
1543 } else { 1524 } else {
1544 DCHECK(closure_scope->is_function_scope()); 1525 DCHECK(closure_scope->is_function_scope());
1545 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 1526 builder()->LoadAccumulatorWithRegister(Register::function_closure());
1546 } 1527 }
1528 execution_result()->SetResultInAccumulator();
1547 } 1529 }
1548 1530
1549 1531
1550 void BytecodeGenerator::PrepareForBinaryExpression() { 1532 void BytecodeGenerator::PrepareForBinaryExpression() {
1551 if (binary_expression_depth_++ == 0) { 1533 if (binary_expression_depth_++ == 0) {
1552 binary_expression_hazard_set_.clear(); 1534 binary_expression_hazard_set_.clear();
1553 } 1535 }
1554 } 1536 }
1555 1537
1556 1538
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 } 1616 }
1635 1617
1636 1618
1637 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 1619 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1638 return info()->feedback_vector()->GetIndex(slot); 1620 return info()->feedback_vector()->GetIndex(slot);
1639 } 1621 }
1640 1622
1641 } // namespace interpreter 1623 } // namespace interpreter
1642 } // namespace internal 1624 } // namespace internal
1643 } // namespace v8 1625 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698