| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 // 2. Get the function to call (passed as receiver) from the stack, check | 1180 // 2. Get the function to call (passed as receiver) from the stack, check |
| 1181 // if it is a function. | 1181 // if it is a function. |
| 1182 // r0: actual number of arguments | 1182 // r0: actual number of arguments |
| 1183 Label non_function; | 1183 Label non_function; |
| 1184 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 1184 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 1185 __ tst(r1, Operand(kSmiTagMask)); | 1185 __ tst(r1, Operand(kSmiTagMask)); |
| 1186 __ b(eq, &non_function); | 1186 __ b(eq, &non_function); |
| 1187 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | 1187 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
| 1188 __ b(ne, &non_function); | 1188 __ b(ne, &non_function); |
| 1189 | 1189 |
| 1190 // 3a. Patch the first argument if necessary when calling a function. | |
| 1191 // r0: actual number of arguments | 1190 // r0: actual number of arguments |
| 1192 // r1: function | 1191 // r1: function |
| 1192 // Change context eagerly in case we need the global receiver. |
| 1193 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 1194 |
| 1193 Label shift_arguments; | 1195 Label shift_arguments; |
| 1194 { Label convert_to_object, use_global_receiver, patch_receiver; | 1196 __ jmp(&shift_arguments); |
| 1195 // Change context eagerly in case we need the global receiver. | |
| 1196 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | |
| 1197 | 1197 |
| 1198 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); | 1198 // 3. Patch the first argument when calling a non-function. The |
| 1199 __ ldr(r2, MemOperand(r2, -kPointerSize)); | 1199 // CALL_NON_FUNCTION builtin expects the non-function callee as |
| 1200 // r0: actual number of arguments | 1200 // receiver, so overwrite the first argument which will ultimately |
| 1201 // r1: function | 1201 // become the receiver. |
| 1202 // r2: first argument | |
| 1203 __ tst(r2, Operand(kSmiTagMask)); | |
| 1204 __ b(eq, &convert_to_object); | |
| 1205 | |
| 1206 __ LoadRoot(r3, Heap::kNullValueRootIndex); | |
| 1207 __ cmp(r2, r3); | |
| 1208 __ b(eq, &use_global_receiver); | |
| 1209 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | |
| 1210 __ cmp(r2, r3); | |
| 1211 __ b(eq, &use_global_receiver); | |
| 1212 | |
| 1213 __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE); | |
| 1214 __ b(lt, &convert_to_object); | |
| 1215 __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE)); | |
| 1216 __ b(le, &shift_arguments); | |
| 1217 | |
| 1218 __ bind(&convert_to_object); | |
| 1219 __ EnterInternalFrame(); // In order to preserve argument count. | |
| 1220 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); // Smi-tagged. | |
| 1221 __ push(r0); | |
| 1222 | |
| 1223 __ push(r2); | |
| 1224 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); | |
| 1225 __ mov(r2, r0); | |
| 1226 | |
| 1227 __ pop(r0); | |
| 1228 __ mov(r0, Operand(r0, ASR, kSmiTagSize)); | |
| 1229 __ LeaveInternalFrame(); | |
| 1230 // Restore the function to r1. | |
| 1231 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | |
| 1232 __ jmp(&patch_receiver); | |
| 1233 | |
| 1234 // Use the global receiver object from the called function as the | |
| 1235 // receiver. | |
| 1236 __ bind(&use_global_receiver); | |
| 1237 const int kGlobalIndex = | |
| 1238 Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; | |
| 1239 __ ldr(r2, FieldMemOperand(cp, kGlobalIndex)); | |
| 1240 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset)); | |
| 1241 __ ldr(r2, FieldMemOperand(r2, kGlobalIndex)); | |
| 1242 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); | |
| 1243 | |
| 1244 __ bind(&patch_receiver); | |
| 1245 __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2)); | |
| 1246 __ str(r2, MemOperand(r3, -kPointerSize)); | |
| 1247 | |
| 1248 __ jmp(&shift_arguments); | |
| 1249 } | |
| 1250 | |
| 1251 // 3b. Patch the first argument when calling a non-function. The | |
| 1252 // CALL_NON_FUNCTION builtin expects the non-function callee as | |
| 1253 // receiver, so overwrite the first argument which will ultimately | |
| 1254 // become the receiver. | |
| 1255 // r0: actual number of arguments | 1202 // r0: actual number of arguments |
| 1256 // r1: function | 1203 // r1: function |
| 1257 __ bind(&non_function); | 1204 __ bind(&non_function); |
| 1258 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); | 1205 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); |
| 1259 __ str(r1, MemOperand(r2, -kPointerSize)); | 1206 __ str(r1, MemOperand(r2, -kPointerSize)); |
| 1260 // Clear r1 to indicate a non-function being called. | 1207 // Clear r1 to indicate a non-function being called. |
| 1261 __ mov(r1, Operand(0, RelocInfo::NONE)); | 1208 __ mov(r1, Operand(0, RelocInfo::NONE)); |
| 1262 | 1209 |
| 1263 // 4. Shift arguments and return address one slot down on the stack | 1210 // 4. Shift arguments and return address one slot down on the stack |
| 1264 // (overwriting the original receiver). Adjust argument count to make | 1211 // (overwriting the original receiver). Adjust argument count to make |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 // Push current limit and index. | 1299 // Push current limit and index. |
| 1353 __ bind(&okay); | 1300 __ bind(&okay); |
| 1354 __ push(r0); // limit | 1301 __ push(r0); // limit |
| 1355 __ mov(r1, Operand(0, RelocInfo::NONE)); // initial index | 1302 __ mov(r1, Operand(0, RelocInfo::NONE)); // initial index |
| 1356 __ push(r1); | 1303 __ push(r1); |
| 1357 | 1304 |
| 1358 // Change context eagerly to get the right global object if necessary. | 1305 // Change context eagerly to get the right global object if necessary. |
| 1359 __ ldr(r0, MemOperand(fp, kFunctionOffset)); | 1306 __ ldr(r0, MemOperand(fp, kFunctionOffset)); |
| 1360 __ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); | 1307 __ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); |
| 1361 | 1308 |
| 1362 // Compute the receiver. | 1309 // Push the receiver. |
| 1363 Label call_to_object, use_global_receiver, push_receiver; | |
| 1364 __ ldr(r0, MemOperand(fp, kRecvOffset)); | 1310 __ ldr(r0, MemOperand(fp, kRecvOffset)); |
| 1365 __ tst(r0, Operand(kSmiTagMask)); | |
| 1366 __ b(eq, &call_to_object); | |
| 1367 __ LoadRoot(r1, Heap::kNullValueRootIndex); | |
| 1368 __ cmp(r0, r1); | |
| 1369 __ b(eq, &use_global_receiver); | |
| 1370 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); | |
| 1371 __ cmp(r0, r1); | |
| 1372 __ b(eq, &use_global_receiver); | |
| 1373 | |
| 1374 // Check if the receiver is already a JavaScript object. | |
| 1375 // r0: receiver | 1311 // r0: receiver |
| 1376 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); | |
| 1377 __ b(lt, &call_to_object); | |
| 1378 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); | |
| 1379 __ b(le, &push_receiver); | |
| 1380 | |
| 1381 // Convert the receiver to a regular object. | |
| 1382 // r0: receiver | |
| 1383 __ bind(&call_to_object); | |
| 1384 __ push(r0); | |
| 1385 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); | |
| 1386 __ b(&push_receiver); | |
| 1387 | |
| 1388 // Use the current global receiver object as the receiver. | |
| 1389 __ bind(&use_global_receiver); | |
| 1390 const int kGlobalOffset = | |
| 1391 Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; | |
| 1392 __ ldr(r0, FieldMemOperand(cp, kGlobalOffset)); | |
| 1393 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset)); | |
| 1394 __ ldr(r0, FieldMemOperand(r0, kGlobalOffset)); | |
| 1395 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | |
| 1396 | |
| 1397 // Push the receiver. | |
| 1398 // r0: receiver | |
| 1399 __ bind(&push_receiver); | |
| 1400 __ push(r0); | 1312 __ push(r0); |
| 1401 | 1313 |
| 1402 // Copy all arguments from the array to the stack. | 1314 // Copy all arguments from the array to the stack. |
| 1403 Label entry, loop; | 1315 Label entry, loop; |
| 1404 __ ldr(r0, MemOperand(fp, kIndexOffset)); | 1316 __ ldr(r0, MemOperand(fp, kIndexOffset)); |
| 1405 __ b(&entry); | 1317 __ b(&entry); |
| 1406 | 1318 |
| 1407 // Load the current argument from the arguments array and push it to the | 1319 // Load the current argument from the arguments array and push it to the |
| 1408 // stack. | 1320 // stack. |
| 1409 // r0: current argument index | 1321 // r0: current argument index |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 __ bind(&dont_adapt_arguments); | 1477 __ bind(&dont_adapt_arguments); |
| 1566 __ Jump(r3); | 1478 __ Jump(r3); |
| 1567 } | 1479 } |
| 1568 | 1480 |
| 1569 | 1481 |
| 1570 #undef __ | 1482 #undef __ |
| 1571 | 1483 |
| 1572 } } // namespace v8::internal | 1484 } } // namespace v8::internal |
| 1573 | 1485 |
| 1574 #endif // V8_TARGET_ARCH_ARM | 1486 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |