Commit 6990fb1c authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [es6] Initial steps towards a correct implementation of IsCallable.

Port 8a378f46

Original commit message:
    This turns the has_instance_call_handler bit on Map into an is_callable
    bit, that matches the spec definition of IsCallable (i.e. instances have
    [[Call]] internal methods).

    Also fix the typeof operator to properly say "function" for everything
    that is callable.

    Also remove the (unused) premature %_GetPrototype optimization from
    Crankshaft, which just complicated the Map bit swap.

R=bmeurer@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, dstence@us.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1330613005

Cr-Commit-Position: refs/heads/master@{#30576}
parent fdbccd64
......@@ -5002,23 +5002,23 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
} else if (String::Equals(check, factory->function_string())) {
__ JumpIfSmi(r3, if_false);
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ CompareObjectType(r3, r3, r4, JS_FUNCTION_TYPE);
__ beq(if_true);
__ cmpi(r4, Operand(JS_FUNCTION_PROXY_TYPE));
__ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset));
__ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset));
__ andi(r4, r4,
Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
__ cmpi(r4, Operand(1 << Map::kIsCallable));
Split(eq, if_true, if_false, fall_through);
} else if (String::Equals(check, factory->object_string())) {
__ JumpIfSmi(r3, if_false);
__ CompareRoot(r3, Heap::kNullValueRootIndex);
__ beq(if_true);
// Check for JS objects => true.
__ CompareObjectType(r3, r3, r4, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ CompareObjectType(r3, r3, r4, FIRST_SPEC_OBJECT_TYPE);
__ blt(if_false);
__ CompareInstanceType(r3, r4, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
__ bgt(if_false);
// Check for undetectable objects => false.
// Check for callable or undetectable objects => false.
__ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset));
__ andi(r0, r4, Operand(1 << Map::kIsUndetectable));
__ andi(r0, r4,
Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
Split(eq, if_true, if_false, fall_through, cr0);
// clang-format off
#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \
......
......@@ -5829,24 +5829,25 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, Label* false_label,
final_branch_condition = ne;
} else if (String::Equals(type_name, factory->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
Register type_reg = scratch;
__ JumpIfSmi(input, false_label);
__ CompareObjectType(input, scratch, type_reg, JS_FUNCTION_TYPE);
__ beq(true_label);
__ cmpi(type_reg, Operand(JS_FUNCTION_PROXY_TYPE));
__ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
__ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ andi(scratch, scratch,
Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
__ cmpi(scratch, Operand(1 << Map::kIsCallable));
final_branch_condition = eq;
} else if (String::Equals(type_name, factory->object_string())) {
Register map = scratch;
__ JumpIfSmi(input, false_label);
__ CompareRoot(input, Heap::kNullValueRootIndex);
__ beq(true_label);
__ CheckObjectTypeRange(input, map, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE,
LAST_NONCALLABLE_SPEC_OBJECT_TYPE, false_label);
// Check for undetectable objects => false.
__ lbz(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
__ ExtractBit(r0, scratch, Map::kIsUndetectable);
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ CompareObjectType(input, scratch, ip, FIRST_SPEC_OBJECT_TYPE);
__ blt(false_label);
// Check for callable or undetectable objects => false.
__ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
__ andi(r0, scratch,
Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
__ cmpi(r0, Operand::Zero());
final_branch_condition = eq;
......
......@@ -1702,20 +1702,6 @@ void MacroAssembler::CompareObjectType(Register object, Register map,
}
void MacroAssembler::CheckObjectTypeRange(Register object, Register map,
InstanceType min_type,
InstanceType max_type,
Label* false_label) {
STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
STATIC_ASSERT(LAST_TYPE < 256);
LoadP(map, FieldMemOperand(object, HeapObject::kMapOffset));
lbz(ip, FieldMemOperand(map, Map::kInstanceTypeOffset));
subi(ip, ip, Operand(min_type));
cmpli(ip, Operand(max_type - min_type));
bgt(false_label);
}
void MacroAssembler::CompareInstanceType(Register map, Register type_reg,
InstanceType type) {
STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
......
......@@ -717,13 +717,6 @@ class MacroAssembler : public Assembler {
void CompareObjectType(Register heap_object, Register map, Register type_reg,
InstanceType type);
// Compare object type for heap object. Branch to false_label if type
// is lower than min_type or greater than max_type.
// Load map into the register map.
void CheckObjectTypeRange(Register heap_object, Register map,
InstanceType min_type, InstanceType max_type,
Label* false_label);
// Compare instance type in a map. map contains a valid map object whose
// object type should be compared with the given type. This both
// sets the flags and leaves the object type in the type_reg register.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment