| 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 // ----------------------------------- | |
| 2037 // Do not transform the receiver for strict mode functions. | 2033 // Do not transform the receiver for strict mode functions. |
| 2038 __ test_b(FieldOperand(edx, SharedFunctionInfo::kStrictModeByteOffset), | 2034 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 2035 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), |
| 2039 1 << SharedFunctionInfo::kStrictModeBitWithinByte); | 2036 1 << SharedFunctionInfo::kStrictModeBitWithinByte); |
| 2040 __ j(not_equal, cont); | 2037 __ j(not_equal, cont); |
| 2041 | 2038 |
| 2042 // Do not transform the receiver for natives (shared already in ecx). | 2039 // Do not transform the receiver for natives (shared already in ecx). |
| 2043 __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset), | 2040 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset), |
| 2044 1 << SharedFunctionInfo::kNativeBitWithinByte); | 2041 1 << SharedFunctionInfo::kNativeBitWithinByte); |
| 2045 __ j(not_equal, cont); | 2042 __ j(not_equal, cont); |
| 2046 } | 2043 } |
| 2047 | 2044 |
| 2048 | 2045 |
| 2049 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) { | 2046 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) { |
| 2050 __ Set(eax, argc); | 2047 __ Set(eax, argc); |
| 2051 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2048 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 2052 } | 2049 } |
| 2053 | 2050 |
| 2054 | 2051 |
| 2055 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { | 2052 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { |
| 2056 // Wrap the receiver and patch it back onto the stack. | 2053 // Wrap the receiver and patch it back onto the stack. |
| 2057 { FrameScope frame_scope(masm, StackFrame::INTERNAL); | 2054 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 2058 __ push(edi); | 2055 __ push(edi); |
| 2059 ToObjectStub stub(masm->isolate()); | 2056 ToObjectStub stub(masm->isolate()); |
| 2060 __ CallStub(&stub); | 2057 __ CallStub(&stub); |
| 2061 __ pop(edi); | 2058 __ pop(edi); |
| 2062 } | 2059 } |
| 2063 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); | 2060 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); |
| 2064 __ jmp(cont); | 2061 __ jmp(cont); |
| 2065 } | 2062 } |
| 2066 | 2063 |
| 2067 | 2064 |
| 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 SharedFunctionInfo::kClassConstructorBitsWithinByte); | |
| 2078 __ j(zero, &non_class_constructor, Label::kNear); | |
| 2079 // If we call a classConstructor Function throw a TypeError | |
| 2080 // indirectly via the CallFunction builtin. | |
| 2081 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | |
| 2082 __ bind(&non_class_constructor); | |
| 2083 } | |
| 2084 | |
| 2085 | |
| 2086 static void CallFunctionNoFeedback(MacroAssembler* masm, | 2065 static void CallFunctionNoFeedback(MacroAssembler* masm, |
| 2087 int argc, bool needs_checks, | 2066 int argc, bool needs_checks, |
| 2088 bool call_as_method) { | 2067 bool call_as_method) { |
| 2089 // edi : the function to call | 2068 // edi : the function to call |
| 2090 Label slow, wrap, cont; | 2069 Label slow, wrap, cont; |
| 2091 | 2070 |
| 2092 if (needs_checks) { | 2071 if (needs_checks) { |
| 2093 // Check that the function really is a JavaScript function. | 2072 // Check that the function really is a JavaScript function. |
| 2094 __ JumpIfSmi(edi, &slow); | 2073 __ JumpIfSmi(edi, &slow); |
| 2095 | 2074 |
| 2096 // Goto slow case if we do not have a function. | 2075 // Goto slow case if we do not have a function. |
| 2097 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2076 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 2098 __ j(not_equal, &slow); | 2077 __ j(not_equal, &slow); |
| 2099 } | 2078 } |
| 2100 | 2079 |
| 2101 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | |
| 2102 EmitClassConstructorCallCheck(masm); | |
| 2103 | |
| 2104 // Fast-case: Just invoke the function. | 2080 // Fast-case: Just invoke the function. |
| 2105 ParameterCount actual(argc); | 2081 ParameterCount actual(argc); |
| 2106 | 2082 |
| 2107 if (call_as_method) { | 2083 if (call_as_method) { |
| 2108 if (needs_checks) { | 2084 if (needs_checks) { |
| 2109 EmitContinueIfStrictOrNative(masm, &cont); | 2085 EmitContinueIfStrictOrNative(masm, &cont); |
| 2110 } | 2086 } |
| 2111 | 2087 |
| 2112 // Load the receiver from the stack. | 2088 // Load the receiver from the stack. |
| 2113 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); | 2089 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 // The compare above could have been a SMI/SMI comparison. Guard against this | 2242 // The compare above could have been a SMI/SMI comparison. Guard against this |
| 2267 // convincing us that we have a monomorphic JSFunction. | 2243 // convincing us that we have a monomorphic JSFunction. |
| 2268 __ JumpIfSmi(edi, &extra_checks_or_miss); | 2244 __ JumpIfSmi(edi, &extra_checks_or_miss); |
| 2269 | 2245 |
| 2270 // Increment the call count for monomorphic function calls. | 2246 // Increment the call count for monomorphic function calls. |
| 2271 __ add(FieldOperand(ebx, edx, times_half_pointer_size, | 2247 __ add(FieldOperand(ebx, edx, times_half_pointer_size, |
| 2272 FixedArray::kHeaderSize + kPointerSize), | 2248 FixedArray::kHeaderSize + kPointerSize), |
| 2273 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2249 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
| 2274 | 2250 |
| 2275 __ bind(&have_js_function); | 2251 __ bind(&have_js_function); |
| 2276 | |
| 2277 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | |
| 2278 EmitClassConstructorCallCheck(masm); | |
| 2279 | |
| 2280 if (CallAsMethod()) { | 2252 if (CallAsMethod()) { |
| 2281 EmitContinueIfStrictOrNative(masm, &cont); | 2253 EmitContinueIfStrictOrNative(masm, &cont); |
| 2282 | 2254 |
| 2283 // Load the receiver from the stack. | 2255 // Load the receiver from the stack. |
| 2284 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); | 2256 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); |
| 2285 | 2257 |
| 2286 __ JumpIfSmi(eax, &wrap); | 2258 __ JumpIfSmi(eax, &wrap); |
| 2287 | 2259 |
| 2288 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); | 2260 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); |
| 2289 __ j(below, &wrap); | 2261 __ j(below, &wrap); |
| (...skipping 3606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5896 Operand(ebp, 7 * kPointerSize), NULL); | 5868 Operand(ebp, 7 * kPointerSize), NULL); |
| 5897 } | 5869 } |
| 5898 | 5870 |
| 5899 | 5871 |
| 5900 #undef __ | 5872 #undef __ |
| 5901 | 5873 |
| 5902 } // namespace internal | 5874 } // namespace internal |
| 5903 } // namespace v8 | 5875 } // namespace v8 |
| 5904 | 5876 |
| 5905 #endif // V8_TARGET_ARCH_IA32 | 5877 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |