OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2294 bool overwrite_value = | 2294 bool overwrite_value = |
2295 (node->value()->AsBinaryOperation() != NULL && | 2295 (node->value()->AsBinaryOperation() != NULL && |
2296 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); | 2296 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); |
2297 Variable* right_var = node->value()->AsVariableProxy()->AsVariable(); | 2297 Variable* right_var = node->value()->AsVariableProxy()->AsVariable(); |
2298 // There are two cases where the target is not read in the right hand | 2298 // There are two cases where the target is not read in the right hand |
2299 // side, that are easy to test for: the right hand side is a literal, | 2299 // side, that are easy to test for: the right hand side is a literal, |
2300 // or the right hand side is a different variable. TakeValue invalidates | 2300 // or the right hand side is a different variable. TakeValue invalidates |
2301 // the target, with an implicit promise that it will be written to again | 2301 // the target, with an implicit promise that it will be written to again |
2302 // before it is read. | 2302 // before it is read. |
2303 // TODO(X64): Implement TakeValue optimization. | 2303 // TODO(X64): Implement TakeValue optimization. |
2304 if (false && literal != NULL || (right_var != NULL && right_var != var)) { | 2304 if (false) { |
| 2305 // if (literal != NULL || (right_var != NULL && right_var != var)) { |
2305 // target.TakeValue(NOT_INSIDE_TYPEOF); | 2306 // target.TakeValue(NOT_INSIDE_TYPEOF); |
2306 } else { | 2307 } else { |
2307 target.GetValue(NOT_INSIDE_TYPEOF); | 2308 target.GetValue(NOT_INSIDE_TYPEOF); |
2308 } | 2309 } |
2309 Load(node->value()); | 2310 Load(node->value()); |
2310 GenericBinaryOperation(node->binary_op(), | 2311 GenericBinaryOperation(node->binary_op(), |
2311 node->type(), | 2312 node->type(), |
2312 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); | 2313 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); |
2313 } | 2314 } |
2314 | 2315 |
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3335 // in register eax. Create a constant result for it. | 3336 // in register eax. Create a constant result for it. |
3336 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); | 3337 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); |
3337 // Call the shared stub to get to the arguments.length. | 3338 // Call the shared stub to get to the arguments.length. |
3338 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); | 3339 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); |
3339 Result result = frame_->CallStub(&stub, &count); | 3340 Result result = frame_->CallStub(&stub, &count); |
3340 frame_->Push(&result); | 3341 frame_->Push(&result); |
3341 } | 3342 } |
3342 | 3343 |
3343 | 3344 |
3344 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* a) { | 3345 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* a) { |
3345 UNIMPLEMENTED(); | 3346 // TODO(X64): Implement this function. |
| 3347 // Ignore arguments and return undefined, to signal failure. |
| 3348 frame_->Push(Factory::undefined_value()); |
3346 } | 3349 } |
3347 | 3350 |
3348 | 3351 |
3349 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { | 3352 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
3350 ASSERT(args->length() == 1); | 3353 ASSERT(args->length() == 1); |
3351 Load(args->at(0)); | 3354 Load(args->at(0)); |
3352 Result value = frame_->Pop(); | 3355 Result value = frame_->Pop(); |
3353 value.ToRegister(); | 3356 value.ToRegister(); |
3354 ASSERT(value.is_valid()); | 3357 ASSERT(value.is_valid()); |
3355 __ testl(value.reg(), | 3358 __ testl(value.reg(), |
3356 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000U))); | 3359 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000U))); |
3357 value.Unuse(); | 3360 value.Unuse(); |
3358 destination()->Split(zero); | 3361 destination()->Split(zero); |
3359 } | 3362 } |
3360 | 3363 |
3361 | 3364 |
3362 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { | 3365 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { |
3363 ASSERT(args->length() == 1); | 3366 ASSERT(args->length() == 1); |
3364 Load(args->at(0)); | 3367 Load(args->at(0)); |
3365 Result value = frame_->Pop(); | 3368 Result value = frame_->Pop(); |
3366 value.ToRegister(); | 3369 value.ToRegister(); |
3367 ASSERT(value.is_valid()); | 3370 ASSERT(value.is_valid()); |
3368 __ testl(value.reg(), Immediate(kSmiTagMask)); | 3371 __ testl(value.reg(), Immediate(kSmiTagMask)); |
3369 value.Unuse(); | 3372 value.Unuse(); |
3370 destination()->Split(zero); | 3373 destination()->Split(zero); |
3371 } | 3374 } |
3372 | 3375 |
3373 | 3376 |
3374 void CodeGenerator::GenerateLog(ZoneList<Expression*>* a) { | 3377 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) { |
3375 UNIMPLEMENTED(); | 3378 // Conditionally generate a log call. |
| 3379 // Args: |
| 3380 // 0 (literal string): The type of logging (corresponds to the flags). |
| 3381 // This is used to determine whether or not to generate the log call. |
| 3382 // 1 (string): Format string. Access the string at argument index 2 |
| 3383 // with '%2s' (see Logger::LogRuntime for all the formats). |
| 3384 // 2 (array): Arguments to the format string. |
| 3385 ASSERT_EQ(args->length(), 3); |
| 3386 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 3387 if (ShouldGenerateLog(args->at(0))) { |
| 3388 Load(args->at(1)); |
| 3389 Load(args->at(2)); |
| 3390 frame_->CallRuntime(Runtime::kLog, 2); |
| 3391 } |
| 3392 #endif |
| 3393 // Finally, we're expected to leave a value on the top of the stack. |
| 3394 frame_->Push(Factory::undefined_value()); |
3376 } | 3395 } |
3377 | 3396 |
| 3397 |
3378 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { | 3398 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { |
3379 ASSERT(args->length() == 2); | 3399 ASSERT(args->length() == 2); |
3380 | 3400 |
3381 // Load the two objects into registers and perform the comparison. | 3401 // Load the two objects into registers and perform the comparison. |
3382 Load(args->at(0)); | 3402 Load(args->at(0)); |
3383 Load(args->at(1)); | 3403 Load(args->at(1)); |
3384 Result right = frame_->Pop(); | 3404 Result right = frame_->Pop(); |
3385 Result left = frame_->Pop(); | 3405 Result left = frame_->Pop(); |
3386 right.ToRegister(); | 3406 right.ToRegister(); |
3387 left.ToRegister(); | 3407 left.ToRegister(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3439 scratch.Unuse(); | 3459 scratch.Unuse(); |
3440 duplicate_value.Unuse(); | 3460 duplicate_value.Unuse(); |
3441 | 3461 |
3442 // Leave. | 3462 // Leave. |
3443 leave.Bind(&value); | 3463 leave.Bind(&value); |
3444 frame_->Push(&value); | 3464 frame_->Push(&value); |
3445 } | 3465 } |
3446 | 3466 |
3447 | 3467 |
3448 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { | 3468 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
3449 UNIMPLEMENTED(); | 3469 ASSERT(args->length() == 1); |
| 3470 JumpTarget leave; |
| 3471 Load(args->at(0)); // Load the object. |
| 3472 frame_->Dup(); |
| 3473 Result object = frame_->Pop(); |
| 3474 object.ToRegister(); |
| 3475 ASSERT(object.is_valid()); |
| 3476 // if (object->IsSmi()) return object. |
| 3477 __ testl(object.reg(), Immediate(kSmiTagMask)); |
| 3478 leave.Branch(zero); |
| 3479 // It is a heap object - get map. |
| 3480 Result temp = allocator()->Allocate(); |
| 3481 ASSERT(temp.is_valid()); |
| 3482 // if (!object->IsJSValue()) return object. |
| 3483 __ CmpObjectType(object.reg(), JS_VALUE_TYPE, temp.reg()); |
| 3484 leave.Branch(not_equal); |
| 3485 __ movq(temp.reg(), FieldOperand(object.reg(), JSValue::kValueOffset)); |
| 3486 object.Unuse(); |
| 3487 frame_->SetElementAt(0, &temp); |
| 3488 leave.Bind(); |
3450 } | 3489 } |
3451 | 3490 |
| 3491 |
3452 // ----------------------------------------------------------------------------- | 3492 // ----------------------------------------------------------------------------- |
3453 // CodeGenerator implementation of Expressions | 3493 // CodeGenerator implementation of Expressions |
3454 | 3494 |
3455 void CodeGenerator::LoadAndSpill(Expression* expression, | 3495 void CodeGenerator::LoadAndSpill(Expression* expression, |
3456 TypeofState typeof_state) { | 3496 TypeofState typeof_state) { |
3457 // TODO(x64): No architecture specific code. Move to shared location. | 3497 // TODO(x64): No architecture specific code. Move to shared location. |
3458 ASSERT(in_spilled_code()); | 3498 ASSERT(in_spilled_code()); |
3459 set_in_spilled_code(false); | 3499 set_in_spilled_code(false); |
3460 Load(expression, typeof_state); | 3500 Load(expression, typeof_state); |
3461 frame_->SpillAll(); | 3501 frame_->SpillAll(); |
(...skipping 3291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6753 break; | 6793 break; |
6754 default: | 6794 default: |
6755 UNREACHABLE(); | 6795 UNREACHABLE(); |
6756 } | 6796 } |
6757 } | 6797 } |
6758 | 6798 |
6759 | 6799 |
6760 #undef __ | 6800 #undef __ |
6761 | 6801 |
6762 } } // namespace v8::internal | 6802 } } // namespace v8::internal |
OLD | NEW |