Commit 57d16cf4 authored by chunyang.dai's avatar chunyang.dai Committed by Commit bot

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

port 8a378f46 (r30552)

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.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#30609}
parent e5ee42fa
...@@ -4873,27 +4873,27 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, ...@@ -4873,27 +4873,27 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ JumpIfSmi(eax, if_false); __ JumpIfSmi(eax, if_false);
// Check for undetectable objects => true. // Check for undetectable objects => true.
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
__ test(ecx, Immediate(1 << Map::kIsUndetectable)); 1 << Map::kIsUndetectable);
Split(not_zero, if_true, if_false, fall_through); Split(not_zero, if_true, if_false, fall_through);
} else if (String::Equals(check, factory->function_string())) { } else if (String::Equals(check, factory->function_string())) {
__ JumpIfSmi(eax, if_false); __ JumpIfSmi(eax, if_false);
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); // Check for callable and not undetectable objects => true.
__ CmpObjectType(eax, JS_FUNCTION_TYPE, edx); __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
__ j(equal, if_true); __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
__ CmpInstanceType(edx, JS_FUNCTION_PROXY_TYPE); __ and_(ecx, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable));
__ cmp(ecx, 1 << Map::kIsCallable);
Split(equal, if_true, if_false, fall_through); Split(equal, if_true, if_false, fall_through);
} else if (String::Equals(check, factory->object_string())) { } else if (String::Equals(check, factory->object_string())) {
__ JumpIfSmi(eax, if_false); __ JumpIfSmi(eax, if_false);
__ cmp(eax, isolate()->factory()->null_value()); __ cmp(eax, isolate()->factory()->null_value());
__ j(equal, if_true); __ j(equal, if_true);
__ CmpObjectType(eax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, edx); STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, edx);
__ j(below, if_false); __ j(below, if_false);
__ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); // Check for callable or undetectable objects => false.
__ j(above, if_false);
// Check for undetectable objects => false.
__ test_b(FieldOperand(edx, Map::kBitFieldOffset), __ test_b(FieldOperand(edx, Map::kBitFieldOffset),
1 << Map::kIsUndetectable); (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable));
Split(zero, if_true, if_false, fall_through); Split(zero, if_true, if_false, fall_through);
// clang-format off // clang-format off
#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \
......
...@@ -6036,24 +6036,24 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { ...@@ -6036,24 +6036,24 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
final_branch_condition = not_zero; final_branch_condition = not_zero;
} else if (String::Equals(type_name, factory()->function_string())) { } else if (String::Equals(type_name, factory()->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ JumpIfSmi(input, false_label, false_distance); __ JumpIfSmi(input, false_label, false_distance);
__ CmpObjectType(input, JS_FUNCTION_TYPE, input); // Check for callable and not undetectable objects => true.
__ j(equal, true_label, true_distance); __ mov(input, FieldOperand(input, HeapObject::kMapOffset));
__ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); __ movzx_b(input, FieldOperand(input, Map::kBitFieldOffset));
__ and_(input, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable));
__ cmp(input, 1 << Map::kIsCallable);
final_branch_condition = equal; final_branch_condition = equal;
} else if (String::Equals(type_name, factory()->object_string())) { } else if (String::Equals(type_name, factory()->object_string())) {
__ JumpIfSmi(input, false_label, false_distance); __ JumpIfSmi(input, false_label, false_distance);
__ cmp(input, factory()->null_value()); __ cmp(input, factory()->null_value());
__ j(equal, true_label, true_distance); __ j(equal, true_label, true_distance);
__ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, input);
__ j(below, false_label, false_distance); __ j(below, false_label, false_distance);
__ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); // Check for callable or undetectable objects => false.
__ j(above, false_label, false_distance);
// Check for undetectable objects => false.
__ test_b(FieldOperand(input, Map::kBitFieldOffset), __ test_b(FieldOperand(input, Map::kBitFieldOffset),
1 << Map::kIsUndetectable); (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable));
final_branch_condition = zero; final_branch_condition = zero;
// clang-format off // clang-format off
......
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