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