Index: src/accessors.cc |
diff --git a/src/accessors.cc b/src/accessors.cc |
index a7340964dcd172ebde31567eee5244531cd2e6d6..9913943501690345451a6ddd567799d81dd7145c 100644 |
--- a/src/accessors.cc |
+++ b/src/accessors.cc |
@@ -969,16 +969,7 @@ const AccessorDescriptor Accessors::FunctionName = { |
// |
-Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) { |
- CALL_HEAP_FUNCTION(function->GetIsolate(), |
- Accessors::FunctionGetArguments(function->GetIsolate(), |
- *function, |
- NULL), |
- Object); |
-} |
- |
- |
-static Object* ConstructArgumentsObjectForInlinedFunction( |
+static Handle<Object> ArgumentsForInlinedFunction( |
JavaScriptFrame* frame, |
Handle<JSFunction> inlined_function, |
int inlined_frame_index) { |
@@ -1002,73 +993,95 @@ static Object* ConstructArgumentsObjectForInlinedFunction( |
arguments->set_elements(*array); |
// Return the freshly allocated arguments object. |
- return *arguments; |
+ return arguments; |
} |
-Object* Accessors::FunctionGetArguments(Isolate* isolate, |
- Object* object, |
- void*) { |
- HandleScope scope(isolate); |
- JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object); |
- if (holder == NULL) return isolate->heap()->undefined_value(); |
- Handle<JSFunction> function(holder, isolate); |
+static int FindFunctionInFrame(JavaScriptFrame* frame, |
+ Handle<JSFunction> function) { |
+ DisallowHeapAllocation no_allocation; |
+ List<JSFunction*> functions(2); |
+ frame->GetFunctions(&functions); |
+ for (int i = functions.length() - 1; i >= 0; i--) { |
+ if (functions[i] == *function) return i; |
+ } |
+ return -1; |
+} |
+ |
+ |
+Handle<Object> GetFunctionArguments(Isolate* isolate, |
+ Handle<JSFunction> function) { |
+ if (function->shared()->native()) return isolate->factory()->null_value(); |
- if (function->shared()->native()) return isolate->heap()->null_value(); |
// Find the top invocation of the function by traversing frames. |
- List<JSFunction*> functions(2); |
for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { |
JavaScriptFrame* frame = it.frame(); |
- frame->GetFunctions(&functions); |
- for (int i = functions.length() - 1; i >= 0; i--) { |
- // Skip all frames that aren't invocations of the given function. |
- if (functions[i] != *function) continue; |
- |
- if (i > 0) { |
- // The function in question was inlined. Inlined functions have the |
- // correct number of arguments and no allocated arguments object, so |
- // we can construct a fresh one by interpreting the function's |
- // deoptimization input data. |
- return ConstructArgumentsObjectForInlinedFunction(frame, function, i); |
- } |
+ int function_index = FindFunctionInFrame(frame, function); |
+ if (function_index < 0) continue; |
+ |
+ if (function_index > 0) { |
+ // The function in question was inlined. Inlined functions have the |
+ // correct number of arguments and no allocated arguments object, so |
+ // we can construct a fresh one by interpreting the function's |
+ // deoptimization input data. |
+ return ArgumentsForInlinedFunction(frame, function, function_index); |
+ } |
- if (!frame->is_optimized()) { |
- // If there is an arguments variable in the stack, we return that. |
- Handle<ScopeInfo> scope_info(function->shared()->scope_info()); |
- int index = scope_info->StackSlotIndex( |
- isolate->heap()->arguments_string()); |
- if (index >= 0) { |
- Handle<Object> arguments(frame->GetExpression(index), isolate); |
- if (!arguments->IsArgumentsMarker()) return *arguments; |
- } |
+ if (!frame->is_optimized()) { |
+ // If there is an arguments variable in the stack, we return that. |
+ Handle<ScopeInfo> scope_info(function->shared()->scope_info()); |
+ int index = scope_info->StackSlotIndex( |
+ isolate->heap()->arguments_string()); |
+ if (index >= 0) { |
+ Handle<Object> arguments(frame->GetExpression(index), isolate); |
+ if (!arguments->IsArgumentsMarker()) return arguments; |
} |
- |
- // If there is no arguments variable in the stack or we have an |
- // optimized frame, we find the frame that holds the actual arguments |
- // passed to the function. |
- it.AdvanceToArgumentsFrame(); |
- frame = it.frame(); |
- |
- // Get the number of arguments and construct an arguments object |
- // mirror for the right frame. |
- const int length = frame->ComputeParametersCount(); |
- Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject( |
- function, length); |
- Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
- |
- // Copy the parameters to the arguments object. |
- ASSERT(array->length() == length); |
- for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); |
- arguments->set_elements(*array); |
- |
- // Return the freshly allocated arguments object. |
- return *arguments; |
} |
- functions.Rewind(0); |
+ |
+ // If there is no arguments variable in the stack or we have an |
+ // optimized frame, we find the frame that holds the actual arguments |
+ // passed to the function. |
+ it.AdvanceToArgumentsFrame(); |
+ frame = it.frame(); |
+ |
+ // Get the number of arguments and construct an arguments object |
+ // mirror for the right frame. |
+ const int length = frame->ComputeParametersCount(); |
+ Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject( |
+ function, length); |
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
+ |
+ // Copy the parameters to the arguments object. |
+ ASSERT(array->length() == length); |
+ for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); |
+ arguments->set_elements(*array); |
+ |
+ // Return the freshly allocated arguments object. |
+ return arguments; |
} |
// No frame corresponding to the given function found. Return null. |
- return isolate->heap()->null_value(); |
+ return isolate->factory()->null_value(); |
+} |
+ |
+ |
+Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) { |
+ return GetFunctionArguments(function->GetIsolate(), function); |
+} |
+ |
+ |
+Object* Accessors::FunctionGetArguments(Isolate* isolate, |
+ Object* object, |
+ void*) { |
+ HandleScope scope(isolate); |
+ Handle<JSFunction> function; |
+ { |
+ DisallowHeapAllocation no_allocation; |
+ JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object); |
+ if (holder == NULL) return isolate->heap()->undefined_value(); |
+ function = Handle<JSFunction>(holder, isolate); |
+ } |
+ return *GetFunctionArguments(isolate, function); |
} |