| 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)) {
|
|
|