Changeset 206514 in webkit


Ignore:
Timestamp:
Sep 28, 2016 6:18:37 AM (8 years ago)
Author:
commit-queue@webkit.org
Message:

Add WebIDL special operation support: serializer
https://bugs.webkit.org/show_bug.cgi?id=156293

Patch by Alejandro G. Castro <alex@igalia.com> on 2016-09-28
Reviewed by Youenn Fablet.

Source/WebCore:

Added support for the serializer special operation for WebIDLs,
current implementation adds support for:

  • just the keyword: serializer; It will return all the attributes of in an object.
  • map of entries with the attributes: serializer = {attribute1, attribute2, ...}

It creates a toJSON method that returns the serialized value
converted into an ECMAScript value. For more information check the
definition of the operation:

http://heycam.github.io/webidl/#idl-serializers

We have created a new function in the API of the objects
that are marked as serializer.

Used the support to add new API for RTCIceCandidate and
RTCSessionDescription.

Updated the tests expectations of the bindings.

Tests: bindings/scripts/test/TestNode.idl

bindings/scripts/test/TestObj.idl
fast/mediastream/RTCIceCandidate.html
fast/mediastream/RTCSessionDescription.html

  • Modules/mediastream/RTCIceCandidate.idl: Added the serializer

operation.

  • Modules/mediastream/RTCSessionDescription.idl: Added the

serializer operation.

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateImplementation): Added the calls to the serializer
code generator.
(GenerateSerializerFunction): Added, generates the toJSON function
adding all the serializable->attributes value to an object as
defined in the spec.

  • bindings/scripts/IDLParser.pm: Modified the serializer parser

that was unused to support the WebIDL spec parts. Added a new
domSerializable type to store the list of attributes in the
possible map.
(parseSerializer): Modified the function to follow the
semicolon rule in the spec, now the serializer line must have a
semicolon like any other line.
(parseSerializerRest): The function now has to get the attributes
list from the pattern parsing function and add them to the
domSerializable item.
(parseSerializationPattern): Now this function returns the list of
attributes in the serializable map or list if we have one.
(parseSerializationAttributes): Added, this function replaces the
Map and List functions, the currently supported parts are similar
for both situations.
(applyMemberList): Added the serializable item to the interface
variable and populate the serializable in case there is not a
defined map.
(parseSerializationPatternMap): Replaced with
parseSerializationAttributes.
(parseSerializationPatternList): Ditto.

  • bindings/scripts/test/JS/JSTestNode.cpp: Modified the expected result.

(WebCore::jsTestNodePrototypeFunctionToJSON):

  • bindings/scripts/test/JS/JSTestObj.cpp: Modified the expected result.

(WebCore::jsTestObjPrototypeFunctionToJSON):

  • bindings/scripts/test/TestNode.idl: Added the serializer test.
  • bindings/scripts/test/TestObj.idl: Added serializer map test.

LayoutTests:

