OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
406 Register holder, | 406 Register holder, |
407 Register name, | 407 Register name, |
408 JSObject* holder_obj) { | 408 JSObject* holder_obj) { |
409 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 409 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
410 __ CallExternalReference( | 410 __ CallExternalReference( |
411 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)), | 411 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)), |
412 5); | 412 5); |
413 } | 413 } |
414 | 414 |
415 | 415 |
416 // Amount of pointers to be reserved on stack for v8::Arguments::implicit_args_. | |
antonm
2010/11/09 13:56:19
I am not a native speaker, but I would rather say
antonm
2010/11/09 13:56:19
'v8::Arguments::implicit_args_': should either be
| |
417 static const int kFastApiCallArguments = 3; | |
418 | |
419 | |
416 // Reserves space for the extra arguments to FastHandleApiCall in the | 420 // Reserves space for the extra arguments to FastHandleApiCall in the |
417 // caller's frame. | 421 // caller's frame. |
418 // | 422 // |
419 // These arguments are set by CheckPrototypes and GenerateFastApiCall. | 423 // These arguments are set by CheckPrototypes and GenerateFastApiCall. |
420 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { | 424 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { |
421 // ----------- S t a t e ------------- | 425 // ----------- S t a t e ------------- |
422 // -- esp[0] : return address | 426 // -- esp[0] : return address |
423 // -- esp[4] : last argument in the internal frame of the caller | 427 // -- esp[4] : last argument in the internal frame of the caller |
424 // ----------------------------------- | 428 // ----------------------------------- |
425 __ pop(scratch); | 429 __ pop(scratch); |
426 __ push(Immediate(Smi::FromInt(0))); | 430 for (int i = 0; i < kFastApiCallArguments; i++) { |
427 __ push(Immediate(Smi::FromInt(0))); | 431 __ push(Immediate(Smi::FromInt(0))); |
428 __ push(Immediate(Smi::FromInt(0))); | 432 } |
429 __ push(Immediate(Smi::FromInt(0))); | |
430 __ push(scratch); | 433 __ push(scratch); |
431 } | 434 } |
432 | 435 |
433 | 436 |
434 // Undoes the effects of ReserveSpaceForFastApiCall. | 437 // Undoes the effects of ReserveSpaceForFastApiCall. |
435 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { | 438 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { |
436 // ----------- S t a t e ------------- | 439 // ----------- S t a t e ------------- |
437 // -- esp[0] : return address | 440 // -- esp[0] : return address. |
438 // -- esp[4] : last fast api call extra argument | 441 // -- esp[4] : last fast api call extra argument. |
439 // -- ... | 442 // -- ... |
440 // -- esp[16] : first fast api call extra argument | 443 // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument. |
441 // -- esp[20] : last argument in the internal frame | 444 // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal |
445 // frame. | |
442 // ----------------------------------- | 446 // ----------------------------------- |
443 __ pop(scratch); | 447 __ pop(scratch); |
444 __ add(Operand(esp), Immediate(kPointerSize * 4)); | 448 __ add(Operand(esp), Immediate(kPointerSize * kFastApiCallArguments)); |
445 __ push(scratch); | 449 __ push(scratch); |
446 } | 450 } |
447 | 451 |
448 | 452 |
449 // Generates call to FastHandleApiCall builtin. | 453 // Generates call to FastHandleApiCall builtin. |
450 static void GenerateFastApiCall(MacroAssembler* masm, | 454 static bool GenerateFastApiCall(MacroAssembler* masm, |
451 const CallOptimization& optimization, | 455 const CallOptimization& optimization, |
452 int argc) { | 456 int argc, |
457 Failure** failure) { | |
453 // ----------- S t a t e ------------- | 458 // ----------- S t a t e ------------- |
454 // -- esp[0] : return address | 459 // -- esp[0] : return address |
455 // -- esp[4] : object passing the type check | 460 // -- esp[4] : object passing the type check |
456 // (last fast api call extra argument, | 461 // (last fast api call extra argument, |
457 // set by CheckPrototypes) | 462 // set by CheckPrototypes) |
458 // -- esp[8] : api call data | 463 // -- esp[8] : api function |
459 // -- esp[12] : api callback | |
460 // -- esp[16] : api function | |
461 // (first fast api call extra argument) | 464 // (first fast api call extra argument) |
462 // -- esp[20] : last argument | 465 // -- esp[12] : api call data |
466 // -- esp[16] : last argument | |
463 // -- ... | 467 // -- ... |
464 // -- esp[(argc + 5) * 4] : first argument | 468 // -- esp[(argc + 3) * 4] : first argument |
465 // -- esp[(argc + 6) * 4] : receiver | 469 // -- esp[(argc + 4) * 4] : receiver |
466 // ----------------------------------- | 470 // ----------------------------------- |
467 | |
468 // Get the function and setup the context. | 471 // Get the function and setup the context. |
469 JSFunction* function = optimization.constant_function(); | 472 JSFunction* function = optimization.constant_function(); |
470 __ mov(edi, Immediate(Handle<JSFunction>(function))); | 473 __ mov(edi, Immediate(Handle<JSFunction>(function))); |
471 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 474 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
472 | 475 |
473 // Pass the additional arguments FastHandleApiCall expects. | 476 // Pass the additional arguments FastHandleApiCall expects. |
474 __ mov(Operand(esp, 4 * kPointerSize), edi); | 477 __ mov(Operand(esp, 2 * kPointerSize), edi); |
475 bool info_loaded = false; | 478 Object* call_data = optimization.api_call_info()->data(); |
476 Object* callback = optimization.api_call_info()->callback(); | 479 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); |
477 if (Heap::InNewSpace(callback)) { | 480 if (Heap::InNewSpace(call_data)) { |
478 info_loaded = true; | 481 __ mov(ecx, api_call_info_handle); |
479 __ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info())); | 482 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); |
480 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kCallbackOffset)); | |
481 __ mov(Operand(esp, 3 * kPointerSize), ebx); | 483 __ mov(Operand(esp, 3 * kPointerSize), ebx); |
482 } else { | 484 } else { |
483 __ mov(Operand(esp, 3 * kPointerSize), Immediate(Handle<Object>(callback))); | 485 __ mov(Operand(esp, 3 * kPointerSize), |
484 } | |
485 Object* call_data = optimization.api_call_info()->data(); | |
486 if (Heap::InNewSpace(call_data)) { | |
487 if (!info_loaded) { | |
488 __ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info())); | |
489 } | |
490 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); | |
491 __ mov(Operand(esp, 2 * kPointerSize), ebx); | |
492 } else { | |
493 __ mov(Operand(esp, 2 * kPointerSize), | |
494 Immediate(Handle<Object>(call_data))); | 486 Immediate(Handle<Object>(call_data))); |
495 } | 487 } |
496 | 488 |
497 // Set the number of arguments. | 489 // Prepare arguments for ApiCallEntryStub. |
498 __ mov(eax, Immediate(argc + 4)); | 490 __ lea(eax, Operand(esp, 3 * kPointerSize)); |
491 __ lea(ebx, Operand(esp, (argc + 3) * kPointerSize)); | |
492 __ Set(edx, Immediate(argc)); | |
499 | 493 |
500 // Jump to the fast api call builtin (tail call). | 494 Object* callback = optimization.api_call_info()->callback(); |
501 Handle<Code> code = Handle<Code>( | 495 Address api_function_address = v8::ToCData<Address>(callback); |
502 Builtins::builtin(Builtins::FastHandleApiCall)); | 496 ApiFunction fun(api_function_address); |
503 ParameterCount expected(0); | 497 |
504 __ InvokeCode(code, expected, expected, | 498 ApiCallEntryStub stub(api_call_info_handle, &fun); |
505 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 499 |
500 __ EnterInternalFrame(); | |
501 | |
502 // Emitting a stub call may try to allocate (if the code is not | |
503 // already generated). Do not allow the assembler to perform a | |
504 // garbage collection but instead return the allocation failure | |
505 // object. | |
506 MaybeObject* result = masm->TryCallStub(&stub); | |
507 if (result->IsFailure()) { | |
508 *failure = Failure::cast(result); | |
509 return false; | |
510 } | |
511 | |
512 __ LeaveInternalFrame(); | |
513 __ ret((argc + 4) * kPointerSize); | |
514 return true; | |
506 } | 515 } |
507 | 516 |
508 | 517 |
509 class CallInterceptorCompiler BASE_EMBEDDED { | 518 class CallInterceptorCompiler BASE_EMBEDDED { |
510 public: | 519 public: |
511 CallInterceptorCompiler(StubCompiler* stub_compiler, | 520 CallInterceptorCompiler(StubCompiler* stub_compiler, |
512 const ParameterCount& arguments, | 521 const ParameterCount& arguments, |
513 Register name) | 522 Register name) |
514 : stub_compiler_(stub_compiler), | 523 : stub_compiler_(stub_compiler), |
515 arguments_(arguments), | 524 arguments_(arguments), |
516 name_(name) {} | 525 name_(name) {} |
517 | 526 |
518 void Compile(MacroAssembler* masm, | 527 bool Compile(MacroAssembler* masm, |
519 JSObject* object, | 528 JSObject* object, |
520 JSObject* holder, | 529 JSObject* holder, |
521 String* name, | 530 String* name, |
522 LookupResult* lookup, | 531 LookupResult* lookup, |
523 Register receiver, | 532 Register receiver, |
524 Register scratch1, | 533 Register scratch1, |
525 Register scratch2, | 534 Register scratch2, |
526 Register scratch3, | 535 Register scratch3, |
527 Label* miss) { | 536 Label* miss, |
537 Failure** failure) { | |
528 ASSERT(holder->HasNamedInterceptor()); | 538 ASSERT(holder->HasNamedInterceptor()); |
529 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 539 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
530 | 540 |
531 // Check that the receiver isn't a smi. | 541 // Check that the receiver isn't a smi. |
532 __ test(receiver, Immediate(kSmiTagMask)); | 542 __ test(receiver, Immediate(kSmiTagMask)); |
533 __ j(zero, miss, not_taken); | 543 __ j(zero, miss, not_taken); |
534 | 544 |
535 CallOptimization optimization(lookup); | 545 CallOptimization optimization(lookup); |
536 | 546 |
537 if (optimization.is_constant_call()) { | 547 if (optimization.is_constant_call()) { |
538 CompileCacheable(masm, | 548 return CompileCacheable(masm, |
539 object, | 549 object, |
540 receiver, | 550 receiver, |
541 scratch1, | 551 scratch1, |
542 scratch2, | 552 scratch2, |
543 scratch3, | 553 scratch3, |
544 holder, | 554 holder, |
545 lookup, | 555 lookup, |
546 name, | 556 name, |
547 optimization, | 557 optimization, |
548 miss); | 558 miss, |
559 failure); | |
549 } else { | 560 } else { |
550 CompileRegular(masm, | 561 CompileRegular(masm, |
551 object, | 562 object, |
552 receiver, | 563 receiver, |
553 scratch1, | 564 scratch1, |
554 scratch2, | 565 scratch2, |
555 scratch3, | 566 scratch3, |
556 name, | 567 name, |
557 holder, | 568 holder, |
558 miss); | 569 miss); |
570 return true; | |
559 } | 571 } |
560 } | 572 } |
561 | 573 |
562 private: | 574 private: |
563 void CompileCacheable(MacroAssembler* masm, | 575 bool CompileCacheable(MacroAssembler* masm, |
564 JSObject* object, | 576 JSObject* object, |
565 Register receiver, | 577 Register receiver, |
566 Register scratch1, | 578 Register scratch1, |
567 Register scratch2, | 579 Register scratch2, |
568 Register scratch3, | 580 Register scratch3, |
569 JSObject* interceptor_holder, | 581 JSObject* interceptor_holder, |
570 LookupResult* lookup, | 582 LookupResult* lookup, |
571 String* name, | 583 String* name, |
572 const CallOptimization& optimization, | 584 const CallOptimization& optimization, |
573 Label* miss_label) { | 585 Label* miss_label, |
586 Failure** failure) { | |
574 ASSERT(optimization.is_constant_call()); | 587 ASSERT(optimization.is_constant_call()); |
575 ASSERT(!lookup->holder()->IsGlobalObject()); | 588 ASSERT(!lookup->holder()->IsGlobalObject()); |
576 | 589 |
577 int depth1 = kInvalidProtoDepth; | 590 int depth1 = kInvalidProtoDepth; |
578 int depth2 = kInvalidProtoDepth; | 591 int depth2 = kInvalidProtoDepth; |
579 bool can_do_fast_api_call = false; | 592 bool can_do_fast_api_call = false; |
580 if (optimization.is_simple_api_call() && | 593 if (optimization.is_simple_api_call() && |
581 !lookup->holder()->IsGlobalObject()) { | 594 !lookup->holder()->IsGlobalObject()) { |
582 depth1 = | 595 depth1 = |
583 optimization.GetPrototypeDepthOfExpectedType(object, | 596 optimization.GetPrototypeDepthOfExpectedType(object, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
625 } else { | 638 } else { |
626 // CheckPrototypes has a side effect of fetching a 'holder' | 639 // CheckPrototypes has a side effect of fetching a 'holder' |
627 // for API (object which is instanceof for the signature). It's | 640 // for API (object which is instanceof for the signature). It's |
628 // safe to omit it here, as if present, it should be fetched | 641 // safe to omit it here, as if present, it should be fetched |
629 // by the previous CheckPrototypes. | 642 // by the previous CheckPrototypes. |
630 ASSERT(depth2 == kInvalidProtoDepth); | 643 ASSERT(depth2 == kInvalidProtoDepth); |
631 } | 644 } |
632 | 645 |
633 // Invoke function. | 646 // Invoke function. |
634 if (can_do_fast_api_call) { | 647 if (can_do_fast_api_call) { |
635 GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 648 bool success = GenerateFastApiCall(masm, optimization, |
649 arguments_.immediate(), failure); | |
650 if (!success) { | |
651 return false; | |
652 } | |
636 } else { | 653 } else { |
637 __ InvokeFunction(optimization.constant_function(), arguments_, | 654 __ InvokeFunction(optimization.constant_function(), arguments_, |
638 JUMP_FUNCTION); | 655 JUMP_FUNCTION); |
639 } | 656 } |
640 | 657 |
641 // Deferred code for fast API call case---clean preallocated space. | 658 // Deferred code for fast API call case---clean preallocated space. |
642 if (can_do_fast_api_call) { | 659 if (can_do_fast_api_call) { |
643 __ bind(&miss_cleanup); | 660 __ bind(&miss_cleanup); |
644 FreeSpaceForFastApiCall(masm, scratch1); | 661 FreeSpaceForFastApiCall(masm, scratch1); |
645 __ jmp(miss_label); | 662 __ jmp(miss_label); |
646 } | 663 } |
647 | 664 |
648 // Invoke a regular function. | 665 // Invoke a regular function. |
649 __ bind(®ular_invoke); | 666 __ bind(®ular_invoke); |
650 if (can_do_fast_api_call) { | 667 if (can_do_fast_api_call) { |
651 FreeSpaceForFastApiCall(masm, scratch1); | 668 FreeSpaceForFastApiCall(masm, scratch1); |
652 } | 669 } |
670 | |
671 return true; | |
653 } | 672 } |
654 | 673 |
655 void CompileRegular(MacroAssembler* masm, | 674 void CompileRegular(MacroAssembler* masm, |
656 JSObject* object, | 675 JSObject* object, |
657 Register receiver, | 676 Register receiver, |
658 Register scratch1, | 677 Register scratch1, |
659 Register scratch2, | 678 Register scratch2, |
660 Register scratch3, | 679 Register scratch3, |
661 String* name, | 680 String* name, |
662 JSObject* interceptor_holder, | 681 JSObject* interceptor_holder, |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1039 | 1058 |
1040 // Check that the maps haven't changed. | 1059 // Check that the maps haven't changed. |
1041 Register reg = | 1060 Register reg = |
1042 CheckPrototypes(object, receiver, holder, scratch1, | 1061 CheckPrototypes(object, receiver, holder, scratch1, |
1043 scratch2, scratch3, name, miss); | 1062 scratch2, scratch3, name, miss); |
1044 | 1063 |
1045 Handle<AccessorInfo> callback_handle(callback); | 1064 Handle<AccessorInfo> callback_handle(callback); |
1046 | 1065 |
1047 __ EnterInternalFrame(); | 1066 __ EnterInternalFrame(); |
1048 // Push the stack address where the list of arguments ends. | 1067 // Push the stack address where the list of arguments ends. |
1049 __ mov(scratch2, esp); | 1068 __ lea(scratch2, Operand(esp, -2 * kPointerSize)); |
1050 __ sub(Operand(scratch2), Immediate(2 * kPointerSize)); | |
1051 __ push(scratch2); | 1069 __ push(scratch2); |
1052 __ push(receiver); // receiver | 1070 __ push(receiver); // receiver |
1053 __ push(reg); // holder | 1071 __ push(reg); // holder |
1054 // Push data from AccessorInfo. | 1072 // Push data from AccessorInfo. |
1055 if (Heap::InNewSpace(callback_handle->data())) { | 1073 if (Heap::InNewSpace(callback_handle->data())) { |
1056 __ mov(scratch2, Immediate(callback_handle)); | 1074 __ mov(scratch2, Immediate(callback_handle)); |
1057 __ push(FieldOperand(scratch2, AccessorInfo::kDataOffset)); | 1075 __ push(FieldOperand(scratch2, AccessorInfo::kDataOffset)); |
1058 } else { | 1076 } else { |
1059 __ push(Immediate(Handle<Object>(callback_handle->data()))); | 1077 __ push(Immediate(Handle<Object>(callback_handle->data()))); |
1060 } | 1078 } |
1061 __ push(name_reg); // name | 1079 __ push(name_reg); // name |
1062 // Save a pointer to where we pushed the arguments pointer. | 1080 // Save a pointer to where we pushed the arguments pointer. |
1063 // This will be passed as the const AccessorInfo& to the C++ callback. | 1081 // This will be passed as the const AccessorInfo& to the C++ callback. |
1064 __ mov(eax, esp); | 1082 STATIC_ASSERT(ApiGetterEntryStub::kStackSpace == 5); |
1065 __ add(Operand(eax), Immediate(4 * kPointerSize)); | 1083 __ lea(eax, Operand(esp, 4 * kPointerSize)); |
1066 __ mov(ebx, esp); | 1084 __ mov(ebx, esp); |
1067 | 1085 |
1068 // Do call through the api. | 1086 // Do call through the api. |
1069 ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace); | |
1070 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1087 Address getter_address = v8::ToCData<Address>(callback->getter()); |
1071 ApiFunction fun(getter_address); | 1088 ApiFunction fun(getter_address); |
1072 ApiGetterEntryStub stub(callback_handle, &fun); | 1089 ApiGetterEntryStub stub(callback_handle, &fun); |
1073 // Emitting a stub call may try to allocate (if the code is not | 1090 // Emitting a stub call may try to allocate (if the code is not |
1074 // already generated). Do not allow the assembler to perform a | 1091 // already generated). Do not allow the assembler to perform a |
1075 // garbage collection but instead return the allocation failure | 1092 // garbage collection but instead return the allocation failure |
1076 // object. | 1093 // object. |
1077 Object* result = NULL; // Initialization to please compiler. | 1094 Object* result = NULL; // Initialization to please compiler. |
1078 { MaybeObject* try_call_result = masm()->TryCallStub(&stub); | 1095 { MaybeObject* try_call_result = masm()->TryCallStub(&stub); |
1079 if (!try_call_result->ToObject(&result)) { | 1096 if (!try_call_result->ToObject(&result)) { |
(...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2201 ebx, edx, edi, name, &miss); | 2218 ebx, edx, edi, name, &miss); |
2202 } | 2219 } |
2203 break; | 2220 break; |
2204 } | 2221 } |
2205 | 2222 |
2206 default: | 2223 default: |
2207 UNREACHABLE(); | 2224 UNREACHABLE(); |
2208 } | 2225 } |
2209 | 2226 |
2210 if (depth != kInvalidProtoDepth) { | 2227 if (depth != kInvalidProtoDepth) { |
2211 GenerateFastApiCall(masm(), optimization, argc); | 2228 Failure* failure; |
2229 bool success = GenerateFastApiCall(masm(), optimization, argc, &failure); | |
2230 if (!success) { | |
2231 return failure; | |
2232 } | |
2212 } else { | 2233 } else { |
2213 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2234 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
2214 } | 2235 } |
2215 | 2236 |
2216 // Handle call cache miss. | 2237 // Handle call cache miss. |
2217 __ bind(&miss); | 2238 __ bind(&miss); |
2218 if (depth != kInvalidProtoDepth) { | 2239 if (depth != kInvalidProtoDepth) { |
2219 FreeSpaceForFastApiCall(masm(), eax); | 2240 FreeSpaceForFastApiCall(masm(), eax); |
2220 } | 2241 } |
2221 __ bind(&miss_in_smi_check); | 2242 __ bind(&miss_in_smi_check); |
(...skipping 24 matching lines...) Expand all Loading... | |
2246 // Get the number of arguments. | 2267 // Get the number of arguments. |
2247 const int argc = arguments().immediate(); | 2268 const int argc = arguments().immediate(); |
2248 | 2269 |
2249 LookupResult lookup; | 2270 LookupResult lookup; |
2250 LookupPostInterceptor(holder, name, &lookup); | 2271 LookupPostInterceptor(holder, name, &lookup); |
2251 | 2272 |
2252 // Get the receiver from the stack. | 2273 // Get the receiver from the stack. |
2253 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2274 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
2254 | 2275 |
2255 CallInterceptorCompiler compiler(this, arguments(), ecx); | 2276 CallInterceptorCompiler compiler(this, arguments(), ecx); |
2256 compiler.Compile(masm(), | 2277 Failure* failure; |
2257 object, | 2278 bool success = compiler.Compile(masm(), |
2258 holder, | 2279 object, |
2259 name, | 2280 holder, |
2260 &lookup, | 2281 name, |
2261 edx, | 2282 &lookup, |
2262 ebx, | 2283 edx, |
2263 edi, | 2284 ebx, |
2264 eax, | 2285 edi, |
2265 &miss); | 2286 eax, |
2287 &miss, | |
2288 &failure); | |
2289 if (!success) { | |
2290 return false; | |
2291 } | |
2266 | 2292 |
2267 // Restore receiver. | 2293 // Restore receiver. |
2268 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2294 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
2269 | 2295 |
2270 // Check that the function really is a function. | 2296 // Check that the function really is a function. |
2271 __ test(eax, Immediate(kSmiTagMask)); | 2297 __ test(eax, Immediate(kSmiTagMask)); |
2272 __ j(zero, &miss, not_taken); | 2298 __ j(zero, &miss, not_taken); |
2273 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); | 2299 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); |
2274 __ j(not_equal, &miss, not_taken); | 2300 __ j(not_equal, &miss, not_taken); |
2275 | 2301 |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3098 // Return the generated code. | 3124 // Return the generated code. |
3099 return GetCode(); | 3125 return GetCode(); |
3100 } | 3126 } |
3101 | 3127 |
3102 | 3128 |
3103 #undef __ | 3129 #undef __ |
3104 | 3130 |
3105 } } // namespace v8::internal | 3131 } } // namespace v8::internal |
3106 | 3132 |
3107 #endif // V8_TARGET_ARCH_IA32 | 3133 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |