Commit b25c040c authored by rossberg@chromium.org's avatar rossberg@chromium.org

Extend API to allow setting length property for function templates.

R=yangguo@chromium.org
BUG=125308

Review URL: https://codereview.chromium.org/11631002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13240 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c9da5fad
......@@ -2302,7 +2302,8 @@ class V8EXPORT FunctionTemplate : public Template {
static Local<FunctionTemplate> New(
InvocationCallback callback = 0,
Handle<Value> data = Handle<Value>(),
Handle<Signature> signature = Handle<Signature>());
Handle<Signature> signature = Handle<Signature>(),
int length = 0);
/** Returns the unique function instance in the current execution context.*/
Local<Function> GetFunction();
......@@ -2314,6 +2315,9 @@ class V8EXPORT FunctionTemplate : public Template {
void SetCallHandler(InvocationCallback callback,
Handle<Value> data = Handle<Value>());
/** Set the predefined length property for the FunctionTemplate. */
void SetLength(int length);
/** Get the InstanceTemplate. */
Local<ObjectTemplate> InstanceTemplate();
......@@ -2326,7 +2330,6 @@ class V8EXPORT FunctionTemplate : public Template {
*/
Local<ObjectTemplate> PrototypeTemplate();
/**
* Set the class name of the FunctionTemplate. This is used for
* printing objects created with the function created from the
......
......@@ -1053,7 +1053,7 @@ void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
v8::Handle<Value> data, v8::Handle<Signature> signature) {
v8::Handle<Value> data, v8::Handle<Signature> signature, int length) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
LOG_API(isolate, "FunctionTemplate::New");
......@@ -1070,6 +1070,7 @@ Local<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback,
if (data.IsEmpty()) data = v8::Undefined();
Utils::ToLocal(obj)->SetCallHandler(callback, data);
}
obj->set_length(length);
obj->set_undetectable(false);
obj->set_needs_access_check(false);
......@@ -1240,6 +1241,14 @@ Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
}
void FunctionTemplate::SetLength(int length) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetLength()")) return;
ENTER_V8(isolate);
Utils::OpenHandle(this)->set_length(length);
}
void FunctionTemplate::SetClassName(Handle<String> name) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
......
......@@ -1260,6 +1260,10 @@ Handle<JSFunction> Factory::CreateApiFunction(
instance_size,
code,
true);
// Set length.
result->shared()->set_length(obj->length());
// Set class name.
Handle<Object> class_name = Handle<Object>(obj->class_name());
if (class_name->IsString()) {
......
......@@ -137,9 +137,10 @@ function NotifyChange(type, object, name, oldValue) {
var notifierPrototype = {};
function ObjectNotifierNotify(changeRecord) {
var target = notifierTargetMap.get(this);
if (!IS_SPEC_OBJECT(this))
throw MakeTypeError("called_on_non_object", ["notify"]);
var target = notifierTargetMap.get(this);
if (IS_UNDEFINED(target))
throw MakeTypeError("observe_notify_non_notifier");
if (!IS_STRING(changeRecord.type))
......
......@@ -4092,6 +4092,7 @@ ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
kHiddenPrototypeBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
......
......@@ -8569,6 +8569,9 @@ class FunctionTemplateInfo: public TemplateInfo {
DECL_ACCESSORS(access_check_info, Object)
DECL_ACCESSORS(flag, Smi)
inline int length();
inline void set_length(int value);
// Following properties use flag bits.
DECL_BOOLEAN_ACCESSORS(hidden_prototype)
DECL_BOOLEAN_ACCESSORS(undetectable)
......@@ -8602,7 +8605,8 @@ class FunctionTemplateInfo: public TemplateInfo {
static const int kAccessCheckInfoOffset =
kInstanceCallHandlerOffset + kPointerSize;
static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
static const int kSize = kFlagOffset + kPointerSize;
static const int kLengthOffset = kFlagOffset + kPointerSize;
static const int kSize = kLengthOffset + kPointerSize;
private:
// Bit position in the flag, from least significant bit position.
......
......@@ -853,6 +853,38 @@ THREADED_TEST(FunctionTemplate) {
}
THREADED_TEST(FunctionTemplateSetLength) {
v8::HandleScope scope;
LocalContext env;
{
Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(
handle_call, Handle<v8::Value>(), Handle<v8::Signature>(), 23);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("obj.length");
CHECK_EQ(23, script->Run()->Int32Value());
}
{
Local<v8::FunctionTemplate> fun_templ =
v8::FunctionTemplate::New(handle_call);
fun_templ->SetLength(22);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("obj.length");
CHECK_EQ(22, script->Run()->Int32Value());
}
{
// Without setting length it defaults to 0.
Local<v8::FunctionTemplate> fun_templ =
v8::FunctionTemplate::New(handle_call);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("obj.length");
CHECK_EQ(0, script->Run()->Int32Value());
}
}
static void* expected_ptr;
static v8::Handle<v8::Value> callback(const v8::Arguments& args) {
void* ptr = v8::External::Unwrap(args.Data());
......
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