From 84277a8b4d86fcc384cbe69f1dbb38f89839e9c7 Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Mon, 28 Apr 2014 13:41:12 +0000 Subject: [PATCH] Convert function.caller to API-style accessor. BUG= R=yangguo@chromium.org Review URL: https://codereview.chromium.org/256803010 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21021 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/accessors.cc | 80 ++++++++++++++++++++++++++++++++++++++--------------- src/accessors.h | 2 +- src/bootstrapper.cc | 6 ++-- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index f0f7791..197fdb6 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -51,8 +51,8 @@ static Handle MakeAccessor(Isolate* isolate, Factory* factory = isolate->factory(); Handle info = factory->NewExecutableAccessorInfo(); info->set_property_attributes(attributes); - info->set_all_can_read(true); - info->set_all_can_write(true); + info->set_all_can_read(false); + info->set_all_can_write(false); info->set_prohibits_overwriting(false); info->set_name(*name); Handle get = v8::FromCData(isolate, getter); @@ -1190,29 +1190,23 @@ class FrameFunctionIterator { }; -Object* Accessors::FunctionGetCaller(Isolate* isolate, - Object* object, - void*) { - HandleScope scope(isolate); +MaybeHandle FindCaller(Isolate* isolate, + Handle function) { DisallowHeapAllocation no_allocation; - JSFunction* holder = FindInstanceOf(isolate, object); - if (holder == NULL) return isolate->heap()->undefined_value(); - if (holder->shared()->native()) return isolate->heap()->null_value(); - Handle function(holder, isolate); - FrameFunctionIterator it(isolate, no_allocation); - + if (function->shared()->native()) { + return MaybeHandle(); + } // Find the function from the frames. if (!it.Find(*function)) { // No frame corresponding to the given function found. Return null. - return isolate->heap()->null_value(); + return MaybeHandle(); } - // Find previously called non-toplevel function. JSFunction* caller; do { caller = it.next(); - if (caller == NULL) return isolate->heap()->null_value(); + if (caller == NULL) return MaybeHandle(); } while (caller->shared()->is_toplevel()); // If caller is a built-in function and caller's caller is also built-in, @@ -1229,24 +1223,64 @@ Object* Accessors::FunctionGetCaller(Isolate* isolate, // allows us to make bound functions use the strict function map // and its associated throwing caller and arguments. if (caller->shared()->bound()) { - return isolate->heap()->null_value(); + return MaybeHandle(); } // Censor if the caller is not a sloppy mode function. // Change from ES5, which used to throw, see: // https://bugs.ecmascript.org/show_bug.cgi?id=310 if (caller->shared()->strict_mode() == STRICT) { - return isolate->heap()->null_value(); + return MaybeHandle(); + } + return Handle(caller); +} + + +void Accessors::FunctionCallerGetter( + v8::Local name, + const v8::PropertyCallbackInfo& info) { + i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); + HandleScope scope(isolate); + Handle object = Utils::OpenHandle(*info.This()); + MaybeHandle maybe_function; + { + DisallowHeapAllocation no_allocation; + JSFunction* function = FindInstanceOf(isolate, *object); + if (function != NULL) maybe_function = Handle(function); } + Handle function; + Handle result; + if (maybe_function.ToHandle(&function)) { + MaybeHandle maybe_caller; + maybe_caller = FindCaller(isolate, function); + Handle caller; + if (maybe_caller.ToHandle(&caller)) { + result = caller; + } else { + result = isolate->factory()->null_value(); + } + } else { + result = isolate->factory()->undefined_value(); + } + info.GetReturnValue().Set(Utils::ToLocal(result)); +} + - return caller; +void Accessors::FunctionCallerSetter( + v8::Local name, + v8::Local val, + const v8::PropertyCallbackInfo& info) { + // Do nothing. } -const AccessorDescriptor Accessors::FunctionCaller = { - FunctionGetCaller, - ReadOnlySetAccessor, - 0 -}; +Handle Accessors::FunctionCallerInfo( + Isolate* isolate, PropertyAttributes attributes) { + return MakeAccessor(isolate, + isolate->factory()->caller_string(), + &FunctionCallerGetter, + &FunctionCallerSetter, + attributes); +} // diff --git a/src/accessors.h b/src/accessors.h index 2dcb860..ed09205 100644 --- a/src/accessors.h +++ b/src/accessors.h @@ -37,11 +37,11 @@ namespace internal { // The list of accessor descriptors. This is a second-order macro // taking a macro to be applied to all accessor descriptor names. #define ACCESSOR_DESCRIPTOR_LIST(V) \ - V(FunctionCaller) \ V(ArrayLength) #define ACCESSOR_INFO_LIST(V) \ V(FunctionArguments) \ + V(FunctionCaller) \ V(FunctionName) \ V(FunctionLength) \ V(FunctionPrototype) \ diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 775db59..5101b87 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -388,7 +388,6 @@ void Genesis::SetFunctionInstanceDescriptor( int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; Map::EnsureDescriptorSlack(map, size); - Handle caller(factory()->NewForeign(&Accessors::FunctionCaller)); PropertyAttributes attribs = static_cast( DONT_ENUM | DONT_DELETE | READ_ONLY); @@ -413,8 +412,11 @@ void Genesis::SetFunctionInstanceDescriptor( args, attribs); map->AppendDescriptor(&d); } + Handle caller = + Accessors::FunctionCallerInfo(isolate(), attribs); { // Add caller. - CallbacksDescriptor d(factory()->caller_string(), caller, attribs); + CallbacksDescriptor d(Handle(Name::cast(caller->name())), + caller, attribs); map->AppendDescriptor(&d); } if (prototypeMode != DONT_ADD_PROTOTYPE) { -- 2.7.4