Revision: 8366
Author:   [email protected]
Date:     Wed Jun 22 05:39:45 2011
Log: Add possibility to configure 'prototype' property via FunctionTemplate

BUG=v8:1479
TEST=test-api/SetPrototypeProperties

Review URL: http://codereview.chromium.org/7229007
http://code.google.com/p/v8/source/detail?r=8366

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/apinatives.js
 /branches/bleeding_edge/src/macros.py
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Fri Jun 10 05:33:55 2011
+++ /branches/bleeding_edge/include/v8.h        Wed Jun 22 05:39:45 2011
@@ -2143,6 +2143,13 @@
    */
   void SetHiddenPrototype(bool value);

+  /**
+   * Sets the property attributes of the 'prototype' property of functions
+ * created from this FunctionTemplate. Can be any combination of ReadOnly,
+   * DontEnum and DontDelete.
+   */
+  void SetPrototypeAttributes(int attributes);
+
   /**
    * Returns true if the given object is an instance of this function
    * template.
=======================================
--- /branches/bleeding_edge/src/api.cc  Tue Jun 21 01:02:34 2011
+++ /branches/bleeding_edge/src/api.cc  Wed Jun 22 05:39:45 2011
@@ -884,6 +884,7 @@
       i::Handle<i::FunctionTemplateInfo> info) {
   info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
   info->set_flag(0);
+  info->set_prototype_attributes(i::Smi::FromInt(v8::None));
 }


@@ -1104,6 +1105,17 @@
   ENTER_V8(isolate);
   Utils::OpenHandle(this)->set_hidden_prototype(value);
 }
+
+
+void FunctionTemplate::SetPrototypeAttributes(int attributes) {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
+    return;
+  }
+  ENTER_V8(isolate);
+  Utils::OpenHandle(this)->set_prototype_attributes(
+      i::Smi::FromInt(attributes));
+}


 void FunctionTemplate::SetNamedInstancePropertyHandler(
=======================================
--- /branches/bleeding_edge/src/apinatives.js   Tue Dec  7 03:01:02 2010
+++ /branches/bleeding_edge/src/apinatives.js   Wed Jun 22 05:39:45 2011
@@ -73,7 +73,15 @@
       if (name) %FunctionSetName(fun, name);
       cache[serialNumber] = fun;
       var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
-      fun.prototype = prototype ? Instantiate(prototype) : {};
+ var attributes = %GetTemplateField(data, kApiPrototypeAttributesOffset);
+      if (attributes != NONE) {
+        %IgnoreAttributesAndSetProperty(
+            fun, "prototype",
+            prototype ? Instantiate(prototype) : {},
+            attributes);
+      } else {
+        fun.prototype = prototype ? Instantiate(prototype) : {};
+      }
       %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
       var parent = %GetTemplateField(data, kApiParentTemplateOffset);
       if (parent) {
=======================================
--- /branches/bleeding_edge/src/macros.py       Mon May 30 02:23:17 2011
+++ /branches/bleeding_edge/src/macros.py       Wed Jun 22 05:39:45 2011
@@ -38,12 +38,13 @@
 const SETTER = 1;

 # These definitions must match the index of the properties in objects.h.
-const kApiTagOffset               = 0;
-const kApiPropertyListOffset      = 1;
-const kApiSerialNumberOffset      = 2;
-const kApiConstructorOffset       = 2;
-const kApiPrototypeTemplateOffset = 5;
-const kApiParentTemplateOffset    = 6;
+const kApiTagOffset                 = 0;
+const kApiPropertyListOffset        = 1;
+const kApiSerialNumberOffset        = 2;
+const kApiConstructorOffset         = 2;
+const kApiPrototypeTemplateOffset   = 5;
+const kApiParentTemplateOffset      = 6;
+const kApiPrototypeAttributesOffset = 15;

 const NO_HINT     = 0;
 const NUMBER_HINT = 1;
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Tue Jun 21 00:52:19 2011
+++ /branches/bleeding_edge/src/objects-inl.h   Wed Jun 22 05:39:45 2011
@@ -3232,6 +3232,8 @@
 ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
           kAccessCheckInfoOffset)
 ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
+ACCESSORS(FunctionTemplateInfo, prototype_attributes, Smi,
+          kPrototypeAttributesOffset)

 ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
 ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Jun 20 03:19:00 2011
+++ /branches/bleeding_edge/src/objects.h       Wed Jun 22 05:39:45 2011
@@ -6786,6 +6786,7 @@
   DECL_ACCESSORS(instance_call_handler, Object)
   DECL_ACCESSORS(access_check_info, Object)
   DECL_ACCESSORS(flag, Smi)
+  DECL_ACCESSORS(prototype_attributes, Smi)

   // Following properties use flag bits.
   DECL_BOOLEAN_ACCESSORS(hidden_prototype)
@@ -6825,7 +6826,8 @@
   static const int kAccessCheckInfoOffset =
       kInstanceCallHandlerOffset + kPointerSize;
   static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
-  static const int kSize = kFlagOffset + kPointerSize;
+  static const int kPrototypeAttributesOffset = kFlagOffset + kPointerSize;
+  static const int kSize = kPrototypeAttributesOffset + kPointerSize;

  private:
   // Bit position in the flag, from least significant bit position.
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Mon Jun 20 04:52:24 2011
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Wed Jun 22 05:39:45 2011
@@ -6840,6 +6840,56 @@
   CHECK(proto2->IsObject());
   CHECK_EQ(proto2.As<v8::Object>(), o3);
 }
+
+
+THREADED_TEST(SetPrototypeProperties) {
+  v8::HandleScope handle_scope;
+  LocalContext context;
+
+  Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+  t1->SetPrototypeAttributes(v8::DontDelete);
+  context->Global()->Set(v8_str("func1"), t1->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func1, 'prototype');"
+      "  return (descriptor['writable'] == true) &&"
+      "         (descriptor['enumerable'] == true) &&"
+      "         (descriptor['configurable'] == false);"
+      "})()")->BooleanValue());
+
+  Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+  t2->SetPrototypeAttributes(v8::DontEnum);
+  context->Global()->Set(v8_str("func2"), t2->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func2, 'prototype');"
+      "  return (descriptor['writable'] == true) &&"
+      "         (descriptor['enumerable'] == false) &&"
+      "         (descriptor['configurable'] == true);"
+      "})()")->BooleanValue());
+
+  Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+  t3->SetPrototypeAttributes(v8::ReadOnly);
+  context->Global()->Set(v8_str("func3"), t3->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func3, 'prototype');"
+      "  return (descriptor['writable'] == false) &&"
+      "         (descriptor['enumerable'] == true) &&"
+      "         (descriptor['configurable'] == true);"
+      "})()")->BooleanValue());
+
+  Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
+  t4->SetPrototypeAttributes(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
+  context->Global()->Set(v8_str("func4"), t4->GetFunction());
+  CHECK(CompileRun(
+      "(function() {"
+      "  descriptor = Object.getOwnPropertyDescriptor(func4, 'prototype');"
+      "  return (descriptor['writable'] == false) &&"
+      "         (descriptor['enumerable'] == false) &&"
+      "         (descriptor['configurable'] == false);"
+      "})()")->BooleanValue());
+}


 THREADED_TEST(SetPrototypeThrows) {

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to