| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/debug.h" | 10 #include "src/debug.h" |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 // if it is a function. | 1058 // if it is a function. |
| 1059 Label slow, non_function; | 1059 Label slow, non_function; |
| 1060 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); | 1060 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); |
| 1061 __ JumpIfSmi(function, &non_function); | 1061 __ JumpIfSmi(function, &non_function); |
| 1062 __ JumpIfNotObjectType(function, scratch1, receiver_type, | 1062 __ JumpIfNotObjectType(function, scratch1, receiver_type, |
| 1063 JS_FUNCTION_TYPE, &slow); | 1063 JS_FUNCTION_TYPE, &slow); |
| 1064 | 1064 |
| 1065 // 3a. Patch the first argument if necessary when calling a function. | 1065 // 3a. Patch the first argument if necessary when calling a function. |
| 1066 Label shift_arguments; | 1066 Label shift_arguments; |
| 1067 __ Mov(call_type, static_cast<int>(call_type_JS_func)); | 1067 __ Mov(call_type, static_cast<int>(call_type_JS_func)); |
| 1068 { Label convert_to_object, use_global_receiver, patch_receiver; | 1068 { Label convert_to_object, use_global_proxy, patch_receiver; |
| 1069 // Change context eagerly in case we need the global receiver. | 1069 // Change context eagerly in case we need the global receiver. |
| 1070 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 1070 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); |
| 1071 | 1071 |
| 1072 // Do not transform the receiver for strict mode functions. | 1072 // Do not transform the receiver for strict mode functions. |
| 1073 // Also do not transform the receiver for native (Compilerhints already in | 1073 // Also do not transform the receiver for native (Compilerhints already in |
| 1074 // x3). | 1074 // x3). |
| 1075 __ Ldr(scratch1, | 1075 __ Ldr(scratch1, |
| 1076 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 1076 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
| 1077 __ Ldr(scratch2.W(), | 1077 __ Ldr(scratch2.W(), |
| 1078 FieldMemOperand(scratch1, SharedFunctionInfo::kCompilerHintsOffset)); | 1078 FieldMemOperand(scratch1, SharedFunctionInfo::kCompilerHintsOffset)); |
| 1079 __ TestAndBranchIfAnySet( | 1079 __ TestAndBranchIfAnySet( |
| 1080 scratch2.W(), | 1080 scratch2.W(), |
| 1081 (1 << SharedFunctionInfo::kStrictModeFunction) | | 1081 (1 << SharedFunctionInfo::kStrictModeFunction) | |
| 1082 (1 << SharedFunctionInfo::kNative), | 1082 (1 << SharedFunctionInfo::kNative), |
| 1083 &shift_arguments); | 1083 &shift_arguments); |
| 1084 | 1084 |
| 1085 // Compute the receiver in sloppy mode. | 1085 // Compute the receiver in sloppy mode. |
| 1086 Register receiver = x2; | 1086 Register receiver = x2; |
| 1087 __ Sub(scratch1, argc, 1); | 1087 __ Sub(scratch1, argc, 1); |
| 1088 __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); | 1088 __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); |
| 1089 __ JumpIfSmi(receiver, &convert_to_object); | 1089 __ JumpIfSmi(receiver, &convert_to_object); |
| 1090 | 1090 |
| 1091 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, | 1091 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, |
| 1092 &use_global_receiver); | 1092 &use_global_proxy); |
| 1093 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_receiver); | 1093 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy); |
| 1094 | 1094 |
| 1095 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 1095 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |
| 1096 __ JumpIfObjectType(receiver, scratch1, scratch2, | 1096 __ JumpIfObjectType(receiver, scratch1, scratch2, |
| 1097 FIRST_SPEC_OBJECT_TYPE, &shift_arguments, ge); | 1097 FIRST_SPEC_OBJECT_TYPE, &shift_arguments, ge); |
| 1098 | 1098 |
| 1099 __ Bind(&convert_to_object); | 1099 __ Bind(&convert_to_object); |
| 1100 | 1100 |
| 1101 { | 1101 { |
| 1102 // Enter an internal frame in order to preserve argument count. | 1102 // Enter an internal frame in order to preserve argument count. |
| 1103 FrameScope scope(masm, StackFrame::INTERNAL); | 1103 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1104 __ SmiTag(argc); | 1104 __ SmiTag(argc); |
| 1105 | 1105 |
| 1106 __ Push(argc, receiver); | 1106 __ Push(argc, receiver); |
| 1107 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 1107 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 1108 __ Mov(receiver, x0); | 1108 __ Mov(receiver, x0); |
| 1109 | 1109 |
| 1110 __ Pop(argc); | 1110 __ Pop(argc); |
| 1111 __ SmiUntag(argc); | 1111 __ SmiUntag(argc); |
| 1112 | 1112 |
| 1113 // Exit the internal frame. | 1113 // Exit the internal frame. |
| 1114 } | 1114 } |
| 1115 | 1115 |
| 1116 // Restore the function and flag in the registers. | 1116 // Restore the function and flag in the registers. |
| 1117 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); | 1117 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); |
| 1118 __ Mov(call_type, static_cast<int>(call_type_JS_func)); | 1118 __ Mov(call_type, static_cast<int>(call_type_JS_func)); |
| 1119 __ B(&patch_receiver); | 1119 __ B(&patch_receiver); |
| 1120 | 1120 |
| 1121 __ Bind(&use_global_receiver); | 1121 __ Bind(&use_global_proxy); |
| 1122 __ Ldr(receiver, GlobalObjectMemOperand()); | 1122 __ Ldr(receiver, GlobalObjectMemOperand()); |
| 1123 __ Ldr(receiver, | 1123 __ Ldr(receiver, |
| 1124 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); | 1124 FieldMemOperand(receiver, GlobalObject::kGlobalProxyOffset)); |
| 1125 | 1125 |
| 1126 | 1126 |
| 1127 __ Bind(&patch_receiver); | 1127 __ Bind(&patch_receiver); |
| 1128 __ Sub(scratch1, argc, 1); | 1128 __ Sub(scratch1, argc, 1); |
| 1129 __ Poke(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); | 1129 __ Poke(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); |
| 1130 | 1130 |
| 1131 __ B(&shift_arguments); | 1131 __ B(&shift_arguments); |
| 1132 } | 1132 } |
| 1133 | 1133 |
| 1134 // 3b. Check for function proxy. | 1134 // 3b. Check for function proxy. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 &push_receiver); | 1271 &push_receiver); |
| 1272 | 1272 |
| 1273 // Change context eagerly to get the right global object if necessary. | 1273 // Change context eagerly to get the right global object if necessary. |
| 1274 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 1274 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); |
| 1275 // Load the shared function info. | 1275 // Load the shared function info. |
| 1276 __ Ldr(x2, FieldMemOperand(function, | 1276 __ Ldr(x2, FieldMemOperand(function, |
| 1277 JSFunction::kSharedFunctionInfoOffset)); | 1277 JSFunction::kSharedFunctionInfoOffset)); |
| 1278 | 1278 |
| 1279 // Compute and push the receiver. | 1279 // Compute and push the receiver. |
| 1280 // Do not transform the receiver for strict mode functions. | 1280 // Do not transform the receiver for strict mode functions. |
| 1281 Label convert_receiver_to_object, use_global_receiver; | 1281 Label convert_receiver_to_object, use_global_proxy; |
| 1282 __ Ldr(w10, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); | 1282 __ Ldr(w10, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); |
| 1283 __ Tbnz(x10, SharedFunctionInfo::kStrictModeFunction, &push_receiver); | 1283 __ Tbnz(x10, SharedFunctionInfo::kStrictModeFunction, &push_receiver); |
| 1284 // Do not transform the receiver for native functions. | 1284 // Do not transform the receiver for native functions. |
| 1285 __ Tbnz(x10, SharedFunctionInfo::kNative, &push_receiver); | 1285 __ Tbnz(x10, SharedFunctionInfo::kNative, &push_receiver); |
| 1286 | 1286 |
| 1287 // Compute the receiver in sloppy mode. | 1287 // Compute the receiver in sloppy mode. |
| 1288 __ JumpIfSmi(receiver, &convert_receiver_to_object); | 1288 __ JumpIfSmi(receiver, &convert_receiver_to_object); |
| 1289 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_receiver); | 1289 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy); |
| 1290 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, | 1290 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, |
| 1291 &use_global_receiver); | 1291 &use_global_proxy); |
| 1292 | 1292 |
| 1293 // Check if the receiver is already a JavaScript object. | 1293 // Check if the receiver is already a JavaScript object. |
| 1294 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 1294 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |
| 1295 __ JumpIfObjectType(receiver, x10, x11, FIRST_SPEC_OBJECT_TYPE, | 1295 __ JumpIfObjectType(receiver, x10, x11, FIRST_SPEC_OBJECT_TYPE, |
| 1296 &push_receiver, ge); | 1296 &push_receiver, ge); |
| 1297 | 1297 |
| 1298 // Call a builtin to convert the receiver to a regular object. | 1298 // Call a builtin to convert the receiver to a regular object. |
| 1299 __ Bind(&convert_receiver_to_object); | 1299 __ Bind(&convert_receiver_to_object); |
| 1300 __ Push(receiver); | 1300 __ Push(receiver); |
| 1301 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 1301 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 1302 __ Mov(receiver, x0); | 1302 __ Mov(receiver, x0); |
| 1303 __ B(&push_receiver); | 1303 __ B(&push_receiver); |
| 1304 | 1304 |
| 1305 __ Bind(&use_global_receiver); | 1305 __ Bind(&use_global_proxy); |
| 1306 __ Ldr(x10, GlobalObjectMemOperand()); | 1306 __ Ldr(x10, GlobalObjectMemOperand()); |
| 1307 __ Ldr(receiver, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset)); | 1307 __ Ldr(receiver, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset)); |
| 1308 | 1308 |
| 1309 // Push the receiver | 1309 // Push the receiver |
| 1310 __ Bind(&push_receiver); | 1310 __ Bind(&push_receiver); |
| 1311 __ Push(receiver); | 1311 __ Push(receiver); |
| 1312 | 1312 |
| 1313 // Copy all arguments from the array to the stack. | 1313 // Copy all arguments from the array to the stack. |
| 1314 Label entry, loop; | 1314 Label entry, loop; |
| 1315 Register current = x0; | 1315 Register current = x0; |
| 1316 __ Ldr(current, MemOperand(fp, kIndexOffset)); | 1316 __ Ldr(current, MemOperand(fp, kIndexOffset)); |
| 1317 __ B(&entry); | 1317 __ B(&entry); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 __ Unreachable(); | 1556 __ Unreachable(); |
| 1557 } | 1557 } |
| 1558 } | 1558 } |
| 1559 | 1559 |
| 1560 | 1560 |
| 1561 #undef __ | 1561 #undef __ |
| 1562 | 1562 |
| 1563 } } // namespace v8::internal | 1563 } } // namespace v8::internal |
| 1564 | 1564 |
| 1565 #endif // V8_TARGET_ARCH_ARM | 1565 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |