Changeset 206870 in webkit


Ignore:
Timestamp:
Oct 6, 2016 10:59:33 AM (8 years ago)
Author:
Yusuke Suzuki
Message:

[WebCore][JSC] Use new @throwTypeError and @throwRangeError intrinsics
https://bugs.webkit.org/show_bug.cgi?id=163001

Reviewed by Keith Miller.

Source/JavaScriptCore:

Previously, the argument of @throwXXXError intrinsics must be string literal.
But it is error-prone restriction. This patch relaxes the restriction to accept
arbitrary values. To keep emitted bytecode small, if the argument is string literal,
we generate the same bytecode as before. If the argument is not string literal,
we evaluate it and perform to_string before passing to throw_static_error.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitThrowStaticError):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwTypeError):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwRangeError):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

Source/WebCore:

Replace throw new @XXXError(...) to @throwXXXError intrinsic.
It reduces the size of bytecode sequence and facilitate inlining.

No behavior change.

  • Modules/fetch/FetchHeaders.js:

(initializeFetchHeaders):

  • Modules/fetch/FetchInternals.js:

(fillFetchHeaders):

  • Modules/fetch/FetchRequest.js:

(initializeFetchRequest):

  • Modules/fetch/FetchResponse.js:

(initializeFetchResponse):
(clone):

  • Modules/mediastream/NavigatorUserMedia.js:

(webkitGetUserMedia):

  • Modules/mediastream/RTCPeerConnection.js:

(initializeRTCPeerConnection):
(getLocalStreams):
(getStreamById):
(addStream):

  • Modules/streams/ReadableStream.js:

(initializeReadableStream):
(getReader):

  • Modules/streams/ReadableStreamDefaultController.js:

(enqueue):
(error):
(close):

  • Modules/streams/ReadableStreamDefaultReader.js:

(releaseLock):

  • Modules/streams/ReadableStreamInternals.js:

(privateInitializeReadableStreamDefaultReader):
(privateInitializeReadableStreamDefaultController):
(doStructuredClone):
(readableStreamError):

  • Modules/streams/StreamInternals.js:

(validateAndNormalizeQueuingStrategy):
(enqueueValueWithSize):

  • Modules/streams/WritableStream.js:

(initializeWritableStream):
(state):

  • xml/XMLHttpRequest.js:

(response):

