Revision: 16341
Author:   [email protected]
Date:     Mon Aug 26 17:40:03 2013 UTC
Log:      Add RemovePrototype to FunctionTemplate

This allows functions created from a FunctionTemplate to not have a
prototype property, which is required by DOM methods.

[email protected]
BUG=chromium:272440

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

Patch from Erik Arvidsson <[email protected]>.
http://code.google.com/p/v8/source/detail?r=16341

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        Mon Aug 26 11:59:14 2013 UTC
+++ /branches/bleeding_edge/include/v8.h        Mon Aug 26 17:40:03 2013 UTC
@@ -3430,6 +3430,12 @@
    */
   void ReadOnlyPrototype();

+  /**
+   * Removes the prototype property from functions created from this
+   * FunctionTemplate.
+   */
+  void RemovePrototype();
+
   /**
    * Returns true if the given object is an instance of this function
    * template.
=======================================
--- /branches/bleeding_edge/src/api.cc  Mon Aug 26 17:00:58 2013 UTC
+++ /branches/bleeding_edge/src/api.cc  Mon Aug 26 17:40:03 2013 UTC
@@ -1450,6 +1450,17 @@
   ENTER_V8(isolate);
   Utils::OpenHandle(this)->set_read_only_prototype(true);
 }
+
+
+void FunctionTemplate::RemovePrototype() {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  if (IsDeadCheck(isolate, "v8::FunctionTemplate::RemovePrototype()")) {
+    return;
+  }
+  ENTER_V8(isolate);
+  Utils::OpenHandle(this)->set_remove_prototype(true);
+}
+

 template<
     typename Getter,
=======================================
--- /branches/bleeding_edge/src/apinatives.js   Mon Aug 26 11:59:14 2013 UTC
+++ /branches/bleeding_edge/src/apinatives.js   Mon Aug 26 17:40:03 2013 UTC
@@ -75,22 +75,26 @@
       var fun = %CreateApiFunction(data);
       if (name) %FunctionSetName(fun, name);
       cache[serialNumber] = fun;
-      var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
       var flags = %GetTemplateField(data, kApiFlagOffset);
-      // 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 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')) {
-        var parent_fun = Instantiate(parent);
-        %SetPrototype(fun.prototype, parent_fun.prototype);
+      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 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')) {
+          var parent_fun = Instantiate(parent);
+          %SetPrototype(fun.prototype, parent_fun.prototype);
+        }
       }
       ConfigureTemplateInstance(fun, data);
     } catch (e) {
=======================================
--- /branches/bleeding_edge/src/macros.py       Mon Jul 22 08:32:24 2013 UTC
+++ /branches/bleeding_edge/src/macros.py       Mon Aug 26 17:40:03 2013 UTC
@@ -67,7 +67,8 @@

 # For apinatives.js
 const kUninitialized = -1;
-const kReadOnlyPrototypeBit = 3; # For FunctionTemplateInfo, matches objects.h
+const kReadOnlyPrototypeBit = 3;
+const kRemovePrototypeBit = 4; # For FunctionTemplateInfo, matches objects.h

 # Note: kDayZeroInJulianDay = ToJulianDay(1970, 0, 1).
 const kInvalidDate        = 'Invalid Date';
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Mon Aug 26 15:30:30 2013 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Mon Aug 26 17:40:03 2013 UTC
@@ -4576,6 +4576,8 @@
                kNeedsAccessCheckBit)
 BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
                kReadOnlyPrototypeBit)
+BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
+               kRemovePrototypeBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
                kIsExpressionBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Aug 26 15:30:30 2013 UTC
+++ /branches/bleeding_edge/src/objects.h       Mon Aug 26 17:40:03 2013 UTC
@@ -9874,6 +9874,7 @@
   // requires access check.
   DECL_BOOLEAN_ACCESSORS(needs_access_check)
   DECL_BOOLEAN_ACCESSORS(read_only_prototype)
+  DECL_BOOLEAN_ACCESSORS(remove_prototype)

   static inline FunctionTemplateInfo* cast(Object* obj);

@@ -9909,6 +9910,7 @@
   static const int kUndetectableBit      = 1;
   static const int kNeedsAccessCheckBit  = 2;
   static const int kReadOnlyPrototypeBit = 3;
+  static const int kRemovePrototypeBit   = 4;

   DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
 };
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Mon Aug 26 11:59:14 2013 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Mon Aug 26 17:40:03 2013 UTC
@@ -9606,6 +9606,26 @@

CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value());
 }
+
+
+THREADED_TEST(FunctionRemovePrototype) {
+  LocalContext context;
+  v8::HandleScope handle_scope(context->GetIsolate());
+
+  Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+  t1->RemovePrototype();
+  Local<v8::Function> fun = t1->GetFunction();
+  context->Global()->Set(v8_str("fun"), fun);
+  CHECK(!CompileRun("'prototype' in fun")->BooleanValue());
+
+  v8::TryCatch try_catch;
+  CompileRun("new fun()");
+  CHECK(try_catch.HasCaught());
+
+  try_catch.Reset();
+  fun->NewInstance();
+  CHECK(try_catch.HasCaught());
+}


 THREADED_TEST(GetterSetterExceptions) {

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to