From b25c040c2c0978814add19fee645470407c7292b Mon Sep 17 00:00:00 2001 From: "rossberg@chromium.org" Date: Wed, 19 Dec 2012 10:28:36 +0000 Subject: [PATCH] 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 --- include/v8.h | 7 +++++-- src/api.cc | 11 ++++++++++- src/factory.cc | 4 ++++ src/object-observe.js | 3 ++- src/objects-inl.h | 1 + src/objects.h | 6 +++++- test/cctest/test-api.cc | 32 ++++++++++++++++++++++++++++++++ 7 files changed, 59 insertions(+), 5 deletions(-) diff --git a/include/v8.h b/include/v8.h index eb0b552..b35500d 100644 --- a/include/v8.h +++ b/include/v8.h @@ -2302,7 +2302,8 @@ class V8EXPORT FunctionTemplate : public Template { static Local New( InvocationCallback callback = 0, Handle data = Handle(), - Handle signature = Handle()); + Handle signature = Handle(), + int length = 0); /** Returns the unique function instance in the current execution context.*/ Local GetFunction(); @@ -2314,6 +2315,9 @@ class V8EXPORT FunctionTemplate : public Template { void SetCallHandler(InvocationCallback callback, Handle data = Handle()); + /** Set the predefined length property for the FunctionTemplate. */ + void SetLength(int length); + /** Get the InstanceTemplate. */ Local InstanceTemplate(); @@ -2326,7 +2330,6 @@ class V8EXPORT FunctionTemplate : public Template { */ Local PrototypeTemplate(); - /** * Set the class name of the FunctionTemplate. This is used for * printing objects created with the function created from the diff --git a/src/api.cc b/src/api.cc index 0a6d25b..11d0a40 100644 --- a/src/api.cc +++ b/src/api.cc @@ -1053,7 +1053,7 @@ void FunctionTemplate::Inherit(v8::Handle value) { Local FunctionTemplate::New(InvocationCallback callback, - v8::Handle data, v8::Handle signature) { + v8::Handle data, v8::Handle 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::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 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 name) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return; diff --git a/src/factory.cc b/src/factory.cc index 0922f9f..8adae4e 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -1260,6 +1260,10 @@ Handle Factory::CreateApiFunction( instance_size, code, true); + + // Set length. + result->shared()->set_length(obj->length()); + // Set class name. Handle class_name = Handle(obj->class_name()); if (class_name->IsString()) { diff --git a/src/object-observe.js b/src/object-observe.js index 2923ec8..d0a84f6 100644 --- a/src/object-observe.js +++ b/src/object-observe.js @@ -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)) diff --git a/src/objects-inl.h b/src/objects-inl.h index 310974f..7493887 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -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) diff --git a/src/objects.h b/src/objects.h index 4951425..ebacbff 100644 --- a/src/objects.h +++ b/src/objects.h @@ -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. diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 0a5583b..60405a6 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -853,6 +853,38 @@ THREADED_TEST(FunctionTemplate) { } +THREADED_TEST(FunctionTemplateSetLength) { + v8::HandleScope scope; + LocalContext env; + { + Local fun_templ = v8::FunctionTemplate::New( + handle_call, Handle(), Handle(), 23); + Local fun = fun_templ->GetFunction(); + env->Global()->Set(v8_str("obj"), fun); + Local