(serialNumber in cache) && (cache[serialNumber] != kUninitialized);
if (!isFunctionCached) {
try {
- var fun = %CreateApiFunction(data);
- if (name) %FunctionSetName(fun, name);
var flags = %GetTemplateField(data, kApiFlagOffset);
- var doNotCache = flags & (1 << kDoNotCacheBit);
- if (!doNotCache) cache[serialNumber] = fun;
- if (flags & (1 << kRemovePrototypeBit)) {
- %FunctionRemovePrototype(fun);
- } else {
- var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
- // 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 has_proto = !(flags & (1 << kRemovePrototypeBit));
+ var prototype;
+ if (has_proto) {
+ var template = %GetTemplateField(data, kApiPrototypeTemplateOffset);
+ prototype = typeof template === 'undefined'
+ ? {} : Instantiate(template);
+
var parent = %GetTemplateField(data, kApiParentTemplateOffset);
// Note: Do not directly use a function template as a condition, our
// internal ToBoolean doesn't handle that!
- if (!(typeof parent === 'undefined')) {
+ if (typeof parent !== 'undefined') {
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);
if (doNotCache) return fun;
} catch (e) {
FunctionTemplateInfo::cast(js_global_template->constructor()));
js_global_function =
factory()->CreateApiFunction(js_global_constructor,
+ factory()->the_hole_value(),
factory()->InnerGlobalObject);
}
FunctionTemplateInfo::cast(data->constructor()));
global_proxy_function =
factory()->CreateApiFunction(global_constructor,
+ factory()->the_hole_value(),
factory()->OuterGlobalObject);
}
}
-Handle<JSFunction> Factory::NewFunction(Handle<String> name,
+Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype,
+ Handle<String> name,
InstanceType type,
int instance_size,
Handle<Code> code,
bool force_initial_map) {
// Allocate the function
- Handle<JSFunction> function = NewFunction(name, code, the_hole_value());
+ Handle<JSFunction> function = NewFunction(name, code, maybe_prototype);
- if (force_initial_map ||
- type != JS_OBJECT_TYPE ||
- instance_size != JSObject::kHeaderSize) {
+ Handle<Object> prototype;
+ if (maybe_prototype.ToHandle(&prototype) &&
+ (force_initial_map ||
+ type != JS_OBJECT_TYPE ||
+ instance_size != JSObject::kHeaderSize)) {
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);
function->set_initial_map(*initial_map);
initial_map->set_constructor(*function);
}
+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,
InstanceType type,
int instance_size,
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> construct_stub = isolate()->builtins()->JSConstructStubApi();
break;
}
+ MaybeHandle<Object> maybe_prototype = prototype;
+ if (obj->remove_prototype()) maybe_prototype = MaybeHandle<Object>();
+
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());
-
- // Set class name.
- Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate());
+ Handle<Object> class_name(obj->class_name(), isolate());
if (class_name->IsString()) {
result->shared()->set_instance_class_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.
if (obj->undetectable()) {
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,
// 'data' may be modified.
int max_number_of_additional_properties = 0;
Handle<Context> context,
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,
InstanceType type,
int instance_size,
Handle<JSFunction> CreateApiFunction(
Handle<FunctionTemplateInfo> data,
+ Handle<Object> prototype,
ApiInstanceType type = JavaScriptObject);
Handle<JSFunction> InstallMembers(Handle<JSFunction> function);
RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ ASSERT(args.length() == 2);
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);
}
Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
Handle<Code> code(isolate->builtins()->builtin(builtin_name));
Handle<JSFunction> optimized =
- isolate->factory()->NewFunction(key,
+ isolate->factory()->NewFunction(MaybeHandle<Object>(),
+ key,
JS_OBJECT_TYPE,
JSObject::kHeaderSize,
code,
F(SetCode, 2, 1) \
F(SetExpectedNumberOfProperties, 2, 1) \
\
- F(CreateApiFunction, 1, 1) \
+ F(CreateApiFunction, 2, 1) \
F(IsTemplate, 1, 1) \
F(GetTemplateField, 2, 1) \
F(DisableAccessChecks, 1, 1) \