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 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 BUILTIN(StrictModePoisonPill) { | 1231 BUILTIN(StrictModePoisonPill) { |
1232 HandleScope scope; | 1232 HandleScope scope; |
1233 return isolate->Throw(*isolate->factory()->NewTypeError( | 1233 return isolate->Throw(*isolate->factory()->NewTypeError( |
1234 "strict_poison_pill", HandleVector<Object>(NULL, 0))); | 1234 "strict_poison_pill", HandleVector<Object>(NULL, 0))); |
1235 } | 1235 } |
1236 | 1236 |
1237 // ----------------------------------------------------------------------------- | 1237 // ----------------------------------------------------------------------------- |
1238 // | 1238 // |
1239 | 1239 |
1240 | 1240 |
1241 // Returns the holder JSObject if the function can legally be called | 1241 // Returns true if the function can legally be called with the given |
1242 // with this receiver. Returns Heap::null_value() if the call is | 1242 // receiver. Returns false if the call is illegal. Any arguments that |
1243 // illegal. Any arguments that don't fit the expected type is | 1243 // don't fit the expected type are overwritten with undefined. |
1244 // overwritten with undefined. Arguments that do fit the expected | 1244 static inline bool TypeCheck(Heap* heap, |
1245 // type is overwritten with the object in the prototype chain that | 1245 int argc, |
1246 // actually has that type. | 1246 Object** argv, |
1247 static inline Object* TypeCheck(Heap* heap, | 1247 FunctionTemplateInfo* info) { |
1248 int argc, | |
1249 Object** argv, | |
1250 FunctionTemplateInfo* info) { | |
1251 Object* recv = argv[0]; | 1248 Object* recv = argv[0]; |
1252 // API calls are only supported with JSObject receivers. | 1249 // API calls are only supported with JSObject receivers. |
1253 if (!recv->IsJSObject()) return heap->null_value(); | 1250 if (!recv->IsJSObject()) return false; |
1254 Object* sig_obj = info->signature(); | 1251 Object* sig_obj = info->signature(); |
1255 if (sig_obj->IsUndefined()) return recv; | 1252 if (sig_obj->IsUndefined()) return true; |
1256 SignatureInfo* sig = SignatureInfo::cast(sig_obj); | 1253 SignatureInfo* sig = SignatureInfo::cast(sig_obj); |
1257 // If necessary, check the receiver | 1254 // If necessary, check the receiver |
1258 Object* recv_type = sig->receiver(); | 1255 Object* recv_type = sig->receiver(); |
1259 | 1256 if (!recv_type->IsUndefined() && |
1260 Object* holder = recv; | 1257 !recv->IsInstanceOf(FunctionTemplateInfo::cast(recv_type))) { |
1261 if (!recv_type->IsUndefined()) { | 1258 return false; |
1262 for (; holder != heap->null_value(); holder = holder->GetPrototype()) { | |
1263 if (holder->IsInstanceOf(FunctionTemplateInfo::cast(recv_type))) { | |
1264 break; | |
1265 } | |
1266 } | |
1267 if (holder == heap->null_value()) return holder; | |
1268 } | 1259 } |
1269 Object* args_obj = sig->args(); | 1260 Object* args_obj = sig->args(); |
1270 // If there is no argument signature we're done | 1261 // If there is no argument signature we're done |
1271 if (args_obj->IsUndefined()) return holder; | 1262 if (args_obj->IsUndefined()) return true; |
1272 FixedArray* args = FixedArray::cast(args_obj); | 1263 FixedArray* args = FixedArray::cast(args_obj); |
1273 int length = args->length(); | 1264 int length = args->length(); |
1274 if (argc <= length) length = argc - 1; | 1265 if (argc <= length) length = argc - 1; |
1275 for (int i = 0; i < length; i++) { | 1266 for (int i = 0; i < length; i++) { |
1276 Object* argtype = args->get(i); | 1267 Object* argtype = args->get(i); |
1277 if (argtype->IsUndefined()) continue; | 1268 if (argtype->IsUndefined()) continue; |
1278 Object** arg = &argv[-1 - i]; | 1269 Object** arg = &argv[-1 - i]; |
1279 Object* current = *arg; | 1270 Object* current = *arg; |
1280 for (; current != heap->null_value(); current = current->GetPrototype()) { | 1271 if (!current->IsInstanceOf(FunctionTemplateInfo::cast(argtype))) { |
1281 if (current->IsInstanceOf(FunctionTemplateInfo::cast(argtype))) { | 1272 *arg = heap->undefined_value(); |
1282 *arg = current; | |
1283 break; | |
1284 } | |
1285 } | 1273 } |
1286 if (current == heap->null_value()) *arg = heap->undefined_value(); | |
1287 } | 1274 } |
1288 return holder; | 1275 return true; |
1289 } | 1276 } |
1290 | 1277 |
1291 | 1278 |
1292 template <bool is_construct> | 1279 template <bool is_construct> |
1293 MUST_USE_RESULT static MaybeObject* HandleApiCallHelper( | 1280 MUST_USE_RESULT static MaybeObject* HandleApiCallHelper( |
1294 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { | 1281 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { |
1295 ASSERT(is_construct == CalledAsConstructor(isolate)); | 1282 ASSERT(is_construct == CalledAsConstructor(isolate)); |
1296 Heap* heap = isolate->heap(); | 1283 Heap* heap = isolate->heap(); |
1297 | 1284 |
1298 HandleScope scope(isolate); | 1285 HandleScope scope(isolate); |
1299 Handle<JSFunction> function = args.called_function(); | 1286 Handle<JSFunction> function = args.called_function(); |
1300 ASSERT(function->shared()->IsApiFunction()); | 1287 ASSERT(function->shared()->IsApiFunction()); |
1301 | 1288 |
1302 FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data(); | 1289 FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data(); |
1303 if (is_construct) { | 1290 if (is_construct) { |
1304 Handle<FunctionTemplateInfo> desc(fun_data, isolate); | 1291 Handle<FunctionTemplateInfo> desc(fun_data, isolate); |
1305 bool pending_exception = false; | 1292 bool pending_exception = false; |
1306 isolate->factory()->ConfigureInstance( | 1293 isolate->factory()->ConfigureInstance( |
1307 desc, Handle<JSObject>::cast(args.receiver()), &pending_exception); | 1294 desc, Handle<JSObject>::cast(args.receiver()), &pending_exception); |
1308 ASSERT(isolate->has_pending_exception() == pending_exception); | 1295 ASSERT(isolate->has_pending_exception() == pending_exception); |
1309 if (pending_exception) return Failure::Exception(); | 1296 if (pending_exception) return Failure::Exception(); |
1310 fun_data = *desc; | 1297 fun_data = *desc; |
1311 } | 1298 } |
1312 | 1299 |
1313 Object* raw_holder = TypeCheck(heap, args.length(), &args[0], fun_data); | 1300 if (!TypeCheck(heap, args.length(), &args[0], fun_data)) { |
1314 | |
1315 if (raw_holder->IsNull()) { | |
1316 // This function cannot be called with the given receiver. Abort! | 1301 // This function cannot be called with the given receiver. Abort! |
1317 Handle<Object> obj = | 1302 Handle<Object> obj = |
1318 isolate->factory()->NewTypeError( | 1303 isolate->factory()->NewTypeError( |
1319 "illegal_invocation", HandleVector(&function, 1)); | 1304 "illegal_invocation", HandleVector(&function, 1)); |
1320 return isolate->Throw(*obj); | 1305 return isolate->Throw(*obj); |
1321 } | 1306 } |
1322 | 1307 |
1323 Object* raw_call_data = fun_data->call_code(); | 1308 Object* raw_call_data = fun_data->call_code(); |
1324 if (!raw_call_data->IsUndefined()) { | 1309 if (!raw_call_data->IsUndefined()) { |
1325 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 1310 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
1326 Object* callback_obj = call_data->callback(); | 1311 Object* callback_obj = call_data->callback(); |
1327 v8::InvocationCallback callback = | 1312 v8::InvocationCallback callback = |
1328 v8::ToCData<v8::InvocationCallback>(callback_obj); | 1313 v8::ToCData<v8::InvocationCallback>(callback_obj); |
1329 Object* data_obj = call_data->data(); | 1314 Object* data_obj = call_data->data(); |
1330 Object* result; | 1315 Object* result; |
1331 | 1316 |
1332 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 1317 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
1333 ASSERT(raw_holder->IsJSObject()); | |
1334 | 1318 |
1335 CustomArguments custom(isolate); | 1319 CustomArguments custom(isolate); |
| 1320 // TODO(2268): Switch to pass holder once embedders have adapted. |
1336 v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), | 1321 v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), |
1337 isolate, data_obj, *function, raw_holder); | 1322 isolate, data_obj, *function, *args.receiver()); |
1338 | 1323 |
1339 v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( | 1324 v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( |
1340 custom.end(), | 1325 custom.end(), |
1341 &args[0] - 1, | 1326 &args[0] - 1, |
1342 args.length() - 1, | 1327 args.length() - 1, |
1343 is_construct); | 1328 is_construct); |
1344 | 1329 |
1345 v8::Handle<v8::Value> value; | 1330 v8::Handle<v8::Value> value; |
1346 { | 1331 { |
1347 // Leaving JavaScript. | 1332 // Leaving JavaScript. |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1921 return Handle<Code>(code_address); \ | 1906 return Handle<Code>(code_address); \ |
1922 } | 1907 } |
1923 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1908 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1924 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1909 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1925 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1910 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1926 #undef DEFINE_BUILTIN_ACCESSOR_C | 1911 #undef DEFINE_BUILTIN_ACCESSOR_C |
1927 #undef DEFINE_BUILTIN_ACCESSOR_A | 1912 #undef DEFINE_BUILTIN_ACCESSOR_A |
1928 | 1913 |
1929 | 1914 |
1930 } } // namespace v8::internal | 1915 } } // namespace v8::internal |
OLD | NEW |