OLD | NEW |
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 | 45 |
46 static Handle<AccessorInfo> MakeAccessor(Isolate* isolate, | 46 static Handle<AccessorInfo> MakeAccessor(Isolate* isolate, |
47 Handle<String> name, | 47 Handle<String> name, |
48 AccessorGetterCallback getter, | 48 AccessorGetterCallback getter, |
49 AccessorSetterCallback setter, | 49 AccessorSetterCallback setter, |
50 PropertyAttributes attributes) { | 50 PropertyAttributes attributes) { |
51 Factory* factory = isolate->factory(); | 51 Factory* factory = isolate->factory(); |
52 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo(); | 52 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo(); |
53 info->set_property_attributes(attributes); | 53 info->set_property_attributes(attributes); |
54 info->set_all_can_read(true); | 54 info->set_all_can_read(false); |
55 info->set_all_can_write(true); | 55 info->set_all_can_write(false); |
56 info->set_prohibits_overwriting(false); | 56 info->set_prohibits_overwriting(false); |
57 info->set_name(*name); | 57 info->set_name(*name); |
58 Handle<Object> get = v8::FromCData(isolate, getter); | 58 Handle<Object> get = v8::FromCData(isolate, getter); |
59 Handle<Object> set = v8::FromCData(isolate, setter); | 59 Handle<Object> set = v8::FromCData(isolate, setter); |
60 info->set_getter(*get); | 60 info->set_getter(*get); |
61 info->set_setter(*set); | 61 info->set_setter(*set); |
62 return info; | 62 return info; |
63 } | 63 } |
64 | 64 |
65 | 65 |
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 ASSERT(functions_.length() > 0); | 1183 ASSERT(functions_.length() > 0); |
1184 frame_iterator_.Advance(); | 1184 frame_iterator_.Advance(); |
1185 index_ = functions_.length() - 1; | 1185 index_ = functions_.length() - 1; |
1186 } | 1186 } |
1187 JavaScriptFrameIterator frame_iterator_; | 1187 JavaScriptFrameIterator frame_iterator_; |
1188 List<JSFunction*> functions_; | 1188 List<JSFunction*> functions_; |
1189 int index_; | 1189 int index_; |
1190 }; | 1190 }; |
1191 | 1191 |
1192 | 1192 |
1193 Object* Accessors::FunctionGetCaller(Isolate* isolate, | 1193 MaybeHandle<JSFunction> FindCaller(Isolate* isolate, |
1194 Object* object, | 1194 Handle<JSFunction> function) { |
1195 void*) { | |
1196 HandleScope scope(isolate); | |
1197 DisallowHeapAllocation no_allocation; | 1195 DisallowHeapAllocation no_allocation; |
1198 JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object); | |
1199 if (holder == NULL) return isolate->heap()->undefined_value(); | |
1200 if (holder->shared()->native()) return isolate->heap()->null_value(); | |
1201 Handle<JSFunction> function(holder, isolate); | |
1202 | |
1203 FrameFunctionIterator it(isolate, no_allocation); | 1196 FrameFunctionIterator it(isolate, no_allocation); |
1204 | 1197 if (function->shared()->native()) { |
| 1198 return MaybeHandle<JSFunction>(); |
| 1199 } |
1205 // Find the function from the frames. | 1200 // Find the function from the frames. |
1206 if (!it.Find(*function)) { | 1201 if (!it.Find(*function)) { |
1207 // No frame corresponding to the given function found. Return null. | 1202 // No frame corresponding to the given function found. Return null. |
1208 return isolate->heap()->null_value(); | 1203 return MaybeHandle<JSFunction>(); |
1209 } | 1204 } |
1210 | |
1211 // Find previously called non-toplevel function. | 1205 // Find previously called non-toplevel function. |
1212 JSFunction* caller; | 1206 JSFunction* caller; |
1213 do { | 1207 do { |
1214 caller = it.next(); | 1208 caller = it.next(); |
1215 if (caller == NULL) return isolate->heap()->null_value(); | 1209 if (caller == NULL) return MaybeHandle<JSFunction>(); |
1216 } while (caller->shared()->is_toplevel()); | 1210 } while (caller->shared()->is_toplevel()); |
1217 | 1211 |
1218 // If caller is a built-in function and caller's caller is also built-in, | 1212 // If caller is a built-in function and caller's caller is also built-in, |
1219 // use that instead. | 1213 // use that instead. |
1220 JSFunction* potential_caller = caller; | 1214 JSFunction* potential_caller = caller; |
1221 while (potential_caller != NULL && potential_caller->IsBuiltin()) { | 1215 while (potential_caller != NULL && potential_caller->IsBuiltin()) { |
1222 caller = potential_caller; | 1216 caller = potential_caller; |
1223 potential_caller = it.next(); | 1217 potential_caller = it.next(); |
1224 } | 1218 } |
1225 if (!caller->shared()->native() && potential_caller != NULL) { | 1219 if (!caller->shared()->native() && potential_caller != NULL) { |
1226 caller = potential_caller; | 1220 caller = potential_caller; |
1227 } | 1221 } |
1228 // If caller is bound, return null. This is compatible with JSC, and | 1222 // If caller is bound, return null. This is compatible with JSC, and |
1229 // allows us to make bound functions use the strict function map | 1223 // allows us to make bound functions use the strict function map |
1230 // and its associated throwing caller and arguments. | 1224 // and its associated throwing caller and arguments. |
1231 if (caller->shared()->bound()) { | 1225 if (caller->shared()->bound()) { |
1232 return isolate->heap()->null_value(); | 1226 return MaybeHandle<JSFunction>(); |
1233 } | 1227 } |
1234 // Censor if the caller is not a sloppy mode function. | 1228 // Censor if the caller is not a sloppy mode function. |
1235 // Change from ES5, which used to throw, see: | 1229 // Change from ES5, which used to throw, see: |
1236 // https://bugs.ecmascript.org/show_bug.cgi?id=310 | 1230 // https://bugs.ecmascript.org/show_bug.cgi?id=310 |
1237 if (caller->shared()->strict_mode() == STRICT) { | 1231 if (caller->shared()->strict_mode() == STRICT) { |
1238 return isolate->heap()->null_value(); | 1232 return MaybeHandle<JSFunction>(); |
1239 } | 1233 } |
1240 | 1234 return Handle<JSFunction>(caller); |
1241 return caller; | |
1242 } | 1235 } |
1243 | 1236 |
1244 | 1237 |
1245 const AccessorDescriptor Accessors::FunctionCaller = { | 1238 void Accessors::FunctionCallerGetter( |
1246 FunctionGetCaller, | 1239 v8::Local<v8::String> name, |
1247 ReadOnlySetAccessor, | 1240 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1248 0 | 1241 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
1249 }; | 1242 HandleScope scope(isolate); |
| 1243 Handle<Object> object = Utils::OpenHandle(*info.This()); |
| 1244 MaybeHandle<JSFunction> maybe_function; |
| 1245 { |
| 1246 DisallowHeapAllocation no_allocation; |
| 1247 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object); |
| 1248 if (function != NULL) maybe_function = Handle<JSFunction>(function); |
| 1249 } |
| 1250 Handle<JSFunction> function; |
| 1251 Handle<Object> result; |
| 1252 if (maybe_function.ToHandle(&function)) { |
| 1253 MaybeHandle<JSFunction> maybe_caller; |
| 1254 maybe_caller = FindCaller(isolate, function); |
| 1255 Handle<JSFunction> caller; |
| 1256 if (maybe_caller.ToHandle(&caller)) { |
| 1257 result = caller; |
| 1258 } else { |
| 1259 result = isolate->factory()->null_value(); |
| 1260 } |
| 1261 } else { |
| 1262 result = isolate->factory()->undefined_value(); |
| 1263 } |
| 1264 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 1265 } |
| 1266 |
| 1267 |
| 1268 void Accessors::FunctionCallerSetter( |
| 1269 v8::Local<v8::String> name, |
| 1270 v8::Local<v8::Value> val, |
| 1271 const v8::PropertyCallbackInfo<void>& info) { |
| 1272 // Do nothing. |
| 1273 } |
| 1274 |
| 1275 |
| 1276 Handle<AccessorInfo> Accessors::FunctionCallerInfo( |
| 1277 Isolate* isolate, PropertyAttributes attributes) { |
| 1278 return MakeAccessor(isolate, |
| 1279 isolate->factory()->caller_string(), |
| 1280 &FunctionCallerGetter, |
| 1281 &FunctionCallerSetter, |
| 1282 attributes); |
| 1283 } |
1250 | 1284 |
1251 | 1285 |
1252 // | 1286 // |
1253 // Accessors::MakeModuleExport | 1287 // Accessors::MakeModuleExport |
1254 // | 1288 // |
1255 | 1289 |
1256 static void ModuleGetExport( | 1290 static void ModuleGetExport( |
1257 v8::Local<v8::String> property, | 1291 v8::Local<v8::String> property, |
1258 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1292 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1259 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder())); | 1293 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder())); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 info->set_data(Smi::FromInt(index)); | 1342 info->set_data(Smi::FromInt(index)); |
1309 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); | 1343 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); |
1310 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); | 1344 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); |
1311 info->set_getter(*getter); | 1345 info->set_getter(*getter); |
1312 if (!(attributes & ReadOnly)) info->set_setter(*setter); | 1346 if (!(attributes & ReadOnly)) info->set_setter(*setter); |
1313 return info; | 1347 return info; |
1314 } | 1348 } |
1315 | 1349 |
1316 | 1350 |
1317 } } // namespace v8::internal | 1351 } } // namespace v8::internal |
OLD | NEW |