| 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 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 } | 993 } |
| 994 } | 994 } |
| 995 } | 995 } |
| 996 } | 996 } |
| 997 | 997 |
| 998 | 998 |
| 999 // ------------------------------------------------------------------------ | 999 // ------------------------------------------------------------------------ |
| 1000 // StubCompiler implementation. | 1000 // StubCompiler implementation. |
| 1001 | 1001 |
| 1002 | 1002 |
| 1003 RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) { | |
| 1004 ASSERT(args[0]->IsJSObject()); | |
| 1005 ASSERT(args[1]->IsJSObject()); | |
| 1006 ASSERT(args[3]->IsSmi()); | |
| 1007 AccessorInfo* callback = AccessorInfo::cast(args[4]); | |
| 1008 Address getter_address = v8::ToCData<Address>(callback->getter()); | |
| 1009 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); | |
| 1010 ASSERT(fun != NULL); | |
| 1011 ASSERT(callback->IsCompatibleReceiver(args[0])); | |
| 1012 v8::AccessorInfo info(&args[0]); | |
| 1013 HandleScope scope(isolate); | |
| 1014 v8::Handle<v8::Value> result; | |
| 1015 { | |
| 1016 // Leaving JavaScript. | |
| 1017 VMState state(isolate, EXTERNAL); | |
| 1018 ExternalCallbackScope call_scope(isolate, getter_address); | |
| 1019 result = fun(v8::Utils::ToLocal(args.at<String>(5)), info); | |
| 1020 } | |
| 1021 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | |
| 1022 if (result.IsEmpty()) return HEAP->undefined_value(); | |
| 1023 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | |
| 1024 result_internal->VerifyApiCallResultType(); | |
| 1025 return *result_internal; | |
| 1026 } | |
| 1027 | |
| 1028 | |
| 1029 RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) { | 1003 RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) { |
| 1030 JSObject* recv = JSObject::cast(args[0]); | 1004 JSObject* recv = JSObject::cast(args[0]); |
| 1031 AccessorInfo* callback = AccessorInfo::cast(args[1]); | 1005 AccessorInfo* callback = AccessorInfo::cast(args[1]); |
| 1032 Address setter_address = v8::ToCData<Address>(callback->setter()); | 1006 Address setter_address = v8::ToCData<Address>(callback->setter()); |
| 1033 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); | 1007 v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); |
| 1034 ASSERT(fun != NULL); | 1008 ASSERT(fun != NULL); |
| 1035 ASSERT(callback->IsCompatibleReceiver(recv)); | 1009 ASSERT(callback->IsCompatibleReceiver(recv)); |
| 1036 Handle<String> name = args.at<String>(2); | 1010 Handle<String> name = args.at<String>(2); |
| 1037 Handle<Object> value = args.at<Object>(3); | 1011 Handle<Object> value = args.at<Object>(3); |
| 1038 HandleScope scope(isolate); | 1012 HandleScope scope(isolate); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 holder->LocalLookupRealNamedProperty(*name, lookup); | 1360 holder->LocalLookupRealNamedProperty(*name, lookup); |
| 1387 if (lookup->IsFound()) return; | 1361 if (lookup->IsFound()) return; |
| 1388 if (holder->GetPrototype()->IsNull()) return; | 1362 if (holder->GetPrototype()->IsNull()) return; |
| 1389 holder->GetPrototype()->Lookup(*name, lookup); | 1363 holder->GetPrototype()->Lookup(*name, lookup); |
| 1390 } | 1364 } |
| 1391 | 1365 |
| 1392 | 1366 |
| 1393 #define __ ACCESS_MASM(masm()) | 1367 #define __ ACCESS_MASM(masm()) |
| 1394 | 1368 |
| 1395 | 1369 |
| 1370 Register BaseLoadStubCompiler::HandlerFrontendHeader(Handle<JSObject> object, |
| 1371 Register object_reg, |
| 1372 Handle<JSObject> holder, |
| 1373 Handle<String> name, |
| 1374 Label* miss, |
| 1375 FrontendCheckType check) { |
| 1376 if (check == PERFORM_INITIAL_CHECKS) { |
| 1377 GenerateNameCheck(name, this->name(), miss); |
| 1378 // Check that the receiver isn't a smi. |
| 1379 __ JumpIfSmi(object_reg, miss); |
| 1380 } |
| 1381 |
| 1382 // Check the prototype chain. |
| 1383 return CheckPrototypes(object, object_reg, holder, |
| 1384 scratch1(), scratch2(), scratch3(), |
| 1385 name, miss); |
| 1386 } |
| 1387 |
| 1388 |
| 1389 Register BaseLoadStubCompiler::HandlerFrontend(Handle<JSObject> object, |
| 1390 Register object_reg, |
| 1391 Handle<JSObject> holder, |
| 1392 Handle<String> name, |
| 1393 Label* success, |
| 1394 FrontendCheckType check) { |
| 1395 Label miss; |
| 1396 |
| 1397 Register reg = HandlerFrontendHeader( |
| 1398 object, object_reg, holder, name, &miss, check); |
| 1399 |
| 1400 HandlerFrontendFooter(success, &miss); |
| 1401 return reg; |
| 1402 } |
| 1403 |
| 1404 |
| 1396 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object, | 1405 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object, |
| 1397 Handle<JSObject> holder, | 1406 Handle<JSObject> holder, |
| 1398 Handle<String> name, | 1407 Handle<String> name, |
| 1399 PropertyIndex index) { | 1408 PropertyIndex index) { |
| 1400 Label miss; | 1409 Label success; |
| 1401 | 1410 Register reg = HandlerFrontend(object, receiver(), holder, name, |
| 1402 GenerateNameCheck(name, this->name(), &miss); | 1411 &success, PERFORM_INITIAL_CHECKS); |
| 1403 GenerateLoadField(object, holder, receiver(), | 1412 __ bind(&success); |
| 1404 scratch1(), scratch2(), scratch3(), | 1413 GenerateLoadField(reg, holder, index); |
| 1405 index, name, &miss); | |
| 1406 __ bind(&miss); | |
| 1407 GenerateLoadMiss(masm(), kind()); | |
| 1408 | 1414 |
| 1409 // Return the generated code. | 1415 // Return the generated code. |
| 1410 return GetCode(Code::FIELD, name); | 1416 return GetCode(Code::FIELD, name); |
| 1411 } | 1417 } |
| 1412 | 1418 |
| 1413 | 1419 |
| 1420 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( |
| 1421 Handle<JSObject> object, |
| 1422 Handle<JSObject> holder, |
| 1423 Handle<String> name, |
| 1424 Handle<JSFunction> value) { |
| 1425 Label success; |
| 1426 HandlerFrontend(object, receiver(), holder, name, |
| 1427 &success, PERFORM_INITIAL_CHECKS); |
| 1428 __ bind(&success); |
| 1429 GenerateLoadConstant(value); |
| 1430 |
| 1431 // Return the generated code. |
| 1432 return GetCode(Code::CONSTANT_FUNCTION, name); |
| 1433 } |
| 1434 |
| 1435 |
| 1414 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( | 1436 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( |
| 1415 Handle<JSObject> object, | 1437 Handle<JSObject> object, |
| 1416 Handle<JSObject> holder, | 1438 Handle<JSObject> holder, |
| 1417 Handle<String> name, | 1439 Handle<String> name, |
| 1418 Handle<AccessorInfo> callback) { | 1440 Handle<AccessorInfo> callback) { |
| 1419 Label miss; | 1441 Label success; |
| 1420 | 1442 |
| 1421 GenerateNameCheck(name, this->name(), &miss); | 1443 Register reg = CallbackHandlerFrontend( |
| 1422 GenerateLoadCallback(object, holder, receiver(), this->name(), | 1444 object, receiver(), holder, name, &success, |
| 1423 scratch1(), scratch2(), scratch3(), scratch4(), | 1445 PERFORM_INITIAL_CHECKS, callback); |
| 1424 callback, name, &miss); | 1446 __ bind(&success); |
| 1425 __ bind(&miss); | 1447 GenerateLoadCallback(reg, callback); |
| 1426 GenerateLoadMiss(masm(), kind()); | |
| 1427 | 1448 |
| 1428 // Return the generated code. | 1449 // Return the generated code. |
| 1429 return GetCode(Code::CALLBACKS, name); | 1450 return GetCode(Code::CALLBACKS, name); |
| 1430 } | 1451 } |
| 1431 | 1452 |
| 1432 | 1453 |
| 1433 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( | |
| 1434 Handle<JSObject> object, | |
| 1435 Handle<JSObject> holder, | |
| 1436 Handle<String> name, | |
| 1437 Handle<JSFunction> value) { | |
| 1438 Label miss; | |
| 1439 | |
| 1440 GenerateNameCheck(name, this->name(), &miss); | |
| 1441 GenerateLoadConstant(object, holder, receiver(), | |
| 1442 scratch1(), scratch2(), scratch3(), | |
| 1443 value, name, &miss); | |
| 1444 __ bind(&miss); | |
| 1445 GenerateLoadMiss(masm(), kind()); | |
| 1446 | |
| 1447 // Return the generated code. | |
| 1448 return GetCode(Code::CONSTANT_FUNCTION, name); | |
| 1449 } | |
| 1450 | |
| 1451 | |
| 1452 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( | 1454 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( |
| 1453 Handle<JSObject> object, | 1455 Handle<JSObject> object, |
| 1454 Handle<JSObject> holder, | 1456 Handle<JSObject> holder, |
| 1455 Handle<String> name) { | 1457 Handle<String> name) { |
| 1456 Label miss; | 1458 Label success; |
| 1457 | 1459 |
| 1458 LookupResult lookup(isolate()); | 1460 LookupResult lookup(isolate()); |
| 1459 LookupPostInterceptor(holder, name, &lookup); | 1461 LookupPostInterceptor(holder, name, &lookup); |
| 1460 | 1462 |
| 1461 GenerateNameCheck(name, this->name(), &miss); | 1463 Register reg = HandlerFrontend(object, receiver(), holder, name, |
| 1464 &success, PERFORM_INITIAL_CHECKS); |
| 1465 __ bind(&success); |
| 1462 // TODO(368): Compile in the whole chain: all the interceptors in | 1466 // TODO(368): Compile in the whole chain: all the interceptors in |
| 1463 // prototypes and ultimate answer. | 1467 // prototypes and ultimate answer. |
| 1464 GenerateLoadInterceptor(object, holder, &lookup, receiver(), this->name(), | 1468 GenerateLoadInterceptor(reg, object, holder, &lookup, name); |
| 1465 scratch1(), scratch2(), scratch3(), | |
| 1466 name, &miss); | |
| 1467 | |
| 1468 __ bind(&miss); | |
| 1469 GenerateLoadMiss(masm(), kind()); | |
| 1470 | 1469 |
| 1471 // Return the generated code. | 1470 // Return the generated code. |
| 1472 return GetCode(Code::INTERCEPTOR, name); | 1471 return GetCode(Code::INTERCEPTOR, name); |
| 1473 } | 1472 } |
| 1474 | 1473 |
| 1475 | 1474 |
| 1475 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( |
| 1476 Register interceptor_reg, |
| 1477 Handle<JSObject> interceptor_holder, |
| 1478 Handle<String> name, |
| 1479 LookupResult* lookup) { |
| 1480 Label success; |
| 1481 Handle<JSObject> holder(lookup->holder()); |
| 1482 if (lookup->IsField()) { |
| 1483 // We found FIELD property in prototype chain of interceptor's holder. |
| 1484 // Retrieve a field from field's holder. |
| 1485 Register reg = HandlerFrontend(interceptor_holder, interceptor_reg, holder, |
| 1486 name, &success, SKIP_INITIAL_CHECKS); |
| 1487 __ bind(&success); |
| 1488 GenerateLoadField(reg, holder, lookup->GetFieldIndex()); |
| 1489 } else { |
| 1490 // We found CALLBACKS property in prototype chain of interceptor's |
| 1491 // holder. |
| 1492 ASSERT(lookup->type() == CALLBACKS); |
| 1493 Handle<AccessorInfo> callback( |
| 1494 AccessorInfo::cast(lookup->GetCallbackObject())); |
| 1495 ASSERT(callback->getter() != NULL); |
| 1496 |
| 1497 Register reg = CallbackHandlerFrontend( |
| 1498 interceptor_holder, interceptor_reg, holder, |
| 1499 name, &success, SKIP_INITIAL_CHECKS, callback); |
| 1500 __ bind(&success); |
| 1501 GenerateLoadCallback(reg, callback); |
| 1502 } |
| 1503 } |
| 1504 |
| 1505 |
| 1506 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
| 1507 Handle<JSObject> object, |
| 1508 Handle<JSObject> holder, |
| 1509 Handle<String> name, |
| 1510 Handle<JSFunction> getter) { |
| 1511 Label success; |
| 1512 HandlerFrontend(object, receiver(), holder, name, |
| 1513 &success, PERFORM_INITIAL_CHECKS); |
| 1514 |
| 1515 __ bind(&success); |
| 1516 GenerateLoadViaGetter(masm(), getter); |
| 1517 |
| 1518 // Return the generated code. |
| 1519 return GetCode(Code::CALLBACKS, name); |
| 1520 } |
| 1521 |
| 1522 |
| 1476 #undef __ | 1523 #undef __ |
| 1477 | 1524 |
| 1478 | 1525 |
| 1479 Handle<Code> LoadStubCompiler::GetCode(Code::StubType type, | 1526 Handle<Code> LoadStubCompiler::GetCode(Code::StubType type, |
| 1480 Handle<String> name, | 1527 Handle<String> name, |
| 1481 InlineCacheState state) { | 1528 InlineCacheState state) { |
| 1482 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); | 1529 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); |
| 1483 Handle<Code> code = GetCodeWithFlags(flags, name); | 1530 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1484 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); | 1531 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); |
| 1485 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1532 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 Handle<FunctionTemplateInfo>( | 1809 Handle<FunctionTemplateInfo>( |
| 1763 FunctionTemplateInfo::cast(signature->receiver())); | 1810 FunctionTemplateInfo::cast(signature->receiver())); |
| 1764 } | 1811 } |
| 1765 } | 1812 } |
| 1766 | 1813 |
| 1767 is_simple_api_call_ = true; | 1814 is_simple_api_call_ = true; |
| 1768 } | 1815 } |
| 1769 | 1816 |
| 1770 | 1817 |
| 1771 } } // namespace v8::internal | 1818 } } // namespace v8::internal |
| OLD | NEW |