| Index: src/ia32/code-stubs-ia32.cc
|
| diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
|
| index 36b8c0ba9d32dc2912bbd3d5e75d69e8837bb57b..1501bd50040d71120d45ab896dffd58f0fb7acf8 100644
|
| --- a/src/ia32/code-stubs-ia32.cc
|
| +++ b/src/ia32/code-stubs-ia32.cc
|
| @@ -2030,14 +2030,17 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) {
|
|
|
|
|
| static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
|
| + // ----------- S t a t e -------------
|
| + // -- edi : the function to call
|
| + // -- edx : the function's shared function info
|
| + // -----------------------------------
|
| // Do not transform the receiver for strict mode functions.
|
| - __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| - __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
|
| + __ test_b(FieldOperand(edx, SharedFunctionInfo::kStrictModeByteOffset),
|
| 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
|
| __ j(not_equal, cont);
|
|
|
| // Do not transform the receiver for natives (shared already in ecx).
|
| - __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
|
| + __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset),
|
| 1 << SharedFunctionInfo::kNativeBitWithinByte);
|
| __ j(not_equal, cont);
|
| }
|
| @@ -2062,6 +2065,30 @@ static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
|
| }
|
|
|
|
|
| +static void EmitClassConstructorCallCheck(MacroAssembler* masm) {
|
| + // ----------- S t a t e -------------
|
| + // -- edi : the function to call
|
| + // -- edx : the function's shared function info
|
| + // -----------------------------------
|
| + // ClassConstructor Check: ES6 section 9.2.1 [[Call]]
|
| + Label non_class_constructor;
|
| + // Check whether the current function is a classConstructor
|
| + __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
|
| + FunctionKind::kClassConstructor);
|
| + // Check whether the current function is a classConstructor This only works
|
| + // since kClassConstructor is more than 1 bit away from the byte boundary in
|
| + // CompilerHints (note that compiler_hints is stored as smi on 32bit
|
| + // architectures)
|
| + __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
|
| + FunctionKind::kClassConstructor << kSmiTagSize);
|
| + __ j(zero, &non_class_constructor, Label::kNear);
|
| + // If we call a classConstructor Function throw a TypeError
|
| + // indirectly via the CallFunction builtin.
|
| + __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
|
| + __ bind(&non_class_constructor);
|
| +}
|
| +
|
| +
|
| static void CallFunctionNoFeedback(MacroAssembler* masm,
|
| int argc, bool needs_checks,
|
| bool call_as_method) {
|
| @@ -2077,6 +2104,9 @@ static void CallFunctionNoFeedback(MacroAssembler* masm,
|
| __ j(not_equal, &slow);
|
| }
|
|
|
| + __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| + EmitClassConstructorCallCheck(masm);
|
| +
|
| // Fast-case: Just invoke the function.
|
| ParameterCount actual(argc);
|
|
|
| @@ -2249,6 +2279,10 @@ void CallICStub::Generate(MacroAssembler* masm) {
|
| Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement)));
|
|
|
| __ bind(&have_js_function);
|
| +
|
| + __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| + EmitClassConstructorCallCheck(masm);
|
| +
|
| if (CallAsMethod()) {
|
| EmitContinueIfStrictOrNative(masm, &cont);
|
|
|
|
|