Location:
trunk/Source
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r206853 r206870  
     12016-10-06  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [WebCore][JSC] Use new @throwTypeError and @throwRangeError intrinsics
     4        https://bugs.webkit.org/show_bug.cgi?id=163001
     5
     6        Reviewed by Keith Miller.
     7
     8        Previously, the argument of @throwXXXError intrinsics must be string literal.
     9        But it is error-prone restriction. This patch relaxes the restriction to accept
     10        arbitrary values. To keep emitted bytecode small, if the argument is string literal,
     11        we generate the same bytecode as before. If the argument is not string literal,
     12        we evaluate it and perform to_string before passing to throw_static_error.
     13
     14        * bytecompiler/BytecodeGenerator.cpp:
     15        (JSC::BytecodeGenerator::emitThrowStaticError):
     16        * bytecompiler/BytecodeGenerator.h:
     17        * bytecompiler/NodesCodegen.cpp:
     18        (JSC::BytecodeIntrinsicNode::emit_intrinsic_throwTypeError):
     19        (JSC::BytecodeIntrinsicNode::emit_intrinsic_throwRangeError):
     20        * dfg/DFGByteCodeParser.cpp:
     21        (JSC::DFG::ByteCodeParser::parseBlock):
     22
    1232016-10-05  Yusuke Suzuki  <utatane.tea@gmail.com>
    224
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r206853 r206870  
    39063906}
    39073907
     3908void BytecodeGenerator::emitThrowStaticError(ErrorType errorType, RegisterID* raw)
     3909{
     3910    RefPtr<RegisterID> message = newTemporary();
     3911    emitToString(message.get(), raw);
     3912    emitOpcode(op_throw_static_error);
     3913    instructions().append(message->index());
     3914    instructions().append(static_cast<unsigned>(errorType));
     3915}
     3916
    39083917void BytecodeGenerator::emitThrowStaticError(ErrorType errorType, const Identifier& message)
    39093918{
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r206853 r206870  
    663663        }
    664664
     665        void emitThrowStaticError(ErrorType, RegisterID*);
    665666        void emitThrowStaticError(ErrorType, const Identifier& message);
    666667        void emitThrowReferenceError(const String& message);
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r206853 r206870  
    902902{
    903903    ArgumentListNode* node = m_args->m_listNode;
    904     ASSERT(node->m_expr->isString());
    905     const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
    906904    ASSERT(!node->m_next);
    907 
    908     generator.emitThrowTypeError(ident);
     905    if (node->m_expr->isString()) {
     906        const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
     907        generator.emitThrowTypeError(ident);
     908    } else {
     909        RefPtr<RegisterID> message = generator.emitNode(node);
     910        generator.emitThrowStaticError(ErrorType::TypeError, message.get());
     911    }
    909912    return dst;
    910913}
     
    913916{
    914917    ArgumentListNode* node = m_args->m_listNode;
    915     ASSERT(node->m_expr->isString());
    916     const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
    917918    ASSERT(!node->m_next);
    918 
    919     generator.emitThrowRangeError(ident);
     919    if (node->m_expr->isString()) {
     920        const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
     921        generator.emitThrowRangeError(ident);
     922    } else {
     923        RefPtr<RegisterID> message = generator.emitNode(node);
     924        generator.emitThrowStaticError(ErrorType::RangeError, message.get());
     925    }
     926
    920927    return dst;
    921928}
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r206853 r206870  
    46614661           
    46624662        case op_throw_static_error:
     4663            addToGraph(Phantom, get(VirtualRegister(currentInstruction[1].u.operand))); // Keep argument live.
    46634664            addToGraph(ThrowStaticError);
    46644665            flushForTerminal();
  • trunk/Source/WebCore/ChangeLog

    r206869 r206870  
     12016-10-06  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [WebCore][JSC] Use new @throwTypeError and @throwRangeError intrinsics
     4        https://bugs.webkit.org/show_bug.cgi?id=163001
     5
     6        Reviewed by Keith Miller.
     7
     8        Replace `throw new @XXXError(...)` to @throwXXXError intrinsic.
     9        It reduces the size of bytecode sequence and facilitate inlining.
     10
     11        No behavior change.
     12
     13        * Modules/fetch/FetchHeaders.js:
     14        (initializeFetchHeaders):
     15        * Modules/fetch/FetchInternals.js:
     16        (fillFetchHeaders):
     17        * Modules/fetch/FetchRequest.js:
     18        (initializeFetchRequest):
     19        * Modules/fetch/FetchResponse.js:
     20        (initializeFetchResponse):
     21        (clone):
     22        * Modules/mediastream/NavigatorUserMedia.js:
     23        (webkitGetUserMedia):
     24        * Modules/mediastream/RTCPeerConnection.js:
     25        (initializeRTCPeerConnection):
     26        (getLocalStreams):
     27        (getStreamById):
     28        (addStream):
     29        * Modules/streams/ReadableStream.js:
     30        (initializeReadableStream):
     31        (getReader):
     32        * Modules/streams/ReadableStreamDefaultController.js:
     33        (enqueue):
     34        (error):
     35        (close):
     36        * Modules/streams/ReadableStreamDefaultReader.js:
     37        (releaseLock):
     38        * Modules/streams/ReadableStreamInternals.js:
     39        (privateInitializeReadableStreamDefaultReader):
     40        (privateInitializeReadableStreamDefaultController):
     41        (doStructuredClone):
     42        (readableStreamError):
     43        * Modules/streams/StreamInternals.js:
     44        (validateAndNormalizeQueuingStrategy):
     45        (enqueueValueWithSize):
     46        * Modules/streams/WritableStream.js:
     47        (initializeWritableStream):
     48        (state):
     49        * xml/XMLHttpRequest.js:
     50        (response):
     51
    1522016-10-06  John Wilander  <wilander@apple.com>
    253
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.js

    r203445 r206870  
    3434
    3535    if (!@isObject(headersInit))
    36         throw new @TypeError("headersInit must be an object");
     36        @throwTypeError("headersInit must be an object");
    3737
    3838    @fillFetchHeaders(this, headersInit);
  • trunk/Source/WebCore/Modules/fetch/FetchInternals.js

    r206814 r206870  
    4040            let header = headersInit[i];
    4141            if (header.length !== 2)
    42                 throw new @TypeError("headersInit sequence items should contain two values");
     42                @throwTypeError("headersInit sequence items should contain two values");
    4343            @Headers.prototype.@appendFromJS.@call(headers, header[0], header[1]);
    4444        }
  • trunk/Source/WebCore/Modules/fetch/FetchRequest.js

    r203675 r206870  
    3333        init = { };
    3434    else if (!@isObject(init))
    35         throw new @TypeError("Request init must be an object");
     35        @throwTypeError("Request init must be an object");
    3636
    3737    let headers = this.@initializeWith(input, init);
  • trunk/Source/WebCore/Modules/fetch/FetchResponse.js

    r206814 r206870  
    3333        init = { };
    3434    else if (!@isObject(init))
    35         throw new @TypeError("Response init must be an object");
     35        @throwTypeError("Response init must be an object");
    3636
    3737    let status = (init.status !== @undefined) ? @toNumber(init.status) : 200;
    3838    if (status < 200  || status > 599)
    39         throw new @RangeError("Status must be between 200 and 599");
     39        @throwRangeError("Status must be between 200 and 599");
    4040
    4141    let statusText = (init.statusText !== @undefined) ? init.statusText : "OK";
     
    4848    if (body !== @undefined && body !== null) {
    4949        if (status == 101 || status == 204 || status == 205 || status == 304)
    50             throw new @TypeError("Response cannot have a body with the given status");
     50            @throwTypeError("Response cannot have a body with the given status");
    5151
    5252        // FIXME: Use @isReadableStream once it is no longer guarded by READABLE_STREAM_API guard.
     
    9696
    9797    if (@Response.prototype.@isDisturbed.@call(this) || (this.@body && @isReadableStreamLocked(this.@body)))
    98         throw new @TypeError("Cannot clone a disturbed Response");
     98        @throwTypeError("Cannot clone a disturbed Response");
    9999
    100100    var cloned = @Response.prototype.@cloneForJS.@call(this);
  • trunk/Source/WebCore/Modules/mediastream/NavigatorUserMedia.js

    r206011 r206870  
    3535
    3636    if (arguments.length < 3)
    37         throw new @TypeError("Not enough arguments");
     37        @throwTypeError("Not enough arguments");
    3838
    3939    if (options !== @Object(options))
    40         throw new @TypeError("Argument 1 (options) to Navigator.webkitGetUserMedia must be an object");
     40        @throwTypeError("Argument 1 (options) to Navigator.webkitGetUserMedia must be an object");
    4141
    4242    if (typeof successCallback !== "function")
    43         throw new @TypeError("Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function");
     43        @throwTypeError("Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function");
    4444    if (typeof errorCallback !== "function")
    45         throw new @TypeError("Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function");
     45        @throwTypeError("Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function");
    4646
    4747    this.mediaDevices.@getUserMedia(options).@then(successCallback, errorCallback);
  • trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.js

    r202810 r206870  
    3636
    3737    if (arguments.length < 1)
    38         throw new @TypeError("Not enough arguments");
     38        @throwTypeError("Not enough arguments");
    3939
    4040    if (!@isObject(configuration))
    41         throw new @TypeError("RTCPeerConnection argument must be a valid Dictionary");
     41        @throwTypeError("RTCPeerConnection argument must be a valid Dictionary");
    4242
    4343    // FIXME: Handle errors in a better way than catching and re-throwing (http://webkit.org/b/158936)
     
    4747        const message = e.name === "TypeMismatchError" ? "Invalid RTCPeerConnection constructor arguments"
    4848            : "Error creating RTCPeerConnection";
    49         throw new @TypeError(message);
     49        @throwTypeError(message);
    5050    }
    5151
     
    6161
    6262    if (!@isRTCPeerConnection(this))
    63         throw new @TypeError("Function should be called on an RTCPeerConnection");
     63        @throwTypeError("Function should be called on an RTCPeerConnection");
    6464
    6565    return this.@localStreams.slice();
     
    7171
    7272    if (!@isRTCPeerConnection(this))
    73         throw new @TypeError("Function should be called on an RTCPeerConnection");
    74 
    75     if (arguments.length < 1)
    76         throw new @TypeError("Not enough arguments");
     73        @throwTypeError("Function should be called on an RTCPeerConnection");
     74
     75    if (arguments.length < 1)
     76        @throwTypeError("Not enough arguments");
    7777
    7878    const streamId = @String(streamIdArg);
     
    8888
    8989    if (!@isRTCPeerConnection(this))
    90         throw new @TypeError("Function should be called on an RTCPeerConnection");
    91 
    92     if (arguments.length < 1)
    93         throw new @TypeError("Not enough arguments");
     90        @throwTypeError("Function should be called on an RTCPeerConnection");
     91
     92    if (arguments.length < 1)
     93        @throwTypeError("Not enough arguments");
    9494
    9595    if (!(stream instanceof @MediaStream))
    96         throw new @TypeError("Argument 1 ('stream') to RTCPeerConnection.addStream must be an instance of MediaStream");
     96        @throwTypeError("Argument 1 ('stream') to RTCPeerConnection.addStream must be an instance of MediaStream");
    9797
    9898    if (this.@localStreams.find(localStream => localStream.id === stream.id))
     
    108108
    109109    if (!@isRTCPeerConnection(this))
    110         throw new @TypeError("Function should be called on an RTCPeerConnection");
    111 
    112     if (arguments.length < 1)
    113         throw new @TypeError("Not enough arguments");
     110        @throwTypeError("Function should be called on an RTCPeerConnection");
     111
     112    if (arguments.length < 1)
     113        @throwTypeError("Not enough arguments");
    114114
    115115    if (!(stream instanceof @MediaStream))
    116         throw new @TypeError("Argument 1 ('stream') to RTCPeerConnection.removeStream must be an instance of MediaStream");
     116        @throwTypeError("Argument 1 ('stream') to RTCPeerConnection.removeStream must be an instance of MediaStream");
    117117
    118118    const indexOfStreamToRemove = this.@localStreams.findIndex(localStream => localStream.id === stream.id);
  • trunk/Source/WebCore/Modules/streams/ReadableStream.js

    r206814 r206870  
    3737
    3838    if (!@isObject(underlyingSource))
    39         throw new @TypeError("ReadableStream constructor takes an object as first argument");
     39        @throwTypeError("ReadableStream constructor takes an object as first argument");
    4040
    4141    if (strategy !== @undefined && !@isObject(strategy))
    42         throw new @TypeError("ReadableStream constructor takes an object as second argument, if any");
     42        @throwTypeError("ReadableStream constructor takes an object as second argument, if any");
    4343
    4444    this.@state = @streamReadable;
     
    5454    if (typeString === "bytes") {
    5555         // FIXME: Implement support of ReadableByteStreamController.
    56         throw new @TypeError("ReadableByteStreamController is not implemented");
     56        @throwTypeError("ReadableByteStreamController is not implemented");
    5757    } else if (type === @undefined) {
    5858        if (strategy.highWaterMark === @undefined)
     
    6060        this.@readableStreamController = new @ReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark);
    6161    } else
    62         throw new @RangeError("Invalid type for underlying source");
     62        @throwRangeError("Invalid type for underlying source");
    6363
    6464    return this;
     
    9090    if (options.mode === 'byob') {
    9191        // FIXME: Update once ReadableByteStreamContoller and ReadableStreamBYOBReader are implemented.
    92         throw new @TypeError("ReadableStreamBYOBReader is not implemented");
     92        @throwTypeError("ReadableStreamBYOBReader is not implemented");
    9393    }
    9494
     
    9696        return new @ReadableStreamDefaultReader(this);
    9797
    98     throw new @RangeError("Invalid mode is specified");
     98    @throwRangeError("Invalid mode is specified");
    9999}
    100100
  • trunk/Source/WebCore/Modules/streams/ReadableStreamDefaultController.js

    r206814 r206870  
    3434
    3535    if (this.@closeRequested)
    36         throw new @TypeError("ReadableStreamDefaultController is requested to close");
     36        @throwTypeError("ReadableStreamDefaultController is requested to close");
    3737
    3838    if (this.@controlledReadableStream.@state !== @streamReadable)
    39         throw new @TypeError("ReadableStream is not readable");
     39        @throwTypeError("ReadableStream is not readable");
    4040
    4141    return @readableStreamDefaultControllerEnqueue(this, chunk);
     
    5151    const stream = this.@controlledReadableStream;
    5252    if (stream.@state !== @streamReadable)
    53         throw new @TypeError("ReadableStream is not readable");
     53        @throwTypeError("ReadableStream is not readable");
    5454
    5555    @readableStreamError(stream, error);
     
    6464
    6565    if (this.@closeRequested)
    66         throw new @TypeError("ReadableStreamDefaultController is already requested to close");
     66        @throwTypeError("ReadableStreamDefaultController is already requested to close");
    6767
    6868    if (this.@controlledReadableStream.@state !== @streamReadable)
    69         throw new @TypeError("ReadableStream is not readable");
     69        @throwTypeError("ReadableStream is not readable");
    7070
    7171    @readableStreamDefaultControllerClose(this);
  • trunk/Source/WebCore/Modules/streams/ReadableStreamDefaultReader.js

    r206814 r206870  
    6363
    6464    if (this.@readRequests.length)
    65         throw new @TypeError("There are still pending read requests, cannot release the lock");
     65        @throwTypeError("There are still pending read requests, cannot release the lock");
    6666
    6767    if (stream.@state === @streamReadable)
  • trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js

    r206814 r206870  
    3333
    3434    if (!@isReadableStream(stream))
    35        throw new @TypeError("ReadableStreamDefaultReader needs a ReadableStream");
     35       @throwTypeError("ReadableStreamDefaultReader needs a ReadableStream");
    3636    if (@isReadableStreamLocked(stream))
    37        throw new @TypeError("ReadableStream is locked");
     37       @throwTypeError("ReadableStream is locked");
    3838
    3939    this.@readRequests = [];
     
    5959
    6060    if (!@isReadableStream(stream))
    61         throw new @TypeError("ReadableStreamDefaultController needs a ReadableStream");
     61        @throwTypeError("ReadableStreamDefaultController needs a ReadableStream");
    6262
    6363    // readableStreamController is initialized with null value.
    6464    if (stream.@readableStreamController !== null)
    65         throw new @TypeError("ReadableStream already has a controller");
     65        @throwTypeError("ReadableStream already has a controller");
    6666
    6767    this.@controlledReadableStream = stream;
     
    158158        return @structuredCloneArrayBufferView(object);
    159159
    160     throw new @TypeError("structuredClone not implemented for: " + object);
     160    @throwTypeError("structuredClone not implemented for: " + object);
    161161}
    162162
     
    270270    } else
    271271        // FIXME: Implement ReadableStreamBYOBReader.
    272         throw new @TypeError("Only ReadableStreamDefaultReader is currently supported");
     272        @throwTypeError("Only ReadableStreamDefaultReader is currently supported");
    273273
    274274    reader.@closedPromiseCapability.@reject.@call(@undefined, error);
  • trunk/Source/WebCore/Modules/streams/StreamInternals.js

    r205549 r206870  
    8080
    8181    if (size !== @undefined && typeof size !== "function")
    82         throw new @TypeError("size parameter must be a function");
     82        @throwTypeError("size parameter must be a function");
    8383
    8484    const normalizedStrategy = { };
     
    8888
    8989    if (@isNaN(normalizedStrategy.highWaterMark) || normalizedStrategy.highWaterMark < 0)
    90         throw new @RangeError("highWaterMark value is negative or not a number");
     90        @throwRangeError("highWaterMark value is negative or not a number");
    9191
    9292    return normalizedStrategy;
     
    115115    size = @Number(size);
    116116    if (!@isFinite(size) || size < 0)
    117         throw new @RangeError("size has an incorrect value");
     117        @throwRangeError("size has an incorrect value");
    118118    queue.content.@push({ value: value, size: size });
    119119    queue.size += size;
  • trunk/Source/WebCore/Modules/streams/WritableStream.js

    r205549 r206870  
    3737
    3838    if (!@isObject(underlyingSink))
    39         throw new @TypeError("WritableStream constructor takes an object as first argument");
     39        @throwTypeError("WritableStream constructor takes an object as first argument");
    4040
    4141    if (!@isObject(strategy))
    42         throw new @TypeError("WritableStream constructor takes an object as second argument, if any");
     42        @throwTypeError("WritableStream constructor takes an object as second argument, if any");
    4343
    4444    this.@underlyingSink = underlyingSink;
     
    171171
    172172    if (!@isWritableStream(this))
    173         throw new @TypeError("The WritableStream.state getter can only be used on instances of WritableStream");
     173        @throwTypeError("The WritableStream.state getter can only be used on instances of WritableStream");
    174174
    175175    switch(this.@state) {
  • trunk/Source/WebCore/xml/XMLHttpRequest.js

    r203494 r206870  
    3030    // FIXME: Add a helper routine for that kind of checks.
    3131    if (!(this instanceof @XMLHttpRequest))
    32         throw new @TypeError("The XMLHttpRequest.response getter can only be used on instances of XMLHttpRequest");
     32        @throwTypeError("The XMLHttpRequest.response getter can only be used on instances of XMLHttpRequest");
    3333
    3434    if (@XMLHttpRequest.prototype.@responseCacheIsValid.@call(this))
Note: See TracChangeset for help on using the changeset viewer.