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

Side by Side Diff: runtime/vm/code_generator_x64.cc

Issue 10280007: Check upper bounds of type arguments when allocating objects of a generic type (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/flow_graph_builder.cc » ('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 (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 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 1116
1117 1117
1118 void CodeGenerator::VisitIncrOpLocalNode(IncrOpLocalNode* node) { 1118 void CodeGenerator::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
1119 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); 1119 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
1120 MarkDeoptPoint(node->id(), node->token_index()); 1120 MarkDeoptPoint(node->id(), node->token_index());
1121 GenerateLoadVariable(RAX, node->local()); 1121 GenerateLoadVariable(RAX, node->local());
1122 if (!node->prefix() && IsResultNeeded(node)) { 1122 if (!node->prefix() && IsResultNeeded(node)) {
1123 // Preserve as result. 1123 // Preserve as result.
1124 __ pushq(RAX); 1124 __ pushq(RAX);
1125 } 1125 }
1126 const Immediate value = Immediate(reinterpret_cast<int64_t>(Smi::New(1)));
1127 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; 1126 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
1128 __ pushq(RAX); 1127 __ pushq(RAX);
1129 __ pushq(value); 1128 __ pushq(Immediate(Smi::RawValue(1)));
1130 GenerateBinaryOperatorCall(node->id(), node->token_index(), operator_name); 1129 GenerateBinaryOperatorCall(node->id(), node->token_index(), operator_name);
1131 // result is in RAX. 1130 // result is in RAX.
1132 if (FLAG_enable_type_checks) { 1131 if (FLAG_enable_type_checks) {
1133 GenerateAssertAssignable(node->id(), 1132 GenerateAssertAssignable(node->id(),
1134 node->token_index(), 1133 node->token_index(),
1135 NULL, 1134 NULL,
1136 node->local().type(), 1135 node->local().type(),
1137 node->local().name()); 1136 node->local().name());
1138 } 1137 }
1139 GenerateStoreVariable(node->local(), RAX, RDX); 1138 GenerateStoreVariable(node->local(), RAX, RDX);
(...skipping 11 matching lines...) Expand all
1151 MarkDeoptPoint(node->getter_id(), node->token_index()); 1150 MarkDeoptPoint(node->getter_id(), node->token_index());
1152 GenerateInstanceGetterCall(node->getter_id(), 1151 GenerateInstanceGetterCall(node->getter_id(),
1153 node->token_index(), 1152 node->token_index(),
1154 node->field_name()); 1153 node->field_name());
1155 // result is in RAX. 1154 // result is in RAX.
1156 __ popq(RDX); // Get receiver. 1155 __ popq(RDX); // Get receiver.
1157 if (!node->prefix() && IsResultNeeded(node)) { 1156 if (!node->prefix() && IsResultNeeded(node)) {
1158 // Preserve as result. 1157 // Preserve as result.
1159 __ pushq(RAX); // Preserve value as result. 1158 __ pushq(RAX); // Preserve value as result.
1160 } 1159 }
1161 const Immediate one_value = Immediate(reinterpret_cast<int64_t>(Smi::New(1)));
1162 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; 1160 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
1163 // RAX: Value. 1161 // RAX: Value.
1164 // RDX: Receiver. 1162 // RDX: Receiver.
1165 __ pushq(RDX); // Preserve receiver. 1163 __ pushq(RDX); // Preserve receiver.
1166 __ pushq(RAX); // Left operand. 1164 __ pushq(RAX); // Left operand.
1167 __ pushq(one_value); // Right operand. 1165 __ pushq(Immediate(Smi::RawValue(1))); // Right operand.
1168 GenerateBinaryOperatorCall(node->operator_id(), 1166 GenerateBinaryOperatorCall(node->operator_id(),
1169 node->token_index(), 1167 node->token_index(),
1170 operator_name); 1168 operator_name);
1171 __ popq(RDX); // Restore receiver. 1169 __ popq(RDX); // Restore receiver.
1172 if (IsResultNeeded(node) && node->prefix()) { 1170 if (IsResultNeeded(node) && node->prefix()) {
1173 // Value stored into field is the result. 1171 // Value stored into field is the result.
1174 __ pushq(RAX); 1172 __ pushq(RAX);
1175 } 1173 }
1176 __ pushq(RDX); // Receiver. 1174 __ pushq(RDX); // Receiver.
1177 __ pushq(RAX); // Value. 1175 __ pushq(RAX); // Value.
(...skipping 16 matching lines...) Expand all
1194 GenerateLoadIndexed(node->load_id(), node->token_index()); 1192 GenerateLoadIndexed(node->load_id(), node->token_index());
1195 // Result is in RAX. 1193 // Result is in RAX.
1196 if (!node->prefix() && IsResultNeeded(node)) { 1194 if (!node->prefix() && IsResultNeeded(node)) {
1197 // Preserve RAX as result. 1195 // Preserve RAX as result.
1198 __ popq(RDX); // Preserved index -> RDX. 1196 __ popq(RDX); // Preserved index -> RDX.
1199 __ popq(RCX); // Preserved array -> RCX. 1197 __ popq(RCX); // Preserved array -> RCX.
1200 __ pushq(RAX); // Preserve original value from indexed load. 1198 __ pushq(RAX); // Preserve original value from indexed load.
1201 __ pushq(RCX); // Array. 1199 __ pushq(RCX); // Array.
1202 __ pushq(RDX); // Index. 1200 __ pushq(RDX); // Index.
1203 } 1201 }
1204 const Immediate value = Immediate(reinterpret_cast<int64_t>(Smi::New(1)));
1205 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-"; 1202 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
1206 __ pushq(RAX); // Left operand. 1203 __ pushq(RAX); // Left operand.
1207 __ pushq(value); // Right operand. 1204 __ pushq(Immediate(Smi::RawValue(1))); // Right operand.
1208 GenerateBinaryOperatorCall(node->operator_id(), 1205 GenerateBinaryOperatorCall(node->operator_id(),
1209 node->token_index(), 1206 node->token_index(),
1210 operator_name); 1207 operator_name);
1211 __ pushq(RAX); 1208 __ pushq(RAX);
1212 // TOS(0): value, TOS(1): index, TOS(2): array. 1209 // TOS(0): value, TOS(1): index, TOS(2): array.
1213 GenerateStoreIndexed(node->store_id(), 1210 GenerateStoreIndexed(node->store_id(),
1214 node->token_index(), 1211 node->token_index(),
1215 node->prefix() && IsResultNeeded(node)); 1212 node->prefix() && IsResultNeeded(node));
1216 } 1213 }
1217 1214
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1372 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1376 __ CompareObject(RCX, *compare_class); 1373 __ CompareObject(RCX, *compare_class);
1377 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); 1374 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump);
1378 __ PushObject(negate_result ? bool_false : bool_true); 1375 __ PushObject(negate_result ? bool_false : bool_true);
1379 __ jmp(&done, Assembler::kNearJump); 1376 __ jmp(&done, Assembler::kNearJump);
1380 __ Bind(&runtime_call); 1377 __ Bind(&runtime_call);
1381 } 1378 }
1382 } 1379 }
1383 } 1380 }
1384 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1381 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1385 const Immediate location = 1382 const Immediate location = Immediate(Smi::RawValue(token_index));
1386 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index))); 1383 const Immediate node_id_as_smi = Immediate(Smi::RawValue(node_id));
1387 const Immediate node_id_as_smi =
1388 Immediate(reinterpret_cast<int64_t>(Smi::New(node_id)));
1389 __ pushq(location); // Push the source location. 1384 __ pushq(location); // Push the source location.
1390 __ pushq(node_id_as_smi); 1385 __ pushq(node_id_as_smi);
1391 __ pushq(RAX); // Push the instance. 1386 __ pushq(RAX); // Push the instance.
1392 __ PushObject(type); // Push the type. 1387 __ PushObject(type); // Push the type.
1393 if (!type.IsInstantiated()) { 1388 if (!type.IsInstantiated()) {
1394 GenerateInstantiatorTypeArguments(token_index); 1389 GenerateInstantiatorTypeArguments(token_index);
1395 } else { 1390 } else {
1396 __ pushq(raw_null); // Null instantiator. 1391 __ pushq(raw_null); // Null instantiator.
1397 } 1392 }
1398 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry); 1393 GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 Label done, runtime_call; 1481 Label done, runtime_call;
1487 __ cmpq(RAX, raw_null); 1482 __ cmpq(RAX, raw_null);
1488 __ j(EQUAL, &done); 1483 __ j(EQUAL, &done);
1489 1484
1490 // Generate throw new TypeError() if the type is malformed. 1485 // Generate throw new TypeError() if the type is malformed.
1491 if (dst_type.IsMalformed()) { 1486 if (dst_type.IsMalformed()) {
1492 const Error& error = Error::Handle(dst_type.malformed_error()); 1487 const Error& error = Error::Handle(dst_type.malformed_error());
1493 const String& error_message = String::ZoneHandle( 1488 const String& error_message = String::ZoneHandle(
1494 String::NewSymbol(error.ToErrorCString())); 1489 String::NewSymbol(error.ToErrorCString()));
1495 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1490 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1496 const Immediate location = 1491 __ pushq(Immediate(Smi::RawValue(token_index))); // Source location.
1497 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
1498 __ pushq(location); // Push the source location.
1499 __ pushq(RAX); // Push the source object. 1492 __ pushq(RAX); // Push the source object.
1500 __ PushObject(dst_name); // Push the name of the destination. 1493 __ PushObject(dst_name); // Push the name of the destination.
1501 __ PushObject(error_message); 1494 __ PushObject(error_message);
1502 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry); 1495 GenerateCallRuntime(node_id, token_index, kMalformedTypeErrorRuntimeEntry);
1503 // We should never return here. 1496 // We should never return here.
1504 __ int3(); 1497 __ int3();
1505 1498
1506 __ Bind(&done); // For a null object. 1499 __ Bind(&done); // For a null object.
1507 return; 1500 return;
1508 } 1501 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1596 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1604 __ movq(RCX, FieldAddress(RCX, Class::signature_function_offset())); 1597 __ movq(RCX, FieldAddress(RCX, Class::signature_function_offset()));
1605 __ cmpq(RCX, raw_null); 1598 __ cmpq(RCX, raw_null);
1606 __ j(NOT_EQUAL, &done); 1599 __ j(NOT_EQUAL, &done);
1607 } 1600 }
1608 } 1601 }
1609 } 1602 }
1610 } 1603 }
1611 __ Bind(&runtime_call); 1604 __ Bind(&runtime_call);
1612 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1605 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1613 const Immediate location = 1606 __ pushq(Immediate(Smi::RawValue(token_index))); // Source location.
1614 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index))); 1607 __ pushq(Immediate(Smi::RawValue(node_id))); // node-id.
1615 const Immediate node_id_as_smi =
1616 Immediate(reinterpret_cast<int64_t>(Smi::New(node_id)));
1617 __ pushq(location); // Push the source location.
1618 __ pushq(node_id_as_smi); // node-id.
1619 __ pushq(RAX); // Push the source object. 1608 __ pushq(RAX); // Push the source object.
1620 __ PushObject(dst_type); // Push the type of the destination. 1609 __ PushObject(dst_type); // Push the type of the destination.
1621 if (!dst_type.IsInstantiated()) { 1610 if (!dst_type.IsInstantiated()) {
1622 GenerateInstantiatorTypeArguments(token_index); 1611 GenerateInstantiatorTypeArguments(token_index);
1623 } else { 1612 } else {
1624 __ pushq(raw_null); // Null instantiator. 1613 __ pushq(raw_null); // Null instantiator.
1625 } 1614 }
1626 __ PushObject(dst_name); // Push the name of the destination. 1615 __ PushObject(dst_name); // Push the name of the destination.
1627 GenerateCallRuntime(node_id, token_index, kTypeCheckRuntimeEntry); 1616 GenerateCallRuntime(node_id, token_index, kTypeCheckRuntimeEntry);
1628 // Pop the parameters supplied to the runtime entry. The result of the 1617 // Pop the parameters supplied to the runtime entry. The result of the
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 // This check should pass if the receiver's class implements the interface 1662 // This check should pass if the receiver's class implements the interface
1674 // 'bool'. Check only class 'Bool' since it is the only legal implementation 1663 // 'bool'. Check only class 'Bool' since it is the only legal implementation
1675 // of the interface 'bool'. 1664 // of the interface 'bool'.
1676 const Class& bool_class = 1665 const Class& bool_class =
1677 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class()); 1666 Class::ZoneHandle(Isolate::Current()->object_store()->bool_class());
1678 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1667 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1679 __ CompareObject(RCX, bool_class); 1668 __ CompareObject(RCX, bool_class);
1680 __ j(EQUAL, &done, Assembler::kNearJump); 1669 __ j(EQUAL, &done, Assembler::kNearJump);
1681 1670
1682 __ Bind(&runtime_call); 1671 __ Bind(&runtime_call);
1683 const Immediate location = 1672 __ pushq(Immediate(Smi::RawValue(token_index))); // Source location.
1684 Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
1685 __ pushq(location); // Push the source location.
1686 __ pushq(RAX); // Push the source object. 1673 __ pushq(RAX); // Push the source object.
1687 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry); 1674 GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry);
1688 // We should never return here. 1675 // We should never return here.
1689 __ int3(); 1676 __ int3();
1690 1677
1691 __ Bind(&done); 1678 __ Bind(&done);
1692 } 1679 }
1693 1680
1694 1681
1695 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) { 1682 void CodeGenerator::VisitComparisonNode(ComparisonNode* node) {
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 // Instantiate non-null type arguments. 2295 // Instantiate non-null type arguments.
2309 if (node->type_arguments().IsUninstantiatedIdentity()) { 2296 if (node->type_arguments().IsUninstantiatedIdentity()) {
2310 // Check if the instantiator type argument vector is a TypeArguments of a 2297 // Check if the instantiator type argument vector is a TypeArguments of a
2311 // matching length and, if so, use it as the instantiated type_arguments. 2298 // matching length and, if so, use it as the instantiated type_arguments.
2312 // No need to check RAX for null (again), because a null instance will 2299 // No need to check RAX for null (again), because a null instance will
2313 // have the wrong class (Null instead of TypeArguments). 2300 // have the wrong class (Null instead of TypeArguments).
2314 Label type_arguments_uninstantiated; 2301 Label type_arguments_uninstantiated;
2315 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 2302 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
2316 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 2303 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
2317 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 2304 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
2318 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>( 2305 Immediate arguments_length =
2319 Smi::New(node->type_arguments().Length()))); 2306 Immediate(Smi::RawValue(node->type_arguments().Length()));
2320 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 2307 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
2321 arguments_length); 2308 arguments_length);
2322 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2309 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2323 __ Bind(&type_arguments_uninstantiated); 2310 __ Bind(&type_arguments_uninstantiated);
2324 } 2311 }
2325 if (node->constructor().IsFactory()) { 2312 if (node->constructor().IsFactory()) {
2326 // A runtime call to instantiate the type arguments is required before 2313 // A runtime call to instantiate the type arguments is required before
2327 // calling the factory. 2314 // calling the factory.
2328 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2315 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2329 __ PushObject(node->type_arguments()); 2316 __ PushObject(node->type_arguments());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2375 } 2362 }
2376 return; 2363 return;
2377 } 2364 }
2378 2365
2379 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 2366 const Class& cls = Class::ZoneHandle(node->constructor().owner());
2380 const bool requires_type_arguments = cls.HasTypeArguments(); 2367 const bool requires_type_arguments = cls.HasTypeArguments();
2381 GenerateTypeArguments(node, requires_type_arguments); 2368 GenerateTypeArguments(node, requires_type_arguments);
2382 2369
2383 // If cls is parameterized, the type arguments and the instantiator's 2370 // If cls is parameterized, the type arguments and the instantiator's
2384 // type arguments are on the stack. 2371 // type arguments are on the stack.
2385 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); 2372 // In checked mode, if the type arguments are uninstantiated, they may need to
2386 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); 2373 // be checked against declared bounds at run time.
2387 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); 2374 Error& malformed_error = Error::Handle();
2388 if (requires_type_arguments) { 2375 if (FLAG_enable_type_checks &&
2376 requires_type_arguments &&
2377 !node->type_arguments().IsNull() &&
2378 !node->type_arguments().IsInstantiated() &&
2379 !node->type_arguments().IsWithinBoundsOf(cls,
2380 node->type_arguments(),
2381 &malformed_error)) {
2382 // The uninstantiated type arguments cannot be verified to be within their
2383 // bounds at compile time, so verify them at runtime.
2384 // Although the type arguments may be uninstantiated at compile time, they
2385 // may represent the identity vector and may be replaced by the instantiated
2386 // type arguments of the instantiator at run time.
2387 __ popq(RCX); // Pop instantiator type arguments.
2388 __ popq(RAX); // Pop type arguments.
2389
2390 // Push the result place holder initialized to NULL.
2391 __ PushObject(Object::ZoneHandle());
2392 __ pushq(Immediate(Smi::RawValue(node->token_index())));
2393 __ PushObject(cls);
2394 __ pushq(RAX); // Push type arguments.
2395 __ pushq(RCX); // Push instantiator type arguments.
2396 GenerateCallRuntime(node->id(),
2397 node->token_index(),
2398 kAllocateObjectWithBoundsCheckRuntimeEntry);
2399 __ popq(RCX); // Pop instantiator type arguments.
2389 __ popq(RCX); // Pop type arguments. 2400 __ popq(RCX); // Pop type arguments.
2390 __ popq(RCX); // Pop instantiator type arguments. 2401 __ popq(RCX); // Pop class.
2402 __ popq(RCX); // Pop source location.
2403 __ popq(RAX); // Pop new instance.
2404 } else {
2405 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
2406 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
2407 GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
2408 if (requires_type_arguments) {
2409 __ popq(RCX); // Pop instantiator type arguments.
2410 __ popq(RCX); // Pop type arguments.
2411 }
2391 } 2412 }
2392 2413
2393 if (IsResultNeeded(node)) { 2414 if (IsResultNeeded(node)) {
2394 __ pushq(RAX); // Set up return value from allocate. 2415 __ pushq(RAX); // Set up return value from allocate.
2395 } 2416 }
2396 2417
2397 // First argument(this) for constructor call which follows. 2418 // First argument(this) for constructor call which follows.
2398 __ pushq(RAX); 2419 __ pushq(RAX);
2399 // Second argument is the implicit construction phase parameter. 2420 // Second argument is the implicit construction phase parameter.
2400 // Run both the constructor initializer list and the constructor body. 2421 // Run both the constructor initializer list and the constructor body.
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
2735 const Error& error = Error::Handle( 2756 const Error& error = Error::Handle(
2736 Parser::FormatError(script, token_index, "Error", format, args)); 2757 Parser::FormatError(script, token_index, "Error", format, args));
2737 va_end(args); 2758 va_end(args);
2738 Isolate::Current()->long_jump_base()->Jump(1, error); 2759 Isolate::Current()->long_jump_base()->Jump(1, error);
2739 UNREACHABLE(); 2760 UNREACHABLE();
2740 } 2761 }
2741 2762
2742 } // namespace dart 2763 } // namespace dart
2743 2764
2744 #endif // defined TARGET_ARCH_X64 2765 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698