| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1108 operator_name, | 1108 operator_name, |
| 1109 kNumberOfArguments, | 1109 kNumberOfArguments, |
| 1110 kNoArgumentNames, | 1110 kNoArgumentNames, |
| 1111 kNumArgumentsChecked); | 1111 kNumArgumentsChecked); |
| 1112 if (IsResultNeeded(node)) { | 1112 if (IsResultNeeded(node)) { |
| 1113 __ pushq(RAX); | 1113 __ pushq(RAX); |
| 1114 } | 1114 } |
| 1115 } | 1115 } |
| 1116 | 1116 |
| 1117 | 1117 |
| 1118 void CodeGenerator::VisitIncrOpInstanceFieldNode( | |
| 1119 IncrOpInstanceFieldNode* node) { | |
| 1120 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | |
| 1121 node->receiver()->Visit(this); | |
| 1122 __ pushq(Address(RSP, 0)); // Duplicate receiver (preserve for setter). | |
| 1123 MarkDeoptPoint(node->getter_id(), node->token_index()); | |
| 1124 GenerateInstanceGetterCall(node->getter_id(), | |
| 1125 node->token_index(), | |
| 1126 node->field_name()); | |
| 1127 // result is in RAX. | |
| 1128 __ popq(RDX); // Get receiver. | |
| 1129 if (!node->prefix() && IsResultNeeded(node)) { | |
| 1130 // Preserve as result. | |
| 1131 __ pushq(RAX); // Preserve value as result. | |
| 1132 } | |
| 1133 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; | |
| 1134 // RAX: Value. | |
| 1135 // RDX: Receiver. | |
| 1136 __ pushq(RDX); // Preserve receiver. | |
| 1137 __ pushq(RAX); // Left operand. | |
| 1138 __ pushq(Immediate(Smi::RawValue(1))); // Right operand. | |
| 1139 GenerateBinaryOperatorCall(node->operator_id(), | |
| 1140 node->token_index(), | |
| 1141 operator_name); | |
| 1142 __ popq(RDX); // Restore receiver. | |
| 1143 if (IsResultNeeded(node) && node->prefix()) { | |
| 1144 // Value stored into field is the result. | |
| 1145 __ pushq(RAX); | |
| 1146 } | |
| 1147 __ pushq(RDX); // Receiver. | |
| 1148 __ pushq(RAX); // Value. | |
| 1149 // It is not necessary to generate a type test of the assigned value here, | |
| 1150 // because the setter will check the type of its incoming arguments. | |
| 1151 GenerateInstanceSetterCall(node->setter_id(), | |
| 1152 node->token_index(), | |
| 1153 node->field_name()); | |
| 1154 } | |
| 1155 | |
| 1156 | |
| 1157 void CodeGenerator::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | |
| 1158 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | |
| 1159 node->array()->Visit(this); | |
| 1160 node->index()->Visit(this); | |
| 1161 MarkDeoptPoint(node->id(), node->token_index()); | |
| 1162 // Preserve array and index for GenerateStoreIndex. | |
| 1163 __ pushq(Address(RSP, kWordSize)); // Copy array. | |
| 1164 __ pushq(Address(RSP, kWordSize)); // Copy index. | |
| 1165 GenerateLoadIndexed(node->load_id(), node->token_index()); | |
| 1166 // Result is in RAX. | |
| 1167 if (!node->prefix() && IsResultNeeded(node)) { | |
| 1168 // Preserve RAX as result. | |
| 1169 __ popq(RDX); // Preserved index -> RDX. | |
| 1170 __ popq(RCX); // Preserved array -> RCX. | |
| 1171 __ pushq(RAX); // Preserve original value from indexed load. | |
| 1172 __ pushq(RCX); // Array. | |
| 1173 __ pushq(RDX); // Index. | |
| 1174 } | |
| 1175 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; | |
| 1176 __ pushq(RAX); // Left operand. | |
| 1177 __ pushq(Immediate(Smi::RawValue(1))); // Right operand. | |
| 1178 GenerateBinaryOperatorCall(node->operator_id(), | |
| 1179 node->token_index(), | |
| 1180 operator_name); | |
| 1181 __ pushq(RAX); | |
| 1182 // TOS(0): value, TOS(1): index, TOS(2): array. | |
| 1183 GenerateStoreIndexed(node->store_id(), | |
| 1184 node->token_index(), | |
| 1185 node->prefix() && IsResultNeeded(node)); | |
| 1186 } | |
| 1187 | |
| 1188 | |
| 1189 static const Class* CoreClass(const char* c_name) { | 1118 static const Class* CoreClass(const char* c_name) { |
| 1190 const String& class_name = String::Handle(String::NewSymbol(c_name)); | 1119 const String& class_name = String::Handle(String::NewSymbol(c_name)); |
| 1191 const Class& cls = Class::ZoneHandle(Library::Handle( | 1120 const Class& cls = Class::ZoneHandle(Library::Handle( |
| 1192 Library::CoreImplLibrary()).LookupClass(class_name)); | 1121 Library::CoreImplLibrary()).LookupClass(class_name)); |
| 1193 ASSERT(!cls.IsNull()); | 1122 ASSERT(!cls.IsNull()); |
| 1194 return &cls; | 1123 return &cls; |
| 1195 } | 1124 } |
| 1196 | 1125 |
| 1197 | 1126 |
| 1198 // If instanceof type test cannot be performed successfully at compile time and | 1127 // If instanceof type test cannot be performed successfully at compile time and |
| (...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2729 const Error& error = Error::Handle( | 2658 const Error& error = Error::Handle( |
| 2730 Parser::FormatError(script, token_index, "Error", format, args)); | 2659 Parser::FormatError(script, token_index, "Error", format, args)); |
| 2731 va_end(args); | 2660 va_end(args); |
| 2732 Isolate::Current()->long_jump_base()->Jump(1, error); | 2661 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2733 UNREACHABLE(); | 2662 UNREACHABLE(); |
| 2734 } | 2663 } |
| 2735 | 2664 |
| 2736 } // namespace dart | 2665 } // namespace dart |
| 2737 | 2666 |
| 2738 #endif // defined TARGET_ARCH_X64 | 2667 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |