| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 operator_name, | 1172 operator_name, |
| 1173 kNumberOfArguments, | 1173 kNumberOfArguments, |
| 1174 kNoArgumentNames, | 1174 kNoArgumentNames, |
| 1175 kNumArgumentsChecked); | 1175 kNumArgumentsChecked); |
| 1176 if (IsResultNeeded(node)) { | 1176 if (IsResultNeeded(node)) { |
| 1177 __ pushl(EAX); | 1177 __ pushl(EAX); |
| 1178 } | 1178 } |
| 1179 } | 1179 } |
| 1180 | 1180 |
| 1181 | 1181 |
| 1182 void CodeGenerator::VisitIncrOpInstanceFieldNode( | |
| 1183 IncrOpInstanceFieldNode* node) { | |
| 1184 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | |
| 1185 node->receiver()->Visit(this); | |
| 1186 __ pushl(Address(ESP, 0)); // Duplicate receiver (preserve for setter). | |
| 1187 MarkDeoptPoint(node->getter_id(), node->token_index()); | |
| 1188 GenerateInstanceGetterCall(node->getter_id(), | |
| 1189 node->token_index(), | |
| 1190 node->field_name()); | |
| 1191 // result is in EAX. | |
| 1192 __ popl(EDX); // Get receiver. | |
| 1193 if (!node->prefix() && IsResultNeeded(node)) { | |
| 1194 // Preserve as result. | |
| 1195 __ pushl(EAX); // Preserve value as result. | |
| 1196 } | |
| 1197 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; | |
| 1198 // EAX: Value. | |
| 1199 // EDX: Receiver. | |
| 1200 __ pushl(EDX); // Preserve receiver. | |
| 1201 __ pushl(EAX); // Left operand. | |
| 1202 __ pushl(Immediate(Smi::RawValue(1))); // Right operand. | |
| 1203 GenerateBinaryOperatorCall(node->operator_id(), | |
| 1204 node->token_index(), | |
| 1205 operator_name); | |
| 1206 __ popl(EDX); // Restore receiver. | |
| 1207 if (IsResultNeeded(node) && node->prefix()) { | |
| 1208 // Value stored into field is the result. | |
| 1209 __ pushl(EAX); | |
| 1210 } | |
| 1211 __ pushl(EDX); // Receiver. | |
| 1212 __ pushl(EAX); // Value. | |
| 1213 // It is not necessary to generate a type test of the assigned value here, | |
| 1214 // because the setter will check the type of its incoming arguments. | |
| 1215 GenerateInstanceSetterCall(node->setter_id(), | |
| 1216 node->token_index(), | |
| 1217 node->field_name()); | |
| 1218 } | |
| 1219 | |
| 1220 | |
| 1221 void CodeGenerator::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | |
| 1222 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | |
| 1223 node->array()->Visit(this); | |
| 1224 node->index()->Visit(this); | |
| 1225 MarkDeoptPoint(node->id(), node->token_index()); | |
| 1226 // Preserve array and index for GenerateStoreIndex. | |
| 1227 __ pushl(Address(ESP, kWordSize)); // Copy array. | |
| 1228 __ pushl(Address(ESP, kWordSize)); // Copy index. | |
| 1229 GenerateLoadIndexed(node->load_id(), node->token_index()); | |
| 1230 // Result is in EAX. | |
| 1231 if (!node->prefix() && IsResultNeeded(node)) { | |
| 1232 // Preserve EAX as result. | |
| 1233 __ popl(EDX); // Preserved index -> EDX. | |
| 1234 __ popl(ECX); // Preserved array -> ECX. | |
| 1235 __ pushl(EAX); // Preserve original value from indexed load. | |
| 1236 __ pushl(ECX); // Array. | |
| 1237 __ pushl(EDX); // Index. | |
| 1238 } | |
| 1239 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; | |
| 1240 __ pushl(EAX); // Left operand. | |
| 1241 __ pushl(Immediate(Smi::RawValue(1))); // Right operand. | |
| 1242 GenerateBinaryOperatorCall(node->operator_id(), | |
| 1243 node->token_index(), | |
| 1244 operator_name); | |
| 1245 __ pushl(EAX); | |
| 1246 // TOS(0): value, TOS(1): index, TOS(2): array. | |
| 1247 GenerateStoreIndexed(node->store_id(), | |
| 1248 node->token_index(), | |
| 1249 node->prefix() && IsResultNeeded(node)); | |
| 1250 } | |
| 1251 | |
| 1252 | |
| 1253 static const Class* CoreClass(const char* c_name) { | 1182 static const Class* CoreClass(const char* c_name) { |
| 1254 const String& class_name = String::Handle(String::NewSymbol(c_name)); | 1183 const String& class_name = String::Handle(String::NewSymbol(c_name)); |
| 1255 const Class& cls = Class::ZoneHandle(Library::Handle( | 1184 const Class& cls = Class::ZoneHandle(Library::Handle( |
| 1256 Library::CoreImplLibrary()).LookupClass(class_name)); | 1185 Library::CoreImplLibrary()).LookupClass(class_name)); |
| 1257 ASSERT(!cls.IsNull()); | 1186 ASSERT(!cls.IsNull()); |
| 1258 return &cls; | 1187 return &cls; |
| 1259 } | 1188 } |
| 1260 | 1189 |
| 1261 | 1190 |
| 1262 // Instance to test is in EAX. Test if its class is in subtype test cache array | 1191 // Instance to test is in EAX. Test if its class is in subtype test cache array |
| (...skipping 1702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2965 const Error& error = Error::Handle( | 2894 const Error& error = Error::Handle( |
| 2966 Parser::FormatError(script, token_index, "Error", format, args)); | 2895 Parser::FormatError(script, token_index, "Error", format, args)); |
| 2967 va_end(args); | 2896 va_end(args); |
| 2968 Isolate::Current()->long_jump_base()->Jump(1, error); | 2897 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2969 UNREACHABLE(); | 2898 UNREACHABLE(); |
| 2970 } | 2899 } |
| 2971 | 2900 |
| 2972 } // namespace dart | 2901 } // namespace dart |
| 2973 | 2902 |
| 2974 #endif // defined TARGET_ARCH_IA32 | 2903 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |