Commit 50945297 authored by ulan@chromium.org's avatar ulan@chromium.org

Refactor function.arguments accessor.

This prepares for API-style accessor conversion.

BUG=
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/253453002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20943 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ea0de1e9
...@@ -969,16 +969,7 @@ const AccessorDescriptor Accessors::FunctionName = { ...@@ -969,16 +969,7 @@ const AccessorDescriptor Accessors::FunctionName = {
// //
Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) { static Handle<Object> ArgumentsForInlinedFunction(
CALL_HEAP_FUNCTION(function->GetIsolate(),
Accessors::FunctionGetArguments(function->GetIsolate(),
*function,
NULL),
Object);
}
static Object* ConstructArgumentsObjectForInlinedFunction(
JavaScriptFrame* frame, JavaScriptFrame* frame,
Handle<JSFunction> inlined_function, Handle<JSFunction> inlined_function,
int inlined_frame_index) { int inlined_frame_index) {
...@@ -1002,73 +993,95 @@ static Object* ConstructArgumentsObjectForInlinedFunction( ...@@ -1002,73 +993,95 @@ static Object* ConstructArgumentsObjectForInlinedFunction(
arguments->set_elements(*array); arguments->set_elements(*array);
// Return the freshly allocated arguments object. // Return the freshly allocated arguments object.
return *arguments; return arguments;
} }
Object* Accessors::FunctionGetArguments(Isolate* isolate, static int FindFunctionInFrame(JavaScriptFrame* frame,
Object* object, Handle<JSFunction> function) {
void*) { DisallowHeapAllocation no_allocation;
HandleScope scope(isolate); List<JSFunction*> functions(2);
JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object); frame->GetFunctions(&functions);
if (holder == NULL) return isolate->heap()->undefined_value(); for (int i = functions.length() - 1; i >= 0; i--) {
Handle<JSFunction> function(holder, isolate); 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. // Find the top invocation of the function by traversing frames.
List<JSFunction*> functions(2);
for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
JavaScriptFrame* frame = it.frame(); JavaScriptFrame* frame = it.frame();
frame->GetFunctions(&functions); int function_index = FindFunctionInFrame(frame, function);
for (int i = functions.length() - 1; i >= 0; i--) { if (function_index < 0) continue;
// Skip all frames that aren't invocations of the given function.
if (functions[i] != *function) continue; if (function_index > 0) {
// The function in question was inlined. Inlined functions have the
if (i > 0) { // correct number of arguments and no allocated arguments object, so
// The function in question was inlined. Inlined functions have the // we can construct a fresh one by interpreting the function's
// correct number of arguments and no allocated arguments object, so // deoptimization input data.
// we can construct a fresh one by interpreting the function's return ArgumentsForInlinedFunction(frame, function, function_index);
// deoptimization input data. }
return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
}
if (!frame->is_optimized()) { if (!frame->is_optimized()) {
// If there is an arguments variable in the stack, we return that. // If there is an arguments variable in the stack, we return that.
Handle<ScopeInfo> scope_info(function->shared()->scope_info()); Handle<ScopeInfo> scope_info(function->shared()->scope_info());
int index = scope_info->StackSlotIndex( int index = scope_info->StackSlotIndex(
isolate->heap()->arguments_string()); isolate->heap()->arguments_string());
if (index >= 0) { if (index >= 0) {
Handle<Object> arguments(frame->GetExpression(index), isolate); Handle<Object> arguments(frame->GetExpression(index), isolate);
if (!arguments->IsArgumentsMarker()) return *arguments; 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. // 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);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment