Changeset 141360 in webkit
- Timestamp:
- Jan 30, 2013 6:21:05 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r141358 r141360 1 2013-01-30 Nils Barth <nbarth@google.com> 2 3 [V8] Add IDL 'enum' support to CodeGeneratorV8.pm 4 https://bugs.webkit.org/show_bug.cgi?id=106553 5 6 Reviewed by Kentaro Hara. 7 8 Add partial support for Web IDL enumerations in V8 bindings 9 10 Binding generators currently cannot handle IDL enumerations. 11 (An enumeration is an DOMString with a limited set of values, thus 12 treated internally as DOMString, with validation code added in 13 bindings.) 14 This adds support for enumerations in V8, adding validation checking 15 to setters. 16 It does not add validation checking to operations (no test case), and 17 does not add support in JSC. 18 19 Test: bindings/scripts/test/TestObj.idl (run-bindings-test) 20 21 * bindings/scripts/IDLParser.pm: 22 - Parser assumes all IDL definitions are interfaces; add support for 23 other definitions 24 - Parser parses but discards enum definitions; instead, record 25 parsed data 26 (Parse): Sort definitions into interfaces and enums. 27 Remove "@definitions eq (someIdlDocument)" test, as this never 28 happens (fossil code) -- parseDefinitions returns list of definitions, 29 never a one-item list consisting of a document (no nested documents). 30 (unquoteString): new utility function to unquote StringToken (token 31 itself still quoted) 32 (parseEnum): 33 (parseEnumValueList): 34 (parseEnumValues): 35 (parseEnumOld): 36 37 * bindings/scripts/CodeGenerator.pm: 38 - Expose parsed enum data to backends (detect enums, list valid 39 values) 40 - Enums treated as DOMString type in internal function 41 (ProcessDocument): 42 (IsEnumType): 43 (ValidEnumValues): 44 (IsRefPtrType): 45 * bindings/scripts/CodeGeneratorV8.pm: 46 - Enums treated as DOMString type in internal functions 47 - Add validation to setter 48 (GenerateNormalAttrSetter): 49 (GetNativeType): 50 (JSValueToNative): 51 (NativeToJSValue): 52 (ConvertToV8StringResource): 53 * bindings/scripts/test/TestObj.idl: 54 - New enum type and enum variable test for IDL enumeration support 55 * bindings/scripts/test/V8/V8TestObj.cpp: 56 - Generated code, desired behavior 57 (WebCore::TestObjV8Internal::enumAttrAttrGetter): 58 (TestObjV8Internal): 59 (WebCore::TestObjV8Internal::enumAttrAttrSetter): 60 (WebCore): 61 * bindings/scripts/test/JS/JSTestObj.cpp: 62 - Generated code, currently incorrect 63 (WebCore): 64 (WebCore::jsTestObjEnumAttr): 65 (WebCore::setJSTestObjEnumAttr): 66 * bindings/scripts/test/JS/JSTestObj.h: 67 - Generated code, currently incorrect 68 (WebCore): 69 1 70 2013-01-30 Nico Weber <thakis@chromium.org> 2 71 -
trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm
r140884 r141360 54 54 my %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1); 55 55 56 my %enumTypeHash = (); 57 56 58 my %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1); 57 59 … … 124 126 require $ifaceName . ".pm"; 125 127 128 %enumTypeHash = map { $_->name => $_->values } @{$useDocument->enumerations}; 129 126 130 # Dynamically load external code generation perl module 127 131 $codeGenerator = $ifaceName->new($object, $useLayerOnTop, $preprocessor, $writeDependencies, $verbose, $targetIdlFilePath); … … 351 355 } 352 356 357 sub IsEnumType 358 { 359 my $object = shift; 360 my $type = shift; 361 362 return 1 if exists $enumTypeHash{$type}; 363 return 0; 364 } 365 366 sub ValidEnumValues 367 { 368 my $object = shift; 369 my $type = shift; 370 371 return @{$enumTypeHash{$type}}; 372 } 373 353 374 sub IsNonPointerType 354 375 { … … 398 419 return 0 if $object->GetSequenceType($type); 399 420 return 0 if $type eq "DOMString"; 421 return 0 if $object->IsEnumType($type); 400 422 401 423 return 1; -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
r141034 r141360 1160 1160 my $attrName = $attribute->signature->name; 1161 1161 my $attrExt = $attribute->signature->extendedAttributes; 1162 my $attrType = $attribute->signature->type; 1162 1163 1163 1164 my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature); … … 1204 1205 END 1205 1206 } else { 1206 my $attrType = $attribute->signature->type;1207 1207 my $reflect = $attribute->signature->extendedAttributes->{"Reflect"}; 1208 1208 if ($reflect && $codeGenerator->InheritsInterface($interface, "Node") && $codeGenerator->IsStringType($attrType)) { … … 1244 1244 push(@implContentDecls, " $nativeType v = $value;\n"); 1245 1245 } 1246 } 1247 1248 if ($codeGenerator->IsEnumType($attrType)) { 1249 # setter ignores invalid enumeration values 1250 my @enumValues = $codeGenerator->ValidEnumValues($attrType); 1251 my @validEqualities = (); 1252 foreach my $enumValue (@enumValues) { 1253 push(@validEqualities, "string == \"$enumValue\""); 1254 } 1255 my $enumValidationExpression = join(" || ", @validEqualities); 1256 push(@implContentDecls, <<END); 1257 String string = v; 1258 if (!($enumValidationExpression)) 1259 return; 1260 END 1246 1261 } 1247 1262 … … 3863 3878 return "bool" if $type eq "boolean"; 3864 3879 3865 return "V8StringResource" if $type eq "DOMString"and $isParameter;3866 return "String" if $type eq "DOMString" ;3880 return "V8StringResource" if ($type eq "DOMString" or $codeGenerator->IsEnumType($type)) and $isParameter; 3881 return "String" if $type eq "DOMString" or $codeGenerator->IsEnumType($type); 3867 3882 3868 3883 return "Range::CompareHow" if $type eq "CompareHow"; … … 3948 3963 3949 3964 if ($type eq "DOMString") { 3965 return $value; 3966 } 3967 3968 if ($codeGenerator->IsEnumType($type)) { 3950 3969 return $value; 3951 3970 } … … 4227 4246 return "$value.v8Value()" if $nativeType eq "ScriptValue"; 4228 4247 4229 if ($codeGenerator->IsStringType($type) ) {4248 if ($codeGenerator->IsStringType($type) or $codeGenerator->IsEnumType($type)) { 4230 4249 my $conv = $signature->extendedAttributes->{"TreatReturnedNullStringAs"}; 4231 4250 if (defined $conv) { … … 4354 4373 4355 4374 die "Wrong native type passed: $nativeType" unless $nativeType =~ /^V8StringResource/; 4356 if ($signature->type eq "DOMString" ) {4375 if ($signature->type eq "DOMString" or $codeGenerator->IsEnumType($signature->type)) { 4357 4376 my $macro = "V8TRYCATCH_FOR_V8STRINGRESOURCE"; 4358 4377 $macro .= "_$suffix" if $suffix; -
trunk/Source/WebCore/bindings/scripts/IDLParser.pm
r135547 r141360 36 36 # Used to represent a parsed IDL document 37 37 struct( idlDocument => { 38 interfaces => '@', # All parsed interfaces 39 fileName => '$' # file name 38 interfaces => '@', # All parsed interfaces 39 enumerations => '@', # All parsed enumerations 40 fileName => '$', # file name 40 41 }); 41 42 … … 87 88 }); 88 89 90 # Used to represent 'enum' definitions 91 struct( domEnum => { 92 name => '$', # Enumeration identifier 93 values => '@', # Enumeration values (list of unique strings) 94 }); 95 89 96 struct( Token => { 90 97 type => '$', # type of token … … 166 173 die $@ . " in $fileName" if $@; 167 174 168 die "No document found" unless @definitions; 169 170 my $document; 171 if ($#definitions == 0 && ref($definitions[0]) eq "idlDocument") { 172 $document = $definitions[0]; 173 } else { 174 $document = idlDocument->new(); 175 push(@{$document->interfaces}, @definitions); 176 } 177 175 die "No definitions founds" unless @definitions; 176 177 my $document = idlDocument->new(); 178 178 $document->fileName($fileName); 179 foreach my $definition (@definitions) { 180 if (ref($definition) eq "domInterface") { 181 push(@{$document->interfaces}, $definition); 182 } elsif (ref($definition) eq "domEnum") { 183 push(@{$document->enumerations}, $definition); 184 } else { 185 die "Unrecognized IDL definition kind: \"" . ref($definition) . "\""; 186 } 187 } 179 188 return $document; 180 189 } … … 252 261 } 253 262 die "Failed in tokenizing at " . $self->{Line}; 263 } 264 265 sub unquoteString 266 { 267 my $self = shift; 268 my $quotedString = shift; 269 if ($quotedString =~ /^"([^"]*)"$/) { 270 return $1; 271 } 272 die "Failed to parse string (" . $quotedString . ") at " . $self->{Line}; 254 273 } 255 274 … … 633 652 { 634 653 my $self = shift; 635 my $extendedAttributeList = shift; 654 my $extendedAttributeList = shift; # ignored: Extended attributes are not applicable to enumerations 636 655 637 656 my $next = $self->nextToken(); 638 657 if ($next->value() eq "enum") { 658 my $enum = domEnum->new(); 639 659 $self->assertTokenValue($self->getToken(), "enum", __LINE__); 640 $self->assertTokenType($self->getToken(), IdentifierToken); 660 my $enumNameToken = $self->getToken(); 661 $self->assertTokenType($enumNameToken, IdentifierToken); 662 $enum->name($enumNameToken->value()); 641 663 $self->assertTokenValue($self->getToken(), "{", __LINE__); 642 $self->parseEnumValueList();664 push(@{$enum->values}, @{$self->parseEnumValueList()}); 643 665 $self->assertTokenValue($self->getToken(), "}", __LINE__); 644 666 $self->assertTokenValue($self->getToken(), ";", __LINE__); 645 return ;667 return $enum; 646 668 } 647 669 $self->assertUnexpectedToken($next->value(), __LINE__); … … 651 673 { 652 674 my $self = shift; 675 my @values = (); 653 676 my $next = $self->nextToken(); 654 677 if ($next->type() == StringToken) { 655 $self->assertTokenType($self->getToken(), StringToken); 656 $self->parseEnumValues(); 657 return; 658 } 678 my $enumValueToken = $self->getToken(); 679 $self->assertTokenType($enumValueToken, StringToken); 680 my $enumValue = $self->unquoteString($enumValueToken->value()); 681 push(@values, $enumValue); 682 push(@values, @{$self->parseEnumValues()}); 683 return \@values; 684 } 685 # value list must be non-empty 659 686 $self->assertUnexpectedToken($next->value(), __LINE__); 660 687 } … … 663 690 { 664 691 my $self = shift; 692 my @values = (); 665 693 my $next = $self->nextToken(); 666 694 if ($next->value() eq ",") { 667 695 $self->assertTokenValue($self->getToken(), ",", __LINE__); 668 $self->assertTokenType($self->getToken(), StringToken); 669 $self->parseEnumValues(); 670 } 696 my $enumValueToken = $self->getToken(); 697 $self->assertTokenType($enumValueToken, StringToken); 698 my $enumValue = $self->unquoteString($enumValueToken->value()); 699 push(@values, $enumValue); 700 push(@values, @{$self->parseEnumValues()}); 701 return \@values; 702 } 703 return \@values; # empty list (end of enumeration-values) 671 704 } 672 705 … … 2188 2221 my $next = $self->nextToken(); 2189 2222 if ($next->value() eq "enum") { 2223 my $enum = domEnum->new(); 2190 2224 $self->assertTokenValue($self->getToken(), "enum", __LINE__); 2191 $self->parseExtendedAttributeListAllowEmpty(); 2192 $self->assertTokenType($self->getToken(), IdentifierToken); 2225 my $enumNameToken = $self->getToken(); 2226 $self->assertTokenType($enumNameToken, IdentifierToken); 2227 $enum->name($enumNameToken->value()); 2193 2228 $self->assertTokenValue($self->getToken(), "{", __LINE__); 2194 $self->parseEnumValueList();2229 push(@{$enum->values}, @{$self->parseEnumValueList()}); 2195 2230 $self->assertTokenValue($self->getToken(), "}", __LINE__); 2196 2231 $self->assertTokenValue($self->getToken(), ";", __LINE__); 2197 return ;2232 return $enum; 2198 2233 } 2199 2234 $self->assertUnexpectedToken($next->value(), __LINE__); -
trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
r140488 r141360 37 37 #include "JSScriptProfile.h" 38 38 #include "JSTestCallback.h" 39 #include "JSTestEnumType.h" 39 40 #include "JSTestObj.h" 40 41 #include "JSTestSubObj.h" … … 51 52 #include "ScriptProfile.h" 52 53 #include "SerializedScriptValue.h" 54 #include "TestEnumType.h" 53 55 #include "TestObj.h" 54 56 #include "bool.h" … … 82 84 { "readOnlyStringAttr", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjReadOnlyStringAttr), (intptr_t)0, NoIntrinsic }, 83 85 { "readOnlyTestObjAttr", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjReadOnlyTestObjAttr), (intptr_t)0, NoIntrinsic }, 86 { "enumAttr", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjEnumAttr), (intptr_t)setJSTestObjEnumAttr, NoIntrinsic }, 84 87 { "shortAttr", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjShortAttr), (intptr_t)setJSTestObjShortAttr, NoIntrinsic }, 85 88 { "unsignedShortAttr", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjUnsignedShortAttr), (intptr_t)setJSTestObjUnsignedShortAttr, NoIntrinsic }, … … 442 445 443 446 447 JSValue jsTestObjEnumAttr(ExecState* exec, JSValue slotBase, PropertyName) 448 { 449 JSTestObj* castedThis = jsCast<JSTestObj*>(asObject(slotBase)); 450 UNUSED_PARAM(exec); 451 TestObj* impl = static_cast<TestObj*>(castedThis->impl()); 452 JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(impl->enumAttr())); 453 return result; 454 } 455 456 444 457 JSValue jsTestObjShortAttr(ExecState* exec, JSValue slotBase, PropertyName) 445 458 { … … 978 991 UNUSED_PARAM(exec); 979 992 TestObj::setStaticStringAttr(value.isEmpty() ? String() : value.toString(exec)->value(exec)); 993 } 994 995 996 void setJSTestObjEnumAttr(ExecState* exec, JSObject* thisObject, JSValue value) 997 { 998 UNUSED_PARAM(exec); 999 JSTestObj* castedThis = jsCast<JSTestObj*>(thisObject); 1000 TestObj* impl = static_cast<TestObj*>(castedThis->impl()); 1001 impl->setEnumAttr(toTestEnumType(value)); 980 1002 } 981 1003 -
trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h
r140488 r141360 229 229 void setJSTestObjConstructorStaticStringAttr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); 230 230 JSC::JSValue jsTestObjConstructorTestSubObj(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); 231 JSC::JSValue jsTestObjEnumAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); 232 void setJSTestObjEnumAttr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); 231 233 JSC::JSValue jsTestObjShortAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); 232 234 void setJSTestObjShortAttr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); -
trunk/Source/WebCore/bindings/scripts/test/TestObj.idl
r140488 r141360 30 30 // This IDL file is for testing the bindings code generator and for tracking 31 31 // changes in its ouput. 32 33 #if defined(TESTING_JS) || defined(TESTING_V8) 34 enum TestEnumType { "", "EnumValue1", "EnumValue2", "EnumValue3" }; 35 #endif 36 32 37 [ 33 38 Constructor(in [Callback] TestCallback testCallback), … … 42 47 static attribute DOMString staticStringAttr; 43 48 static readonly attribute TestSubObjConstructor TestSubObj; 49 attribute TestEnumType enumAttr; 44 50 #endif 45 51 attribute short shortAttr; -
trunk/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
r141105 r141360 146 146 } 147 147 148 static v8::Handle<v8::Value> enumAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 149 { 150 TestObj* imp = V8TestObj::toNative(info.Holder()); 151 return v8String(imp->enumAttr(), info.GetIsolate(), ReturnUnsafeHandle); 152 } 153 154 static void enumAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) 155 { 156 TestObj* imp = V8TestObj::toNative(info.Holder()); 157 V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, v, value); 158 String string = v; 159 if (!(string == "" || string == "EnumValue1" || string == "EnumValue2" || string == "EnumValue3")) 160 return; 161 imp->setEnumAttr(v); 162 return; 163 } 164 148 165 static v8::Handle<v8::Value> shortAttrAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 149 166 { … … 1852 1869 // Attribute 'TestSubObj' (Type: 'readonly attribute' ExtAttr: '') 1853 1870 {"TestSubObj", TestObjV8Internal::TestObjConstructorGetter, 0, &V8TestSubObj::info, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */}, 1871 // Attribute 'enumAttr' (Type: 'attribute' ExtAttr: '') 1872 {"enumAttr", TestObjV8Internal::enumAttrAttrGetter, TestObjV8Internal::enumAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */}, 1854 1873 // Attribute 'shortAttr' (Type: 'attribute' ExtAttr: '') 1855 1874 {"shortAttr", TestObjV8Internal::shortAttrAttrGetter, TestObjV8Internal::shortAttrAttrSetter, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
Note: See TracChangeset
for help on using the changeset viewer.