📄 builtins.cc.svn-base
字号:
Object* raw_holder = TypeCheck(__argc__, __argv__, fun_data); if (raw_holder->IsNull()) { // This function cannot be called with the given receiver. Abort! Handle<Object> obj = Factory::NewTypeError("illegal_invocation", HandleVector(&function, 1)); return Top::Throw(*obj); } Object* raw_call_data = fun_data->call_code(); if (!raw_call_data->IsUndefined()) { CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); Object* callback_obj = call_data->callback(); v8::InvocationCallback callback = v8::ToCData<v8::InvocationCallback>(callback_obj); Object* data_obj = call_data->data(); Object* result; v8::Local<v8::Object> self = v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); Handle<Object> data_handle(data_obj); v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); ASSERT(raw_holder->IsJSObject()); v8::Local<v8::Function> callee = v8::Utils::ToLocal(function); Handle<JSObject> holder_handle(JSObject::cast(raw_holder)); v8::Local<v8::Object> holder = v8::Utils::ToLocal(holder_handle); LOG(ApiObjectAccess("call", JSObject::cast(*receiver))); v8::Arguments args = v8::ImplementationUtilities::NewArguments( data, holder, callee, is_construct, reinterpret_cast<void**>(__argv__ - 1), __argc__ - 1); v8::Handle<v8::Value> value; { // Leaving JavaScript. VMState state(OTHER); value = callback(args); } if (value.IsEmpty()) { result = Heap::undefined_value(); } else { result = *reinterpret_cast<Object**>(*value); } RETURN_IF_SCHEDULED_EXCEPTION(); if (!is_construct || result->IsJSObject()) return result; } return *receiver;}BUILTIN_END// Handle calls to non-function objects created through the API that// support calls.BUILTIN(HandleApiCallAsFunction) { // Non-functions are never called as constructors. ASSERT(!CalledAsConstructor()); // Get the object called. JSObject* obj = JSObject::cast(*receiver); // Get the invocation callback from the function descriptor that was // used to create the called object. ASSERT(obj->map()->has_instance_call_handler()); JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); Object* template_info = constructor->shared()->function_data(); Object* handler = FunctionTemplateInfo::cast(template_info)->instance_call_handler(); ASSERT(!handler->IsUndefined()); CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); Object* callback_obj = call_data->callback(); v8::InvocationCallback callback = v8::ToCData<v8::InvocationCallback>(callback_obj); // Get the data for the call and perform the callback. Object* data_obj = call_data->data(); Object* result; { HandleScope scope; v8::Local<v8::Object> self = v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); Handle<Object> data_handle(data_obj); v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); Handle<JSFunction> callee_handle(constructor); v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle); LOG(ApiObjectAccess("call non-function", JSObject::cast(*receiver))); v8::Arguments args = v8::ImplementationUtilities::NewArguments( data, self, callee, false, reinterpret_cast<void**>(__argv__ - 1), __argc__ - 1); v8::Handle<v8::Value> value; { // Leaving JavaScript. VMState state(OTHER); value = callback(args); } if (value.IsEmpty()) { result = Heap::undefined_value(); } else { result = *reinterpret_cast<Object**>(*value); } } // Check for exceptions and return result. RETURN_IF_SCHEDULED_EXCEPTION(); return result;}BUILTIN_END// TODO(1238487): This is a nasty hack. We need to improve the way we// call builtins considerable to get rid of this and the hairy macros// in builtins.cc.Object* Builtins::builtin_passed_function;static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) { LoadIC::GenerateArrayLength(masm);}static void Generate_LoadIC_ShortStringLength(MacroAssembler* masm) { LoadIC::GenerateShortStringLength(masm);}static void Generate_LoadIC_MediumStringLength(MacroAssembler* masm) { LoadIC::GenerateMediumStringLength(masm);}static void Generate_LoadIC_LongStringLength(MacroAssembler* masm) { LoadIC::GenerateLongStringLength(masm);}static void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) { LoadIC::GenerateFunctionPrototype(masm);}static void Generate_LoadIC_Initialize(MacroAssembler* masm) { LoadIC::GenerateInitialize(masm);}static void Generate_LoadIC_PreMonomorphic(MacroAssembler* masm) { LoadIC::GeneratePreMonomorphic(masm);}static void Generate_LoadIC_Miss(MacroAssembler* masm) { LoadIC::GenerateMiss(masm);}static void Generate_LoadIC_Megamorphic(MacroAssembler* masm) { LoadIC::GenerateMegamorphic(masm);}static void Generate_LoadIC_Normal(MacroAssembler* masm) { LoadIC::GenerateNormal(masm);}static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) { KeyedLoadIC::GenerateInitialize(masm);}static void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) { KeyedLoadIC::GenerateMiss(masm);}static void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) { KeyedLoadIC::GenerateGeneric(masm);}static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) { KeyedLoadIC::GeneratePreMonomorphic(masm);}static void Generate_StoreIC_Initialize(MacroAssembler* masm) { StoreIC::GenerateInitialize(masm);}static void Generate_StoreIC_Miss(MacroAssembler* masm) { StoreIC::GenerateMiss(masm);}static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) { StoreIC::GenerateMegamorphic(masm);}static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) { KeyedStoreIC::GenerateGeneric(masm);}static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) { KeyedStoreIC::GenerateMiss(masm);}static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) { KeyedStoreIC::GenerateInitialize(masm);}Object* Builtins::builtins_[builtin_count] = { NULL, };const char* Builtins::names_[builtin_count] = { NULL, };#define DEF_ENUM_C(name) FUNCTION_ADDR(Builtin_##name), Address Builtins::c_functions_[cfunction_count] = { BUILTIN_LIST_C(DEF_ENUM_C) };#undef DEF_ENUM_C#define DEF_JS_NAME(name, ignore) #name,#define DEF_JS_ARGC(ignore, argc) argc,const char* Builtins::javascript_names_[id_count] = { BUILTINS_LIST_JS(DEF_JS_NAME)};int Builtins::javascript_argc_[id_count] = { BUILTINS_LIST_JS(DEF_JS_ARGC)};#undef DEF_JS_NAME#undef DEF_JS_ARGCstatic bool is_initialized = false;void Builtins::Setup(bool create_heap_objects) { ASSERT(!is_initialized); // Create a scope for the handles in the builtins. HandleScope scope; struct BuiltinDesc { byte* generator; byte* c_code; const char* s_name; // name is only used for generating log information. int name; Code::Flags flags; };#define DEF_FUNCTION_PTR_C(name) \ { FUNCTION_ADDR(Generate_Adaptor), \ FUNCTION_ADDR(Builtin_##name), \ #name, \ c_##name, \ Code::ComputeFlags(Code::BUILTIN) \ },#define DEF_FUNCTION_PTR_A(name, kind, state) \ { FUNCTION_ADDR(Generate_##name), \ NULL, \ #name, \ name, \ Code::ComputeFlags(Code::kind, state) \ }, // Define array of pointers to generators and C builtin functions. static BuiltinDesc functions[] = { BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) // Terminator: { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0) } };#undef DEF_FUNCTION_PTR_C#undef DEF_FUNCTION_PTR_A // For now we generate builtin adaptor code into a stack-allocated // buffer, before copying it into individual code objects. byte buffer[4*KB]; // Traverse the list of builtins and generate an adaptor in a // separate code object for each one. for (int i = 0; i < builtin_count; i++) { if (create_heap_objects) { MacroAssembler masm(buffer, sizeof buffer); // Generate the code/adaptor. typedef void (*Generator)(MacroAssembler*, int); Generator g = FUNCTION_CAST<Generator>(functions[i].generator); // We pass all arguments to the generator, but it may not use all of // them. This works because the first arguments are on top of the // stack. g(&masm, functions[i].name); // Move the code into the object heap. CodeDesc desc; masm.GetCode(&desc); Code::Flags flags = functions[i].flags; Object* code = Heap::CreateCode(desc, NULL, flags); if (code->IsRetryAfterGC()) { CHECK(Heap::CollectGarbage(Failure::cast(code)->requested(), Failure::cast(code)->allocation_space())); code = Heap::CreateCode(desc, NULL, flags); } // Add any unresolved jumps or calls to the fixup list in the // bootstrapper. Bootstrapper::AddFixup(Code::cast(code), &masm); // Log the event and add the code to the builtins array. LOG(CodeCreateEvent("Builtin", Code::cast(code), functions[i].s_name)); builtins_[i] = code;#ifdef DEBUG if (FLAG_print_builtin_code) { PrintF("Builtin: %s\n", functions[i].s_name); code->Print(); PrintF("\n"); }#endif } else { // Deserializing. The values will be filled in during IterateBuiltins. builtins_[i] = NULL; } names_[i] = functions[i].s_name; } // Mark as initialized. is_initialized = true;}void Builtins::TearDown() { is_initialized = false;}void Builtins::IterateBuiltins(ObjectVisitor* v) { v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count);}const char* Builtins::Lookup(byte* pc) { if (is_initialized) { // may be called during initialization (disassembler!) for (int i = 0; i < builtin_count; i++) { Code* entry = Code::cast(builtins_[i]); if (entry->contains(pc)) { return names_[i]; } } } return NULL;}} } // namespace v8::internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -