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

Unified 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, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator_x64.cc
===================================================================
--- runtime/vm/code_generator_x64.cc (revision 7210)
+++ runtime/vm/code_generator_x64.cc (working copy)
@@ -1123,10 +1123,9 @@
// Preserve as result.
__ pushq(RAX);
}
- const Immediate value = Immediate(reinterpret_cast<int64_t>(Smi::New(1)));
const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
__ pushq(RAX);
- __ pushq(value);
+ __ pushq(Immediate(Smi::RawValue(1)));
GenerateBinaryOperatorCall(node->id(), node->token_index(), operator_name);
// result is in RAX.
if (FLAG_enable_type_checks) {
@@ -1158,13 +1157,12 @@
// Preserve as result.
__ pushq(RAX); // Preserve value as result.
}
- const Immediate one_value = Immediate(reinterpret_cast<int64_t>(Smi::New(1)));
const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
// RAX: Value.
// RDX: Receiver.
__ pushq(RDX); // Preserve receiver.
__ pushq(RAX); // Left operand.
- __ pushq(one_value); // Right operand.
+ __ pushq(Immediate(Smi::RawValue(1))); // Right operand.
GenerateBinaryOperatorCall(node->operator_id(),
node->token_index(),
operator_name);
@@ -1201,10 +1199,9 @@
__ pushq(RCX); // Array.
__ pushq(RDX); // Index.
}
- const Immediate value = Immediate(reinterpret_cast<int64_t>(Smi::New(1)));
const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
__ pushq(RAX); // Left operand.
- __ pushq(value); // Right operand.
+ __ pushq(Immediate(Smi::RawValue(1))); // Right operand.
GenerateBinaryOperatorCall(node->operator_id(),
node->token_index(),
operator_name);
@@ -1382,10 +1379,8 @@
}
}
__ PushObject(Object::ZoneHandle()); // Make room for the result.
- const Immediate location =
- Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
- const Immediate node_id_as_smi =
- Immediate(reinterpret_cast<int64_t>(Smi::New(node_id)));
+ const Immediate location = Immediate(Smi::RawValue(token_index));
+ const Immediate node_id_as_smi = Immediate(Smi::RawValue(node_id));
__ pushq(location); // Push the source location.
__ pushq(node_id_as_smi);
__ pushq(RAX); // Push the instance.
@@ -1493,9 +1488,7 @@
const String& error_message = String::ZoneHandle(
String::NewSymbol(error.ToErrorCString()));
__ PushObject(Object::ZoneHandle()); // Make room for the result.
- const Immediate location =
- Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
- __ pushq(location); // Push the source location.
+ __ pushq(Immediate(Smi::RawValue(token_index))); // Source location.
__ pushq(RAX); // Push the source object.
__ PushObject(dst_name); // Push the name of the destination.
__ PushObject(error_message);
@@ -1610,12 +1603,8 @@
}
__ Bind(&runtime_call);
__ PushObject(Object::ZoneHandle()); // Make room for the result.
- const Immediate location =
- Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
- const Immediate node_id_as_smi =
- Immediate(reinterpret_cast<int64_t>(Smi::New(node_id)));
- __ pushq(location); // Push the source location.
- __ pushq(node_id_as_smi); // node-id.
+ __ pushq(Immediate(Smi::RawValue(token_index))); // Source location.
+ __ pushq(Immediate(Smi::RawValue(node_id))); // node-id.
__ pushq(RAX); // Push the source object.
__ PushObject(dst_type); // Push the type of the destination.
if (!dst_type.IsInstantiated()) {
@@ -1680,9 +1669,7 @@
__ j(EQUAL, &done, Assembler::kNearJump);
__ Bind(&runtime_call);
- const Immediate location =
- Immediate(reinterpret_cast<int64_t>(Smi::New(token_index)));
- __ pushq(location); // Push the source location.
+ __ pushq(Immediate(Smi::RawValue(token_index))); // Source location.
__ pushq(RAX); // Push the source object.
GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry);
// We should never return here.
@@ -2315,8 +2302,8 @@
__ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
__ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
__ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
- Immediate arguments_length = Immediate(reinterpret_cast<int64_t>(
- Smi::New(node->type_arguments().Length())));
+ Immediate arguments_length =
+ Immediate(Smi::RawValue(node->type_arguments().Length()));
__ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
arguments_length);
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
@@ -2382,12 +2369,46 @@
// If cls is parameterized, the type arguments and the instantiator's
// type arguments are on the stack.
- const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
- const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
- GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
- if (requires_type_arguments) {
+ // In checked mode, if the type arguments are uninstantiated, they may need to
+ // be checked against declared bounds at run time.
+ Error& malformed_error = Error::Handle();
+ if (FLAG_enable_type_checks &&
+ requires_type_arguments &&
+ !node->type_arguments().IsNull() &&
+ !node->type_arguments().IsInstantiated() &&
+ !node->type_arguments().IsWithinBoundsOf(cls,
+ node->type_arguments(),
+ &malformed_error)) {
+ // The uninstantiated type arguments cannot be verified to be within their
+ // bounds at compile time, so verify them at runtime.
+ // Although the type arguments may be uninstantiated at compile time, they
+ // may represent the identity vector and may be replaced by the instantiated
+ // type arguments of the instantiator at run time.
+ __ popq(RCX); // Pop instantiator type arguments.
+ __ popq(RAX); // Pop type arguments.
+
+ // Push the result place holder initialized to NULL.
+ __ PushObject(Object::ZoneHandle());
+ __ pushq(Immediate(Smi::RawValue(node->token_index())));
+ __ PushObject(cls);
+ __ pushq(RAX); // Push type arguments.
+ __ pushq(RCX); // Push instantiator type arguments.
+ GenerateCallRuntime(node->id(),
+ node->token_index(),
+ kAllocateObjectWithBoundsCheckRuntimeEntry);
+ __ popq(RCX); // Pop instantiator type arguments.
__ popq(RCX); // Pop type arguments.
- __ popq(RCX); // Pop instantiator type arguments.
+ __ popq(RCX); // Pop class.
+ __ popq(RCX); // Pop source location.
+ __ popq(RAX); // Pop new instance.
+ } else {
+ const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
+ const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
+ GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
+ if (requires_type_arguments) {
+ __ popq(RCX); // Pop instantiator type arguments.
+ __ popq(RCX); // Pop type arguments.
+ }
}
if (IsResultNeeded(node)) {
« 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