OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 __ sra(a0, a0, kSmiTagSize); // Un-tag. | 1107 __ sra(a0, a0, kSmiTagSize); // Un-tag. |
1108 // Leave internal frame. | 1108 // Leave internal frame. |
1109 } | 1109 } |
1110 // Restore the function to a1, and the flag to t0. | 1110 // Restore the function to a1, and the flag to t0. |
1111 __ sll(at, a0, kPointerSizeLog2); | 1111 __ sll(at, a0, kPointerSizeLog2); |
1112 __ addu(at, sp, at); | 1112 __ addu(at, sp, at); |
1113 __ lw(a1, MemOperand(at)); | 1113 __ lw(a1, MemOperand(at)); |
1114 __ li(t0, Operand(0, RelocInfo::NONE32)); | 1114 __ li(t0, Operand(0, RelocInfo::NONE32)); |
1115 __ Branch(&patch_receiver); | 1115 __ Branch(&patch_receiver); |
1116 | 1116 |
1117 // Use the global receiver object from the called function as the | |
1118 // receiver. | |
1119 __ bind(&use_global_receiver); | 1117 __ bind(&use_global_receiver); |
1120 __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 1118 __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
1121 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); | 1119 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); |
1122 | 1120 |
1123 __ bind(&patch_receiver); | 1121 __ bind(&patch_receiver); |
1124 __ sll(at, a0, kPointerSizeLog2); | 1122 __ sll(at, a0, kPointerSizeLog2); |
1125 __ addu(a3, sp, at); | 1123 __ addu(a3, sp, at); |
1126 __ sw(a2, MemOperand(a3, -kPointerSize)); | 1124 __ sw(a2, MemOperand(a3, -kPointerSize)); |
1127 | 1125 |
1128 __ Branch(&shift_arguments); | 1126 __ Branch(&shift_arguments); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 // 5b. Get the code to call from the function and check that the number of | 1196 // 5b. Get the code to call from the function and check that the number of |
1199 // expected arguments matches what we're providing. If so, jump | 1197 // expected arguments matches what we're providing. If so, jump |
1200 // (tail-call) to the code in register edx without checking arguments. | 1198 // (tail-call) to the code in register edx without checking arguments. |
1201 // a0: actual number of arguments | 1199 // a0: actual number of arguments |
1202 // a1: function | 1200 // a1: function |
1203 __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 1201 __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
1204 __ lw(a2, | 1202 __ lw(a2, |
1205 FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset)); | 1203 FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset)); |
1206 __ sra(a2, a2, kSmiTagSize); | 1204 __ sra(a2, a2, kSmiTagSize); |
1207 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1205 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
1208 __ SetCallKind(t1, CALL_AS_METHOD); | 1206 __ SetCallKind(t1, CALL_AS_FUNCTION); |
1209 // Check formal and actual parameter counts. | 1207 // Check formal and actual parameter counts. |
1210 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1208 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1211 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); | 1209 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); |
1212 | 1210 |
1213 ParameterCount expected(0); | 1211 ParameterCount expected(0); |
1214 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, | 1212 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, |
1215 NullCallWrapper(), CALL_AS_METHOD); | 1213 NullCallWrapper(), CALL_AS_FUNCTION); |
1216 } | 1214 } |
1217 | 1215 |
1218 | 1216 |
1219 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 1217 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
1220 const int kIndexOffset = | 1218 const int kIndexOffset = |
1221 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1219 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1222 const int kLimitOffset = | 1220 const int kLimitOffset = |
1223 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1221 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1224 const int kArgsOffset = 2 * kPointerSize; | 1222 const int kArgsOffset = 2 * kPointerSize; |
1225 const int kRecvOffset = 3 * kPointerSize; | 1223 const int kRecvOffset = 3 * kPointerSize; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE)); | 1296 __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE)); |
1299 | 1297 |
1300 // Convert the receiver to a regular object. | 1298 // Convert the receiver to a regular object. |
1301 // a0: receiver | 1299 // a0: receiver |
1302 __ bind(&call_to_object); | 1300 __ bind(&call_to_object); |
1303 __ push(a0); | 1301 __ push(a0); |
1304 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 1302 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
1305 __ mov(a0, v0); // Put object in a0 to match other paths to push_receiver. | 1303 __ mov(a0, v0); // Put object in a0 to match other paths to push_receiver. |
1306 __ Branch(&push_receiver); | 1304 __ Branch(&push_receiver); |
1307 | 1305 |
1308 // Use the current global receiver object as the receiver. | |
1309 __ bind(&use_global_receiver); | 1306 __ bind(&use_global_receiver); |
1310 __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 1307 __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
1311 __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | 1308 __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); |
1312 | 1309 |
1313 // Push the receiver. | 1310 // Push the receiver. |
1314 // a0: receiver | 1311 // a0: receiver |
1315 __ bind(&push_receiver); | 1312 __ bind(&push_receiver); |
1316 __ push(a0); | 1313 __ push(a0); |
1317 | 1314 |
1318 // Copy all arguments from the array to the stack. | 1315 // Copy all arguments from the array to the stack. |
(...skipping 16 matching lines...) Expand all Loading... |
1335 __ lw(a0, MemOperand(fp, kIndexOffset)); | 1332 __ lw(a0, MemOperand(fp, kIndexOffset)); |
1336 __ Addu(a0, a0, Operand(1 << kSmiTagSize)); | 1333 __ Addu(a0, a0, Operand(1 << kSmiTagSize)); |
1337 __ sw(a0, MemOperand(fp, kIndexOffset)); | 1334 __ sw(a0, MemOperand(fp, kIndexOffset)); |
1338 | 1335 |
1339 // Test if the copy loop has finished copying all the elements from the | 1336 // Test if the copy loop has finished copying all the elements from the |
1340 // arguments object. | 1337 // arguments object. |
1341 __ bind(&entry); | 1338 __ bind(&entry); |
1342 __ lw(a1, MemOperand(fp, kLimitOffset)); | 1339 __ lw(a1, MemOperand(fp, kLimitOffset)); |
1343 __ Branch(&loop, ne, a0, Operand(a1)); | 1340 __ Branch(&loop, ne, a0, Operand(a1)); |
1344 | 1341 |
1345 // Invoke the function. | 1342 // Call the function. |
1346 Label call_proxy; | 1343 Label call_proxy; |
1347 ParameterCount actual(a0); | 1344 ParameterCount actual(a0); |
1348 __ sra(a0, a0, kSmiTagSize); | 1345 __ sra(a0, a0, kSmiTagSize); |
1349 __ lw(a1, MemOperand(fp, kFunctionOffset)); | 1346 __ lw(a1, MemOperand(fp, kFunctionOffset)); |
1350 __ GetObjectType(a1, a2, a2); | 1347 __ GetObjectType(a1, a2, a2); |
1351 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); | 1348 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); |
1352 | 1349 |
1353 __ InvokeFunction(a1, actual, CALL_FUNCTION, | 1350 __ InvokeFunction(a1, actual, CALL_FUNCTION, |
1354 NullCallWrapper(), CALL_AS_METHOD); | 1351 NullCallWrapper(), CALL_AS_FUNCTION); |
1355 | 1352 |
1356 frame_scope.GenerateLeaveFrame(); | 1353 frame_scope.GenerateLeaveFrame(); |
1357 __ Ret(USE_DELAY_SLOT); | 1354 __ Ret(USE_DELAY_SLOT); |
1358 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. | 1355 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. |
1359 | 1356 |
1360 // Invoke the function proxy. | 1357 // Call the function proxy. |
1361 __ bind(&call_proxy); | 1358 __ bind(&call_proxy); |
1362 __ push(a1); // Add function proxy as last argument. | 1359 __ push(a1); // Add function proxy as last argument. |
1363 __ Addu(a0, a0, Operand(1)); | 1360 __ Addu(a0, a0, Operand(1)); |
1364 __ li(a2, Operand(0, RelocInfo::NONE32)); | 1361 __ li(a2, Operand(0, RelocInfo::NONE32)); |
1365 __ SetCallKind(t1, CALL_AS_METHOD); | 1362 __ SetCallKind(t1, CALL_AS_FUNCTION); |
1366 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); | 1363 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); |
1367 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1364 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1368 RelocInfo::CODE_TARGET); | 1365 RelocInfo::CODE_TARGET); |
1369 // Tear down the internal frame and remove function, receiver and args. | 1366 // Tear down the internal frame and remove function, receiver and args. |
1370 } | 1367 } |
1371 | 1368 |
1372 __ Ret(USE_DELAY_SLOT); | 1369 __ Ret(USE_DELAY_SLOT); |
1373 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. | 1370 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. |
1374 } | 1371 } |
1375 | 1372 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1518 __ bind(&dont_adapt_arguments); | 1515 __ bind(&dont_adapt_arguments); |
1519 __ Jump(a3); | 1516 __ Jump(a3); |
1520 } | 1517 } |
1521 | 1518 |
1522 | 1519 |
1523 #undef __ | 1520 #undef __ |
1524 | 1521 |
1525 } } // namespace v8::internal | 1522 } } // namespace v8::internal |
1526 | 1523 |
1527 #endif // V8_TARGET_ARCH_MIPS | 1524 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |