OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "accessors.h" | 30 #include "accessors.h" |
31 #include "ast.h" | 31 #include "ast.h" |
32 #include "deoptimizer.h" | 32 #include "deoptimizer.h" |
33 #include "execution.h" | 33 #include "execution.h" |
34 #include "factory.h" | 34 #include "factory.h" |
35 #include "safepoint-table.h" | 35 #include "safepoint-table.h" |
36 #include "scopeinfo.h" | 36 #include "scopeinfo.h" |
37 #include "top.h" | |
38 | 37 |
39 namespace v8 { | 38 namespace v8 { |
40 namespace internal { | 39 namespace internal { |
41 | 40 |
42 | 41 |
43 template <class C> | 42 template <class C> |
44 static C* FindInPrototypeChain(Object* obj, bool* found_it) { | 43 static C* FindInPrototypeChain(Object* obj, bool* found_it) { |
45 ASSERT(!*found_it); | 44 ASSERT(!*found_it); |
| 45 Heap* heap = HEAP; |
46 while (!Is<C>(obj)) { | 46 while (!Is<C>(obj)) { |
47 if (obj == Heap::null_value()) return NULL; | 47 if (obj == heap->null_value()) return NULL; |
48 obj = obj->GetPrototype(); | 48 obj = obj->GetPrototype(); |
49 } | 49 } |
50 *found_it = true; | 50 *found_it = true; |
51 return C::cast(obj); | 51 return C::cast(obj); |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 // Entry point that never should be called. | 55 // Entry point that never should be called. |
56 MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) { | 56 MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) { |
57 UNREACHABLE(); | 57 UNREACHABLE(); |
(...skipping 25 matching lines...) Expand all Loading... |
83 JSArray* holder = FindInPrototypeChain<JSArray>(object, &found_it); | 83 JSArray* holder = FindInPrototypeChain<JSArray>(object, &found_it); |
84 if (!found_it) return Smi::FromInt(0); | 84 if (!found_it) return Smi::FromInt(0); |
85 return holder->length(); | 85 return holder->length(); |
86 } | 86 } |
87 | 87 |
88 | 88 |
89 // The helper function will 'flatten' Number objects. | 89 // The helper function will 'flatten' Number objects. |
90 Object* Accessors::FlattenNumber(Object* value) { | 90 Object* Accessors::FlattenNumber(Object* value) { |
91 if (value->IsNumber() || !value->IsJSValue()) return value; | 91 if (value->IsNumber() || !value->IsJSValue()) return value; |
92 JSValue* wrapper = JSValue::cast(value); | 92 JSValue* wrapper = JSValue::cast(value); |
93 ASSERT( | 93 ASSERT(Isolate::Current()->context()->global_context()->number_function()-> |
94 Top::context()->global_context()->number_function()->has_initial_map()); | 94 has_initial_map()); |
95 Map* number_map = | 95 Map* number_map = Isolate::Current()->context()->global_context()-> |
96 Top::context()->global_context()->number_function()->initial_map(); | 96 number_function()->initial_map(); |
97 if (wrapper->map() == number_map) return wrapper->value(); | 97 if (wrapper->map() == number_map) return wrapper->value(); |
98 return value; | 98 return value; |
99 } | 99 } |
100 | 100 |
101 | 101 |
102 MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) { | 102 MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) { |
103 value = FlattenNumber(value); | 103 value = FlattenNumber(value); |
104 | 104 |
105 // Need to call methods that may trigger GC. | 105 // Need to call methods that may trigger GC. |
106 HandleScope scope; | 106 HandleScope scope; |
(...skipping 12 matching lines...) Expand all Loading... |
119 object = *object_handle; | 119 object = *object_handle; |
120 value = *value_handle; | 120 value = *value_handle; |
121 | 121 |
122 if (uint32_v->Number() == number_v->Number()) { | 122 if (uint32_v->Number() == number_v->Number()) { |
123 if (object->IsJSArray()) { | 123 if (object->IsJSArray()) { |
124 return JSArray::cast(object)->SetElementsLength(*uint32_v); | 124 return JSArray::cast(object)->SetElementsLength(*uint32_v); |
125 } else { | 125 } else { |
126 // This means one of the object's prototypes is a JSArray and | 126 // This means one of the object's prototypes is a JSArray and |
127 // the object does not have a 'length' property. | 127 // the object does not have a 'length' property. |
128 // Calling SetProperty causes an infinite loop. | 128 // Calling SetProperty causes an infinite loop. |
129 return object->SetLocalPropertyIgnoreAttributes(Heap::length_symbol(), | 129 return object->SetLocalPropertyIgnoreAttributes(HEAP->length_symbol(), |
130 value, NONE); | 130 value, NONE); |
131 } | 131 } |
132 } | 132 } |
133 return Top::Throw(*Factory::NewRangeError("invalid_array_length", | 133 return Isolate::Current()->Throw( |
134 HandleVector<Object>(NULL, 0))); | 134 *FACTORY->NewRangeError("invalid_array_length", |
| 135 HandleVector<Object>(NULL, 0))); |
135 } | 136 } |
136 | 137 |
137 | 138 |
138 const AccessorDescriptor Accessors::ArrayLength = { | 139 const AccessorDescriptor Accessors::ArrayLength = { |
139 ArrayGetLength, | 140 ArrayGetLength, |
140 ArraySetLength, | 141 ArraySetLength, |
141 0 | 142 0 |
142 }; | 143 }; |
143 | 144 |
144 | 145 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 // | 314 // |
314 | 315 |
315 | 316 |
316 MaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) { | 317 MaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) { |
317 HandleScope scope; | 318 HandleScope scope; |
318 Handle<Script> script(Script::cast(JSValue::cast(object)->value())); | 319 Handle<Script> script(Script::cast(JSValue::cast(object)->value())); |
319 InitScriptLineEnds(script); | 320 InitScriptLineEnds(script); |
320 ASSERT(script->line_ends()->IsFixedArray()); | 321 ASSERT(script->line_ends()->IsFixedArray()); |
321 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); | 322 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); |
322 // We do not want anyone to modify this array from JS. | 323 // We do not want anyone to modify this array from JS. |
323 ASSERT(*line_ends == Heap::empty_fixed_array() || | 324 ASSERT(*line_ends == HEAP->empty_fixed_array() || |
324 line_ends->map() == Heap::fixed_cow_array_map()); | 325 line_ends->map() == HEAP->fixed_cow_array_map()); |
325 Handle<JSArray> js_array = Factory::NewJSArrayWithElements(line_ends); | 326 Handle<JSArray> js_array = FACTORY->NewJSArrayWithElements(line_ends); |
326 return *js_array; | 327 return *js_array; |
327 } | 328 } |
328 | 329 |
329 | 330 |
330 const AccessorDescriptor Accessors::ScriptLineEnds = { | 331 const AccessorDescriptor Accessors::ScriptLineEnds = { |
331 ScriptGetLineEnds, | 332 ScriptGetLineEnds, |
332 IllegalSetter, | 333 IllegalSetter, |
333 0 | 334 0 |
334 }; | 335 }; |
335 | 336 |
(...skipping 25 matching lines...) Expand all Loading... |
361 Object* script = JSValue::cast(object)->value(); | 362 Object* script = JSValue::cast(object)->value(); |
362 if (!Script::cast(script)->eval_from_shared()->IsUndefined()) { | 363 if (!Script::cast(script)->eval_from_shared()->IsUndefined()) { |
363 Handle<SharedFunctionInfo> eval_from_shared( | 364 Handle<SharedFunctionInfo> eval_from_shared( |
364 SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared())); | 365 SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared())); |
365 | 366 |
366 if (eval_from_shared->script()->IsScript()) { | 367 if (eval_from_shared->script()->IsScript()) { |
367 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script())); | 368 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script())); |
368 return *GetScriptWrapper(eval_from_script); | 369 return *GetScriptWrapper(eval_from_script); |
369 } | 370 } |
370 } | 371 } |
371 return Heap::undefined_value(); | 372 return HEAP->undefined_value(); |
372 } | 373 } |
373 | 374 |
374 | 375 |
375 const AccessorDescriptor Accessors::ScriptEvalFromScript = { | 376 const AccessorDescriptor Accessors::ScriptEvalFromScript = { |
376 ScriptGetEvalFromScript, | 377 ScriptGetEvalFromScript, |
377 IllegalSetter, | 378 IllegalSetter, |
378 0 | 379 0 |
379 }; | 380 }; |
380 | 381 |
381 | 382 |
382 // | 383 // |
383 // Accessors::ScriptGetEvalFromScriptPosition | 384 // Accessors::ScriptGetEvalFromScriptPosition |
384 // | 385 // |
385 | 386 |
386 | 387 |
387 MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) { | 388 MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) { |
388 HandleScope scope; | 389 HandleScope scope; |
389 Handle<Script> script(Script::cast(JSValue::cast(object)->value())); | 390 Handle<Script> script(Script::cast(JSValue::cast(object)->value())); |
390 | 391 |
391 // If this is not a script compiled through eval there is no eval position. | 392 // If this is not a script compiled through eval there is no eval position. |
392 int compilation_type = Smi::cast(script->compilation_type())->value(); | 393 int compilation_type = Smi::cast(script->compilation_type())->value(); |
393 if (compilation_type != Script::COMPILATION_TYPE_EVAL) { | 394 if (compilation_type != Script::COMPILATION_TYPE_EVAL) { |
394 return Heap::undefined_value(); | 395 return HEAP->undefined_value(); |
395 } | 396 } |
396 | 397 |
397 // Get the function from where eval was called and find the source position | 398 // Get the function from where eval was called and find the source position |
398 // from the instruction offset. | 399 // from the instruction offset. |
399 Handle<Code> code(SharedFunctionInfo::cast( | 400 Handle<Code> code(SharedFunctionInfo::cast( |
400 script->eval_from_shared())->code()); | 401 script->eval_from_shared())->code()); |
401 return Smi::FromInt(code->SourcePosition(code->instruction_start() + | 402 return Smi::FromInt(code->SourcePosition(code->instruction_start() + |
402 script->eval_from_instructions_offset()->value())); | 403 script->eval_from_instructions_offset()->value())); |
403 } | 404 } |
404 | 405 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 | 439 |
439 | 440 |
440 // | 441 // |
441 // Accessors::FunctionPrototype | 442 // Accessors::FunctionPrototype |
442 // | 443 // |
443 | 444 |
444 | 445 |
445 MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) { | 446 MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) { |
446 bool found_it = false; | 447 bool found_it = false; |
447 JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it); | 448 JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it); |
448 if (!found_it) return Heap::undefined_value(); | 449 if (!found_it) return HEAP->undefined_value(); |
449 while (!function->should_have_prototype()) { | 450 while (!function->should_have_prototype()) { |
450 found_it = false; | 451 found_it = false; |
451 function = FindInPrototypeChain<JSFunction>(object->GetPrototype(), | 452 function = FindInPrototypeChain<JSFunction>(object->GetPrototype(), |
452 &found_it); | 453 &found_it); |
453 // There has to be one because we hit the getter. | 454 // There has to be one because we hit the getter. |
454 ASSERT(found_it); | 455 ASSERT(found_it); |
455 } | 456 } |
456 | 457 |
457 if (!function->has_prototype()) { | 458 if (!function->has_prototype()) { |
458 Object* prototype; | 459 Object* prototype; |
459 { MaybeObject* maybe_prototype = Heap::AllocateFunctionPrototype(function); | 460 { MaybeObject* maybe_prototype = HEAP->AllocateFunctionPrototype(function); |
460 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; | 461 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; |
461 } | 462 } |
462 Object* result; | 463 Object* result; |
463 { MaybeObject* maybe_result = function->SetPrototype(prototype); | 464 { MaybeObject* maybe_result = function->SetPrototype(prototype); |
464 if (!maybe_result->ToObject(&result)) return maybe_result; | 465 if (!maybe_result->ToObject(&result)) return maybe_result; |
465 } | 466 } |
466 } | 467 } |
467 return function->prototype(); | 468 return function->prototype(); |
468 } | 469 } |
469 | 470 |
470 | 471 |
471 MaybeObject* Accessors::FunctionSetPrototype(JSObject* object, | 472 MaybeObject* Accessors::FunctionSetPrototype(JSObject* object, |
472 Object* value, | 473 Object* value, |
473 void*) { | 474 void*) { |
474 bool found_it = false; | 475 bool found_it = false; |
475 JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it); | 476 JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it); |
476 if (!found_it) return Heap::undefined_value(); | 477 if (!found_it) return HEAP->undefined_value(); |
477 if (!function->should_have_prototype()) { | 478 if (!function->should_have_prototype()) { |
478 // Since we hit this accessor, object will have no prototype property. | 479 // Since we hit this accessor, object will have no prototype property. |
479 return object->SetLocalPropertyIgnoreAttributes(Heap::prototype_symbol(), | 480 return object->SetLocalPropertyIgnoreAttributes(HEAP->prototype_symbol(), |
480 value, | 481 value, |
481 NONE); | 482 NONE); |
482 } | 483 } |
483 | 484 |
484 if (function->has_initial_map()) { | 485 if (function->has_initial_map()) { |
485 // If the function has allocated the initial map | 486 // If the function has allocated the initial map |
486 // replace it with a copy containing the new prototype. | 487 // replace it with a copy containing the new prototype. |
487 Object* new_map; | 488 Object* new_map; |
488 { MaybeObject* maybe_new_map = | 489 { MaybeObject* maybe_new_map = |
489 function->initial_map()->CopyDropTransitions(); | 490 function->initial_map()->CopyDropTransitions(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 | 539 |
539 | 540 |
540 // | 541 // |
541 // Accessors::FunctionName | 542 // Accessors::FunctionName |
542 // | 543 // |
543 | 544 |
544 | 545 |
545 MaybeObject* Accessors::FunctionGetName(Object* object, void*) { | 546 MaybeObject* Accessors::FunctionGetName(Object* object, void*) { |
546 bool found_it = false; | 547 bool found_it = false; |
547 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); | 548 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); |
548 if (!found_it) return Heap::undefined_value(); | 549 if (!found_it) return HEAP->undefined_value(); |
549 return holder->shared()->name(); | 550 return holder->shared()->name(); |
550 } | 551 } |
551 | 552 |
552 | 553 |
553 const AccessorDescriptor Accessors::FunctionName = { | 554 const AccessorDescriptor Accessors::FunctionName = { |
554 FunctionGetName, | 555 FunctionGetName, |
555 ReadOnlySetAccessor, | 556 ReadOnlySetAccessor, |
556 0 | 557 0 |
557 }; | 558 }; |
558 | 559 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 Handle<Object> GetValue() { | 598 Handle<Object> GetValue() { |
598 switch (representation_) { | 599 switch (representation_) { |
599 case TAGGED: | 600 case TAGGED: |
600 return Handle<Object>(Memory::Object_at(addr_)); | 601 return Handle<Object>(Memory::Object_at(addr_)); |
601 | 602 |
602 case INT32: { | 603 case INT32: { |
603 int value = Memory::int32_at(addr_); | 604 int value = Memory::int32_at(addr_); |
604 if (Smi::IsValid(value)) { | 605 if (Smi::IsValid(value)) { |
605 return Handle<Object>(Smi::FromInt(value)); | 606 return Handle<Object>(Smi::FromInt(value)); |
606 } else { | 607 } else { |
607 return Factory::NewNumberFromInt(value); | 608 return Isolate::Current()->factory()->NewNumberFromInt(value); |
608 } | 609 } |
609 } | 610 } |
610 | 611 |
611 case DOUBLE: { | 612 case DOUBLE: { |
612 double value = Memory::double_at(addr_); | 613 double value = Memory::double_at(addr_); |
613 return Factory::NewNumber(value); | 614 return Isolate::Current()->factory()->NewNumber(value); |
614 } | 615 } |
615 | 616 |
616 case LITERAL: | 617 case LITERAL: |
617 return literal_; | 618 return literal_; |
618 | 619 |
619 default: | 620 default: |
620 UNREACHABLE(); | 621 UNREACHABLE(); |
621 return Handle<Object>::null(); | 622 return Handle<Object>::null(); |
622 } | 623 } |
623 } | 624 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 } | 726 } |
726 | 727 |
727 UNREACHABLE(); | 728 UNREACHABLE(); |
728 } | 729 } |
729 | 730 |
730 | 731 |
731 static MaybeObject* ConstructArgumentsObjectForInlinedFunction( | 732 static MaybeObject* ConstructArgumentsObjectForInlinedFunction( |
732 JavaScriptFrame* frame, | 733 JavaScriptFrame* frame, |
733 Handle<JSFunction> inlined_function, | 734 Handle<JSFunction> inlined_function, |
734 int inlined_frame_index) { | 735 int inlined_frame_index) { |
| 736 Factory* factory = Isolate::Current()->factory(); |
735 int args_count = inlined_function->shared()->formal_parameter_count(); | 737 int args_count = inlined_function->shared()->formal_parameter_count(); |
736 ScopedVector<SlotRef> args_slots(args_count); | 738 ScopedVector<SlotRef> args_slots(args_count); |
737 ComputeSlotMappingForArguments(frame, inlined_frame_index, &args_slots); | 739 ComputeSlotMappingForArguments(frame, inlined_frame_index, &args_slots); |
738 Handle<JSObject> arguments = | 740 Handle<JSObject> arguments = |
739 Factory::NewArgumentsObject(inlined_function, args_count); | 741 factory->NewArgumentsObject(inlined_function, args_count); |
740 Handle<FixedArray> array = Factory::NewFixedArray(args_count); | 742 Handle<FixedArray> array = factory->NewFixedArray(args_count); |
741 for (int i = 0; i < args_count; ++i) { | 743 for (int i = 0; i < args_count; ++i) { |
742 Handle<Object> value = args_slots[i].GetValue(); | 744 Handle<Object> value = args_slots[i].GetValue(); |
743 array->set(i, *value); | 745 array->set(i, *value); |
744 } | 746 } |
745 arguments->set_elements(*array); | 747 arguments->set_elements(*array); |
746 | 748 |
747 // Return the freshly allocated arguments object. | 749 // Return the freshly allocated arguments object. |
748 return *arguments; | 750 return *arguments; |
749 } | 751 } |
750 | 752 |
751 | 753 |
752 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) { | 754 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) { |
753 HandleScope scope; | 755 Isolate* isolate = Isolate::Current(); |
| 756 HandleScope scope(isolate); |
754 bool found_it = false; | 757 bool found_it = false; |
755 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); | 758 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); |
756 if (!found_it) return Heap::undefined_value(); | 759 if (!found_it) return isolate->heap()->undefined_value(); |
757 Handle<JSFunction> function(holder); | 760 Handle<JSFunction> function(holder, isolate); |
758 | 761 |
759 // Find the top invocation of the function by traversing frames. | 762 // Find the top invocation of the function by traversing frames. |
760 List<JSFunction*> functions(2); | 763 List<JSFunction*> functions(2); |
761 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { | 764 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { |
762 JavaScriptFrame* frame = it.frame(); | 765 JavaScriptFrame* frame = it.frame(); |
763 frame->GetFunctions(&functions); | 766 frame->GetFunctions(&functions); |
764 for (int i = functions.length() - 1; i >= 0; i--) { | 767 for (int i = functions.length() - 1; i >= 0; i--) { |
765 // Skip all frames that aren't invocations of the given function. | 768 // Skip all frames that aren't invocations of the given function. |
766 if (functions[i] != *function) continue; | 769 if (functions[i] != *function) continue; |
767 | 770 |
768 if (i > 0) { | 771 if (i > 0) { |
769 // The function in question was inlined. Inlined functions have the | 772 // The function in question was inlined. Inlined functions have the |
770 // correct number of arguments and no allocated arguments object, so | 773 // correct number of arguments and no allocated arguments object, so |
771 // we can construct a fresh one by interpreting the function's | 774 // we can construct a fresh one by interpreting the function's |
772 // deoptimization input data. | 775 // deoptimization input data. |
773 return ConstructArgumentsObjectForInlinedFunction(frame, function, i); | 776 return ConstructArgumentsObjectForInlinedFunction(frame, function, i); |
774 } | 777 } |
775 | 778 |
776 if (!frame->is_optimized()) { | 779 if (!frame->is_optimized()) { |
777 // If there is an arguments variable in the stack, we return that. | 780 // If there is an arguments variable in the stack, we return that. |
778 Handle<SerializedScopeInfo> info(function->shared()->scope_info()); | 781 Handle<SerializedScopeInfo> info(function->shared()->scope_info()); |
779 int index = info->StackSlotIndex(Heap::arguments_symbol()); | 782 int index = info->StackSlotIndex(isolate->heap()->arguments_symbol()); |
780 if (index >= 0) { | 783 if (index >= 0) { |
781 Handle<Object> arguments(frame->GetExpression(index)); | 784 Handle<Object> arguments(frame->GetExpression(index), isolate); |
782 if (!arguments->IsArgumentsMarker()) return *arguments; | 785 if (!arguments->IsArgumentsMarker()) return *arguments; |
783 } | 786 } |
784 } | 787 } |
785 | 788 |
786 // If there is no arguments variable in the stack or we have an | 789 // If there is no arguments variable in the stack or we have an |
787 // optimized frame, we find the frame that holds the actual arguments | 790 // optimized frame, we find the frame that holds the actual arguments |
788 // passed to the function. | 791 // passed to the function. |
789 it.AdvanceToArgumentsFrame(); | 792 it.AdvanceToArgumentsFrame(); |
790 frame = it.frame(); | 793 frame = it.frame(); |
791 | 794 |
792 // Get the number of arguments and construct an arguments object | 795 // Get the number of arguments and construct an arguments object |
793 // mirror for the right frame. | 796 // mirror for the right frame. |
794 const int length = frame->ComputeParametersCount(); | 797 const int length = frame->ComputeParametersCount(); |
795 Handle<JSObject> arguments = Factory::NewArgumentsObject(function, | 798 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject( |
796 length); | 799 function, length); |
797 Handle<FixedArray> array = Factory::NewFixedArray(length); | 800 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
798 | 801 |
799 // Copy the parameters to the arguments object. | 802 // Copy the parameters to the arguments object. |
800 ASSERT(array->length() == length); | 803 ASSERT(array->length() == length); |
801 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); | 804 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); |
802 arguments->set_elements(*array); | 805 arguments->set_elements(*array); |
803 | 806 |
804 // Return the freshly allocated arguments object. | 807 // Return the freshly allocated arguments object. |
805 return *arguments; | 808 return *arguments; |
806 } | 809 } |
807 functions.Rewind(0); | 810 functions.Rewind(0); |
808 } | 811 } |
809 | 812 |
810 // No frame corresponding to the given function found. Return null. | 813 // No frame corresponding to the given function found. Return null. |
811 return Heap::null_value(); | 814 return isolate->heap()->null_value(); |
812 } | 815 } |
813 | 816 |
814 | 817 |
815 const AccessorDescriptor Accessors::FunctionArguments = { | 818 const AccessorDescriptor Accessors::FunctionArguments = { |
816 FunctionGetArguments, | 819 FunctionGetArguments, |
817 ReadOnlySetAccessor, | 820 ReadOnlySetAccessor, |
818 0 | 821 0 |
819 }; | 822 }; |
820 | 823 |
821 | 824 |
822 // | 825 // |
823 // Accessors::FunctionCaller | 826 // Accessors::FunctionCaller |
824 // | 827 // |
825 | 828 |
826 | 829 |
827 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) { | 830 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) { |
828 HandleScope scope; | 831 Isolate* isolate = Isolate::Current(); |
| 832 HandleScope scope(isolate); |
829 AssertNoAllocation no_alloc; | 833 AssertNoAllocation no_alloc; |
830 bool found_it = false; | 834 bool found_it = false; |
831 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); | 835 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); |
832 if (!found_it) return Heap::undefined_value(); | 836 if (!found_it) return isolate->heap()->undefined_value(); |
833 Handle<JSFunction> function(holder); | 837 Handle<JSFunction> function(holder, isolate); |
834 | 838 |
835 List<JSFunction*> functions(2); | 839 List<JSFunction*> functions(2); |
836 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { | 840 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { |
837 JavaScriptFrame* frame = it.frame(); | 841 JavaScriptFrame* frame = it.frame(); |
838 frame->GetFunctions(&functions); | 842 frame->GetFunctions(&functions); |
839 for (int i = functions.length() - 1; i >= 0; i--) { | 843 for (int i = functions.length() - 1; i >= 0; i--) { |
840 if (functions[i] == *function) { | 844 if (functions[i] == *function) { |
841 // Once we have found the frame, we need to go to the caller | 845 // Once we have found the frame, we need to go to the caller |
842 // frame. This may require skipping through a number of top-level | 846 // frame. This may require skipping through a number of top-level |
843 // frames, e.g. frames for scripts not functions. | 847 // frames, e.g. frames for scripts not functions. |
844 if (i > 0) { | 848 if (i > 0) { |
845 ASSERT(!functions[i - 1]->shared()->is_toplevel()); | 849 ASSERT(!functions[i - 1]->shared()->is_toplevel()); |
846 return functions[i - 1]; | 850 return functions[i - 1]; |
847 } else { | 851 } else { |
848 for (it.Advance(); !it.done(); it.Advance()) { | 852 for (it.Advance(); !it.done(); it.Advance()) { |
849 frame = it.frame(); | 853 frame = it.frame(); |
850 functions.Rewind(0); | 854 functions.Rewind(0); |
851 frame->GetFunctions(&functions); | 855 frame->GetFunctions(&functions); |
852 if (!functions.last()->shared()->is_toplevel()) { | 856 if (!functions.last()->shared()->is_toplevel()) { |
853 return functions.last(); | 857 return functions.last(); |
854 } | 858 } |
855 ASSERT(functions.length() == 1); | 859 ASSERT(functions.length() == 1); |
856 } | 860 } |
857 if (it.done()) return Heap::null_value(); | 861 if (it.done()) return isolate->heap()->null_value(); |
858 break; | 862 break; |
859 } | 863 } |
860 } | 864 } |
861 } | 865 } |
862 functions.Rewind(0); | 866 functions.Rewind(0); |
863 } | 867 } |
864 | 868 |
865 // No frame corresponding to the given function found. Return null. | 869 // No frame corresponding to the given function found. Return null. |
866 return Heap::null_value(); | 870 return isolate->heap()->null_value(); |
867 } | 871 } |
868 | 872 |
869 | 873 |
870 const AccessorDescriptor Accessors::FunctionCaller = { | 874 const AccessorDescriptor Accessors::FunctionCaller = { |
871 FunctionGetCaller, | 875 FunctionGetCaller, |
872 ReadOnlySetAccessor, | 876 ReadOnlySetAccessor, |
873 0 | 877 0 |
874 }; | 878 }; |
875 | 879 |
876 | 880 |
(...skipping 21 matching lines...) Expand all Loading... |
898 } | 902 } |
899 | 903 |
900 | 904 |
901 const AccessorDescriptor Accessors::ObjectPrototype = { | 905 const AccessorDescriptor Accessors::ObjectPrototype = { |
902 ObjectGetPrototype, | 906 ObjectGetPrototype, |
903 ObjectSetPrototype, | 907 ObjectSetPrototype, |
904 0 | 908 0 |
905 }; | 909 }; |
906 | 910 |
907 } } // namespace v8::internal | 911 } } // namespace v8::internal |
OLD | NEW |