| Index: runtime/vm/code_generator_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/code_generator_ia32.cc (revision 1225)
|
| +++ runtime/vm/code_generator_ia32.cc (working copy)
|
| @@ -265,7 +265,9 @@
|
| Function::ZoneHandle(parsed_function_.function().raw());
|
| __ LoadObject(EAX, function);
|
| __ pushl(EAX);
|
| - GenerateCallRuntime(0, kTraceFunctionEntryRuntimeEntry);
|
| + GenerateCallRuntime(AstNode::kNoId,
|
| + 0,
|
| + kTraceFunctionEntryRuntimeEntry);
|
| __ popl(EAX);
|
| __ popl(EDX);
|
| __ popl(ECX);
|
| @@ -298,7 +300,7 @@
|
| // at entry point.
|
| pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode,
|
| assembler_->CodeSize(),
|
| - AstNode::kInvalidId,
|
| + AstNode::kNoId,
|
| 0,
|
| -1);
|
| __ jmp(&StubCode::FixCallersTargetLabel());
|
| @@ -369,7 +371,7 @@
|
| intptr_t pc = descriptors.PC(i);
|
| PcDescriptors::Kind kind = descriptors.DescriptorKind(i);
|
| // 'node_id' is set for kDeopt and kIcCall and must be unique for one kind.
|
| - intptr_t node_id = AstNode::kInvalidId;
|
| + intptr_t node_id = AstNode::kNoId;
|
| if (check_ids) {
|
| if ((descriptors.DescriptorKind(i) == PcDescriptors::kDeopt) ||
|
| (descriptors.DescriptorKind(i) == PcDescriptors::kIcCall)) {
|
| @@ -378,7 +380,7 @@
|
| }
|
| for (intptr_t k = i + 1; k < descriptors.Length(); k++) {
|
| if (kind == descriptors.DescriptorKind(k)) {
|
| - if (node_id != AstNode::kInvalidId) {
|
| + if (node_id != AstNode::kNoId) {
|
| ASSERT(descriptors.NodeId(k) != node_id);
|
| }
|
| ASSERT(pc != descriptors.PC(k));
|
| @@ -576,7 +578,8 @@
|
| __ j(BELOW_EQUAL, &argc_in_range, Assembler::kNearJump);
|
| }
|
| if (function.IsClosureFunction()) {
|
| - GenerateCallRuntime(function.token_index(),
|
| + GenerateCallRuntime(AstNode::kNoId,
|
| + function.token_index(),
|
| kClosureArgumentMismatchRuntimeEntry);
|
| } else {
|
| __ Stop("Wrong number of arguments");
|
| @@ -700,7 +703,8 @@
|
|
|
| __ Bind(&wrong_num_arguments);
|
| if (function.IsClosureFunction()) {
|
| - GenerateCallRuntime(function.token_index(),
|
| + GenerateCallRuntime(AstNode::kNoId,
|
| + function.token_index(),
|
| kClosureArgumentMismatchRuntimeEntry);
|
| } else {
|
| // Invoke noSuchMethod function.
|
| @@ -718,7 +722,9 @@
|
| if (FLAG_trace_functions) {
|
| __ pushl(EAX); // Preserve result.
|
| __ PushObject(function);
|
| - GenerateCallRuntime(0, kTraceFunctionExitRuntimeEntry);
|
| + GenerateCallRuntime(AstNode::kNoId,
|
| + 0,
|
| + kTraceFunctionExitRuntimeEntry);
|
| __ popl(EAX); // Remove argument.
|
| __ popl(EAX); // Restore result.
|
| }
|
| @@ -790,6 +796,7 @@
|
| // Generate type check.
|
| if (FLAG_enable_type_checks) {
|
| GenerateAssertAssignable(
|
| + node->id(),
|
| node->value()->token_index(),
|
| Type::ZoneHandle(parsed_function().function().result_type()),
|
| String::ZoneHandle(String::NewSymbol("function result")));
|
| @@ -816,7 +823,9 @@
|
| Function::ZoneHandle(parsed_function_.function().raw());
|
| __ LoadObject(EBX, function);
|
| __ pushl(EBX);
|
| - GenerateCallRuntime(0, kTraceFunctionExitRuntimeEntry);
|
| + GenerateCallRuntime(AstNode::kNoId,
|
| + 0,
|
| + kTraceFunctionExitRuntimeEntry);
|
| __ popl(EAX); // Remove argument.
|
| __ popl(EAX); // Restore result.
|
| }
|
| @@ -1008,7 +1017,8 @@
|
| node->value()->Visit(this);
|
| __ popl(EAX);
|
| if (FLAG_enable_type_checks) {
|
| - GenerateAssertAssignable(node->value()->token_index(),
|
| + GenerateAssertAssignable(node->id(),
|
| + node->value()->token_index(),
|
| node->local().type(),
|
| node->local().name());
|
| }
|
| @@ -1036,7 +1046,8 @@
|
| MarkDeoptPoint(node->id(), node->token_index());
|
| __ popl(EAX); // Value.
|
| if (FLAG_enable_type_checks) {
|
| - GenerateAssertAssignable(node->value()->token_index(),
|
| + GenerateAssertAssignable(node->id(),
|
| + node->value()->token_index(),
|
| Type::ZoneHandle(node->field().type()),
|
| String::ZoneHandle(node->field().name()));
|
| }
|
| @@ -1137,7 +1148,8 @@
|
| MarkDeoptPoint(node->id(), node->token_index());
|
| __ popl(EAX); // Value.
|
| if (FLAG_enable_type_checks) {
|
| - GenerateAssertAssignable(node->value()->token_index(),
|
| + GenerateAssertAssignable(node->id(),
|
| + node->value()->token_index(),
|
| Type::ZoneHandle(node->field().type()),
|
| String::ZoneHandle(node->field().name()));
|
| }
|
| @@ -1157,7 +1169,7 @@
|
| node->operand()->Visit(this);
|
| MarkDeoptPoint(node->id(), node->token_index());
|
| Label done;
|
| - GenerateConditionTypeCheck(node->operand()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->operand()->token_index());
|
| __ popl(EDX);
|
| __ LoadObject(EAX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -1219,8 +1231,10 @@
|
| GenerateBinaryOperatorCall(node->id(), node->token_index(), operator_name);
|
| // result is in EAX.
|
| if (FLAG_enable_type_checks) {
|
| - GenerateAssertAssignable(
|
| - node->token_index(), node->local().type(), node->local().name());
|
| + GenerateAssertAssignable(node->id(),
|
| + node->token_index(),
|
| + node->local().type(),
|
| + node->local().name());
|
| }
|
| GenerateStoreVariable(node->local(), EAX, EDX);
|
| if (node->prefix() && IsResultNeeded(node)) {
|
| @@ -1303,7 +1317,8 @@
|
| node->field_name());
|
| } else {
|
| if (FLAG_enable_type_checks) {
|
| - GenerateAssertAssignable(node->token_index(),
|
| + GenerateAssertAssignable(node->id(),
|
| + node->token_index(),
|
| Type::ZoneHandle(node->field().type()),
|
| String::ZoneHandle(node->field().name()));
|
| }
|
| @@ -1355,7 +1370,8 @@
|
| // Destroys ECX.
|
| // Returns:
|
| // - true or false on stack.
|
| -void CodeGenerator::GenerateInstanceOf(intptr_t token_index,
|
| +void CodeGenerator::GenerateInstanceOf(intptr_t node_id,
|
| + intptr_t token_index,
|
| const Type& type,
|
| bool negate_result) {
|
| ASSERT(type.IsFinalized());
|
| @@ -1432,7 +1448,7 @@
|
| } else {
|
| __ pushl(raw_null); // Null instantiator.
|
| }
|
| - GenerateCallRuntime(token_index, kInstanceofRuntimeEntry);
|
| + GenerateCallRuntime(node_id, token_index, kInstanceofRuntimeEntry);
|
| // Pop the two parameters supplied to the runtime entry. The result of the
|
| // instanceof runtime call will be left as the result of the operation.
|
| __ addl(ESP, Immediate(3 * kWordSize));
|
| @@ -1472,7 +1488,8 @@
|
| // Destroys ECX and EDX.
|
| // Returns:
|
| // - object in EAX for successful assignable check (or throws TypeError).
|
| -void CodeGenerator::GenerateAssertAssignable(intptr_t token_index,
|
| +void CodeGenerator::GenerateAssertAssignable(intptr_t node_id,
|
| + intptr_t token_index,
|
| const Type& dst_type,
|
| const String& dst_name) {
|
| ASSERT(FLAG_enable_type_checks);
|
| @@ -1590,7 +1607,7 @@
|
| __ pushl(raw_null); // Null instantiator.
|
| }
|
| __ PushObject(dst_name); // Push the name of the destination.
|
| - GenerateCallRuntime(token_index, kTypeCheckRuntimeEntry);
|
| + GenerateCallRuntime(node_id, token_index, kTypeCheckRuntimeEntry);
|
| // Pop the parameters supplied to the runtime entry. The result of the
|
| // type check runtime call is the checked value.
|
| __ addl(ESP, Immediate(5 * kWordSize));
|
| @@ -1609,13 +1626,16 @@
|
| for (int i = 0; i < num_fixed_params + num_opt_params; i++) {
|
| LocalVariable* parameter = scope->VariableAt(i);
|
| GenerateLoadVariable(EAX, *parameter);
|
| - GenerateAssertAssignable(
|
| - parameter->token_index(), parameter->type(), parameter->name());
|
| + GenerateAssertAssignable(AstNode::kNoId,
|
| + parameter->token_index(),
|
| + parameter->type(),
|
| + parameter->name());
|
| }
|
| }
|
|
|
|
|
| -void CodeGenerator::GenerateConditionTypeCheck(intptr_t token_index) {
|
| +void CodeGenerator::GenerateConditionTypeCheck(intptr_t node_id,
|
| + intptr_t token_index) {
|
| if (!FLAG_enable_type_checks) {
|
| return;
|
| }
|
| @@ -1647,7 +1667,7 @@
|
| Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
|
| __ pushl(location); // Push the source location.
|
| __ pushl(EAX); // Push the source object.
|
| - GenerateCallRuntime(token_index, kConditionTypeErrorRuntimeEntry);
|
| + GenerateCallRuntime(node_id, token_index, kConditionTypeErrorRuntimeEntry);
|
| // Pop the parameters supplied to the runtime entry. The result of the
|
| // type check runtime call is the checked value.
|
| __ addl(ESP, Immediate(3 * kWordSize));
|
| @@ -1665,7 +1685,8 @@
|
| if (Token::IsInstanceofOperator(node->kind())) {
|
| __ popl(EAX); // Left operand.
|
| ASSERT(node->right()->IsTypeNode());
|
| - GenerateInstanceOf(node->token_index(),
|
| + GenerateInstanceOf(node->id(),
|
| + node->token_index(),
|
| node->right()->AsTypeNode()->type(),
|
| (node->kind() == Token::kISNOT));
|
| if (!IsResultNeeded(node)) {
|
| @@ -1797,7 +1818,7 @@
|
| SourceLabel* label = node->label();
|
| __ Bind(label->continue_label());
|
| node->condition()->Visit(this);
|
| - GenerateConditionTypeCheck(node->condition()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
|
| __ popl(EAX);
|
| __ LoadObject(EDX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -1818,7 +1839,7 @@
|
| CountBackwardLoop();
|
| __ Bind(label->continue_label());
|
| node->condition()->Visit(this);
|
| - GenerateConditionTypeCheck(node->condition()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
|
| __ popl(EAX);
|
| __ LoadObject(EDX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -1835,7 +1856,7 @@
|
| __ Bind(&loop);
|
| if (node->condition() != NULL) {
|
| node->condition()->Visit(this);
|
| - GenerateConditionTypeCheck(node->condition()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
|
| __ popl(EAX);
|
| __ LoadObject(EDX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -1887,7 +1908,7 @@
|
| const Bool& bool_true = Bool::ZoneHandle(Bool::True());
|
| Label false_label, done;
|
| node->condition()->Visit(this);
|
| - GenerateConditionTypeCheck(node->condition()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
|
| __ popl(EAX);
|
| __ LoadObject(EDX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -1947,7 +1968,7 @@
|
| const Bool& bool_true = Bool::ZoneHandle(Bool::True());
|
| Label false_label;
|
| node->condition()->Visit(this);
|
| - GenerateConditionTypeCheck(node->condition()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
|
| __ popl(EAX);
|
| __ LoadObject(EDX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -1973,7 +1994,7 @@
|
| const Bool& bool_false = Bool::ZoneHandle(Bool::False());
|
| Label load_false, done;
|
| node->left()->Visit(this);
|
| - GenerateConditionTypeCheck(node->left()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->left()->token_index());
|
| __ popl(EAX);
|
| __ LoadObject(EDX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -1984,7 +2005,7 @@
|
| __ j(EQUAL, &done);
|
| }
|
| node->right()->Visit(this);
|
| - GenerateConditionTypeCheck(node->right()->token_index());
|
| + GenerateConditionTypeCheck(node->id(), node->right()->token_index());
|
| __ popl(EAX);
|
| __ LoadObject(EDX, bool_true);
|
| __ cmpl(EAX, EDX);
|
| @@ -2257,7 +2278,8 @@
|
| __ PushObject(result); // Make room for the result of the runtime call.
|
| __ PushObject(node->type_arguments());
|
| __ pushl(EAX); // Push instantiator type arguments.
|
| - GenerateCallRuntime(node->token_index(),
|
| + GenerateCallRuntime(node->id(),
|
| + node->token_index(),
|
| kInstantiateTypeArgumentsRuntimeEntry);
|
| __ popl(EAX); // Pop instantiator type arguments.
|
| __ popl(EAX); // Pop uninstantiated type arguments.
|
| @@ -2574,11 +2596,11 @@
|
| __ PushObject(result); // Make room for the result of the runtime call.
|
| __ pushl(EAX); // Push the exception object.
|
| node->stacktrace()->Visit(this);
|
| - GenerateCallRuntime(node->token_index(), kReThrowRuntimeEntry);
|
| + GenerateCallRuntime(node->id(), node->token_index(), kReThrowRuntimeEntry);
|
| } else {
|
| __ PushObject(result); // Make room for the result of the runtime call.
|
| __ pushl(EAX); // Push the exception object.
|
| - GenerateCallRuntime(node->token_index(), kThrowRuntimeEntry);
|
| + GenerateCallRuntime(node->id(), node->token_index(), kThrowRuntimeEntry);
|
| }
|
| // We should never return here.
|
| __ int3();
|
| @@ -2608,20 +2630,21 @@
|
| void CodeGenerator::GenerateCall(intptr_t token_index,
|
| const ExternalLabel* ext_label) {
|
| __ call(ext_label);
|
| - AddCurrentDescriptor(PcDescriptors::kOther, AstNode::kInvalidId, token_index);
|
| + AddCurrentDescriptor(PcDescriptors::kOther, AstNode::kNoId, token_index);
|
| }
|
|
|
|
|
| -void CodeGenerator::GenerateCallRuntime(intptr_t token_index,
|
| +void CodeGenerator::GenerateCallRuntime(intptr_t node_id,
|
| + intptr_t token_index,
|
| const RuntimeEntry& entry) {
|
| __ CallRuntimeFromDart(entry);
|
| - AddCurrentDescriptor(PcDescriptors::kOther, AstNode::kInvalidId, token_index);
|
| + AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index);
|
| }
|
|
|
|
|
| void CodeGenerator::MarkDeoptPoint(intptr_t node_id,
|
| intptr_t token_index) {
|
| - ASSERT(node_id != AstNode::kInvalidId);
|
| + ASSERT(node_id != AstNode::kNoId);
|
| AddCurrentDescriptor(PcDescriptors::kDeopt, node_id, token_index);
|
| }
|
|
|
|
|