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

Unified Diff: runtime/vm/code_generator_ia32.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
Index: runtime/vm/code_generator_ia32.cc
===================================================================
--- runtime/vm/code_generator_ia32.cc (revision 7209)
+++ runtime/vm/code_generator_ia32.cc (working copy)
@@ -1183,10 +1183,9 @@
// Preserve as result.
__ pushl(EAX);
}
- const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1)));
const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
__ pushl(EAX);
- __ pushl(value);
+ __ pushl(Immediate(Smi::RawValue(1)));
GenerateBinaryOperatorCall(node->id(), node->token_index(), operator_name);
// result is in EAX.
if (FLAG_enable_type_checks) {
@@ -1218,13 +1217,12 @@
// Preserve as result.
__ pushl(EAX); // Preserve value as result.
}
- const Immediate one_value = Immediate(reinterpret_cast<int32_t>(Smi::New(1)));
const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
// EAX: Value.
// EDX: Receiver.
__ pushl(EDX); // Preserve receiver.
__ pushl(EAX); // Left operand.
- __ pushl(one_value); // Right operand.
+ __ pushl(Immediate(Smi::RawValue(1))); // Right operand.
GenerateBinaryOperatorCall(node->operator_id(),
node->token_index(),
operator_name);
@@ -1261,10 +1259,9 @@
__ pushl(ECX); // Array.
__ pushl(EDX); // Index.
}
- const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1)));
const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
__ pushl(EAX); // Left operand.
- __ pushl(value); // Right operand.
+ __ pushl(Immediate(Smi::RawValue(1))); // Right operand.
GenerateBinaryOperatorCall(node->operator_id(),
node->token_index(),
operator_name);
@@ -1459,10 +1456,8 @@
&is_instance_of, &is_not_instance_of);
__ PushObject(Object::ZoneHandle()); // Make room for the result.
- const Immediate location =
- Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
- const Immediate node_id_as_smi =
- Immediate(reinterpret_cast<int32_t>(Smi::New(node_id)));
+ const Immediate location = Immediate(Smi::RawValue(token_index));
+ const Immediate node_id_as_smi = Immediate(Smi::RawValue(node_id));
__ pushl(location); // Push the source location.
__ pushl(node_id_as_smi); // node-id.
__ pushl(EAX); // Push the instance.
@@ -1824,9 +1819,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<int32_t>(Smi::New(token_index)));
- __ pushl(location); // Push the source location.
+ __ pushl(Immediate(Smi::RawValue(token_index))); // Source location.
__ pushl(EAX); // Push the source object.
__ PushObject(dst_name); // Push the name of the destination.
__ PushObject(error_message);
@@ -1843,12 +1836,8 @@
__ Bind(&runtime_call);
__ PushObject(Object::ZoneHandle()); // Make room for the result.
- const Immediate location =
- Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
- const Immediate node_id_as_smi =
- Immediate(reinterpret_cast<int32_t>(Smi::New(node_id)));
- __ pushl(location); // Push the source location.
- __ pushl(node_id_as_smi); // node-id.
+ __ pushl(Immediate(Smi::RawValue(token_index))); // Source location.
+ __ pushl(Immediate(Smi::RawValue(node_id))); // node-id.
__ pushl(EAX); // Push the source object.
__ PushObject(dst_type); // Push the type of the destination.
if (dst_type.IsInstantiated()) {
@@ -1914,9 +1903,7 @@
__ j(EQUAL, &done, Assembler::kNearJump);
__ Bind(&runtime_call);
- const Immediate location =
- Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
- __ pushl(location); // Push the source location.
+ __ pushl(Immediate(Smi::RawValue(token_index))); // Source location.
__ pushl(EAX); // Push the source object.
GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry);
// We should never return here.
@@ -2550,8 +2537,8 @@
__ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class()));
__ cmpl(ECX, FieldAddress(EAX, Object::class_offset()));
__ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
- Immediate arguments_length = Immediate(reinterpret_cast<int32_t>(
- Smi::New(node->type_arguments().Length())));
+ Immediate arguments_length =
+ Immediate(Smi::RawValue(node->type_arguments().Length()));
__ cmpl(FieldAddress(EAX, TypeArguments::length_offset()),
arguments_length);
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
@@ -2617,12 +2604,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.
+ __ popl(ECX); // Pop instantiator type arguments.
+ __ popl(EAX); // Pop type arguments.
+
+ // Push the result place holder initialized to NULL.
+ __ PushObject(Object::ZoneHandle());
+ __ pushl(Immediate(Smi::RawValue(node->token_index())));
+ __ PushObject(cls);
+ __ pushl(EAX); // Push type arguments.
+ __ pushl(ECX); // Push instantiator type arguments.
+ GenerateCallRuntime(node->id(),
+ node->token_index(),
+ kAllocateObjectWithBoundsCheckRuntimeEntry);
+ __ popl(ECX); // Pop instantiator type arguments.
__ popl(ECX); // Pop type arguments.
- __ popl(ECX); // Pop instantiator type arguments.
+ __ popl(ECX); // Pop class.
+ __ popl(ECX); // Pop source location.
+ __ popl(EAX); // 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) {
+ __ popl(ECX); // Pop instantiator type arguments.
+ __ popl(ECX); // Pop type arguments.
+ }
}
if (IsResultNeeded(node)) {

Powered by Google App Engine
This is Rietveld 408576698