Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/accessors.cc

Issue 253453002: Refactor function.arguments accessor. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 951 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 ReadOnlySetAccessor, 962 ReadOnlySetAccessor,
963 0 963 0
964 }; 964 };
965 965
966 966
967 // 967 //
968 // Accessors::FunctionArguments 968 // Accessors::FunctionArguments
969 // 969 //
970 970
971 971
972 Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) { 972 static Handle<Object> ArgumentsForInlinedFunction(
973 CALL_HEAP_FUNCTION(function->GetIsolate(),
974 Accessors::FunctionGetArguments(function->GetIsolate(),
975 *function,
976 NULL),
977 Object);
978 }
979
980
981 static Object* ConstructArgumentsObjectForInlinedFunction(
982 JavaScriptFrame* frame, 973 JavaScriptFrame* frame,
983 Handle<JSFunction> inlined_function, 974 Handle<JSFunction> inlined_function,
984 int inlined_frame_index) { 975 int inlined_frame_index) {
985 Isolate* isolate = inlined_function->GetIsolate(); 976 Isolate* isolate = inlined_function->GetIsolate();
986 Factory* factory = isolate->factory(); 977 Factory* factory = isolate->factory();
987 SlotRefValueBuilder slot_refs( 978 SlotRefValueBuilder slot_refs(
988 frame, 979 frame,
989 inlined_frame_index, 980 inlined_frame_index,
990 inlined_function->shared()->formal_parameter_count()); 981 inlined_function->shared()->formal_parameter_count());
991 982
992 int args_count = slot_refs.args_length(); 983 int args_count = slot_refs.args_length();
993 Handle<JSObject> arguments = 984 Handle<JSObject> arguments =
994 factory->NewArgumentsObject(inlined_function, args_count); 985 factory->NewArgumentsObject(inlined_function, args_count);
995 Handle<FixedArray> array = factory->NewFixedArray(args_count); 986 Handle<FixedArray> array = factory->NewFixedArray(args_count);
996 slot_refs.Prepare(isolate); 987 slot_refs.Prepare(isolate);
997 for (int i = 0; i < args_count; ++i) { 988 for (int i = 0; i < args_count; ++i) {
998 Handle<Object> value = slot_refs.GetNext(isolate, 0); 989 Handle<Object> value = slot_refs.GetNext(isolate, 0);
999 array->set(i, *value); 990 array->set(i, *value);
1000 } 991 }
1001 slot_refs.Finish(isolate); 992 slot_refs.Finish(isolate);
1002 arguments->set_elements(*array); 993 arguments->set_elements(*array);
1003 994
1004 // Return the freshly allocated arguments object. 995 // Return the freshly allocated arguments object.
1005 return *arguments; 996 return arguments;
997 }
998
999
1000 static int FindFunctionInFrame(JavaScriptFrame* frame,
1001 Handle<JSFunction> function) {
1002 DisallowHeapAllocation no_allocation;
1003 List<JSFunction*> functions(2);
1004 frame->GetFunctions(&functions);
1005 for (int i = functions.length() - 1; i >= 0; i--) {
1006 if (functions[i] == *function) return i;
1007 }
1008 return -1;
1009 }
1010
1011
1012 Handle<Object> GetFunctionArguments(Isolate* isolate,
1013 Handle<JSFunction> function) {
1014 if (function->shared()->native()) return isolate->factory()->null_value();
1015
1016 // Find the top invocation of the function by traversing frames.
1017 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
1018 JavaScriptFrame* frame = it.frame();
1019 int function_index = FindFunctionInFrame(frame, function);
1020 if (function_index < 0) continue;
1021
1022 if (function_index > 0) {
1023 // The function in question was inlined. Inlined functions have the
1024 // correct number of arguments and no allocated arguments object, so
1025 // we can construct a fresh one by interpreting the function's
1026 // deoptimization input data.
1027 return ArgumentsForInlinedFunction(frame, function, function_index);
1028 }
1029
1030 if (!frame->is_optimized()) {
1031 // If there is an arguments variable in the stack, we return that.
1032 Handle<ScopeInfo> scope_info(function->shared()->scope_info());
1033 int index = scope_info->StackSlotIndex(
1034 isolate->heap()->arguments_string());
1035 if (index >= 0) {
1036 Handle<Object> arguments(frame->GetExpression(index), isolate);
1037 if (!arguments->IsArgumentsMarker()) return arguments;
1038 }
1039 }
1040
1041 // If there is no arguments variable in the stack or we have an
1042 // optimized frame, we find the frame that holds the actual arguments
1043 // passed to the function.
1044 it.AdvanceToArgumentsFrame();
1045 frame = it.frame();
1046
1047 // Get the number of arguments and construct an arguments object
1048 // mirror for the right frame.
1049 const int length = frame->ComputeParametersCount();
1050 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
1051 function, length);
1052 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
1053
1054 // Copy the parameters to the arguments object.
1055 ASSERT(array->length() == length);
1056 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
1057 arguments->set_elements(*array);
1058
1059 // Return the freshly allocated arguments object.
1060 return arguments;
1061 }
1062
1063 // No frame corresponding to the given function found. Return null.
1064 return isolate->factory()->null_value();
1065 }
1066
1067
1068 Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
1069 return GetFunctionArguments(function->GetIsolate(), function);
1006 } 1070 }
1007 1071
1008 1072
1009 Object* Accessors::FunctionGetArguments(Isolate* isolate, 1073 Object* Accessors::FunctionGetArguments(Isolate* isolate,
1010 Object* object, 1074 Object* object,
1011 void*) { 1075 void*) {
1012 HandleScope scope(isolate); 1076 HandleScope scope(isolate);
1013 JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object); 1077 Handle<JSFunction> function;
1014 if (holder == NULL) return isolate->heap()->undefined_value(); 1078 {
1015 Handle<JSFunction> function(holder, isolate); 1079 DisallowHeapAllocation no_allocation;
1016 1080 JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
1017 if (function->shared()->native()) return isolate->heap()->null_value(); 1081 if (holder == NULL) return isolate->heap()->undefined_value();
1018 // Find the top invocation of the function by traversing frames. 1082 function = Handle<JSFunction>(holder, isolate);
1019 List<JSFunction*> functions(2);
1020 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
1021 JavaScriptFrame* frame = it.frame();
1022 frame->GetFunctions(&functions);
1023 for (int i = functions.length() - 1; i >= 0; i--) {
1024 // Skip all frames that aren't invocations of the given function.
1025 if (functions[i] != *function) continue;
1026
1027 if (i > 0) {
1028 // The function in question was inlined. Inlined functions have the
1029 // correct number of arguments and no allocated arguments object, so
1030 // we can construct a fresh one by interpreting the function's
1031 // deoptimization input data.
1032 return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
1033 }
1034
1035 if (!frame->is_optimized()) {
1036 // If there is an arguments variable in the stack, we return that.
1037 Handle<ScopeInfo> scope_info(function->shared()->scope_info());
1038 int index = scope_info->StackSlotIndex(
1039 isolate->heap()->arguments_string());
1040 if (index >= 0) {
1041 Handle<Object> arguments(frame->GetExpression(index), isolate);
1042 if (!arguments->IsArgumentsMarker()) return *arguments;
1043 }
1044 }
1045
1046 // If there is no arguments variable in the stack or we have an
1047 // optimized frame, we find the frame that holds the actual arguments
1048 // passed to the function.
1049 it.AdvanceToArgumentsFrame();
1050 frame = it.frame();
1051
1052 // Get the number of arguments and construct an arguments object
1053 // mirror for the right frame.
1054 const int length = frame->ComputeParametersCount();
1055 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
1056 function, length);
1057 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
1058
1059 // Copy the parameters to the arguments object.
1060 ASSERT(array->length() == length);
1061 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
1062 arguments->set_elements(*array);
1063
1064 // Return the freshly allocated arguments object.
1065 return *arguments;
1066 }
1067 functions.Rewind(0);
1068 } 1083 }
1069 1084 return *GetFunctionArguments(isolate, function);
1070 // No frame corresponding to the given function found. Return null.
1071 return isolate->heap()->null_value();
1072 } 1085 }
1073 1086
1074 1087
1075 const AccessorDescriptor Accessors::FunctionArguments = { 1088 const AccessorDescriptor Accessors::FunctionArguments = {
1076 FunctionGetArguments, 1089 FunctionGetArguments,
1077 ReadOnlySetAccessor, 1090 ReadOnlySetAccessor,
1078 0 1091 0
1079 }; 1092 };
1080 1093
1081 1094
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 info->set_data(Smi::FromInt(index)); 1261 info->set_data(Smi::FromInt(index));
1249 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); 1262 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport);
1250 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); 1263 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport);
1251 info->set_getter(*getter); 1264 info->set_getter(*getter);
1252 if (!(attributes & ReadOnly)) info->set_setter(*setter); 1265 if (!(attributes & ReadOnly)) info->set_setter(*setter);
1253 return info; 1266 return info;
1254 } 1267 }
1255 1268
1256 1269
1257 } } // namespace v8::internal 1270 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698