Pass in the prototype to CreateApiFunction rather than setting it on the result.
BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/253603003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21066 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8452271f1b
commit
22cdf0c0fd
@ -48,31 +48,29 @@ function InstantiateFunction(data, name) {
|
|||||||
(serialNumber in cache) && (cache[serialNumber] != kUninitialized);
|
(serialNumber in cache) && (cache[serialNumber] != kUninitialized);
|
||||||
if (!isFunctionCached) {
|
if (!isFunctionCached) {
|
||||||
try {
|
try {
|
||||||
var fun = %CreateApiFunction(data);
|
|
||||||
if (name) %FunctionSetName(fun, name);
|
|
||||||
var flags = %GetTemplateField(data, kApiFlagOffset);
|
var flags = %GetTemplateField(data, kApiFlagOffset);
|
||||||
var doNotCache = flags & (1 << kDoNotCacheBit);
|
var has_proto = !(flags & (1 << kRemovePrototypeBit));
|
||||||
if (!doNotCache) cache[serialNumber] = fun;
|
var prototype;
|
||||||
if (flags & (1 << kRemovePrototypeBit)) {
|
if (has_proto) {
|
||||||
%FunctionRemovePrototype(fun);
|
var template = %GetTemplateField(data, kApiPrototypeTemplateOffset);
|
||||||
} else {
|
prototype = typeof template === 'undefined'
|
||||||
var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
|
? {} : Instantiate(template);
|
||||||
// Note: Do not directly use an object template as a condition, our
|
|
||||||
// internal ToBoolean doesn't handle that!
|
|
||||||
fun.prototype = typeof prototype === 'undefined' ?
|
|
||||||
{} : Instantiate(prototype);
|
|
||||||
if (flags & (1 << kReadOnlyPrototypeBit)) {
|
|
||||||
%FunctionSetReadOnlyPrototype(fun);
|
|
||||||
}
|
|
||||||
%SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
|
|
||||||
var parent = %GetTemplateField(data, kApiParentTemplateOffset);
|
var parent = %GetTemplateField(data, kApiParentTemplateOffset);
|
||||||
// Note: Do not directly use a function template as a condition, our
|
// Note: Do not directly use a function template as a condition, our
|
||||||
// internal ToBoolean doesn't handle that!
|
// internal ToBoolean doesn't handle that!
|
||||||
if (!(typeof parent === 'undefined')) {
|
if (typeof parent !== 'undefined') {
|
||||||
var parent_fun = Instantiate(parent);
|
var parent_fun = Instantiate(parent);
|
||||||
%SetPrototype(fun.prototype, parent_fun.prototype);
|
%SetPrototype(prototype, parent_fun.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var fun = %CreateApiFunction(data, prototype);
|
||||||
|
if (name) %FunctionSetName(fun, name);
|
||||||
|
var doNotCache = flags & (1 << kDoNotCacheBit);
|
||||||
|
if (!doNotCache) cache[serialNumber] = fun;
|
||||||
|
if (has_proto && flags & (1 << kReadOnlyPrototypeBit)) {
|
||||||
|
%FunctionSetReadOnlyPrototype(fun);
|
||||||
|
}
|
||||||
ConfigureTemplateInstance(fun, data);
|
ConfigureTemplateInstance(fun, data);
|
||||||
if (doNotCache) return fun;
|
if (doNotCache) return fun;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -729,6 +729,7 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
|
|||||||
FunctionTemplateInfo::cast(js_global_template->constructor()));
|
FunctionTemplateInfo::cast(js_global_template->constructor()));
|
||||||
js_global_function =
|
js_global_function =
|
||||||
factory()->CreateApiFunction(js_global_constructor,
|
factory()->CreateApiFunction(js_global_constructor,
|
||||||
|
factory()->the_hole_value(),
|
||||||
factory()->InnerGlobalObject);
|
factory()->InnerGlobalObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -756,6 +757,7 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
|
|||||||
FunctionTemplateInfo::cast(data->constructor()));
|
FunctionTemplateInfo::cast(data->constructor()));
|
||||||
global_proxy_function =
|
global_proxy_function =
|
||||||
factory()->CreateApiFunction(global_constructor,
|
factory()->CreateApiFunction(global_constructor,
|
||||||
|
factory()->the_hole_value(),
|
||||||
factory()->OuterGlobalObject);
|
factory()->OuterGlobalObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1255,19 +1255,30 @@ Handle<Object> Factory::NewError(const char* constructor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
|
Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype,
|
||||||
|
Handle<String> name,
|
||||||
InstanceType type,
|
InstanceType type,
|
||||||
int instance_size,
|
int instance_size,
|
||||||
Handle<Code> code,
|
Handle<Code> code,
|
||||||
bool force_initial_map) {
|
bool force_initial_map) {
|
||||||
// Allocate the function
|
// Allocate the function
|
||||||
Handle<JSFunction> function = NewFunction(name, code, the_hole_value());
|
Handle<JSFunction> function = NewFunction(name, code, maybe_prototype);
|
||||||
|
|
||||||
if (force_initial_map ||
|
Handle<Object> prototype;
|
||||||
type != JS_OBJECT_TYPE ||
|
if (maybe_prototype.ToHandle(&prototype) &&
|
||||||
instance_size != JSObject::kHeaderSize) {
|
(force_initial_map ||
|
||||||
|
type != JS_OBJECT_TYPE ||
|
||||||
|
instance_size != JSObject::kHeaderSize)) {
|
||||||
Handle<Map> initial_map = NewMap(type, instance_size);
|
Handle<Map> initial_map = NewMap(type, instance_size);
|
||||||
Handle<JSObject> prototype = NewFunctionPrototype(function);
|
if (prototype->IsJSObject()) {
|
||||||
|
JSObject::SetLocalPropertyIgnoreAttributes(
|
||||||
|
Handle<JSObject>::cast(prototype),
|
||||||
|
constructor_string(),
|
||||||
|
function,
|
||||||
|
DONT_ENUM).Assert();
|
||||||
|
} else if (!function->shared()->is_generator()) {
|
||||||
|
prototype = NewFunctionPrototype(function);
|
||||||
|
}
|
||||||
initial_map->set_prototype(*prototype);
|
initial_map->set_prototype(*prototype);
|
||||||
function->set_initial_map(*initial_map);
|
function->set_initial_map(*initial_map);
|
||||||
initial_map->set_constructor(*function);
|
initial_map->set_constructor(*function);
|
||||||
@ -1280,6 +1291,16 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
|
||||||
|
InstanceType type,
|
||||||
|
int instance_size,
|
||||||
|
Handle<Code> code,
|
||||||
|
bool force_initial_map) {
|
||||||
|
return NewFunction(
|
||||||
|
the_hole_value(), name, type, instance_size, code, force_initial_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
|
Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
|
||||||
InstanceType type,
|
InstanceType type,
|
||||||
int instance_size,
|
int instance_size,
|
||||||
@ -2057,7 +2078,9 @@ Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
|
|||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::CreateApiFunction(
|
Handle<JSFunction> Factory::CreateApiFunction(
|
||||||
Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) {
|
Handle<FunctionTemplateInfo> obj,
|
||||||
|
Handle<Object> prototype,
|
||||||
|
ApiInstanceType instance_type) {
|
||||||
Handle<Code> code = isolate()->builtins()->HandleApiCall();
|
Handle<Code> code = isolate()->builtins()->HandleApiCall();
|
||||||
Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();
|
Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();
|
||||||
|
|
||||||
@ -2093,20 +2116,31 @@ Handle<JSFunction> Factory::CreateApiFunction(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeHandle<Object> maybe_prototype = prototype;
|
||||||
|
if (obj->remove_prototype()) maybe_prototype = MaybeHandle<Object>();
|
||||||
|
|
||||||
Handle<JSFunction> result = NewFunction(
|
Handle<JSFunction> result = NewFunction(
|
||||||
Factory::empty_string(), type, instance_size, code, true);
|
maybe_prototype, Factory::empty_string(), type,
|
||||||
|
instance_size, code, true);
|
||||||
|
|
||||||
// Set length.
|
|
||||||
result->shared()->set_length(obj->length());
|
result->shared()->set_length(obj->length());
|
||||||
|
Handle<Object> class_name(obj->class_name(), isolate());
|
||||||
// Set class name.
|
|
||||||
Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate());
|
|
||||||
if (class_name->IsString()) {
|
if (class_name->IsString()) {
|
||||||
result->shared()->set_instance_class_name(*class_name);
|
result->shared()->set_instance_class_name(*class_name);
|
||||||
result->shared()->set_name(*class_name);
|
result->shared()->set_name(*class_name);
|
||||||
}
|
}
|
||||||
|
result->shared()->set_function_data(*obj);
|
||||||
|
result->shared()->set_construct_stub(*construct_stub);
|
||||||
|
result->shared()->DontAdaptArguments();
|
||||||
|
|
||||||
Handle<Map> map = Handle<Map>(result->initial_map());
|
if (obj->remove_prototype()) {
|
||||||
|
ASSERT(result->shared()->IsApiFunction());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// Down from here is only valid for API functions that can be used as a
|
||||||
|
// constructor (don't set the "remove prototype" flag).
|
||||||
|
|
||||||
|
Handle<Map> map(result->initial_map());
|
||||||
|
|
||||||
// Mark as undetectable if needed.
|
// Mark as undetectable if needed.
|
||||||
if (obj->undetectable()) {
|
if (obj->undetectable()) {
|
||||||
@ -2136,10 +2170,6 @@ Handle<JSFunction> Factory::CreateApiFunction(
|
|||||||
map->set_has_instance_call_handler();
|
map->set_has_instance_call_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
result->shared()->set_function_data(*obj);
|
|
||||||
result->shared()->set_construct_stub(*construct_stub);
|
|
||||||
result->shared()->DontAdaptArguments();
|
|
||||||
|
|
||||||
// Recursively copy parent instance templates' accessors,
|
// Recursively copy parent instance templates' accessors,
|
||||||
// 'data' may be modified.
|
// 'data' may be modified.
|
||||||
int max_number_of_additional_properties = 0;
|
int max_number_of_additional_properties = 0;
|
||||||
|
@ -464,6 +464,12 @@ class Factory V8_FINAL {
|
|||||||
Handle<Context> context,
|
Handle<Context> context,
|
||||||
PretenureFlag pretenure = TENURED);
|
PretenureFlag pretenure = TENURED);
|
||||||
|
|
||||||
|
Handle<JSFunction> NewFunction(MaybeHandle<Object> maybe_prototype,
|
||||||
|
Handle<String> name,
|
||||||
|
InstanceType type,
|
||||||
|
int instance_size,
|
||||||
|
Handle<Code> code,
|
||||||
|
bool force_initial_map);
|
||||||
Handle<JSFunction> NewFunction(Handle<String> name,
|
Handle<JSFunction> NewFunction(Handle<String> name,
|
||||||
InstanceType type,
|
InstanceType type,
|
||||||
int instance_size,
|
int instance_size,
|
||||||
@ -551,6 +557,7 @@ class Factory V8_FINAL {
|
|||||||
|
|
||||||
Handle<JSFunction> CreateApiFunction(
|
Handle<JSFunction> CreateApiFunction(
|
||||||
Handle<FunctionTemplateInfo> data,
|
Handle<FunctionTemplateInfo> data,
|
||||||
|
Handle<Object> prototype,
|
||||||
ApiInstanceType type = JavaScriptObject);
|
ApiInstanceType type = JavaScriptObject);
|
||||||
|
|
||||||
Handle<JSFunction> InstallMembers(Handle<JSFunction> function);
|
Handle<JSFunction> InstallMembers(Handle<JSFunction> function);
|
||||||
|
@ -2112,9 +2112,10 @@ RUNTIME_FUNCTION(Runtime_RegExpCompile) {
|
|||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
|
RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
ASSERT(args.length() == 1);
|
ASSERT(args.length() == 2);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
|
CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
|
||||||
return *isolate->factory()->CreateApiFunction(data);
|
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
|
||||||
|
return *isolate->factory()->CreateApiFunction(data, prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2786,7 +2787,8 @@ static Handle<JSFunction> InstallBuiltin(Isolate* isolate,
|
|||||||
Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
|
Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
|
||||||
Handle<Code> code(isolate->builtins()->builtin(builtin_name));
|
Handle<Code> code(isolate->builtins()->builtin(builtin_name));
|
||||||
Handle<JSFunction> optimized =
|
Handle<JSFunction> optimized =
|
||||||
isolate->factory()->NewFunction(key,
|
isolate->factory()->NewFunction(MaybeHandle<Object>(),
|
||||||
|
key,
|
||||||
JS_OBJECT_TYPE,
|
JS_OBJECT_TYPE,
|
||||||
JSObject::kHeaderSize,
|
JSObject::kHeaderSize,
|
||||||
code,
|
code,
|
||||||
|
@ -202,7 +202,7 @@ namespace internal {
|
|||||||
F(SetCode, 2, 1) \
|
F(SetCode, 2, 1) \
|
||||||
F(SetExpectedNumberOfProperties, 2, 1) \
|
F(SetExpectedNumberOfProperties, 2, 1) \
|
||||||
\
|
\
|
||||||
F(CreateApiFunction, 1, 1) \
|
F(CreateApiFunction, 2, 1) \
|
||||||
F(IsTemplate, 1, 1) \
|
F(IsTemplate, 1, 1) \
|
||||||
F(GetTemplateField, 2, 1) \
|
F(GetTemplateField, 2, 1) \
|
||||||
F(DisableAccessChecks, 1, 1) \
|
F(DisableAccessChecks, 1, 1) \
|
||||||
|
Loading…
Reference in New Issue
Block a user