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