Commit 84277a8b authored by ulan@chromium.org's avatar ulan@chromium.org

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
parent dc438dce
...@@ -51,8 +51,8 @@ static Handle<AccessorInfo> MakeAccessor(Isolate* isolate, ...@@ -51,8 +51,8 @@ static Handle<AccessorInfo> MakeAccessor(Isolate* isolate,
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo(); Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
info->set_property_attributes(attributes); info->set_property_attributes(attributes);
info->set_all_can_read(true); info->set_all_can_read(false);
info->set_all_can_write(true); info->set_all_can_write(false);
info->set_prohibits_overwriting(false); info->set_prohibits_overwriting(false);
info->set_name(*name); info->set_name(*name);
Handle<Object> get = v8::FromCData(isolate, getter); Handle<Object> get = v8::FromCData(isolate, getter);
...@@ -1190,29 +1190,23 @@ class FrameFunctionIterator { ...@@ -1190,29 +1190,23 @@ class FrameFunctionIterator {
}; };
Object* Accessors::FunctionGetCaller(Isolate* isolate, MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
Object* object, Handle<JSFunction> function) {
void*) {
HandleScope scope(isolate);
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
if (holder == NULL) return isolate->heap()->undefined_value();
if (holder->shared()->native()) return isolate->heap()->null_value();
Handle<JSFunction> function(holder, isolate);
FrameFunctionIterator it(isolate, no_allocation); FrameFunctionIterator it(isolate, no_allocation);
if (function->shared()->native()) {
return MaybeHandle<JSFunction>();
}
// Find the function from the frames. // Find the function from the frames.
if (!it.Find(*function)) { if (!it.Find(*function)) {
// No frame corresponding to the given function found. Return null. // No frame corresponding to the given function found. Return null.
return isolate->heap()->null_value(); return MaybeHandle<JSFunction>();
} }
// Find previously called non-toplevel function. // Find previously called non-toplevel function.
JSFunction* caller; JSFunction* caller;
do { do {
caller = it.next(); caller = it.next();
if (caller == NULL) return isolate->heap()->null_value(); if (caller == NULL) return MaybeHandle<JSFunction>();
} while (caller->shared()->is_toplevel()); } while (caller->shared()->is_toplevel());
// If caller is a built-in function and caller's caller is also built-in, // If caller is a built-in function and caller's caller is also built-in,
...@@ -1229,24 +1223,64 @@ Object* Accessors::FunctionGetCaller(Isolate* isolate, ...@@ -1229,24 +1223,64 @@ Object* Accessors::FunctionGetCaller(Isolate* isolate,
// allows us to make bound functions use the strict function map // allows us to make bound functions use the strict function map
// and its associated throwing caller and arguments. // and its associated throwing caller and arguments.
if (caller->shared()->bound()) { if (caller->shared()->bound()) {
return isolate->heap()->null_value(); return MaybeHandle<JSFunction>();
} }
// Censor if the caller is not a sloppy mode function. // Censor if the caller is not a sloppy mode function.
// Change from ES5, which used to throw, see: // Change from ES5, which used to throw, see:
// https://bugs.ecmascript.org/show_bug.cgi?id=310 // https://bugs.ecmascript.org/show_bug.cgi?id=310
if (caller->shared()->strict_mode() == STRICT) { if (caller->shared()->strict_mode() == STRICT) {
return isolate->heap()->null_value(); return MaybeHandle<JSFunction>();
}
return Handle<JSFunction>(caller);
}
void Accessors::FunctionCallerGetter(
v8::Local<v8::String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
Handle<Object> object = Utils::OpenHandle(*info.This());
MaybeHandle<JSFunction> maybe_function;
{
DisallowHeapAllocation no_allocation;
JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
if (function != NULL) maybe_function = Handle<JSFunction>(function);
} }
Handle<JSFunction> function;
Handle<Object> result;
if (maybe_function.ToHandle(&function)) {
MaybeHandle<JSFunction> maybe_caller;
maybe_caller = FindCaller(isolate, function);
Handle<JSFunction> 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<v8::String> name,
v8::Local<v8::Value> val,
const v8::PropertyCallbackInfo<void>& info) {
// Do nothing.
} }
const AccessorDescriptor Accessors::FunctionCaller = { Handle<AccessorInfo> Accessors::FunctionCallerInfo(
FunctionGetCaller, Isolate* isolate, PropertyAttributes attributes) {
ReadOnlySetAccessor, return MakeAccessor(isolate,
0 isolate->factory()->caller_string(),
}; &FunctionCallerGetter,
&FunctionCallerSetter,
attributes);
}
// //
......
...@@ -37,11 +37,11 @@ namespace internal { ...@@ -37,11 +37,11 @@ namespace internal {
// The list of accessor descriptors. This is a second-order macro // The list of accessor descriptors. This is a second-order macro
// taking a macro to be applied to all accessor descriptor names. // taking a macro to be applied to all accessor descriptor names.
#define ACCESSOR_DESCRIPTOR_LIST(V) \ #define ACCESSOR_DESCRIPTOR_LIST(V) \
V(FunctionCaller) \
V(ArrayLength) V(ArrayLength)
#define ACCESSOR_INFO_LIST(V) \ #define ACCESSOR_INFO_LIST(V) \
V(FunctionArguments) \ V(FunctionArguments) \
V(FunctionCaller) \
V(FunctionName) \ V(FunctionName) \
V(FunctionLength) \ V(FunctionLength) \
V(FunctionPrototype) \ V(FunctionPrototype) \
......
...@@ -388,7 +388,6 @@ void Genesis::SetFunctionInstanceDescriptor( ...@@ -388,7 +388,6 @@ void Genesis::SetFunctionInstanceDescriptor(
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
Map::EnsureDescriptorSlack(map, size); Map::EnsureDescriptorSlack(map, size);
Handle<Foreign> caller(factory()->NewForeign(&Accessors::FunctionCaller));
PropertyAttributes attribs = static_cast<PropertyAttributes>( PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE | READ_ONLY); DONT_ENUM | DONT_DELETE | READ_ONLY);
...@@ -413,8 +412,11 @@ void Genesis::SetFunctionInstanceDescriptor( ...@@ -413,8 +412,11 @@ void Genesis::SetFunctionInstanceDescriptor(
args, attribs); args, attribs);
map->AppendDescriptor(&d); map->AppendDescriptor(&d);
} }
Handle<AccessorInfo> caller =
Accessors::FunctionCallerInfo(isolate(), attribs);
{ // Add caller. { // Add caller.
CallbacksDescriptor d(factory()->caller_string(), caller, attribs); CallbacksDescriptor d(Handle<Name>(Name::cast(caller->name())),
caller, attribs);
map->AppendDescriptor(&d); map->AppendDescriptor(&d);
} }
if (prototypeMode != DONT_ADD_PROTOTYPE) { if (prototypeMode != DONT_ADD_PROTOTYPE) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment