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

Side by Side Diff: src/accessors.cc

Issue 410923003: Fix accessors to use holder instead of this (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove invalid assert and fix comment Created 6 years, 5 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/contexts.h" 10 #include "src/contexts.h"
11 #include "src/deoptimizer.h" 11 #include "src/deoptimizer.h"
12 #include "src/execution.h" 12 #include "src/execution.h"
13 #include "src/factory.h" 13 #include "src/factory.h"
14 #include "src/frames-inl.h" 14 #include "src/frames-inl.h"
15 #include "src/isolate.h" 15 #include "src/isolate.h"
16 #include "src/list-inl.h" 16 #include "src/list-inl.h"
17 #include "src/property-details.h" 17 #include "src/property-details.h"
18 #include "src/prototype.h" 18 #include "src/prototype.h"
19 19
20 namespace v8 { 20 namespace v8 {
21 namespace internal { 21 namespace internal {
22 22
23 23
24 // We have a slight impedance mismatch between the external API and the way we
25 // use callbacks internally: Externally, callbacks can only be used with
26 // v8::Object, but internally we even have callbacks on entities which are
27 // higher in the hierarchy, so we can only return i::Object here, not
28 // i::JSObject.
29 Handle<Object> GetThisFrom(const v8::PropertyCallbackInfo<v8::Value>& info) {
30 return Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
31 }
32
33
34 Handle<AccessorInfo> Accessors::MakeAccessor( 24 Handle<AccessorInfo> Accessors::MakeAccessor(
35 Isolate* isolate, 25 Isolate* isolate,
36 Handle<String> name, 26 Handle<String> name,
37 AccessorGetterCallback getter, 27 AccessorGetterCallback getter,
38 AccessorSetterCallback setter, 28 AccessorSetterCallback setter,
39 PropertyAttributes attributes) { 29 PropertyAttributes attributes) {
40 Factory* factory = isolate->factory(); 30 Factory* factory = isolate->factory();
41 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo(); 31 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
42 info->set_property_attributes(attributes); 32 info->set_property_attributes(attributes);
43 info->set_all_can_read(false); 33 info->set_all_can_read(false);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 return value; 155 return value;
166 } 156 }
167 157
168 158
169 void Accessors::ArrayLengthGetter( 159 void Accessors::ArrayLengthGetter(
170 v8::Local<v8::String> name, 160 v8::Local<v8::String> name,
171 const v8::PropertyCallbackInfo<v8::Value>& info) { 161 const v8::PropertyCallbackInfo<v8::Value>& info) {
172 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 162 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
173 DisallowHeapAllocation no_allocation; 163 DisallowHeapAllocation no_allocation;
174 HandleScope scope(isolate); 164 HandleScope scope(isolate);
175 Object* object = *GetThisFrom(info); 165 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
176 // Traverse the prototype chain until we reach an array. 166 Object* result = holder->length();
177 JSArray* holder = FindInstanceOf<JSArray>(isolate, object);
178 Object* result;
179 if (holder != NULL) {
180 result = holder->length();
181 } else {
182 result = Smi::FromInt(0);
183 }
184 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); 167 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
185 } 168 }
186 169
187 170
188 void Accessors::ArrayLengthSetter( 171 void Accessors::ArrayLengthSetter(
189 v8::Local<v8::String> name, 172 v8::Local<v8::String> name,
190 v8::Local<v8::Value> val, 173 v8::Local<v8::Value> val,
191 const v8::PropertyCallbackInfo<void>& info) { 174 const v8::PropertyCallbackInfo<void>& info) {
192 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 175 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
193 HandleScope scope(isolate); 176 HandleScope scope(isolate);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 // 230 //
248 // Accessors::StringLength 231 // Accessors::StringLength
249 // 232 //
250 233
251 void Accessors::StringLengthGetter( 234 void Accessors::StringLengthGetter(
252 v8::Local<v8::String> name, 235 v8::Local<v8::String> name,
253 const v8::PropertyCallbackInfo<v8::Value>& info) { 236 const v8::PropertyCallbackInfo<v8::Value>& info) {
254 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 237 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
255 DisallowHeapAllocation no_allocation; 238 DisallowHeapAllocation no_allocation;
256 HandleScope scope(isolate); 239 HandleScope scope(isolate);
257 Object* value = *GetThisFrom(info); 240
258 Object* result; 241 // We have a slight impedance mismatch between the external API and the way we
259 if (value->IsJSValue()) value = JSValue::cast(value)->value(); 242 // use callbacks internally: Externally, callbacks can only be used with
260 if (value->IsString()) { 243 // v8::Object, but internally we have callbacks on entities which are higher
261 result = Smi::FromInt(String::cast(value)->length()); 244 // in the hierarchy, in this case for String values.
262 } else { 245
263 // If object is not a string we return 0 to be compatible with WebKit. 246 Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
264 // Note: Firefox returns the length of ToString(object). 247 if (!value->IsString()) {
265 result = Smi::FromInt(0); 248 // Not a string value. That means that we either got a String wrapper or
249 // a Value with a String wrapper in its prototype chain.
250 value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
266 } 251 }
252 Object* result = Smi::FromInt(String::cast(value)->length());
267 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); 253 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
268 } 254 }
269 255
270 256
271 void Accessors::StringLengthSetter( 257 void Accessors::StringLengthSetter(
272 v8::Local<v8::String> name, 258 v8::Local<v8::String> name,
273 v8::Local<v8::Value> value, 259 v8::Local<v8::Value> value,
274 const v8::PropertyCallbackInfo<void>& info) { 260 const v8::PropertyCallbackInfo<void>& info) {
275 UNREACHABLE(); 261 UNREACHABLE();
276 } 262 }
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 &ScriptEvalFromFunctionNameSetter, 818 &ScriptEvalFromFunctionNameSetter,
833 attributes); 819 attributes);
834 } 820 }
835 821
836 822
837 // 823 //
838 // Accessors::FunctionPrototype 824 // Accessors::FunctionPrototype
839 // 825 //
840 826
841 static Handle<Object> GetFunctionPrototype(Isolate* isolate, 827 static Handle<Object> GetFunctionPrototype(Isolate* isolate,
842 Handle<Object> receiver) { 828 Handle<JSFunction> function) {
843 Handle<JSFunction> function;
844 {
845 DisallowHeapAllocation no_allocation;
846 JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver);
847 if (function_raw == NULL) return isolate->factory()->undefined_value();
848 while (!function_raw->should_have_prototype()) {
849 PrototypeIterator iter(isolate, function_raw);
850 function_raw = FindInstanceOf<JSFunction>(isolate, iter.GetCurrent());
851 // There has to be one because we hit the getter.
852 ASSERT(function_raw != NULL);
853 }
854 function = Handle<JSFunction>(function_raw, isolate);
855 }
856
857 if (!function->has_prototype()) { 829 if (!function->has_prototype()) {
858 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function); 830 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
859 JSFunction::SetPrototype(function, proto); 831 JSFunction::SetPrototype(function, proto);
860 } 832 }
861 return Handle<Object>(function->prototype(), isolate); 833 return Handle<Object>(function->prototype(), isolate);
862 } 834 }
863 835
864 836
865 static Handle<Object> SetFunctionPrototype(Isolate* isolate, 837 static Handle<Object> SetFunctionPrototype(Isolate* isolate,
866 Handle<JSObject> receiver, 838 Handle<JSObject> receiver,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 Isolate* isolate = function->GetIsolate(); 884 Isolate* isolate = function->GetIsolate();
913 return SetFunctionPrototype(isolate, function, prototype); 885 return SetFunctionPrototype(isolate, function, prototype);
914 } 886 }
915 887
916 888
917 void Accessors::FunctionPrototypeGetter( 889 void Accessors::FunctionPrototypeGetter(
918 v8::Local<v8::String> name, 890 v8::Local<v8::String> name,
919 const v8::PropertyCallbackInfo<v8::Value>& info) { 891 const v8::PropertyCallbackInfo<v8::Value>& info) {
920 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 892 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
921 HandleScope scope(isolate); 893 HandleScope scope(isolate);
922 Handle<Object> object = GetThisFrom(info); 894 Handle<JSFunction> function =
923 Handle<Object> result = GetFunctionPrototype(isolate, object); 895 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
896 Handle<Object> result = GetFunctionPrototype(isolate, function);
924 info.GetReturnValue().Set(Utils::ToLocal(result)); 897 info.GetReturnValue().Set(Utils::ToLocal(result));
925 } 898 }
926 899
927 900
928 void Accessors::FunctionPrototypeSetter( 901 void Accessors::FunctionPrototypeSetter(
929 v8::Local<v8::String> name, 902 v8::Local<v8::String> name,
930 v8::Local<v8::Value> val, 903 v8::Local<v8::Value> val,
931 const v8::PropertyCallbackInfo<void>& info) { 904 const v8::PropertyCallbackInfo<void>& info) {
932 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 905 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
933 HandleScope scope(isolate); 906 HandleScope scope(isolate);
(...skipping 18 matching lines...) Expand all
952 // 925 //
953 // Accessors::FunctionLength 926 // Accessors::FunctionLength
954 // 927 //
955 928
956 929
957 void Accessors::FunctionLengthGetter( 930 void Accessors::FunctionLengthGetter(
958 v8::Local<v8::String> name, 931 v8::Local<v8::String> name,
959 const v8::PropertyCallbackInfo<v8::Value>& info) { 932 const v8::PropertyCallbackInfo<v8::Value>& info) {
960 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 933 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
961 HandleScope scope(isolate); 934 HandleScope scope(isolate);
962 Handle<Object> object = GetThisFrom(info); 935 Handle<JSFunction> function =
963 MaybeHandle<JSFunction> maybe_function; 936 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
964
965 {
966 DisallowHeapAllocation no_allocation;
967 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
968 if (function != NULL) maybe_function = Handle<JSFunction>(function);
969 }
970 937
971 int length = 0; 938 int length = 0;
972 Handle<JSFunction> function; 939 if (function->shared()->is_compiled()) {
973 if (maybe_function.ToHandle(&function)) { 940 length = function->shared()->length();
974 if (function->shared()->is_compiled()) { 941 } else {
942 // If the function isn't compiled yet, the length is not computed
943 // correctly yet. Compile it now and return the right length.
944 if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
975 length = function->shared()->length(); 945 length = function->shared()->length();
976 } else { 946 }
977 // If the function isn't compiled yet, the length is not computed 947 if (isolate->has_pending_exception()) {
978 // correctly yet. Compile it now and return the right length. 948 isolate->OptionalRescheduleException(false);
979 if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
980 length = function->shared()->length();
981 }
982 if (isolate->has_pending_exception()) {
983 isolate->OptionalRescheduleException(false);
984 }
985 } 949 }
986 } 950 }
987 Handle<Object> result(Smi::FromInt(length), isolate); 951 Handle<Object> result(Smi::FromInt(length), isolate);
988 info.GetReturnValue().Set(Utils::ToLocal(result)); 952 info.GetReturnValue().Set(Utils::ToLocal(result));
989 } 953 }
990 954
991 955
992 void Accessors::FunctionLengthSetter( 956 void Accessors::FunctionLengthSetter(
993 v8::Local<v8::String> name, 957 v8::Local<v8::String> name,
994 v8::Local<v8::Value> val, 958 v8::Local<v8::Value> val,
(...skipping 15 matching lines...) Expand all
1010 // 974 //
1011 // Accessors::FunctionName 975 // Accessors::FunctionName
1012 // 976 //
1013 977
1014 978
1015 void Accessors::FunctionNameGetter( 979 void Accessors::FunctionNameGetter(
1016 v8::Local<v8::String> name, 980 v8::Local<v8::String> name,
1017 const v8::PropertyCallbackInfo<v8::Value>& info) { 981 const v8::PropertyCallbackInfo<v8::Value>& info) {
1018 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 982 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1019 HandleScope scope(isolate); 983 HandleScope scope(isolate);
1020 Handle<Object> object = GetThisFrom(info); 984 Handle<JSFunction> function =
1021 MaybeHandle<JSFunction> maybe_function; 985 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1022 986 Handle<Object> result(function->shared()->name(), isolate);
1023 {
1024 DisallowHeapAllocation no_allocation;
1025 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
1026 if (function != NULL) maybe_function = Handle<JSFunction>(function);
1027 }
1028
1029 Handle<JSFunction> function;
1030 Handle<Object> result;
1031 if (maybe_function.ToHandle(&function)) {
1032 result = Handle<Object>(function->shared()->name(), isolate);
1033 } else {
1034 result = isolate->factory()->undefined_value();
1035 }
1036 info.GetReturnValue().Set(Utils::ToLocal(result)); 987 info.GetReturnValue().Set(Utils::ToLocal(result));
1037 } 988 }
1038 989
1039 990
1040 void Accessors::FunctionNameSetter( 991 void Accessors::FunctionNameSetter(
1041 v8::Local<v8::String> name, 992 v8::Local<v8::String> name,
1042 v8::Local<v8::Value> val, 993 v8::Local<v8::Value> val,
1043 const v8::PropertyCallbackInfo<void>& info) { 994 const v8::PropertyCallbackInfo<void>& info) {
1044 // Do nothing. 995 // Do nothing.
1045 } 996 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) { 1110 Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
1160 return GetFunctionArguments(function->GetIsolate(), function); 1111 return GetFunctionArguments(function->GetIsolate(), function);
1161 } 1112 }
1162 1113
1163 1114
1164 void Accessors::FunctionArgumentsGetter( 1115 void Accessors::FunctionArgumentsGetter(
1165 v8::Local<v8::String> name, 1116 v8::Local<v8::String> name,
1166 const v8::PropertyCallbackInfo<v8::Value>& info) { 1117 const v8::PropertyCallbackInfo<v8::Value>& info) {
1167 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 1118 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1168 HandleScope scope(isolate); 1119 HandleScope scope(isolate);
1169 Handle<Object> object = GetThisFrom(info); 1120 Handle<JSFunction> function =
1170 MaybeHandle<JSFunction> maybe_function; 1121 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1171 1122 Handle<Object> result = GetFunctionArguments(isolate, function);
1172 {
1173 DisallowHeapAllocation no_allocation;
1174 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
1175 if (function != NULL) maybe_function = Handle<JSFunction>(function);
1176 }
1177
1178 Handle<JSFunction> function;
1179 Handle<Object> result;
1180 if (maybe_function.ToHandle(&function)) {
1181 result = GetFunctionArguments(isolate, function);
1182 } else {
1183 result = isolate->factory()->undefined_value();
1184 }
1185 info.GetReturnValue().Set(Utils::ToLocal(result)); 1123 info.GetReturnValue().Set(Utils::ToLocal(result));
1186 } 1124 }
1187 1125
1188 1126
1189 void Accessors::FunctionArgumentsSetter( 1127 void Accessors::FunctionArgumentsSetter(
1190 v8::Local<v8::String> name, 1128 v8::Local<v8::String> name,
1191 v8::Local<v8::Value> val, 1129 v8::Local<v8::Value> val,
1192 const v8::PropertyCallbackInfo<void>& info) { 1130 const v8::PropertyCallbackInfo<void>& info) {
1193 // Do nothing. 1131 // Do nothing.
1194 } 1132 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 } 1252 }
1315 return Handle<JSFunction>(caller); 1253 return Handle<JSFunction>(caller);
1316 } 1254 }
1317 1255
1318 1256
1319 void Accessors::FunctionCallerGetter( 1257 void Accessors::FunctionCallerGetter(
1320 v8::Local<v8::String> name, 1258 v8::Local<v8::String> name,
1321 const v8::PropertyCallbackInfo<v8::Value>& info) { 1259 const v8::PropertyCallbackInfo<v8::Value>& info) {
1322 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 1260 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1323 HandleScope scope(isolate); 1261 HandleScope scope(isolate);
1324 Handle<Object> object = GetThisFrom(info); 1262 Handle<JSFunction> function =
1325 MaybeHandle<JSFunction> maybe_function; 1263 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1326 {
1327 DisallowHeapAllocation no_allocation;
1328 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
1329 if (function != NULL) maybe_function = Handle<JSFunction>(function);
1330 }
1331 Handle<JSFunction> function;
1332 Handle<Object> result; 1264 Handle<Object> result;
1333 if (maybe_function.ToHandle(&function)) { 1265 MaybeHandle<JSFunction> maybe_caller;
1334 MaybeHandle<JSFunction> maybe_caller; 1266 maybe_caller = FindCaller(isolate, function);
1335 maybe_caller = FindCaller(isolate, function); 1267 Handle<JSFunction> caller;
1336 Handle<JSFunction> caller; 1268 if (maybe_caller.ToHandle(&caller)) {
1337 if (maybe_caller.ToHandle(&caller)) { 1269 result = caller;
1338 result = caller;
1339 } else {
1340 result = isolate->factory()->null_value();
1341 }
1342 } else { 1270 } else {
1343 result = isolate->factory()->undefined_value(); 1271 result = isolate->factory()->null_value();
1344 } 1272 }
1345 info.GetReturnValue().Set(Utils::ToLocal(result)); 1273 info.GetReturnValue().Set(Utils::ToLocal(result));
1346 } 1274 }
1347 1275
1348 1276
1349 void Accessors::FunctionCallerSetter( 1277 void Accessors::FunctionCallerSetter(
1350 v8::Local<v8::String> name, 1278 v8::Local<v8::String> name,
1351 v8::Local<v8::Value> val, 1279 v8::Local<v8::Value> val,
1352 const v8::PropertyCallbackInfo<void>& info) { 1280 const v8::PropertyCallbackInfo<void>& info) {
1353 // Do nothing. 1281 // Do nothing.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 info->set_data(Smi::FromInt(index)); 1351 info->set_data(Smi::FromInt(index));
1424 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); 1352 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport);
1425 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); 1353 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport);
1426 info->set_getter(*getter); 1354 info->set_getter(*getter);
1427 if (!(attributes & ReadOnly)) info->set_setter(*setter); 1355 if (!(attributes & ReadOnly)) info->set_setter(*setter);
1428 return info; 1356 return info;
1429 } 1357 }
1430 1358
1431 1359
1432 } } // namespace v8::internal 1360 } } // 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