diff options
author | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-27 12:41:22 +0000 |
---|---|---|
committer | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-27 12:41:22 +0000 |
commit | 4b6af4f75e9ad65588f01d9e980a0cc427695d91 (patch) | |
tree | 1a1314085360c475c3c439c94b8877c7a07c8ad5 | |
parent | 3050f7d57b2dee4784df2cb0812c3b5845956ee1 (diff) | |
download | chromium_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.pm | 112 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 35 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.h | 35 |
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. |