Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 2d1e7ba6247ad1330a60cd3e2022315f189b1dfc..d9344808e0d9d77cf1ed08552826a4ff5fe26616 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -1729,18 +1729,62 @@ Condition LCodeGen::EmitIsObject(Register input, |
Register temp2, |
Label* is_not_object, |
Label* is_object) { |
- Abort("EmitIsObject unimplemented."); |
- return ne; |
+ __ BranchOnSmi(input, is_not_object); |
+ |
+ __ LoadRoot(temp1, Heap::kNullValueRootIndex); |
+ __ cmp(input, temp1); |
+ __ b(eq, is_object); |
+ |
+ // Load map. |
+ __ ldr(temp1, FieldMemOperand(input, HeapObject::kMapOffset)); |
+ // Undetectable objects behave like undefined. |
+ __ ldrb(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset)); |
+ __ tst(temp2, Operand(1 << Map::kIsUndetectable)); |
+ __ b(ne, is_not_object); |
+ |
+ // Load instance type and check that it is in object type range. |
+ __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); |
+ __ cmp(temp2, Operand(FIRST_JS_OBJECT_TYPE)); |
+ __ b(lt, is_not_object); |
+ __ cmp(temp2, Operand(LAST_JS_OBJECT_TYPE)); |
+ return le; |
} |
void LCodeGen::DoIsObject(LIsObject* instr) { |
- Abort("DoIsObject unimplemented."); |
+ Register reg = ToRegister(instr->input()); |
+ Register result = ToRegister(instr->result()); |
+ Register temp = scratch0(); |
+ Label is_false, is_true, done; |
+ |
+ Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); |
+ __ b(true_cond, &is_true); |
+ |
+ __ bind(&is_false); |
+ __ LoadRoot(result, Heap::kFalseValueRootIndex); |
+ __ b(al, &done); |
Mads Ager (chromium)
2011/01/24 12:24:46
This is the same as __ b(&done);
I'll change that
|
+ |
+ __ bind(&is_true); |
+ __ LoadRoot(result, Heap::kTrueValueRootIndex); |
+ |
+ __ bind(&done); |
} |
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { |
- Abort("DoIsObjectAndBranch unimplemented."); |
+ Register reg = ToRegister(instr->input()); |
+ Register temp1 = ToRegister(instr->temp()); |
+ Register temp2 = scratch0(); |
+ |
+ int true_block = chunk_->LookupDestination(instr->true_block_id()); |
+ int false_block = chunk_->LookupDestination(instr->false_block_id()); |
+ Label* true_label = chunk_->GetAssemblyLabel(true_block); |
+ Label* false_label = chunk_->GetAssemblyLabel(false_block); |
+ |
+ Condition true_cond = EmitIsObject(reg, temp1, temp2, false_label, |
+ true_label); |
+ |
+ EmitBranch(true_block, false_block, true_cond); |
} |