diff options
Diffstat (limited to 'V8Binding/v8/src/builtins.cc')
-rw-r--r-- | V8Binding/v8/src/builtins.cc | 764 |
1 files changed, 0 insertions, 764 deletions
diff --git a/V8Binding/v8/src/builtins.cc b/V8Binding/v8/src/builtins.cc deleted file mode 100644 index afb5427..0000000 --- a/V8Binding/v8/src/builtins.cc +++ /dev/null @@ -1,764 +0,0 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "v8.h" - -#include "api.h" -#include "arguments.h" -#include "bootstrapper.h" -#include "builtins.h" -#include "ic-inl.h" - -namespace v8 { -namespace internal { - -// ---------------------------------------------------------------------------- -// Support macros for defining builtins in C. -// ---------------------------------------------------------------------------- -// -// A builtin function is defined by writing: -// -// BUILTIN(name) { -// ... -// } -// BUILTIN_END -// -// In the body of the builtin function, the variable 'receiver' is visible. -// The arguments can be accessed through the Arguments object args. -// -// args[0]: Receiver (also available as 'receiver') -// args[1]: First argument -// ... -// args[n]: Last argument -// args.length(): Number of arguments including the receiver. -// ---------------------------------------------------------------------------- - - -// TODO(428): We should consider passing whether or not the -// builtin was invoked as a constructor as part of the -// arguments. Maybe we also want to pass the called function? -#define BUILTIN(name) \ - static Object* Builtin_##name(Arguments args) { \ - Handle<Object> receiver = args.at<Object>(0); - - -#define BUILTIN_END \ - return Heap::undefined_value(); \ -} - - -static inline bool CalledAsConstructor() { -#ifdef DEBUG - // Calculate the result using a full stack frame iterator and check - // that the state of the stack is as we assume it to be in the - // code below. - StackFrameIterator it; - ASSERT(it.frame()->is_exit()); - it.Advance(); - StackFrame* frame = it.frame(); - bool reference_result = frame->is_construct(); -#endif - Address fp = Top::c_entry_fp(Top::GetCurrentThread()); - // Because we know fp points to an exit frame we can use the relevant - // part of ExitFrame::ComputeCallerState directly. - const int kCallerOffset = ExitFrameConstants::kCallerFPOffset; - Address caller_fp = Memory::Address_at(fp + kCallerOffset); - // This inlines the part of StackFrame::ComputeType that grabs the - // type of the current frame. Note that StackFrame::ComputeType - // has been specialized for each architecture so if any one of them - // changes this code has to be changed as well. - const int kMarkerOffset = StandardFrameConstants::kMarkerOffset; - const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT); - Object* marker = Memory::Object_at(caller_fp + kMarkerOffset); - bool result = (marker == kConstructMarker); - ASSERT_EQ(result, reference_result); - return result; -} - -// ---------------------------------------------------------------------------- - - -Handle<Code> Builtins::GetCode(JavaScript id, bool* resolved) { - Code* code = Builtins::builtin(Builtins::Illegal); - *resolved = false; - - if (Top::context() != NULL) { - Object* object = Top::builtins()->javascript_builtin(id); - if (object->IsJSFunction()) { - Handle<JSFunction> function(JSFunction::cast(object)); - // Make sure the number of parameters match the formal parameter count. - ASSERT(function->shared()->formal_parameter_count() == - Builtins::GetArgumentsCount(id)); - if (function->is_compiled() || CompileLazy(function, CLEAR_EXCEPTION)) { - code = function->code(); - *resolved = true; - } - } - } - - return Handle<Code>(code); -} - - -BUILTIN(Illegal) { - UNREACHABLE(); -} -BUILTIN_END - - -BUILTIN(EmptyFunction) { -} -BUILTIN_END - - -BUILTIN(ArrayCodeGeneric) { - Counters::array_function_runtime.Increment(); - - JSArray* array; - if (CalledAsConstructor()) { - array = JSArray::cast(*receiver); - } else { - // Allocate the JS Array - JSFunction* constructor = - Top::context()->global_context()->array_function(); - Object* obj = Heap::AllocateJSObject(constructor); - if (obj->IsFailure()) return obj; - array = JSArray::cast(obj); - } - - // 'array' now contains the JSArray we should initialize. - - // Optimize the case where there is one argument and the argument is a - // small smi. - if (args.length() == 2) { - Object* obj = args[1]; - if (obj->IsSmi()) { - int len = Smi::cast(obj)->value(); - if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) { - Object* obj = Heap::AllocateFixedArrayWithHoles(len); - if (obj->IsFailure()) return obj; - array->SetContent(FixedArray::cast(obj)); - return array; - } - } - // Take the argument as the length. - obj = array->Initialize(0); - if (obj->IsFailure()) return obj; - return array->SetElementsLength(args[1]); - } - - // Optimize the case where there are no parameters passed. - if (args.length() == 1) { - return array->Initialize(JSArray::kPreallocatedArrayElements); - } - - // Take the arguments as elements. - int number_of_elements = args.length() - 1; - Smi* len = Smi::FromInt(number_of_elements); - Object* obj = Heap::AllocateFixedArrayWithHoles(len->value()); - if (obj->IsFailure()) return obj; - FixedArray* elms = FixedArray::cast(obj); - WriteBarrierMode mode = elms->GetWriteBarrierMode(); - // Fill in the content - for (int index = 0; index < number_of_elements; index++) { - elms->set(index, args[index+1], mode); - } - - // Set length and elements on the array. - array->set_elements(FixedArray::cast(obj)); - array->set_length(len, SKIP_WRITE_BARRIER); - - return array; -} -BUILTIN_END - - -BUILTIN(ArrayPush) { - JSArray* array = JSArray::cast(*receiver); - ASSERT(array->HasFastElements()); - - // Make sure we have space for the elements. - int len = Smi::cast(array->length())->value(); - - // Set new length. - int new_length = len + args.length() - 1; - FixedArray* elms = FixedArray::cast(array->elements()); - - if (new_length <= elms->length()) { - // Backing storage has extra space for the provided values. - for (int index = 0; index < args.length() - 1; index++) { - elms->set(index + len, args[index+1]); - } - } else { - // New backing storage is needed. - int capacity = new_length + (new_length >> 1) + 16; - Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); - if (obj->IsFailure()) return obj; - FixedArray* new_elms = FixedArray::cast(obj); - WriteBarrierMode mode = new_elms->GetWriteBarrierMode(); - // Fill out the new array with old elements. - for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode); - // Add the provided values. - for (int index = 0; index < args.length() - 1; index++) { - new_elms->set(index + len, args[index+1], mode); - } - // Set the new backing storage. - array->set_elements(new_elms); - } - // Set the length. - array->set_length(Smi::FromInt(new_length), SKIP_WRITE_BARRIER); - return array->length(); -} -BUILTIN_END - - -BUILTIN(ArrayPop) { - JSArray* array = JSArray::cast(*receiver); - ASSERT(array->HasFastElements()); - Object* undefined = Heap::undefined_value(); - - int len = Smi::cast(array->length())->value(); - if (len == 0) return undefined; - - // Get top element - FixedArray* elms = FixedArray::cast(array->elements()); - Object* top = elms->get(len - 1); - - // Set the length. - array->set_length(Smi::FromInt(len - 1), SKIP_WRITE_BARRIER); - - if (!top->IsTheHole()) { - // Delete the top element. - elms->set_the_hole(len - 1); - return top; - } - - // Remember to check the prototype chain. - JSFunction* array_function = - Top::context()->global_context()->array_function(); - JSObject* prototype = JSObject::cast(array_function->prototype()); - top = prototype->GetElement(len - 1); - - return top; -} -BUILTIN_END - - -// ----------------------------------------------------------------------------- -// - - -// Returns the holder JSObject if the function can legally be called -// with this receiver. Returns Heap::null_value() if the call is -// illegal. Any arguments that don't fit the expected type is -// overwritten with undefined. Arguments that do fit the expected -// type is overwritten with the object in the prototype chain that -// actually has that type. -static inline Object* TypeCheck(int argc, - Object** argv, - FunctionTemplateInfo* info) { - Object* recv = argv[0]; - Object* sig_obj = info->signature(); - if (sig_obj->IsUndefined()) return recv; - SignatureInfo* sig = SignatureInfo::cast(sig_obj); - // If necessary, check the receiver - Object* recv_type = sig->receiver(); - - Object* holder = recv; - if (!recv_type->IsUndefined()) { - for (; holder != Heap::null_value(); holder = holder->GetPrototype()) { - if (holder->IsInstanceOf(FunctionTemplateInfo::cast(recv_type))) { - break; - } - } - if (holder == Heap::null_value()) return holder; - } - Object* args_obj = sig->args(); - // If there is no argument signature we're done - if (args_obj->IsUndefined()) return holder; - FixedArray* args = FixedArray::cast(args_obj); - int length = args->length(); - if (argc <= length) length = argc - 1; - for (int i = 0; i < length; i++) { - Object* argtype = args->get(i); - if (argtype->IsUndefined()) continue; - Object** arg = &argv[-1 - i]; - Object* current = *arg; - for (; current != Heap::null_value(); current = current->GetPrototype()) { - if (current->IsInstanceOf(FunctionTemplateInfo::cast(argtype))) { - *arg = current; - break; - } - } - if (current == Heap::null_value()) *arg = Heap::undefined_value(); - } - return holder; -} - - -BUILTIN(HandleApiCall) { - HandleScope scope; - bool is_construct = CalledAsConstructor(); - - // TODO(428): Remove use of static variable, handle API callbacks directly. - Handle<JSFunction> function = - Handle<JSFunction>(JSFunction::cast(Builtins::builtin_passed_function)); - - if (is_construct) { - Handle<FunctionTemplateInfo> desc = - Handle<FunctionTemplateInfo>( - FunctionTemplateInfo::cast(function->shared()->function_data())); - bool pending_exception = false; - Factory::ConfigureInstance(desc, Handle<JSObject>::cast(receiver), - &pending_exception); - ASSERT(Top::has_pending_exception() == pending_exception); - if (pending_exception) return Failure::Exception(); - } - - FunctionTemplateInfo* fun_data = - FunctionTemplateInfo::cast(function->shared()->function_data()); - Object* raw_holder = TypeCheck(args.length(), &args[0], 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 new_args = v8::ImplementationUtilities::NewArguments( - data, - holder, - callee, - is_construct, - reinterpret_cast<void**>(&args[0] - 1), - args.length() - 1); - - v8::Handle<v8::Value> value; - { - // Leaving JavaScript. - VMState state(EXTERNAL); - value = callback(new_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 - - -// Helper function to handle calls to non-function objects created through the -// API. The object can be called as either a constructor (using new) or just as -// a function (without new). -static Object* HandleApiCallAsFunctionOrConstructor(bool is_construct_call, - Arguments args) { - // Non-functions are never called as constructors. Even if this is an object - // called as a constructor the delegate call is not a construct call. - ASSERT(!CalledAsConstructor()); - - Handle<Object> receiver = args.at<Object>(0); - - // 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 new_args = v8::ImplementationUtilities::NewArguments( - data, - self, - callee, - is_construct_call, - reinterpret_cast<void**>(&args[0] - 1), - args.length() - 1); - v8::Handle<v8::Value> value; - { - // Leaving JavaScript. - VMState state(EXTERNAL); - value = callback(new_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; -} - - -// Handle calls to non-function objects created through the API. This delegate -// function is used when the call is a normal function call. -BUILTIN(HandleApiCallAsFunction) { - return HandleApiCallAsFunctionOrConstructor(false, args); -} -BUILTIN_END - - -// Handle calls to non-function objects created through the API. This delegate -// function is used when the call is a construct call. -BUILTIN(HandleApiCallAsConstructor) { - return HandleApiCallAsFunctionOrConstructor(true, args); -} -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_StringLength(MacroAssembler* masm) { - LoadIC::GenerateStringLength(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_ExtendStorage(MacroAssembler* masm) { - StoreIC::GenerateExtendStorage(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_ExtendStorage(MacroAssembler* masm) { - KeyedStoreIC::GenerateExtendStorage(masm); -} - - -static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) { - KeyedStoreIC::GenerateMiss(masm); -} - - -static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) { - KeyedStoreIC::GenerateInitialize(masm); -} - - -#ifdef ENABLE_DEBUGGER_SUPPORT -static void Generate_LoadIC_DebugBreak(MacroAssembler* masm) { - Debug::GenerateLoadICDebugBreak(masm); -} - - -static void Generate_StoreIC_DebugBreak(MacroAssembler* masm) { - Debug::GenerateStoreICDebugBreak(masm); -} - - -static void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) { - Debug::GenerateKeyedLoadICDebugBreak(masm); -} - - -static void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) { - Debug::GenerateKeyedStoreICDebugBreak(masm); -} - - -static void Generate_ConstructCall_DebugBreak(MacroAssembler* masm) { - Debug::GenerateConstructCallDebugBreak(masm); -} - - -static void Generate_Return_DebugBreak(MacroAssembler* masm) { - Debug::GenerateReturnDebugBreak(masm); -} - - -static void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) { - Debug::GenerateStubNoRegistersDebugBreak(masm); -} -#endif - -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_ARGC - -static 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, NOT_IN_LOOP, 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) - BUILTIN_LIST_DEBUG_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; - { - // During startup it's OK to always allocate and defer GC to later. - // This simplifies things because we don't need to retry. - AlwaysAllocateScope __scope__; - code = Heap::CreateCode(desc, NULL, flags, masm.CodeObject()); - if (code->IsFailure()) { - v8::internal::V8::FatalProcessOutOfMemory("CreateCode"); - } - } - // 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(Logger::BUILTIN_TAG, - Code::cast(code), functions[i].s_name)); - builtins_[i] = code; -#ifdef ENABLE_DISASSEMBLER - if (FLAG_print_builtin_code) { - PrintF("Builtin: %s\n", functions[i].s_name); - Code::cast(code)->Disassemble(functions[i].s_name); - 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 |