Index: src/x64/codegen-x64.cc |
=================================================================== |
--- src/x64/codegen-x64.cc (revision 2271) |
+++ src/x64/codegen-x64.cc (working copy) |
@@ -1495,8 +1495,6 @@ |
Load(node->value()); |
} else { |
- // TODO(X64): Make compound assignments work. |
- /* |
Literal* literal = node->value()->AsLiteral(); |
bool overwrite_value = |
(node->value()->AsBinaryOperation() != NULL && |
@@ -1507,18 +1505,16 @@ |
// or the right hand side is a different variable. TakeValue invalidates |
// the target, with an implicit promise that it will be written to again |
// before it is read. |
- if (literal != NULL || (right_var != NULL && right_var != var)) { |
- target.TakeValue(NOT_INSIDE_TYPEOF); |
+ // TODO(X64): Implement TakeValue optimization. |
+ if (false && literal != NULL || (right_var != NULL && right_var != var)) { |
+ // target.TakeValue(NOT_INSIDE_TYPEOF); |
} else { |
target.GetValue(NOT_INSIDE_TYPEOF); |
} |
- */ |
Load(node->value()); |
- /* |
GenericBinaryOperation(node->binary_op(), |
node->type(), |
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); |
- */ |
} |
if (var != NULL && |
@@ -2275,36 +2271,93 @@ |
void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { |
- UNIMPLEMENTED(); |
+ ASSERT(args->length() == 1); |
+ |
+ // ArgumentsAccessStub expects the key in edx and the formal |
+ // parameter count in eax. |
Lasse Reichstein
2009/06/25 11:54:59
rdx * 2
|
+ Load(args->at(0)); |
+ Result key = frame_->Pop(); |
+ // Explicitly create a constant result. |
+ Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); |
+ // Call the shared stub to get to arguments[key]. |
+ ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
+ Result result = frame_->CallStub(&stub, &key, &count); |
+ frame_->Push(&result); |
} |
+ |
+void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { |
+ ASSERT(args->length() == 1); |
+ Load(args->at(0)); |
+ Result value = frame_->Pop(); |
+ value.ToRegister(); |
+ ASSERT(value.is_valid()); |
+ __ testl(value.reg(), Immediate(kSmiTagMask)); |
+ destination()->false_target()->Branch(equal); |
+ // It is a heap object - get map. |
+ // Check if the object is a JS array or not. |
+ __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, kScratchRegister); |
+ value.Unuse(); |
+ destination()->Split(equal); |
+} |
+ |
+ |
void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { |
- UNIMPLEMENTED();} |
+ ASSERT(args->length() == 0); |
+ // ArgumentsAccessStub takes the parameter count as an input argument |
+ // in register eax. Create a constant result for it. |
Lasse Reichstein
2009/06/25 11:54:59
rax
|
+ Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); |
+ // Call the shared stub to get to the arguments.length. |
+ ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); |
+ Result result = frame_->CallStub(&stub, &count); |
+ frame_->Push(&result); |
+} |
+ |
void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* a) { |
UNIMPLEMENTED(); |
} |
-void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { |
- UNIMPLEMENTED(); |
-} |
void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
UNIMPLEMENTED(); |
} |
+ |
void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { |
- UNIMPLEMENTED(); |
+ ASSERT(args->length() == 1); |
+ Load(args->at(0)); |
+ Result value = frame_->Pop(); |
+ value.ToRegister(); |
+ ASSERT(value.is_valid()); |
+ __ testl(value.reg(), Immediate(kSmiTagMask)); |
+ value.Unuse(); |
+ destination()->Split(zero); |
} |
+ |
void CodeGenerator::GenerateLog(ZoneList<Expression*>* a) { |
UNIMPLEMENTED(); |
} |
void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { |
- UNIMPLEMENTED(); |
+ ASSERT(args->length() == 2); |
+ |
+ // Load the two objects into registers and perform the comparison. |
+ Load(args->at(0)); |
+ Load(args->at(1)); |
+ Result right = frame_->Pop(); |
+ Result left = frame_->Pop(); |
+ right.ToRegister(); |
+ left.ToRegister(); |
+ __ cmpq(right.reg(), left.reg()); |
+ right.Unuse(); |
+ left.Unuse(); |
+ destination()->Split(equal); |
} |
+ |
+ |
void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* a) { |
UNIMPLEMENTED(); |
} |
@@ -2313,10 +2366,50 @@ |
UNIMPLEMENTED(); |
} |
+ |
void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { |
- UNIMPLEMENTED(); |
+ ASSERT(args->length() == 2); |
+ JumpTarget leave; |
+ Load(args->at(0)); // Load the object. |
+ Load(args->at(1)); // Load the value. |
+ Result value = frame_->Pop(); |
+ Result object = frame_->Pop(); |
+ value.ToRegister(); |
+ object.ToRegister(); |
+ |
+ // if (object->IsSmi()) return value. |
+ __ testl(object.reg(), Immediate(kSmiTagMask)); |
+ leave.Branch(zero, &value); |
+ |
+ // It is a heap object - get its map. |
+ Result scratch = allocator_->Allocate(); |
+ ASSERT(scratch.is_valid()); |
+ // if (!object->IsJSValue()) return value. |
+ __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg()); |
+ leave.Branch(not_equal, &value); |
+ |
+ // Store the value. |
+ __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); |
+ // Update the write barrier. Save the value as it will be |
+ // overwritten by the write barrier code and is needed afterward. |
+ Result duplicate_value = allocator_->Allocate(); |
+ ASSERT(duplicate_value.is_valid()); |
+ __ movq(duplicate_value.reg(), value.reg()); |
+ // The object register is also overwritten by the write barrier and |
+ // possibly aliased in the frame. |
+ frame_->Spill(object.reg()); |
+ __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), |
+ scratch.reg()); |
+ object.Unuse(); |
+ scratch.Unuse(); |
+ duplicate_value.Unuse(); |
+ |
+ // Leave. |
+ leave.Bind(&value); |
+ frame_->Push(&value); |
} |
+ |
void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
UNIMPLEMENTED(); |
} |