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 |