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 |