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 3310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3321 | 3321 |
3322 __ bind(&done); | 3322 __ bind(&done); |
3323 } | 3323 } |
3324 | 3324 |
3325 | 3325 |
3326 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3326 void CallFunctionStub::Generate(MacroAssembler* masm) { |
3327 // a1 : the function to call | 3327 // a1 : the function to call |
3328 // a2 : cache cell for call target | 3328 // a2 : cache cell for call target |
3329 Label slow, non_function; | 3329 Label slow, non_function; |
3330 | 3330 |
| 3331 // Check that the function is really a JavaScript function. |
| 3332 // a1: pushed function (to be verified) |
| 3333 __ JumpIfSmi(a1, &non_function); |
| 3334 |
3331 // The receiver might implicitly be the global object. This is | 3335 // The receiver might implicitly be the global object. This is |
3332 // indicated by passing the hole as the receiver to the call | 3336 // indicated by passing the hole as the receiver to the call |
3333 // function stub. | 3337 // function stub. |
3334 if (ReceiverMightBeImplicit()) { | 3338 if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) { |
3335 Label call; | 3339 Label try_call, call, patch_current_context; |
3336 // Get the receiver from the stack. | 3340 if (ReceiverMightBeImplicit()) { |
3337 // function, receiver [, arguments] | 3341 // Get the receiver from the stack. |
3338 __ lw(t0, MemOperand(sp, argc_ * kPointerSize)); | 3342 // function, receiver [, arguments] |
3339 // Call as function is indicated with the hole. | 3343 __ lw(t0, MemOperand(sp, argc_ * kPointerSize)); |
3340 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 3344 // Call as function is indicated with the hole. |
3341 __ Branch(&call, ne, t0, Operand(at)); | 3345 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 3346 __ Branch(&try_call, ne, t0, Operand(at)); |
| 3347 } |
3342 // Patch the receiver on the stack with the global receiver object. | 3348 // Patch the receiver on the stack with the global receiver object. |
3343 __ lw(a3, | 3349 // Goto slow case if we do not have a function. |
3344 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 3350 __ GetObjectType(a1, a3, a3); |
3345 __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset)); | 3351 __ Branch(&patch_current_context, ne, a3, Operand(JS_FUNCTION_TYPE)); |
| 3352 CallStubCompiler::FetchGlobalProxy(masm, a3, a1); |
3346 __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); | 3353 __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); |
| 3354 __ Branch(&call); |
| 3355 |
| 3356 __ bind(&patch_current_context); |
| 3357 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); |
| 3358 __ sw(t0, MemOperand(sp, argc_ * kPointerSize)); |
| 3359 __ Branch(&slow); |
| 3360 |
| 3361 __ bind(&try_call); |
| 3362 // Get the map of the function object. |
| 3363 __ GetObjectType(a1, a3, a3); |
| 3364 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); |
| 3365 |
3347 __ bind(&call); | 3366 __ bind(&call); |
| 3367 } else { |
| 3368 // Get the map of the function object. |
| 3369 __ GetObjectType(a1, a3, a3); |
| 3370 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); |
3348 } | 3371 } |
3349 | 3372 |
3350 // Check that the function is really a JavaScript function. | |
3351 // a1: pushed function (to be verified) | |
3352 __ JumpIfSmi(a1, &non_function); | |
3353 // Get the map of the function object. | |
3354 __ GetObjectType(a1, a3, a3); | |
3355 __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); | |
3356 | |
3357 if (RecordCallTarget()) { | 3373 if (RecordCallTarget()) { |
3358 GenerateRecordCallTarget(masm); | 3374 GenerateRecordCallTarget(masm); |
3359 } | 3375 } |
3360 | 3376 |
3361 // Fast-case: Invoke the function now. | 3377 // Fast-case: Invoke the function now. |
3362 // a1: pushed function | 3378 // a1: pushed function |
3363 ParameterCount actual(argc_); | 3379 ParameterCount actual(argc_); |
3364 | 3380 |
3365 if (ReceiverMightBeImplicit()) { | 3381 if (ReceiverMightBeImplicit()) { |
3366 Label call_as_function; | 3382 Label call_as_function; |
(...skipping 22 matching lines...) Expand all Loading... |
3389 masm->isolate()->heap()->undefined_value()); | 3405 masm->isolate()->heap()->undefined_value()); |
3390 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3406 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
3391 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); | 3407 __ sw(at, FieldMemOperand(a2, Cell::kValueOffset)); |
3392 } | 3408 } |
3393 // Check for function proxy. | 3409 // Check for function proxy. |
3394 __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); | 3410 __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); |
3395 __ push(a1); // Put proxy as additional argument. | 3411 __ push(a1); // Put proxy as additional argument. |
3396 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); | 3412 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); |
3397 __ li(a2, Operand(0, RelocInfo::NONE32)); | 3413 __ li(a2, Operand(0, RelocInfo::NONE32)); |
3398 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); | 3414 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); |
3399 __ SetCallKind(t1, CALL_AS_METHOD); | 3415 __ SetCallKind(t1, CALL_AS_FUNCTION); |
3400 { | 3416 { |
3401 Handle<Code> adaptor = | 3417 Handle<Code> adaptor = |
3402 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3418 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
3403 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 3419 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
3404 } | 3420 } |
3405 | 3421 |
3406 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 3422 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
3407 // of the original receiver from the call site). | 3423 // of the original receiver from the call site). |
3408 __ bind(&non_function); | 3424 __ bind(&non_function); |
3409 __ sw(a1, MemOperand(sp, argc_ * kPointerSize)); | 3425 __ sw(a1, MemOperand(sp, argc_ * kPointerSize)); |
(...skipping 2606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6016 __ bind(&fast_elements_case); | 6032 __ bind(&fast_elements_case); |
6017 GenerateCase(masm, FAST_ELEMENTS); | 6033 GenerateCase(masm, FAST_ELEMENTS); |
6018 } | 6034 } |
6019 | 6035 |
6020 | 6036 |
6021 #undef __ | 6037 #undef __ |
6022 | 6038 |
6023 } } // namespace v8::internal | 6039 } } // namespace v8::internal |
6024 | 6040 |
6025 #endif // V8_TARGET_ARCH_MIPS | 6041 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |