OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 2012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2023 __ jmp(&done); | 2023 __ jmp(&done); |
2024 | 2024 |
2025 __ bind(¬_array_function); | 2025 __ bind(¬_array_function); |
2026 CreateWeakCellStub weak_cell_stub(isolate); | 2026 CreateWeakCellStub weak_cell_stub(isolate); |
2027 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); | 2027 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); |
2028 __ bind(&done); | 2028 __ bind(&done); |
2029 } | 2029 } |
2030 | 2030 |
2031 | 2031 |
2032 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2032 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
| 2033 // ----------- S t a t e ------------- |
| 2034 // -- edi : the function to call |
| 2035 // -- edx : the function's shared function info |
| 2036 // ----------------------------------- |
2033 // Do not transform the receiver for strict mode functions. | 2037 // Do not transform the receiver for strict mode functions. |
2034 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2038 __ test_b(FieldOperand(edx, SharedFunctionInfo::kStrictModeByteOffset), |
2035 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), | |
2036 1 << SharedFunctionInfo::kStrictModeBitWithinByte); | 2039 1 << SharedFunctionInfo::kStrictModeBitWithinByte); |
2037 __ j(not_equal, cont); | 2040 __ j(not_equal, cont); |
2038 | 2041 |
2039 // Do not transform the receiver for natives (shared already in ecx). | 2042 // Do not transform the receiver for natives (shared already in ecx). |
2040 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset), | 2043 __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset), |
2041 1 << SharedFunctionInfo::kNativeBitWithinByte); | 2044 1 << SharedFunctionInfo::kNativeBitWithinByte); |
2042 __ j(not_equal, cont); | 2045 __ j(not_equal, cont); |
2043 } | 2046 } |
2044 | 2047 |
2045 | 2048 |
2046 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) { | 2049 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) { |
2047 __ Set(eax, argc); | 2050 __ Set(eax, argc); |
2048 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2051 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2049 } | 2052 } |
2050 | 2053 |
2051 | 2054 |
2052 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { | 2055 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { |
2053 // Wrap the receiver and patch it back onto the stack. | 2056 // Wrap the receiver and patch it back onto the stack. |
2054 { FrameScope frame_scope(masm, StackFrame::INTERNAL); | 2057 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
2055 __ push(edi); | 2058 __ push(edi); |
2056 ToObjectStub stub(masm->isolate()); | 2059 ToObjectStub stub(masm->isolate()); |
2057 __ CallStub(&stub); | 2060 __ CallStub(&stub); |
2058 __ pop(edi); | 2061 __ pop(edi); |
2059 } | 2062 } |
2060 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); | 2063 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); |
2061 __ jmp(cont); | 2064 __ jmp(cont); |
2062 } | 2065 } |
2063 | 2066 |
2064 | 2067 |
| 2068 static void EmitClassConstructorCallCheck(MacroAssembler* masm) { |
| 2069 // ----------- S t a t e ------------- |
| 2070 // -- edi : the function to call |
| 2071 // -- edx : the function's shared function info |
| 2072 // ----------------------------------- |
| 2073 // ClassConstructor Check: ES6 section 9.2.1 [[Call]] |
| 2074 Label non_class_constructor; |
| 2075 // Check whether the current function is a classConstructor |
| 2076 __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset), |
| 2077 FunctionKind::kClassConstructor); |
| 2078 // Check whether the current function is a classConstructor This only works |
| 2079 // since kClassConstructor is more than 1 bit away from the byte boundary in |
| 2080 // CompilerHints (note that compiler_hints is stored as smi on 32bit |
| 2081 // architectures) |
| 2082 __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset), |
| 2083 FunctionKind::kClassConstructor << kSmiTagSize); |
| 2084 __ j(zero, &non_class_constructor, Label::kNear); |
| 2085 // If we call a classConstructor Function throw a TypeError |
| 2086 // indirectly via the CallFunction builtin. |
| 2087 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
| 2088 __ bind(&non_class_constructor); |
| 2089 } |
| 2090 |
| 2091 |
2065 static void CallFunctionNoFeedback(MacroAssembler* masm, | 2092 static void CallFunctionNoFeedback(MacroAssembler* masm, |
2066 int argc, bool needs_checks, | 2093 int argc, bool needs_checks, |
2067 bool call_as_method) { | 2094 bool call_as_method) { |
2068 // edi : the function to call | 2095 // edi : the function to call |
2069 Label slow, wrap, cont; | 2096 Label slow, wrap, cont; |
2070 | 2097 |
2071 if (needs_checks) { | 2098 if (needs_checks) { |
2072 // Check that the function really is a JavaScript function. | 2099 // Check that the function really is a JavaScript function. |
2073 __ JumpIfSmi(edi, &slow); | 2100 __ JumpIfSmi(edi, &slow); |
2074 | 2101 |
2075 // Goto slow case if we do not have a function. | 2102 // Goto slow case if we do not have a function. |
2076 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2103 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
2077 __ j(not_equal, &slow); | 2104 __ j(not_equal, &slow); |
2078 } | 2105 } |
2079 | 2106 |
| 2107 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 2108 EmitClassConstructorCallCheck(masm); |
| 2109 |
2080 // Fast-case: Just invoke the function. | 2110 // Fast-case: Just invoke the function. |
2081 ParameterCount actual(argc); | 2111 ParameterCount actual(argc); |
2082 | 2112 |
2083 if (call_as_method) { | 2113 if (call_as_method) { |
2084 if (needs_checks) { | 2114 if (needs_checks) { |
2085 EmitContinueIfStrictOrNative(masm, &cont); | 2115 EmitContinueIfStrictOrNative(masm, &cont); |
2086 } | 2116 } |
2087 | 2117 |
2088 // Load the receiver from the stack. | 2118 // Load the receiver from the stack. |
2089 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); | 2119 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2242 // The compare above could have been a SMI/SMI comparison. Guard against this | 2272 // The compare above could have been a SMI/SMI comparison. Guard against this |
2243 // convincing us that we have a monomorphic JSFunction. | 2273 // convincing us that we have a monomorphic JSFunction. |
2244 __ JumpIfSmi(edi, &extra_checks_or_miss); | 2274 __ JumpIfSmi(edi, &extra_checks_or_miss); |
2245 | 2275 |
2246 // Increment the call count for monomorphic function calls. | 2276 // Increment the call count for monomorphic function calls. |
2247 __ add(FieldOperand(ebx, edx, times_half_pointer_size, | 2277 __ add(FieldOperand(ebx, edx, times_half_pointer_size, |
2248 FixedArray::kHeaderSize + kPointerSize), | 2278 FixedArray::kHeaderSize + kPointerSize), |
2249 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2279 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
2250 | 2280 |
2251 __ bind(&have_js_function); | 2281 __ bind(&have_js_function); |
| 2282 |
| 2283 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 2284 EmitClassConstructorCallCheck(masm); |
| 2285 |
2252 if (CallAsMethod()) { | 2286 if (CallAsMethod()) { |
2253 EmitContinueIfStrictOrNative(masm, &cont); | 2287 EmitContinueIfStrictOrNative(masm, &cont); |
2254 | 2288 |
2255 // Load the receiver from the stack. | 2289 // Load the receiver from the stack. |
2256 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); | 2290 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); |
2257 | 2291 |
2258 __ JumpIfSmi(eax, &wrap); | 2292 __ JumpIfSmi(eax, &wrap); |
2259 | 2293 |
2260 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); | 2294 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); |
2261 __ j(below, &wrap); | 2295 __ j(below, &wrap); |
(...skipping 3606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5868 Operand(ebp, 7 * kPointerSize), NULL); | 5902 Operand(ebp, 7 * kPointerSize), NULL); |
5869 } | 5903 } |
5870 | 5904 |
5871 | 5905 |
5872 #undef __ | 5906 #undef __ |
5873 | 5907 |
5874 } // namespace internal | 5908 } // namespace internal |
5875 } // namespace v8 | 5909 } // namespace v8 |
5876 | 5910 |
5877 #endif // V8_TARGET_ARCH_IA32 | 5911 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |