| 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 |