summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordeanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-27 12:41:22 +0000
committerdeanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-27 12:41:22 +0000
commit4b6af4f75e9ad65588f01d9e980a0cc427695d91 (patch)
tree1a1314085360c475c3c439c94b8877c7a07c8ad5
parent3050f7d57b2dee4784df2cb0812c3b5845956ee1 (diff)
downloadchromium_src-4b6af4f75e9ad65588f01d9e980a0cc427695d91.zip
chromium_src-4b6af4f75e9ad65588f01d9e980a0cc427695d91.tar.gz
chromium_src-4b6af4f75e9ad65588f01d9e980a0cc427695d91.tar.bz2
Move a bunch of code-driven binding template configuration to a data-driven approach. This reduces the code size, and the overall binary size.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1435 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--webkit/port/bindings/scripts/CodeGeneratorV8.pm112
-rw-r--r--webkit/port/bindings/v8/v8_proxy.cpp35
-rw-r--r--webkit/port/bindings/v8/v8_proxy.h35
3 files changed, 139 insertions, 43 deletions
diff --git a/webkit/port/bindings/scripts/CodeGeneratorV8.pm b/webkit/port/bindings/scripts/CodeGeneratorV8.pm
index 5cc176c..e617d6e 100644
--- a/webkit/port/bindings/scripts/CodeGeneratorV8.pm
+++ b/webkit/port/bindings/scripts/CodeGeneratorV8.pm
@@ -831,9 +831,9 @@ sub GenerateImplementation
}
}
- if ($hasConstructors) {
- GenerateConstructorGetter($implClassName);
- }
+ if ($hasConstructors) {
+ GenerateConstructorGetter($implClassName);
+ }
# Generate methods for functions.
foreach my $function (@{$dataNode->functions}) {
@@ -857,25 +857,12 @@ sub GenerateImplementation
}
}
- push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
-
- # Generate the template configuration method
- push(@implContent, <<END
-static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
- v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
- instance->SetInternalFieldCount(2);
- v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
- v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
-END
-);
-
- my $needsAccessCheck = 0;
- if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) {
- push(@implContent,
- " instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::External::New((void*)V8ClassIndex::${classIndex}));\n");
- $needsAccessCheck = 1;
+ # Attributes
+ my $has_attributes = 0;
+ if (@{$dataNode->attributes}) {
+ $has_attributes = 1;
+ push(@implContent, "static const BatchedAttribute attrs[] = {\n");
}
-
foreach my $attribute (@{$dataNode->attributes}) {
my $attrName = $attribute->signature->name;
my $attrExt = $attribute->signature->extendedAttributes;
@@ -907,15 +894,15 @@ END
$propAttr .= "|v8::DontEnum";
}
- my $holder = "instance";
- my $data = "v8::Handle<v8::Value>()";
+ my $on_proto = "0 /* on instance */";
+ my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
# Constructor
if ($attribute->signature->type =~ /Constructor$/) {
my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
$constructorType =~ s/Constructor$//;
my $constructorIndex = uc($constructorType);
- $data = "v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${constructorIndex}))";
+ $data = "V8ClassIndex::${constructorIndex}";
$getter = "${interfaceName}Internal::${implClassName}ConstructorGetter";
$setter = "0";
$propAttr = "v8::ReadOnly";
@@ -950,26 +937,72 @@ END
# An accessor can be installed on the proto
if ($attrExt->{"v8OnProto"}) {
- $holder = "proto";
+ $on_proto = "1 /* on proto */";
}
my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
"' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
push(@implContent, <<END);
-
// $commentInfo
- $holder->SetAccessor(
- v8::String::New("$attrName"),
- $getter,
- $setter,
- $data,
- $accessControl,
- static_cast<v8::PropertyAttribute>($propAttr));
+ { "$attrName",
+ $getter,
+ $setter,
+ $data,
+ $accessControl,
+ static_cast<v8::PropertyAttribute>($propAttr),
+ $on_proto },
END
+ }
+ if ($has_attributes) {
+ push(@implContent, "};\n");
+ }
+ # Setup constants
+ my $has_constants = 0;
+ if (@{$dataNode->constants}) {
+ $has_constants = 1;
+ push(@implContent, "static const BatchedConstant consts[] = {\n");
+ }
+ foreach my $constant (@{$dataNode->constants}) {
+ my $name = $constant->name;
+ my $value = $constant->value;
+ # TODO we need the static_cast here only because of one constant, NodeFilter.idl
+ # defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better if we
+ # handled this here, and converted it to a -1 constant in the c++ output.
+ push(@implContent, <<END);
+ { "${name}", static_cast<signed int>($value) },
+END
}
+ if ($has_constants) {
+ push(@implContent, "};\n");
+ }
+
+ push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
+
+ my $access_check = "/* no access check */";
+ if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) {
+ $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::External::New((void*)V8ClassIndex::${classIndex}));";
+ }
+
+ # Generate the template configuration method
+ push(@implContent, <<END
+static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ instance->SetInternalFieldCount(2);
+ v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+ $access_check
+END
+);
+ # Set up our attributes if we have them
+ if ($has_attributes) {
+ push(@implContent, <<END);
+ BatchConfigureAttributes(instance, proto, attrs, sizeof(attrs)/sizeof(*attrs));
+END
+ }
+ # Define our functions with Set() or SetAccessor()
foreach my $function (@{$dataNode->functions}) {
my $attrExt = $function->signature->extendedAttributes;
my $name = $function->signature->name;
@@ -1053,13 +1086,9 @@ END
# Set the class name. This is used when printing objects.
push(@implContent, " desc->SetClassName(v8::String::New(\"" . GetClassName(${interfaceName}) . "\"));\n");
- # Setup constants
- foreach my $constant (@{$dataNode->constants}) {
- my $name = $constant->name;
- my $value = $constant->value;
+ if ($has_constants) {
push(@implContent, <<END);
- desc->Set(v8::String::New("${name}"), v8::Integer::New(static_cast<signed int>($value)), v8::ReadOnly);
- proto->Set(v8::String::New("${name}"), v8::Integer::New(static_cast<signed int>($value)), v8::ReadOnly);
+ BatchConfigureConstants(desc, proto, consts, sizeof(consts)/sizeof(*consts));
END
}
@@ -1067,10 +1096,8 @@ END
return desc;
}
-static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_;
-static v8::Persistent<v8::FunctionTemplate> ${className}_cache_;
-
v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
+ static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_;
if (${className}_raw_cache_.IsEmpty()) {
v8::HandleScope scope;
v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::CheckNewLegal);
@@ -1080,6 +1107,7 @@ v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
}
v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
+ static v8::Persistent<v8::FunctionTemplate> ${className}_cache_;
if (${className}_cache_.IsEmpty())
${className}_cache_ = Configure${className}Template(GetRawTemplate());
return ${className}_cache_;
diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp
index b5398a1..5cfcd62 100644
--- a/webkit/port/bindings/v8/v8_proxy.cpp
+++ b/webkit/port/bindings/v8/v8_proxy.cpp
@@ -183,7 +183,40 @@ void V8Proxy::UnregisterGlobalHandle(void* host,
ASSERT(info->host_ == host);
delete info;
}
-#endif
+#endif // ifndef NDEBUG
+
+void BatchConfigureAttributes(v8::Handle<v8::ObjectTemplate> inst,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedAttribute* attrs,
+ size_t num_attrs) {
+ for (size_t i = 0; i < num_attrs; ++i) {
+ const BatchedAttribute* a = &attrs[i];
+ (a->on_proto ? proto : inst)->SetAccessor(
+ v8::String::New(a->name),
+ a->getter,
+ a->setter,
+ a->data == V8ClassIndex::INVALID_CLASS_INDEX
+ ? v8::Handle<v8::Value>()
+ : v8::Integer::New(V8ClassIndex::ToInt(a->data)),
+ a->settings,
+ a->attribute);
+ }
+}
+
+void BatchConfigureConstants(v8::Handle<v8::FunctionTemplate> desc,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedConstant* consts,
+ size_t num_consts) {
+ for (size_t i = 0; i < num_consts; ++i) {
+ const BatchedConstant* c = &consts[i];
+ desc->Set(v8::String::New(c->name),
+ v8::Integer::New(c->value),
+ v8::ReadOnly);
+ proto->Set(v8::String::New(c->name),
+ v8::Integer::New(c->value),
+ v8::ReadOnly);
+ }
+}
typedef HashMap<Node*, v8::Object*> NodeMap;
diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h
index 40909c0..23d1f95 100644
--- a/webkit/port/bindings/v8/v8_proxy.h
+++ b/webkit/port/bindings/v8/v8_proxy.h
@@ -103,6 +103,41 @@ class GlobalHandleInfo {
#endif // NDEBUG
+// The following Batch structs and methods are used for setting multiple
+// properties on an ObjectTemplate, used from the generated bindings
+// initialization (ConfigureXXXTemplate). This greatly reduces the binary
+// size by moving from code driven setup to data table driven setup.
+
+// BatchedAttribute translates into calls to SetAccessor() on either the
+// instance or the prototype ObjectTemplate, based on |on_proto|.
+struct BatchedAttribute {
+ const char* const name;
+ v8::AccessorGetter getter;
+ v8::AccessorSetter setter;
+ V8ClassIndex::V8WrapperType data;
+ v8::AccessControl settings;
+ v8::PropertyAttribute attribute;
+ bool on_proto;
+};
+
+void BatchConfigureAttributes(v8::Handle<v8::ObjectTemplate> inst,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedAttribute* attrs,
+ size_t num_attrs);
+
+// BhatchedConstant translates into calls to Set() for setting up an object's
+// constants. It sets the constant on both the FunctionTemplate |desc| and the
+// ObjectTemplate |proto|. PropertyAttributes is always ReadOnly.
+struct BatchedConstant {
+ const char* const name;
+ int value;
+};
+
+void BatchConfigureConstants(v8::Handle<v8::FunctionTemplate> desc,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedConstant* consts,
+ size_t num_consts);
+
class V8Proxy {
public:
// The types of javascript errors that can be thrown.