Verify the new API of the objects and check what happens when user
modifies the values and types of the attributes, or adds a null value.

  • fast/mediastream/RTCIceCandidate-expected.txt:
  • fast/mediastream/RTCIceCandidate.html:
  • fast/mediastream/RTCSessionDescription-expected.txt:
  • fast/mediastream/RTCSessionDescription.html:
Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r206511 r206514  
     12016-09-28  Alejandro G. Castro  <alex@igalia.com>
     2
     3        Add WebIDL special operation support: serializer
     4        https://bugs.webkit.org/show_bug.cgi?id=156293
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Verify the new API of the objects and check what happens when user
     9        modifies the values and types of the attributes, or adds a null value.
     10
     11        * fast/mediastream/RTCIceCandidate-expected.txt:
     12        * fast/mediastream/RTCIceCandidate.html:
     13        * fast/mediastream/RTCSessionDescription-expected.txt:
     14        * fast/mediastream/RTCSessionDescription.html:
     15
    1162016-09-28  Khaled Hosny  <khaledhosny@eglug.org>
    217
  • trunk/LayoutTests/fast/mediastream/RTCIceCandidate-expected.txt

    r202267 r206514  
    88PASS candidate.sdpMid is "bar"
    99PASS candidate.sdpMLineIndex is 6
     10PASS RTCIceCandidate.prototype.toJSON is defined.
     11PASS Object.getOwnPropertyDescriptor(RTCIceCandidate.prototype, "toJSON").enumerable is true
     12PASS Object.getOwnPropertyDescriptor(RTCIceCandidate.prototype, "toJSON").writable is true
     13PASS Object.getOwnPropertyDescriptor(RTCIceCandidate.prototype, "toJSON").configurable is true
     14PASS RTCIceCandidate.prototype.toJSON.length is 0
     15PASS RTCIceCandidate.prototype.toJSON.name is "toJSON"
     16PASS Object.getOwnPropertyDescriptor(jsonMap, "candidate").enumerable is true
     17PASS Object.getOwnPropertyDescriptor(jsonMap, "candidate").writable is true
     18PASS Object.getOwnPropertyDescriptor(jsonMap, "candidate").configurable is true
     19PASS childCandidate.toJSON(); threw exception TypeError: Can only call RTCIceCandidate.toJSON on instances of RTCIceCandidate.
     20PASS JSON.stringify(candidate.toJSON()) is "{\"candidate\":\"foo\",\"sdpMid\":\"bar\",\"sdpMLineIndex\":6}"
     21PASS JSON.stringify(candidate.toJSON()) is "{\"candidate\":\"foo\",\"sdpMid\":\"bar\",\"sdpMLineIndex\":6}"
     22PASS JSON.stringify(candidate.toJSON()) is "{\"candidate\":\"foo\",\"sdpMid\":\"bar\",\"sdpMLineIndex\":6}"
     23PASS JSON.stringify(candidate.toJSON()) is "{\"candidate\":\"foo\",\"sdpMid\":\"bar\",\"sdpMLineIndex\":6}"
     24PASS JSON.stringify(candidate.toJSON()) is "{\"candidate\":\"foo\",\"sdpMid\":\"bar\",\"sdpMLineIndex\":6}"
    1025
    1126Attributes are readonly
  • trunk/LayoutTests/fast/mediastream/RTCIceCandidate.html

    r202267 r206514  
    1414            shouldBe('candidate.sdpMid', '"bar"');
    1515            shouldBe('candidate.sdpMLineIndex', '6');
     16            shouldBeDefined('RTCIceCandidate.prototype.toJSON');
     17            shouldBeTrue('Object.getOwnPropertyDescriptor(RTCIceCandidate.prototype, "toJSON").enumerable');
     18            shouldBeTrue('Object.getOwnPropertyDescriptor(RTCIceCandidate.prototype, "toJSON").writable');
     19            shouldBeTrue('Object.getOwnPropertyDescriptor(RTCIceCandidate.prototype, "toJSON").configurable');
     20            shouldBe('RTCIceCandidate.prototype.toJSON.length', '0');
     21            shouldBe('RTCIceCandidate.prototype.toJSON.name', '"toJSON"');
     22
     23            var jsonMap = candidate.toJSON();
     24            shouldBeTrue('Object.getOwnPropertyDescriptor(jsonMap, "candidate").enumerable');
     25            shouldBeTrue('Object.getOwnPropertyDescriptor(jsonMap, "candidate").writable');
     26            shouldBeTrue('Object.getOwnPropertyDescriptor(jsonMap, "candidate").configurable');
     27
     28            var childRTCIceCandidate = function() {};
     29            childRTCIceCandidate.prototype = Object.create(RTCIceCandidate.prototype);
     30            var childCandidate = new childRTCIceCandidate();
     31            shouldThrow('childCandidate.toJSON();');
     32
     33            shouldBeEqualToString('JSON.stringify(candidate.toJSON())', '{"candidate":"foo","sdpMid":"bar","sdpMLineIndex":6}');
     34            candidate.newAttribute = "new value";
     35            shouldBeEqualToString('JSON.stringify(candidate.toJSON())', '{"candidate":"foo","sdpMid":"bar","sdpMLineIndex":6}');
     36            candidate.sdpMLineIndex = "not a number";
     37            shouldBeEqualToString('JSON.stringify(candidate.toJSON())', '{"candidate":"foo","sdpMid":"bar","sdpMLineIndex":6}');
     38            candidate.sdpMid = 7;
     39            shouldBeEqualToString('JSON.stringify(candidate.toJSON())', '{"candidate":"foo","sdpMid":"bar","sdpMLineIndex":6}');
     40            candidate.sdpMid = null;
     41            shouldBeEqualToString('JSON.stringify(candidate.toJSON())', '{"candidate":"foo","sdpMid":"bar","sdpMLineIndex":6}');
     42
    1643            debug("");
    1744
  • trunk/LayoutTests/fast/mediastream/RTCSessionDescription-expected.txt

    r201420 r206514  
    77PASS sessionDescription.type is "offer"
    88PASS sessionDescription.sdp is "foobar"
     9PASS JSON.stringify(sessionDescription.toJSON()) is "{\"type\":\"offer\",\"sdp\":\"foobar\"}"
    910*** Attributes are read-only.
    1011PASS sessionDescription.type = 'answer' did not throw exception.
  • trunk/LayoutTests/fast/mediastream/RTCSessionDescription.html

    r201420 r206514  
    1515            shouldBe('sessionDescription.type', '"offer"');
    1616            shouldBe('sessionDescription.sdp', '"foobar"');
     17            shouldBeEqualToString('JSON.stringify(sessionDescription.toJSON())', '{"type":"offer","sdp":"foobar"}');
    1718
    1819            debug("*** Attributes are read-only.");
  • trunk/Source/WebCore/ChangeLog

    r206513 r206514  
     12016-09-28  Alejandro G. Castro  <alex@igalia.com>
     2
     3        Add WebIDL special operation support: serializer
     4        https://bugs.webkit.org/show_bug.cgi?id=156293
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Added support for the serializer special operation for WebIDLs,
     9        current implementation adds support for:
     10          - just the keyword: serializer; It will return all the
     11            attributes of in an object.
     12          - map of entries with the attributes: serializer = {attribute1,
     13            attribute2, ...}
     14
     15        It creates a toJSON method that returns the serialized value
     16        converted into an ECMAScript value. For more information check the
     17        definition of the operation:
     18
     19        http://heycam.github.io/webidl/#idl-serializers
     20
     21        We have created a new function in the API of the objects
     22        that are marked as serializer.
     23
     24        Used the support to add new API for RTCIceCandidate and
     25        RTCSessionDescription.
     26
     27        Updated the tests expectations of the bindings.
     28
     29        Tests: bindings/scripts/test/TestNode.idl
     30               bindings/scripts/test/TestObj.idl
     31               fast/mediastream/RTCIceCandidate.html
     32               fast/mediastream/RTCSessionDescription.html
     33
     34        * Modules/mediastream/RTCIceCandidate.idl: Added the serializer
     35        operation.
     36        * Modules/mediastream/RTCSessionDescription.idl: Added the
     37        serializer operation.
     38        * bindings/scripts/CodeGeneratorJS.pm:
     39        (GenerateImplementation): Added the calls to the serializer
     40        code generator.
     41        (GenerateSerializerFunction): Added, generates the toJSON function
     42        adding all the serializable->attributes value to an object as
     43        defined in the spec.
     44        * bindings/scripts/IDLParser.pm: Modified the serializer parser
     45        that was unused to support the WebIDL spec parts. Added a new
     46        domSerializable type to store the list of attributes in the
     47        possible map.
     48        (parseSerializer): Modified the function to follow the
     49        semicolon rule in the spec, now the serializer line must have a
     50        semicolon like any other line.
     51        (parseSerializerRest): The function now has to get the attributes
     52        list from the pattern parsing function and add them to the
     53        domSerializable item.
     54        (parseSerializationPattern): Now this function returns the list of
     55        attributes in the serializable map or list if we have one.
     56        (parseSerializationAttributes): Added, this function replaces the
     57        Map and List functions, the currently supported parts are similar
     58        for both situations.
     59        (applyMemberList): Added the serializable item to the interface
     60        variable and populate the serializable in case there is not a
     61        defined map.
     62        (parseSerializationPatternMap): Replaced with
     63        parseSerializationAttributes.
     64        (parseSerializationPatternList): Ditto.
     65        * bindings/scripts/test/JS/JSTestNode.cpp: Modified the expected result.
     66        (WebCore::jsTestNodePrototypeFunctionToJSON):
     67        * bindings/scripts/test/JS/JSTestObj.cpp: Modified the expected result.
     68        (WebCore::jsTestObjPrototypeFunctionToJSON):
     69        * bindings/scripts/test/TestNode.idl: Added the serializer test.
     70        * bindings/scripts/test/TestObj.idl: Added serializer map test.
     71
    1722016-09-28  Michael Catanzaro  <mcatanzaro@igalia.com>
    273
  • trunk/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl

    r202551 r206514  
    4040    readonly attribute DOMString? sdpMid;
    4141    readonly attribute unsigned short? sdpMLineIndex;
     42
     43    serializer = {candidate, sdpMid, sdpMLineIndex};
    4244};
    4345
  • trunk/Source/WebCore/Modules/mediastream/RTCSessionDescription.idl

    r202551 r206514  
    3939    [SetterRaisesException] readonly attribute RTCSdpType type;
    4040    readonly attribute DOMString sdp;
     41
     42    serializer = {type, sdp};
    4143};
    4244
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r206386 r206514  
    665665
    666666    $count += scalar @{$interface->iterable->functions} if $interface->iterable;
     667    $count += scalar @{$interface->serializable->functions} if $interface->serializable;
    667668
    668669    return $count;
     
    16811682    my @functions = @{$interface->functions};
    16821683    push(@functions, @{$interface->iterable->functions}) if IsKeyValueIterableInterface($interface);
     1684    push(@functions, @{$interface->serializable->functions}) if $interface->serializable;
    16831685    foreach my $function (@functions) {
    16841686        next if ($function->signature->extendedAttributes->{"PrivateIdentifier"} and not $function->signature->extendedAttributes->{"PublicIdentifier"});
     
    23232325    my @functions = @{$interface->functions};
    23242326    push(@functions, @{$interface->iterable->functions}) if IsKeyValueIterableInterface($interface);
     2327    push(@functions, @{$interface->serializable->functions}) if $interface->serializable;
    23252328
    23262329    my $numConstants = @{$interface->constants};
     
    35343537    }
    35353538
    3536     if ($interface->iterable) {
    3537         GenerateImplementationIterableFunctions($interface);
    3538     }
     3539
     3540    GenerateImplementationIterableFunctions($interface) if $interface->iterable;
     3541    GenerateSerializerFunction($interface, $interfaceName, $className) if $interface->serializable;
    35393542
    35403543    if ($needsVisitChildren) {
     
    37573760    my $conditionalString = $codeGenerator->GenerateConditionalString($interface);
    37583761    push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
     3762}
     3763
     3764sub GenerateSerializerFunction
     3765{
     3766    my ($interface, $interfaceName, $className) = @_;
     3767    my $serializerFunctionName = "toJSON";
     3768    my $serializerNativeFunctionName = $codeGenerator->WK_lcfirst($className) . "PrototypeFunction" . $codeGenerator->WK_ucfirst($serializerFunctionName);
     3769
     3770    AddToImplIncludes("ObjectConstructor.h");
     3771    push(@implContent, "EncodedJSValue JSC_HOST_CALL ${serializerNativeFunctionName}(ExecState* state)\n");
     3772    push(@implContent, "{\n");
     3773    push(@implContent, "    ASSERT(state);\n");
     3774    push(@implContent, "    auto thisValue = state->thisValue();\n");
     3775    push(@implContent, "    auto castedThis = jsDynamicCast<JS$interfaceName*>(thisValue);\n");
     3776    push(@implContent, "    VM& vm = state->vm();\n");
     3777    push(@implContent, "    auto throwScope = DECLARE_THROW_SCOPE(vm);\n");
     3778    push(@implContent, "    if (UNLIKELY(!castedThis)){\n");
     3779    push(@implContent, "        return throwThisTypeError(*state, throwScope, \"$interfaceName\", \"$serializerFunctionName\");\n");
     3780    push(@implContent, "    }\n");
     3781    push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(castedThis, ${className}::info());\n\n") unless $interfaceName eq "EventTarget";
     3782    push(@implContent, "    auto* result = constructEmptyObject(state);\n");
     3783    foreach my $attribute (@{$interface->attributes}) {
     3784        my $name = $attribute->signature->name;
     3785        if (grep $_ eq $name, @{$interface->serializable->attributes}) {
     3786            my $getFunctionName = GetAttributeGetterName($interface, $className, $attribute);
     3787            push(@implContent, "    auto ${name}Value = ${getFunctionName}(state, JSValue::encode(thisValue), Identifier());\n");
     3788            push(@implContent, "    ASSERT(!throwScope.exception());\n");
     3789            push(@implContent, "    result->putDirect(vm, Identifier::fromString(&vm, \"${name}\"), JSValue::decode(${name}Value));\n");
     3790        }
     3791    }
     3792    push(@implContent, "    return JSValue::encode(result);\n");
     3793    push(@implContent, "}\n\n");
    37593794}
    37603795
  • trunk/Source/WebCore/bindings/scripts/IDLParser.pm

    r204871 r206514  
    6161    isPartial => '$', # Used for partial interfaces
    6262    iterable => '$', # Used for iterable interfaces
     63    serializable => '$', # Used for serializable interfaces
    6364});
    6465
     
    106107    functions => '@', # Iterable functions (entries, keys, values, [Symbol.Iterator], forEach)
    107108    extendedAttributes => '$', # Extended attributes
     109});
     110
     111# Used to represent serializable interface
     112struct( domSerializable => {
     113    attributes => '@', # List of attributes to serialize
     114    functions => '@', # toJSON function
    108115});
    109116
     
    10571064    if ($next->value() eq "serializer") {
    10581065        $self->assertTokenValue($self->getToken(), "serializer", __LINE__);
    1059         return $self->parseSerializerRest($extendedAttributeList);
     1066        my $next = $self->nextToken();
     1067        my $newDataNode;
     1068        if ($next->value() ne ";") {
     1069            $newDataNode = $self->parseSerializerRest($extendedAttributeList);
     1070            my $next = $self->nextToken();
     1071        } else {
     1072            $newDataNode = domSerializable->new();
     1073        }
     1074
     1075        my $toJSONFunction = domFunction->new();
     1076        $toJSONFunction->signature(domSignature->new());
     1077        $toJSONFunction->signature->extendedAttributes($extendedAttributeList);
     1078        $toJSONFunction->signature->name("toJSON");
     1079        push(@{$newDataNode->functions}, $toJSONFunction);
     1080
     1081        $self->assertTokenValue($self->getToken(), ";", __LINE__);
     1082        return $newDataNode;
    10601083    }
    10611084    $self->assertUnexpectedToken($next->value(), __LINE__);
     
    10701093    if ($next->value() eq "=") {
    10711094        $self->assertTokenValue($self->getToken(), "=", __LINE__);
    1072         return $self->parseSerializationPattern($extendedAttributeList);
     1095        my $attributes = $self->parseSerializationPattern();
     1096
     1097        my $newDataNode = domSerializable->new();
     1098        $newDataNode->attributes($attributes);
     1099
     1100        return $newDataNode;
    10731101    }
    10741102    if ($next->type() == IdentifierToken || $next->value() eq "(") {
     
    10801108{
    10811109    my $self = shift;
    1082     my $extendedAttributeList = shift;
    10831110
    10841111    my $next = $self->nextToken();
    10851112    if ($next->value() eq "{") {
    10861113        $self->assertTokenValue($self->getToken(), "{", __LINE__);
    1087         $self->parseSerializationPatternMap();
     1114        my $attributes = $self->parseSerializationAttributes();
    10881115        $self->assertTokenValue($self->getToken(), "}", __LINE__);
    1089         return;
     1116        return \@{$attributes};
    10901117    }
    10911118    if ($next->value() eq "[") {
    1092         $self->assertTokenValue($self->getToken(), "[", __LINE__);
    1093         $self->parseSerializationPatternList();
    1094         $self->assertTokenValue($self->getToken(), "]", __LINE__);
    1095         return;
     1119        die "Serialization of lists pattern is not currently supported.";
    10961120    }
    10971121    if ($next->type() == IdentifierToken) {
    1098         $self->assertTokenType($self->getToken(), IdentifierToken);
    1099         return;
    1100     }
    1101     $self->assertUnexpectedToken($next->value(), __LINE__);
    1102 }
    1103 
    1104 sub parseSerializationPatternMap
    1105 {
    1106     my $self = shift;
    1107     my $next = $self->nextToken();
    1108     if ($next->value() eq "getter") {
    1109         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
    1110         return;
    1111     }
    1112     if ($next->value() eq "inherit") {
    1113         $self->assertTokenValue($self->getToken(), "inherit", __LINE__);
    1114         $self->parseIdentifiers();
    1115         return;
    1116     }
    1117     if ($next->type() == IdentifierToken) {
    1118         $self->assertTokenType($self->getToken(), IdentifierToken);
    1119         $self->parseIdentifiers();
    1120     }
    1121 }
    1122 
    1123 sub parseSerializationPatternList
    1124 {
    1125     my $self = shift;
    1126     my $next = $self->nextToken();
    1127     if ($next->value() eq "getter") {
    1128         $self->assertTokenValue($self->getToken(), "getter", __LINE__);
    1129         return;
    1130     }
    1131     if ($next->type() == IdentifierToken) {
    1132         $self->assertTokenType($self->getToken(), IdentifierToken);
    1133         $self->parseIdentifiers();
    1134     }
     1122        my @attributes = ();
     1123        my $token = $self->getToken();
     1124        $self->assertTokenType($token, IdentifierToken);
     1125        push(@attributes, $token->value());
     1126        return \@attributes;
     1127    }
     1128    $self->assertUnexpectedToken($next->value(), __LINE__);
     1129}
     1130
     1131sub parseSerializationAttributes
     1132{
     1133    my $self = shift;
     1134    my $token = $self->getToken();
     1135
     1136    if ($token->value() eq "getter") {
     1137        die "Serializer getter keyword is not currently supported.";
     1138
     1139    }
     1140    if ($token->value() eq "inherit") {
     1141        die "Serializer inherit keyword is not currently supported.";
     1142    }
     1143
     1144    my @attributes = ();
     1145    $self->assertTokenType($token, IdentifierToken);
     1146    push(@attributes, $token->value());
     1147    push(@attributes, @{$self->parseIdentifiers()});
     1148    return \@attributes;
    11351149}
    11361150
     
    22682282            next;
    22692283        }
     2284        if (ref($item) eq "domSerializable") {
     2285            $interface->serializable($item);
     2286            next;
     2287        }
     2288    }
     2289
     2290    if ($interface->serializable) {
     2291        my $numSerializerAttributes = @{$interface->serializable->attributes};
     2292        if ($numSerializerAttributes == 0) {
     2293            foreach my $attribute (@{$interface->attributes}) {
     2294                push(@{$interface->serializable->attributes}, $attribute->signature->name);
     2295            }
     2296        }
    22702297    }
    22712298}
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp

    r206390 r206514  
    2727#include "JSDOMIterator.h"
    2828#include "JSDOMPromise.h"
     29#include "ObjectConstructor.h"
    2930#include "RuntimeEnabledFeatures.h"
    3031#include "URL.h"
     
    4546JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionValues(JSC::ExecState*);
    4647JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionForEach(JSC::ExecState*);
     48JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionToJSON(JSC::ExecState*);
    4749
    4850// Attributes
     
    116118    { "values", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNodePrototypeFunctionValues), (intptr_t) (0) } },
    117119    { "forEach", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNodePrototypeFunctionForEach), (intptr_t) (1) } },
     120    { "toJSON", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNodePrototypeFunctionToJSON), (intptr_t) (0) } },
    118121};
    119122
     
    286289{
    287290    return iteratorForEach<JSTestNode>(*state, "forEach");
     291}
     292
     293EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionToJSON(ExecState* state)
     294{
     295    ASSERT(state);
     296    auto thisValue = state->thisValue();
     297    auto castedThis = jsDynamicCast<JSTestNode*>(thisValue);
     298    VM& vm = state->vm();
     299    auto throwScope = DECLARE_THROW_SCOPE(vm);
     300    if (UNLIKELY(!castedThis)){
     301        return throwThisTypeError(*state, throwScope, "TestNode", "toJSON");
     302    }
     303    ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestNode::info());
     304
     305    auto* result = constructEmptyObject(state);
     306    auto nameValue = jsTestNodeName(state, JSValue::encode(thisValue), Identifier());
     307    ASSERT(!throwScope.exception());
     308    result->putDirect(vm, Identifier::fromString(&vm, "name"), JSValue::decode(nameValue));
     309    return JSValue::encode(result);
    288310}
    289311
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp

    r206390 r206514  
    5252#include "JSTestSubObj.h"
    5353#include "JSXPathNSResolver.h"
     54#include "ObjectConstructor.h"
    5455#include "RuntimeEnabledFeatures.h"
    5556#include "SVGDocument.h"
     
    783784JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionAttachShadowRoot(JSC::ExecState*);
    784785JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionToString(JSC::ExecState*);
     786JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionToJSON(JSC::ExecState*);
    785787
    786788// Attributes
     
    13881390    { "attachShadowRoot", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionAttachShadowRoot), (intptr_t) (1) } },
    13891391    { "toString", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionToString), (intptr_t) (0) } },
     1392    { "toJSON", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionToJSON), (intptr_t) (0) } },
    13901393#if ENABLE(Condition1)
    13911394    { "CONDITIONAL_CONST", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
     
    73767379}
    73777380
     7381EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionToJSON(ExecState* state)
     7382{
     7383    ASSERT(state);
     7384    auto thisValue = state->thisValue();
     7385    auto castedThis = jsDynamicCast<JSTestObj*>(thisValue);
     7386    VM& vm = state->vm();
     7387    auto throwScope = DECLARE_THROW_SCOPE(vm);
     7388    if (UNLIKELY(!castedThis)){
     7389        return throwThisTypeError(*state, throwScope, "TestObj", "toJSON");
     7390    }
     7391    ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     7392
     7393    auto* result = constructEmptyObject(state);
     7394    auto readOnlyStringAttrValue = jsTestObjReadOnlyStringAttr(state, JSValue::encode(thisValue), Identifier());
     7395    ASSERT(!throwScope.exception());
     7396    result->putDirect(vm, Identifier::fromString(&vm, "readOnlyStringAttr"), JSValue::decode(readOnlyStringAttrValue));
     7397    auto enumAttrValue = jsTestObjEnumAttr(state, JSValue::encode(thisValue), Identifier());
     7398    ASSERT(!throwScope.exception());
     7399    result->putDirect(vm, Identifier::fromString(&vm, "enumAttr"), JSValue::decode(enumAttrValue));
     7400    auto longAttrValue = jsTestObjLongAttr(state, JSValue::encode(thisValue), Identifier());
     7401    ASSERT(!throwScope.exception());
     7402    result->putDirect(vm, Identifier::fromString(&vm, "longAttr"), JSValue::decode(longAttrValue));
     7403    auto createValue = jsTestObjCreate(state, JSValue::encode(thisValue), Identifier());
     7404    ASSERT(!throwScope.exception());
     7405    result->putDirect(vm, Identifier::fromString(&vm, "create"), JSValue::decode(createValue));
     7406    return JSValue::encode(result);
     7407}
     7408
    73787409void JSTestObj::visitChildren(JSCell* cell, SlotVisitor& visitor)
    73797410{
  • trunk/Source/WebCore/bindings/scripts/test/TestNode.idl

    r205953 r206514  
    2828    [EnabledAtRuntime=DOMIterator] iterable<TestNode>;
    2929    Promise testWorkerPromise();
     30
     31    serializer;
    3032};
  • trunk/Source/WebCore/bindings/scripts/test/TestObj.idl

    r206011 r206514  
    411411
    412412    stringifier attribute USVString stringifierAttribute;
     413
     414
     415    serializer = {readOnlyStringAttr, create, enumAttr, longAttr};
    413416};
    414417
Note: See TracChangeset for help on using the changeset viewer.