[JSC] Add @throwXXXError bytecode intrinsic
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Oct 2016 07:44:23 +0000 (07:44 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Oct 2016 07:44:23 +0000 (07:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162995

Reviewed by Saam Barati.

Source/JavaScriptCore:

Builtin JS code need to check arguments carefully since it is somewhat standard library for JS.
So bunch of `throw new @TypeError("...")` exists while usual code does not have so many.
However the above code bloats 32 instructions per site, enlarges the size of bytecodes of builtins,
and prevent us from inlining. We should have a way to reduce this size.

Fortunately, we already have such a opcode: op_throw_static_error. In this patch,
1. We extends op_throw_static_error to throw arbitrary errors. Previously, only TypeError and ReferenceError are allowed.
   We can embed ErrorType enum in op_throw_static_error to throw any types of errors.
2. We introduce several new bytecode intrinsics, `@throwTypeError("...")`, `@throwRangeError("...")`,
   and `@throwOutOfMemoryError()`. And use it inside builtin JS instead of `throw new @TypeError("...")` thingy.
3. DFG Node for throw_static_error is incorrectly named as "ThrowReferenceError". This patch renames it to "ThrowStaticError".

* builtins/ArrayConstructor.js:
* builtins/ArrayIteratorPrototype.js:
(next):
* builtins/ArrayPrototype.js:
(values):
(keys):
(entries):
(reduce):
(reduceRight):
(every):
(forEach):
(filter):
(map):
(some):
(fill):
(find):
(findIndex):
(includes):
(sort):
(concatSlowPath):
(copyWithin):
* builtins/DatePrototype.js:
(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):
(toLocaleDateString.toDateTimeOptionsDateDate):
(toLocaleDateString):
(toLocaleTimeString.toDateTimeOptionsTimeTime):
(toLocaleTimeString):
* builtins/FunctionPrototype.js:
(bind):
* builtins/GeneratorPrototype.js:
(globalPrivate.generatorResume):
* builtins/GlobalOperations.js:
(globalPrivate.speciesConstructor):
* builtins/MapPrototype.js:
(forEach):
* builtins/ModuleLoaderPrototype.js:
(provide):
* builtins/ObjectConstructor.js:
(values):
(entries):
(assign):
* builtins/PromiseConstructor.js:
(race):
(reject):
(resolve):
* builtins/PromiseOperations.js:
(globalPrivate.newPromiseCapability.executor):
(globalPrivate.newPromiseCapability):
(globalPrivate.initializePromise):
* builtins/PromisePrototype.js:
* builtins/ReflectObject.js:
(apply):
(deleteProperty):
(has):
* builtins/RegExpPrototype.js:
(globalPrivate.regExpExec):
(match):
(replace):
(search):
(split):
(intrinsic.RegExpTestIntrinsic.test):
* builtins/SetPrototype.js:
(forEach):
* builtins/StringConstructor.js:
(raw):
* builtins/StringIteratorPrototype.js:
(next):
* builtins/StringPrototype.js:
(match):
(globalPrivate.repeatSlowPath):
(repeat):
(padStart):
(padEnd):
(intrinsic.StringPrototypeReplaceIntrinsic.replace):
(localeCompare):
(search):
(split):
* builtins/TypedArrayConstructor.js:
(of):
(from):
* builtins/TypedArrayPrototype.js:
(globalPrivate.typedArraySpeciesConstructor):
(every):
(find):
(findIndex):
(forEach):
(some):
(subarray):
(reduce):
(reduceRight):
(map):
(filter):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitThrowStaticError):
(JSC::BytecodeGenerator::emitThrowReferenceError):
(JSC::BytecodeGenerator::emitThrowTypeError):
(JSC::BytecodeGenerator::emitThrowRangeError):
(JSC::BytecodeGenerator::emitThrowOutOfMemoryError):
(JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwTypeError):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwRangeError):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwOutOfMemoryError):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw_static_error):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw_static_error): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL): Deleted.
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/Error.cpp:
(JSC::createError):
(WTF::printInternal):
* runtime/Error.h:

LayoutTests:

* js/Object-assign-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206853 268f45cc-cd09-0410-ab3c-d52691b4dbfc

52 files changed:
LayoutTests/ChangeLog
LayoutTests/js/Object-assign-expected.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/ArrayConstructor.js
Source/JavaScriptCore/builtins/ArrayIteratorPrototype.js
Source/JavaScriptCore/builtins/ArrayPrototype.js
Source/JavaScriptCore/builtins/DatePrototype.js
Source/JavaScriptCore/builtins/FunctionPrototype.js
Source/JavaScriptCore/builtins/GeneratorPrototype.js
Source/JavaScriptCore/builtins/GlobalOperations.js
Source/JavaScriptCore/builtins/MapPrototype.js
Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js
Source/JavaScriptCore/builtins/ObjectConstructor.js
Source/JavaScriptCore/builtins/PromiseConstructor.js
Source/JavaScriptCore/builtins/PromiseOperations.js
Source/JavaScriptCore/builtins/PromisePrototype.js
Source/JavaScriptCore/builtins/ReflectObject.js
Source/JavaScriptCore/builtins/RegExpPrototype.js
Source/JavaScriptCore/builtins/SetPrototype.js
Source/JavaScriptCore/builtins/StringConstructor.js
Source/JavaScriptCore/builtins/StringIteratorPrototype.js
Source/JavaScriptCore/builtins/StringPrototype.js
Source/JavaScriptCore/builtins/TypedArrayConstructor.js
Source/JavaScriptCore/builtins/TypedArrayPrototype.js
Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.h
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/Error.h

index 14ae879..8986fa7 100644 (file)
@@ -1,3 +1,12 @@
+2016-10-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] Add @throwXXXError bytecode intrinsic
+        https://bugs.webkit.org/show_bug.cgi?id=162995
+
+        Reviewed by Saam Barati.
+
+        * js/Object-assign-expected.txt:
+
 2016-10-05  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Introduce InputEvent bindings in preparation for the input events spec
index cbd7ccc..362eb21 100644 (file)
@@ -6,9 +6,9 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS Object.assign.length is 2
 PASS Object.assign.name is 'assign'
 check TypeError on null/undefined
-PASS Object.assign() threw exception TypeError: can't convert undefined to object.
-PASS Object.assign(undefined) threw exception TypeError: can't convert undefined to object.
-PASS Object.assign(null) threw exception TypeError: can't convert null to object.
+PASS Object.assign() threw exception TypeError: Object.assign requires that input parameter not be null or undefined.
+PASS Object.assign(undefined) threw exception TypeError: Object.assign requires that input parameter not be null or undefined.
+PASS Object.assign(null) threw exception TypeError: Object.assign requires that input parameter not be null or undefined.
 PASS var target = {}, ret = Object.assign(target); target === ret is true
 multiple sources are copied
 PASS var target = {}, ret = Object.assign(target, {a: 1}); target === ret is true
index ad4381c..71a7d09 100644 (file)
@@ -1,5 +1,172 @@
 2016-10-05  Yusuke Suzuki  <utatane.tea@gmail.com>
 
+        [JSC] Add @throwXXXError bytecode intrinsic
+        https://bugs.webkit.org/show_bug.cgi?id=162995
+
+        Reviewed by Saam Barati.
+
+        Builtin JS code need to check arguments carefully since it is somewhat standard library for JS.
+        So bunch of `throw new @TypeError("...")` exists while usual code does not have so many.
+        However the above code bloats 32 instructions per site, enlarges the size of bytecodes of builtins,
+        and prevent us from inlining. We should have a way to reduce this size.
+
+        Fortunately, we already have such a opcode: op_throw_static_error. In this patch,
+        1. We extends op_throw_static_error to throw arbitrary errors. Previously, only TypeError and ReferenceError are allowed.
+           We can embed ErrorType enum in op_throw_static_error to throw any types of errors.
+        2. We introduce several new bytecode intrinsics, `@throwTypeError("...")`, `@throwRangeError("...")`,
+           and `@throwOutOfMemoryError()`. And use it inside builtin JS instead of `throw new @TypeError("...")` thingy.
+        3. DFG Node for throw_static_error is incorrectly named as "ThrowReferenceError". This patch renames it to "ThrowStaticError".
+
+        * builtins/ArrayConstructor.js:
+        * builtins/ArrayIteratorPrototype.js:
+        (next):
+        * builtins/ArrayPrototype.js:
+        (values):
+        (keys):
+        (entries):
+        (reduce):
+        (reduceRight):
+        (every):
+        (forEach):
+        (filter):
+        (map):
+        (some):
+        (fill):
+        (find):
+        (findIndex):
+        (includes):
+        (sort):
+        (concatSlowPath):
+        (copyWithin):
+        * builtins/DatePrototype.js:
+        (toLocaleString.toDateTimeOptionsAnyAll):
+        (toLocaleString):
+        (toLocaleDateString.toDateTimeOptionsDateDate):
+        (toLocaleDateString):
+        (toLocaleTimeString.toDateTimeOptionsTimeTime):
+        (toLocaleTimeString):
+        * builtins/FunctionPrototype.js:
+        (bind):
+        * builtins/GeneratorPrototype.js:
+        (globalPrivate.generatorResume):
+        * builtins/GlobalOperations.js:
+        (globalPrivate.speciesConstructor):
+        * builtins/MapPrototype.js:
+        (forEach):
+        * builtins/ModuleLoaderPrototype.js:
+        (provide):
+        * builtins/ObjectConstructor.js:
+        (values):
+        (entries):
+        (assign):
+        * builtins/PromiseConstructor.js:
+        (race):
+        (reject):
+        (resolve):
+        * builtins/PromiseOperations.js:
+        (globalPrivate.newPromiseCapability.executor):
+        (globalPrivate.newPromiseCapability):
+        (globalPrivate.initializePromise):
+        * builtins/PromisePrototype.js:
+        * builtins/ReflectObject.js:
+        (apply):
+        (deleteProperty):
+        (has):
+        * builtins/RegExpPrototype.js:
+        (globalPrivate.regExpExec):
+        (match):
+        (replace):
+        (search):
+        (split):
+        (intrinsic.RegExpTestIntrinsic.test):
+        * builtins/SetPrototype.js:
+        (forEach):
+        * builtins/StringConstructor.js:
+        (raw):
+        * builtins/StringIteratorPrototype.js:
+        (next):
+        * builtins/StringPrototype.js:
+        (match):
+        (globalPrivate.repeatSlowPath):
+        (repeat):
+        (padStart):
+        (padEnd):
+        (intrinsic.StringPrototypeReplaceIntrinsic.replace):
+        (localeCompare):
+        (search):
+        (split):
+        * builtins/TypedArrayConstructor.js:
+        (of):
+        (from):
+        * builtins/TypedArrayPrototype.js:
+        (globalPrivate.typedArraySpeciesConstructor):
+        (every):
+        (find):
+        (findIndex):
+        (forEach):
+        (some):
+        (subarray):
+        (reduce):
+        (reduceRight):
+        (map):
+        (filter):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitThrowStaticError):
+        (JSC::BytecodeGenerator::emitThrowReferenceError):
+        (JSC::BytecodeGenerator::emitThrowTypeError):
+        (JSC::BytecodeGenerator::emitThrowRangeError):
+        (JSC::BytecodeGenerator::emitThrowOutOfMemoryError):
+        (JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_throwTypeError):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_throwRangeError):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_throwOutOfMemoryError):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_throw_static_error):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_throw_static_error): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL): Deleted.
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/Error.cpp:
+        (JSC::createError):
+        (WTF::printInternal):
+        * runtime/Error.h:
+
+2016-10-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
         Unreviewed, attempt to fix CLoop build after r206846
         https://bugs.webkit.org/show_bug.cgi?id=162941
 
index 975da4a..d159eb2 100644 (file)
@@ -47,19 +47,19 @@ function from(items /*, mapFn, thisArg */)
 
     if (mapFn !== @undefined) {
         if (typeof mapFn !== "function")
-            throw new @TypeError("Array.from requires that the second argument, when provided, be a function");
+            @throwTypeError("Array.from requires that the second argument, when provided, be a function");
 
         if (arguments.length > 2)
             thisArg = arguments[2];
     }
 
     if (items == null)
-        throw new @TypeError("Array.from requires an array-like object - not null or undefined");
+        @throwTypeError("Array.from requires an array-like object - not null or undefined");
 
     var iteratorMethod = items.@iteratorSymbol;
     if (iteratorMethod != null) {
         if (typeof iteratorMethod !== "function")
-            throw new @TypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
+            @throwTypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
 
         var result = @isConstructor(thisObj) ? new thisObj() : [];
 
index 03bcaa6..92640f7 100644 (file)
@@ -29,11 +29,11 @@ function next()
     "use strict";
 
     if (this == null)
-        throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined");
+        @throwTypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined");
 
     let next = this.@arrayIteratorNext;
     if (next === @undefined)
-        throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance");
+        @throwTypeError("%ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance");
 
     return next.@call(this);
 }
index 09d6448..75a7a58 100644 (file)
@@ -40,7 +40,7 @@ function values()
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.values requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.values requires that |this| not be null or undefined");
 
     return new @createArrayIterator(@Object(this), "value", @arrayIteratorValueNext);
 }
@@ -50,7 +50,7 @@ function keys()
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.keys requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.keys requires that |this| not be null or undefined");
 
     return new @createArrayIterator(@Object(this), "key", @arrayIteratorKeyNext);
 }
@@ -60,7 +60,7 @@ function entries()
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.entries requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.entries requires that |this| not be null or undefined");
 
     return new @createArrayIterator(@Object(this), "key+value", @arrayIteratorKeyValueNext);
 }
@@ -70,16 +70,16 @@ function reduce(callback /*, initialValue */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.reduce requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.reduce requires that |this| not be null or undefined");
 
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.reduce callback must be a function");
+        @throwTypeError("Array.prototype.reduce callback must be a function");
 
     if (length === 0 && arguments.length < 2)
-        throw new @TypeError("reduce of empty array with no initial value");
+        @throwTypeError("reduce of empty array with no initial value");
 
     var accumulator, k = 0;
     if (arguments.length > 1)
@@ -88,7 +88,7 @@ function reduce(callback /*, initialValue */)
         while (k < length && !(k in array))
             k += 1;
         if (k >= length)
-            throw new @TypeError("reduce of empty array with no initial value");
+            @throwTypeError("reduce of empty array with no initial value");
         accumulator = array[k++];
     }
 
@@ -105,16 +105,16 @@ function reduceRight(callback /*, initialValue */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.reduceRight requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.reduceRight requires that |this| not be null or undefined");
 
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.reduceRight callback must be a function");
+        @throwTypeError("Array.prototype.reduceRight callback must be a function");
 
     if (length === 0 && arguments.length < 2)
-        throw new @TypeError("reduceRight of empty array with no initial value");
+        @throwTypeError("reduceRight of empty array with no initial value");
 
     var accumulator, k = length - 1;
     if (arguments.length > 1)
@@ -123,7 +123,7 @@ function reduceRight(callback /*, initialValue */)
         while (k >= 0 && !(k in array))
             k -= 1;
         if (k < 0)
-            throw new @TypeError("reduceRight of empty array with no initial value");
+            @throwTypeError("reduceRight of empty array with no initial value");
         accumulator = array[k--];
     }
 
@@ -140,13 +140,13 @@ function every(callback /*, thisArg */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.every requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.every requires that |this| not be null or undefined");
     
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.every callback must be a function");
+        @throwTypeError("Array.prototype.every callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     
@@ -165,13 +165,13 @@ function forEach(callback /*, thisArg */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.forEach requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.forEach requires that |this| not be null or undefined");
     
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.forEach callback must be a function");
+        @throwTypeError("Array.prototype.forEach callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     
@@ -186,13 +186,13 @@ function filter(callback /*, thisArg */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.filter requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.filter requires that |this| not be null or undefined");
     
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.filter callback must be a function");
+        @throwTypeError("Array.prototype.filter callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
@@ -235,13 +235,13 @@ function map(callback /*, thisArg */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.map requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.map requires that |this| not be null or undefined");
     
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.map callback must be a function");
+        @throwTypeError("Array.prototype.map callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
@@ -281,13 +281,13 @@ function some(callback /*, thisArg */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.some requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.some requires that |this| not be null or undefined");
     
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.some callback must be a function");
+        @throwTypeError("Array.prototype.some callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     for (var i = 0; i < length; i++) {
@@ -304,7 +304,7 @@ function fill(value /* [, start [, end]] */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.fill requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.fill requires that |this| not be null or undefined");
 
     var array = @Object(this);
     var length = @toLength(array.length);
@@ -345,13 +345,13 @@ function find(callback /*, thisArg */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.find requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.find requires that |this| not be null or undefined");
     
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.find callback must be a function");
+        @throwTypeError("Array.prototype.find callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     for (var i = 0; i < length; i++) {
@@ -367,13 +367,13 @@ function findIndex(callback /*, thisArg */)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.findIndex requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.findIndex requires that |this| not be null or undefined");
     
     var array = @Object(this);
     var length = @toLength(array.length);
 
     if (typeof callback !== "function")
-        throw new @TypeError("Array.prototype.findIndex callback must be a function");
+        @throwTypeError("Array.prototype.findIndex callback must be a function");
     
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     for (var i = 0; i < length; i++) {
@@ -388,7 +388,7 @@ function includes(searchElement /*, fromIndex*/)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.includes requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.includes requires that |this| not be null or undefined");
 
     var array = @Object(this);
     var length = @toLength(array.length);
@@ -638,10 +638,10 @@ function sort(comparator)
     }
 
     if (this == null)
-        throw new @TypeError("Array.prototype.sort requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.sort requires that |this| not be null or undefined");
 
     if (typeof this == "string")
-        throw new @TypeError("Attempted to assign to readonly property.");
+        @throwTypeError("Attempted to assign to readonly property.");
 
     var array = @Object(this);
 
@@ -658,7 +658,7 @@ function concatSlowPath()
     "use strict";
 
     if (this == null)
-        throw new @TypeError("Array.prototype.concat requires that |this| not be null or undefined");
+        @throwTypeError("Array.prototype.concat requires that |this| not be null or undefined");
 
     var currentElement = @Object(this);
 
@@ -697,7 +697,7 @@ function concatSlowPath()
                 resultIndex += length;
             } else {
                 if (length + resultIndex > @MAX_SAFE_INTEGER)
-                    throw @TypeError("length exceeded the maximum safe integer");
+                    @throwTypeError("length exceeded the maximum safe integer");
                 for (var i = 0; i < length; i++) {
                     if (i in currentElement)
                         @putByValDirect(result, resultIndex, currentElement[i]);
@@ -706,7 +706,7 @@ function concatSlowPath()
             }
         } else {
             if (resultIndex >= @MAX_SAFE_INTEGER)
-                throw @TypeError("length exceeded the maximum safe integer");
+                @throwTypeError("length exceeded the maximum safe integer");
             @putByValDirect(result, resultIndex++, currentElement);
         }
         currentElement = arguments[argIndex];
@@ -748,7 +748,7 @@ function copyWithin(target, start /*, end */)
     }
 
     if (this == null)
-        throw new @TypeError("Array.copyWithin requires that |this| not be null or undefined");
+        @throwTypeError("Array.copyWithin requires that |this| not be null or undefined");
 
     var array = @Object(this);
     var length = @toLength(array.length);
index b49e75d..99afb26 100644 (file)
@@ -38,7 +38,7 @@ function toLocaleString(/* locales, options */)
         if (opts === @undefined)
             options = null;
         else if (opts === null)
-            throw new @TypeError("null is not an object");
+            @throwTypeError("null is not an object");
         else
             options = @Object(opts);
 
@@ -95,7 +95,7 @@ function toLocaleDateString(/* locales, options */)
         if (opts === @undefined)
             options = null;
         else if (opts === null)
-            throw new @TypeError("null is not an object");
+            @throwTypeError("null is not an object");
         else
             options = @Object(opts);
 
@@ -145,7 +145,7 @@ function toLocaleTimeString(/* locales, options */)
         if (opts === @undefined)
             options = null;
         else if (opts === null)
-            throw new @TypeError("null is not an object");
+            @throwTypeError("null is not an object");
         else
             options = @Object(opts);
 
index a55e0f3..879c902 100644 (file)
@@ -63,7 +63,7 @@ function bind(thisValue)
 
     let target = this;
     if (typeof target !== "function")
-        throw new @TypeError("|this| is not a function inside Function.prototype.bind");
+        @throwTypeError("|this| is not a function inside Function.prototype.bind");
 
     let argumentCount = arguments.length;
     let boundArgs = null;
index 499dbd3..4128a35 100644 (file)
@@ -36,10 +36,10 @@ function generatorResume(generator, sentValue, resumeMode)
     let value = @undefined;
 
     if (typeof state !== 'number')
-        throw new @TypeError("|this| should be a generator");
+        @throwTypeError("|this| should be a generator");
 
     if (state === @GeneratorStateExecuting)
-        throw new @TypeError("Generator is executing");
+        @throwTypeError("Generator is executing");
 
     if (state === @GeneratorStateCompleted) {
         if (resumeMode === @GeneratorResumeModeThrow)
index 4f6a7d1..22220cf 100644 (file)
@@ -71,11 +71,11 @@ function speciesConstructor(obj, defaultConstructor)
     if (constructor === @undefined)
         return defaultConstructor;
     if (!@isObject(constructor))
-        throw new @TypeError("|this|.constructor is not an Object or undefined");
+        @throwTypeError("|this|.constructor is not an Object or undefined");
     constructor = constructor.@speciesSymbol;
     if (constructor == null)
         return defaultConstructor;
     if (@isConstructor(constructor))
         return constructor;
-    throw new @TypeError("|this|.constructor[Symbol.species] is not a constructor");
+    @throwTypeError("|this|.constructor[Symbol.species] is not a constructor");
 }
index 620a015..79a6320 100644 (file)
@@ -28,10 +28,10 @@ function forEach(callback /*, thisArg */)
     "use strict";
 
     if (!@isMap(this))
-        throw new @TypeError("Map operation called on non-Map object");
+        @throwTypeError("Map operation called on non-Map object");
 
     if (typeof callback !== 'function')
-        throw new @TypeError("Map.prototype.forEach callback must be a function");
+        @throwTypeError("Map.prototype.forEach callback must be a function");
 
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     var iterator = @MapIterator(this);
index d4c7e05..0a98258 100644 (file)
@@ -481,14 +481,14 @@ function provide(key, stage, value)
 
     if (stage === @ModuleFetch) {
         if (entry.state > @ModuleFetch)
-            throw new @TypeError("Requested module is already fetched.");
+            @throwTypeError("Requested module is already fetched.");
         this.fulfillFetch(entry, value);
         return;
     }
 
     if (stage === @ModuleTranslate) {
         if (entry.state > @ModuleTranslate)
-            throw new @TypeError("Requested module is already translated.");
+            @throwTypeError("Requested module is already translated.");
         this.fulfillFetch(entry, @undefined);
         this.fulfillTranslate(entry, value);
         return;
@@ -496,7 +496,7 @@ function provide(key, stage, value)
 
     if (stage === @ModuleInstantiate) {
         if (entry.state > @ModuleInstantiate)
-            throw new @TypeError("Requested module is already instantiated.");
+            @throwTypeError("Requested module is already instantiated.");
         this.fulfillFetch(entry, @undefined);
         this.fulfillTranslate(entry, value);
         entry.translate.then((source) => {
@@ -505,7 +505,7 @@ function provide(key, stage, value)
         return;
     }
 
-    throw new @TypeError("Requested module is already ready to be executed.");
+    @throwTypeError("Requested module is already ready to be executed.");
 }
 
 function loadAndEvaluateModule(moduleName, referrer, initiator)
@@ -542,7 +542,7 @@ function linkAndEvaluateModule(key, initiator)
 
     var entry = this.ensureRegistered(key);
     if (entry.state < @ModuleLink)
-        throw new @TypeError("Requested module is not instantiated yet.");
+        @throwTypeError("Requested module is not instantiated yet.");
 
     this.link(entry, initiator);
     return this.moduleEvaluation(entry.module, initiator);
index d53744e..d855beb 100644 (file)
@@ -53,7 +53,7 @@ function values(object)
     "use strict";
     
     if (object == null)
-        throw new @TypeError("Object.values requires that input parameter not be null or undefined");
+        @throwTypeError("Object.values requires that input parameter not be null or undefined");
 
     return @enumerableOwnProperties(object, @iterationKindValue);
 }
@@ -63,7 +63,7 @@ function entries(object)
     "use strict";
     
     if (object == null)
-        throw new @TypeError("Object.entries requires that input parameter not be null or undefined");
+        @throwTypeError("Object.entries requires that input parameter not be null or undefined");
     
     return @enumerableOwnProperties(object, @iterationKindKeyValue);
 }
@@ -73,7 +73,7 @@ function assign(target/*[*/, /*...*/sources/*] */)
     "use strict";
 
     if (target == null)
-        throw new @TypeError("can't convert " + target + " to object");
+        @throwTypeError("Object.assign requires that input parameter not be null or undefined");
 
     let objTarget = @Object(target);
     for (let s = 1, argumentsLength = arguments.length; s < argumentsLength; ++s) {
index 8cf1999..3f0848d 100644 (file)
@@ -28,7 +28,7 @@ function all(iterable)
     "use strict";
 
     if (!@isObject(this))
-        throw new @TypeError("|this| is not a object");
+        @throwTypeError("|this| is not a object");
 
     var promiseCapability = @newPromiseCapability(this);
 
@@ -80,7 +80,7 @@ function race(iterable)
     "use strict";
 
     if (!@isObject(this))
-        throw new @TypeError("|this| is not a object");
+        @throwTypeError("|this| is not a object");
 
     var promiseCapability = @newPromiseCapability(this);
 
@@ -101,7 +101,7 @@ function reject(reason)
     "use strict";
 
     if (!@isObject(this))
-        throw new @TypeError("|this| is not a object");
+        @throwTypeError("|this| is not a object");
 
     var promiseCapability = @newPromiseCapability(this);
 
@@ -115,7 +115,7 @@ function resolve(value)
     "use strict";
 
     if (!@isObject(this))
-        throw new @TypeError("|this| is not a object");
+        @throwTypeError("|this| is not a object");
 
     if (@isPromise(value)) {
         var valueConstructor = value.constructor;
index 9ed8306..f4a09d4 100644 (file)
@@ -51,7 +51,7 @@ function newPromiseCapability(constructor)
     "use strict";
 
     if (!@isConstructor(constructor))
-        throw new @TypeError("promise capability requires a constructor function");
+        @throwTypeError("promise capability requires a constructor function");
 
     var promiseCapability = {
         @promise: @undefined,
@@ -62,9 +62,9 @@ function newPromiseCapability(constructor)
     function executor(resolve, reject)
     {
         if (promiseCapability.@resolve !== @undefined)
-            throw new @TypeError("resolve function is already set");
+            @throwTypeError("resolve function is already set");
         if (promiseCapability.@reject !== @undefined)
-            throw new @TypeError("reject function is already set");
+            @throwTypeError("reject function is already set");
 
         promiseCapability.@resolve = resolve;
         promiseCapability.@reject = reject;
@@ -73,10 +73,10 @@ function newPromiseCapability(constructor)
     var promise = new constructor(executor);
 
     if (typeof promiseCapability.@resolve !== "function")
-        throw new @TypeError("executor did not take a resolve function");
+        @throwTypeError("executor did not take a resolve function");
 
     if (typeof promiseCapability.@reject !== "function")
-        throw new @TypeError("executor did not take a reject function");
+        @throwTypeError("executor did not take a reject function");
 
     promiseCapability.@promise = promise;
 
@@ -208,7 +208,7 @@ function initializePromise(executor)
     "use strict";
 
     if (typeof executor !== 'function')
-        throw new @TypeError("Promise constructor takes a function argument");
+        @throwTypeError("Promise constructor takes a function argument");
 
     this.@promiseState = @promiseStatePending;
     this.@promiseFulfillReactions = [];
index 3ea992f..184955a 100644 (file)
@@ -35,7 +35,7 @@ function then(onFulfilled, onRejected)
     "use strict";
 
     if (!@isPromise(this))
-        throw new @TypeError("|this| is not a object");
+        @throwTypeError("|this| is not a object");
 
     var constructor = @speciesConstructor(this, @Promise);
 
index 46b752b..1aaa1f4 100644 (file)
@@ -29,10 +29,10 @@ function apply(target, thisArgument, argumentsList)
     "use strict";
 
     if (typeof target !== "function")
-        throw new @TypeError("Reflect.apply requires the first argument be a function");
+        @throwTypeError("Reflect.apply requires the first argument be a function");
 
     if (!@isObject(argumentsList))
-        throw new @TypeError("Reflect.apply requires the third argument be an object");
+        @throwTypeError("Reflect.apply requires the third argument be an object");
 
     return target.@apply(thisArgument, argumentsList);
 }
@@ -44,7 +44,7 @@ function deleteProperty(target, propertyKey)
     // raised by the delete operator under the strict mode.
 
     if (!@isObject(target))
-        throw new @TypeError("Reflect.deleteProperty requires the first argument be an object");
+        @throwTypeError("Reflect.deleteProperty requires the first argument be an object");
 
     return delete target[propertyKey];
 }
@@ -55,7 +55,7 @@ function has(target, propertyKey)
     "use strict";
 
     if (!@isObject(target))
-        throw new @TypeError("Reflect.has requires the first argument be an object");
+        @throwTypeError("Reflect.has requires the first argument be an object");
 
     return propertyKey in target;
 }
index 9d945a4..017a81c 100644 (file)
@@ -56,7 +56,7 @@ function regExpExec(regexp, str)
     if (exec !== builtinExec && typeof exec === "function") {
         let result = exec.@call(regexp, str);
         if (result !== null && !@isObject(result))
-            throw new @TypeError("The result of a RegExp exec must be null or an object");
+            @throwTypeError("The result of a RegExp exec must be null or an object");
         return result;
     }
     return builtinExec.@call(regexp, str);
@@ -84,7 +84,7 @@ function match(strArg)
     "use strict";
 
     if (!@isObject(this))
-        throw new @TypeError("RegExp.prototype.@@match requires that |this| be an Object");
+        @throwTypeError("RegExp.prototype.@@match requires that |this| be an Object");
 
     let regexp = this;
 
@@ -116,10 +116,10 @@ function match(strArg)
         }
 
         if (resultList.length > maximumReasonableMatchSize)
-            throw new @Error("Out of memory");
+            @throwOutOfMemoryError();
 
         if (!@isObject(result))
-            throw new @TypeError("RegExp.prototype.@@match call to RegExp.exec didn't return null or an object");
+            @throwTypeError("RegExp.prototype.@@match call to RegExp.exec didn't return null or an object");
 
         let resultString = @toString(result[0]);
 
@@ -208,7 +208,7 @@ function replace(strArg, replace)
     }
 
     if (!@isObject(this))
-        throw new @TypeError("RegExp.prototype.@@replace requires that |this| be an Object");
+        @throwTypeError("RegExp.prototype.@@replace requires that |this| be an Object");
 
     let regexp = this;
 
@@ -309,7 +309,7 @@ function search(strArg)
     // 1. Let rx be the this value.
     // 2. If Type(rx) is not Object, throw a TypeError exception.
     if (!@isObject(this))
-        throw new @TypeError("RegExp.prototype.@@search requires that |this| be an Object");
+        @throwTypeError("RegExp.prototype.@@search requires that |this| be an Object");
 
     // 3. Let S be ? ToString(string).
     let str = @toString(strArg)
@@ -374,7 +374,7 @@ function split(string, limit)
     // 1. Let rx be the this value.
     // 2. If Type(rx) is not Object, throw a TypeError exception.
     if (!@isObject(this))
-        throw new @TypeError("RegExp.prototype.@@split requires that |this| be an Object");
+        @throwTypeError("RegExp.prototype.@@split requires that |this| be an Object");
     let regexp = this;
 
     // 3. Let S be ? ToString(string).
@@ -514,7 +514,7 @@ function test(strArg)
     // 1. Let R be the this value.
     // 2. If Type(R) is not Object, throw a TypeError exception.
     if (!@isObject(regexp))
-        throw new @TypeError("RegExp.prototype.test requires that |this| be an Object");
+        @throwTypeError("RegExp.prototype.test requires that |this| be an Object");
 
     // 3. Let string be ? ToString(S).
     let str = @toString(strArg);
index 55271b5..8345f2e 100644 (file)
@@ -28,10 +28,10 @@ function forEach(callback /*, thisArg */)
     "use strict";
 
     if (!@isSet(this))
-        throw new @TypeError("Set operation called on non-Set object");
+        @throwTypeError("Set operation called on non-Set object");
 
     if (typeof callback !== 'function')
-        throw new @TypeError("Set.prototype.forEach callback must be a function");
+        @throwTypeError("Set.prototype.forEach callback must be a function");
 
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     var iterator = @SetIterator(this);
index 90b435f..a329332 100644 (file)
@@ -28,12 +28,12 @@ function raw(template)
     "use strict";
 
     if (template === null || template === @undefined)
-        throw new @TypeError("String.raw requires template not be null or undefined");
+        @throwTypeError("String.raw requires template not be null or undefined");
     var cookedSegments = @Object(template);
 
     var rawValue = cookedSegments.raw;
     if (rawValue === null || rawValue === @undefined)
-        throw new @TypeError("String.raw requires template.raw not be null or undefined");
+        @throwTypeError("String.raw requires template.raw not be null or undefined");
     var rawSegments = @Object(rawValue);
 
     var numberOfSubstitutions = arguments.length - 1;
index f774ec4..52762db 100644 (file)
@@ -28,11 +28,11 @@ function next()
     "use strict";
 
     if (this == null)
-        throw new @TypeError("%StringIteratorPrototype%.next requires that |this| not be null or undefined");
+        @throwTypeError("%StringIteratorPrototype%.next requires that |this| not be null or undefined");
 
     var position = this.@stringIteratorNextIndex;
     if (position === @undefined)
-        throw new @TypeError("%StringIteratorPrototype%.next requires that |this| be a String Iterator instance");
+        @throwTypeError("%StringIteratorPrototype%.next requires that |this| be a String Iterator instance");
 
     var done = true;
     var value = @undefined;
index 2dc716f..1cef4f9 100644 (file)
@@ -30,7 +30,7 @@ function match(regexp)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("String.prototype.match requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.match requires that |this| not be null or undefined");
 
     if (regexp != null) {
         var matcher = regexp.@matchSymbol;
@@ -57,7 +57,7 @@ function repeatSlowPath(string, count)
         return string;
 
     if (string.length * count > @MAX_STRING_LENGTH)
-        throw new @Error("Out of memory");
+        @throwOutOfMemoryError();
 
     // Bit operation onto |count| is safe because |count| should be within Int32 range,
     // Repeat log N times to generate the repeated string rope.
@@ -102,13 +102,13 @@ function repeat(count)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("String.prototype.repeat requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.repeat requires that |this| not be null or undefined");
 
     var string = @toString(this);
     count = @toInteger(count);
 
     if (count < 0 || count === @Infinity)
-        throw new @RangeError("String.prototype.repeat argument must be greater than or equal to 0 and not be Infinity");
+        @throwRangeError("String.prototype.repeat argument must be greater than or equal to 0 and not be Infinity");
 
     if (string.length === 1)
         return @repeatCharacter(string, count);
@@ -121,7 +121,7 @@ function padStart(maxLength/*, fillString*/)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("String.prototype.padStart requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.padStart requires that |this| not be null or undefined");
 
     var string = @toString(this);
     maxLength = @toLength(maxLength);
@@ -141,7 +141,7 @@ function padStart(maxLength/*, fillString*/)
     }
 
     if (maxLength > @MAX_STRING_LENGTH)
-        throw new @Error("Out of memory");
+        @throwOutOfMemoryError();
 
     var fillLength = maxLength - stringLength;
     var truncatedStringFiller;
@@ -158,7 +158,7 @@ function padEnd(maxLength/*, fillString*/)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("String.prototype.padEnd requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.padEnd requires that |this| not be null or undefined");
 
     var string = @toString(this);
     maxLength = @toLength(maxLength);
@@ -178,7 +178,7 @@ function padEnd(maxLength/*, fillString*/)
     }
 
     if (maxLength > @MAX_STRING_LENGTH)
-        throw new @Error("Out of memory");
+        @throwOutOfMemoryError();
 
     var fillLength = maxLength - stringLength;
     var truncatedStringFiller;
@@ -216,7 +216,7 @@ function replace(search, replace)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("String.prototype.replace requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.replace requires that |this| not be null or undefined");
 
     if (search != null) {
         let replacer = search.@replaceSymbol;
@@ -241,7 +241,7 @@ function localeCompare(that/*, locales, options */)
 
     // 1. Let O be RequireObjectCoercible(this value).
     if (this == null)
-        throw new @TypeError("String.prototype.localeCompare requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.localeCompare requires that |this| not be null or undefined");
 
     // 2. Let S be ToString(O).
     // 3. ReturnIfAbrupt(S).
@@ -268,7 +268,7 @@ function search(regexp)
     "use strict";
 
     if (this == null)
-        throw new @TypeError("String.prototype.search requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.search requires that |this| not be null or undefined");
 
     if (regexp != null) {
         var searcher = regexp.@searchSymbol;
@@ -286,7 +286,7 @@ function split(separator, limit)
     "use strict";
     
     if (this == null)
-        throw new @TypeError("String.prototype.split requires that |this| not be null or undefined");
+        @throwTypeError("String.prototype.split requires that |this| not be null or undefined");
     
     if (separator != null) {
         var splitter = separator.@splitSymbol;
index 0361568..1763b20 100644 (file)
@@ -34,7 +34,7 @@ function of(/* items... */)
     let len = arguments.length;
     let constructFunction = this.@allocateTypedArray;
     if (constructFunction === @undefined)
-        throw new @TypeError("TypedArray.of requires its this argument to subclass a TypedArray constructor");
+        @throwTypeError("TypedArray.of requires its this argument to subclass a TypedArray constructor");
 
     let result = constructFunction(len);
 
@@ -54,19 +54,19 @@ function from(items /* [ , mapfn [ , thisArg ] ] */)
 
     if (mapFn !== @undefined) {
         if (typeof mapFn !== "function")
-            throw new @TypeError("TypedArray.from requires that the second argument, when provided, be a function");
+            @throwTypeError("TypedArray.from requires that the second argument, when provided, be a function");
 
         if (arguments.length > 2)
             thisArg = arguments[2];
     }
 
     if (items == null)
-        throw new @TypeError("TypedArray.from requires an array-like object - not null or undefined");
+        @throwTypeError("TypedArray.from requires an array-like object - not null or undefined");
 
     let iteratorMethod = items.@iteratorSymbol;
     if (iteratorMethod != null) {
         if (typeof iteratorMethod !== "function")
-            throw new @TypeError("TypedArray.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
+            @throwTypeError("TypedArray.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
 
         let accumulator = [];
 
@@ -89,7 +89,7 @@ function from(items /* [ , mapfn [ , thisArg ] ] */)
 
         let constructFunction = this.@allocateTypedArray;
         if (constructFunction === @undefined)
-            throw new @TypeError("TypedArray.from requires its this argument subclass a TypedArray constructor");
+            @throwTypeError("TypedArray.from requires its this argument subclass a TypedArray constructor");
 
         let result = constructFunction(k);
 
@@ -105,7 +105,7 @@ function from(items /* [ , mapfn [ , thisArg ] ] */)
 
     let constructFunction = this.@allocateTypedArray;
     if (constructFunction === @undefined)
-        throw new @TypeError("this does not subclass a TypedArray constructor");
+        @throwTypeError("this does not subclass a TypedArray constructor");
 
     let result = constructFunction(arrayLikeLength);
 
index e4d959a..dbe06b9 100644 (file)
@@ -40,7 +40,7 @@ function typedArraySpeciesConstructor(value)
         return @typedArrayGetOriginalConstructor(value);
 
     if (!@isObject(constructor))
-        throw new @TypeError("|this|.constructor is not an Object or undefined");
+        @throwTypeError("|this|.constructor is not an Object or undefined");
 
     constructor = constructor.@speciesSymbol;
     if (constructor == null)
@@ -96,7 +96,7 @@ function every(callback /*, thisArg */)
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.every callback must be a function");
+        @throwTypeError("TypedArray.prototype.every callback must be a function");
 
     for (var i = 0; i < length; i++) {
         if (!callback.@call(thisArg, this[i], i, this))
@@ -136,7 +136,7 @@ function find(callback /* [, thisArg] */)
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.find callback must be a function");
+        @throwTypeError("TypedArray.prototype.find callback must be a function");
 
     for (var i = 0; i < length; i++) {
         let elem = this[i];
@@ -153,7 +153,7 @@ function findIndex(callback /* [, thisArg] */)
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.findIndex callback must be a function");
+        @throwTypeError("TypedArray.prototype.findIndex callback must be a function");
 
     for (var i = 0; i < length; i++) {
         if (callback.@call(thisArg, this[i], i, this))
@@ -169,7 +169,7 @@ function forEach(callback /* [, thisArg] */)
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.forEach callback must be a function");
+        @throwTypeError("TypedArray.prototype.forEach callback must be a function");
 
     for (var i = 0; i < length; i++)
         callback.@call(thisArg, this[i], i, this);
@@ -183,7 +183,7 @@ function some(callback /* [, thisArg] */)
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.some callback must be a function");
+        @throwTypeError("TypedArray.prototype.some callback must be a function");
 
     for (var i = 0; i < length; i++) {
         if (callback.@call(thisArg, this[i], i, this))
@@ -263,7 +263,7 @@ function subarray(begin, end)
     "use strict";
 
     if (!@isTypedArrayView(this))
-        throw new @TypeError("|this| should be a typed array view");
+        @throwTypeError("|this| should be a typed array view");
 
     let start = @toInteger(begin);
     let finish;
@@ -283,10 +283,10 @@ function reduce(callback /* [, initialValue] */)
     var length = @typedArrayLength(this);
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.reduce callback must be a function");
+        @throwTypeError("TypedArray.prototype.reduce callback must be a function");
 
     if (length === 0 && arguments.length < 2)
-        throw new @TypeError("TypedArray.prototype.reduce of empty array with no initial value");
+        @throwTypeError("TypedArray.prototype.reduce of empty array with no initial value");
 
     var accumulator, k = 0;
     if (arguments.length > 1)
@@ -308,10 +308,10 @@ function reduceRight(callback /* [, initialValue] */)
     var length = @typedArrayLength(this);
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.reduceRight callback must be a function");
+        @throwTypeError("TypedArray.prototype.reduceRight callback must be a function");
 
     if (length === 0 && arguments.length < 2)
-        throw new @TypeError("TypedArray.prototype.reduceRight of empty array with no initial value");
+        @throwTypeError("TypedArray.prototype.reduceRight of empty array with no initial value");
 
     var accumulator, k = length - 1;
     if (arguments.length > 1)
@@ -333,7 +333,7 @@ function map(callback /*, thisArg */)
     var length = @typedArrayLength(this);
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.map callback must be a function");
+        @throwTypeError("TypedArray.prototype.map callback must be a function");
 
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
 
@@ -367,7 +367,7 @@ function filter(callback /*, thisArg */)
     var length = @typedArrayLength(this);
 
     if (typeof callback !== "function")
-        throw new @TypeError("TypedArray.prototype.filter callback must be a function");
+        @throwTypeError("TypedArray.prototype.filter callback must be a function");
 
     var thisArg = arguments.length > 1 ? arguments[1] : @undefined;
     var kept = [];
index 3b80b61..ff8ffa3 100644 (file)
@@ -48,6 +48,9 @@ class Identifier;
     macro(isMap) \
     macro(isSet) \
     macro(tailCallForwardArguments) \
+    macro(throwTypeError) \
+    macro(throwRangeError) \
+    macro(throwOutOfMemoryError) \
     macro(tryGetById) \
     macro(putByValDirect) \
     macro(toNumber) \
index 960e1ef..8e33f54 100644 (file)
@@ -1674,9 +1674,10 @@ void CodeBlock::dumpBytecode(
         }
         case op_throw_static_error: {
             int k0 = (++it)->u.operand;
-            int k1 = (++it)->u.operand;
+            ErrorType k1 = static_cast<ErrorType>((++it)->u.unsignedValue);
             printLocationAndOp(out, exec, location, it, "throw_static_error");
-            out.printf("%s, %s", constantName(k0).data(), k1 ? "true" : "false");
+            out.printf("%s, ", constantName(k0).data());
+            out.print(k1);
             break;
         }
         case op_debug: {
index afbc5e0..3bb2fa8 100644 (file)
@@ -3905,18 +3905,36 @@ int BytecodeGenerator::labelScopeDepth() const
     return localScopeDepth() + m_finallyDepth;
 }
 
-void BytecodeGenerator::emitThrowReferenceError(const String& message)
+void BytecodeGenerator::emitThrowStaticError(ErrorType errorType, const Identifier& message)
 {
     emitOpcode(op_throw_static_error);
-    instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, message)))->index());
-    instructions().append(true);
+    instructions().append(addConstantValue(addStringConstant(message))->index());
+    instructions().append(static_cast<unsigned>(errorType));
+}
+
+void BytecodeGenerator::emitThrowReferenceError(const String& message)
+{
+    emitThrowStaticError(ErrorType::ReferenceError, Identifier::fromString(m_vm, message));
 }
 
 void BytecodeGenerator::emitThrowTypeError(const String& message)
 {
-    emitOpcode(op_throw_static_error);
-    instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, message)))->index());
-    instructions().append(false);
+    emitThrowStaticError(ErrorType::TypeError, Identifier::fromString(m_vm, message));
+}
+
+void BytecodeGenerator::emitThrowTypeError(const Identifier& message)
+{
+    emitThrowStaticError(ErrorType::TypeError, message);
+}
+
+void BytecodeGenerator::emitThrowRangeError(const Identifier& message)
+{
+    emitThrowStaticError(ErrorType::RangeError, message);
+}
+
+void BytecodeGenerator::emitThrowOutOfMemoryError()
+{
+    emitThrowStaticError(ErrorType::Error, Identifier::fromString(m_vm, "Out of memory"));
 }
 
 void BytecodeGenerator::emitPushFunctionNameScope(const Identifier& property, RegisterID* callee, bool isCaptured)
@@ -4104,9 +4122,7 @@ bool BytecodeGenerator::emitReadOnlyExceptionIfNeeded(const Variable& variable)
     // If we're in strict mode, we always throw.
     // If we're not in strict mode, we throw for "const" variables but not the function callee.
     if (isStrictMode() || variable.isConst()) {
-        emitOpcode(op_throw_static_error);
-        instructions().append(addConstantValue(addStringConstant(Identifier::fromString(m_vm, StrictModeReadonlyPropertyWriteError)))->index());
-        instructions().append(false);
+        emitThrowTypeError(Identifier::fromString(m_vm, StrictModeReadonlyPropertyWriteError));
         return true;
     }
     return false;
index 3e56ca7..f995332 100644 (file)
@@ -662,8 +662,12 @@ namespace JSC {
             emitUnaryNoDstOp(op_throw, exc);
         }
 
+        void emitThrowStaticError(ErrorType, const Identifier& message);
         void emitThrowReferenceError(const String& message);
         void emitThrowTypeError(const String& message);
+        void emitThrowTypeError(const Identifier& message);
+        void emitThrowRangeError(const Identifier& message);
+        void emitThrowOutOfMemoryError();
 
         void emitPushCatchScope(VariableEnvironment&);
         void emitPopCatchScope(VariableEnvironment&);
index 615fbde..1698fa9 100644 (file)
@@ -898,6 +898,36 @@ RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tailCallForwardArguments(Bytec
     return generator.emitCallForwardArgumentsInTailPosition(finalDst.get(), function.get(), thisRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd(), DebuggableCall::No);
 }
 
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwTypeError(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    ASSERT(node->m_expr->isString());
+    const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
+    ASSERT(!node->m_next);
+
+    generator.emitThrowTypeError(ident);
+    return dst;
+}
+
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwRangeError(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    ASSERT(node->m_expr->isString());
+    const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
+    ASSERT(!node->m_next);
+
+    generator.emitThrowRangeError(ident);
+    return dst;
+}
+
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_throwOutOfMemoryError(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ASSERT(!m_args->m_listNode);
+
+    generator.emitThrowOutOfMemoryError();
+    return dst;
+}
+
 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetById(BytecodeGenerator& generator, RegisterID* dst)
 {
     ArgumentListNode* node = m_args->m_listNode;
index 9f5f0e0..0bbee34 100644 (file)
@@ -1785,7 +1785,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         break;
         
     case Throw:
-    case ThrowReferenceError:
+    case ThrowStaticError:
         m_state.setIsValid(false);
         break;
             
index 8cdf50a..eff23a8 100644 (file)
@@ -4660,7 +4660,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             LAST_OPCODE(op_throw);
             
         case op_throw_static_error:
-            addToGraph(ThrowReferenceError);
+            addToGraph(ThrowStaticError);
             flushForTerminal();
             addToGraph(Unreachable);
             LAST_OPCODE(op_throw_static_error);
index 179963d..2ebfa42 100644 (file)
@@ -1265,7 +1265,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
             return;
         }
         
-    case ThrowReferenceError:
+    case ThrowStaticError:
         write(SideState);
         return;
         
index 0711de7..fb83332 100644 (file)
@@ -282,7 +282,7 @@ bool doesGC(Graph& graph, Node* node)
     case NewFunction:
     case NewGeneratorFunction:
     case NewTypedArray:
-    case ThrowReferenceError:
+    case ThrowStaticError:
     case GetPropertyEnumerator:
     case GetEnumeratorStructurePname:
     case GetEnumeratorGenericPname:
index b53ac88..144f265 100644 (file)
@@ -1757,7 +1757,7 @@ private:
         case TailCall:
         case TailCallVarargs:
         case Throw:
-        case ThrowReferenceError:
+        case ThrowStaticError:
         case CountExecution:
         case ForceOSRExit:
         case CheckBadCell:
index 714b8b2..749fbbd 100644 (file)
@@ -350,7 +350,7 @@ namespace JSC { namespace DFG {
     \
     /* These aren't terminals but always exit */ \
     macro(Throw, NodeMustGenerate) \
-    macro(ThrowReferenceError, NodeMustGenerate) \
+    macro(ThrowStaticError, NodeMustGenerate) \
     \
     /* Block terminals. */\
     macro(Jump, NodeMustGenerate) \
index bea3616..4f0438a 100644 (file)
@@ -1057,7 +1057,7 @@ private:
         case Switch:
         case ProfileType:
         case ProfileControlFlow:
-        case ThrowReferenceError:
+        case ThrowStaticError:
         case ForceOSRExit:
         case SetArgument:
         case SetFunctionName:
index fa327c9..9c62615 100644 (file)
@@ -304,7 +304,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case TailCallVarargs:
     case TailCallForwardVarargs:
     case Throw:
-    case ThrowReferenceError:
+    case ThrowStaticError:
     case CountExecution:
     case ForceOSRExit:
     case CheckWatchdogTimer:
index 9aa093a..bcd8b1a 100644 (file)
@@ -3479,7 +3479,7 @@ void SpeculativeJIT::compile(Node* node)
     }
         
     case Throw:
-    case ThrowReferenceError: {
+    case ThrowStaticError: {
         // We expect that throw statements are rare and are intended to exit the code block
         // anyway, so we just OSR back to the old JIT for now.
         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
index c0cf423..335ccc7 100644 (file)
@@ -3479,7 +3479,7 @@ void SpeculativeJIT::compile(Node* node)
     }
         
     case Throw:
-    case ThrowReferenceError: {
+    case ThrowStaticError: {
         // We expect that throw statements are rare and are intended to exit the code block
         // anyway, so we just OSR back to the old JIT for now.
         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
index e808f43..74568a2 100644 (file)
@@ -179,7 +179,7 @@ inline CapabilityLevel canCompile(Node* node)
     case MultiPutByOffset:
     case ToPrimitive:
     case Throw:
-    case ThrowReferenceError:
+    case ThrowStaticError:
     case Unreachable:
     case In:
     case HasOwnProperty:
index 9889fb0..7cf76fb 100644 (file)
@@ -890,7 +890,7 @@ private:
             compileForceOSRExit();
             break;
         case Throw:
-        case ThrowReferenceError:
+        case ThrowStaticError:
             compileThrow();
             break;
         case InvalidationPoint:
index 5f66f2e..b901bb4 100644 (file)
@@ -618,12 +618,6 @@ void JIT::emit_op_switch_string(Instruction* currentInstruction)
     jump(returnValueGPR);
 }
 
-void JIT::emit_op_throw_static_error(Instruction* currentInstruction)
-{
-    move(TrustedImm64(JSValue::encode(m_codeBlock->getConstant(currentInstruction[1].u.operand))), regT0);
-    callOperation(operationThrowStaticError, regT0, currentInstruction[2].u.operand);
-}
-
 void JIT::emit_op_debug(Instruction* currentInstruction)
 {
     load32(codeBlock()->debuggerRequestsAddress(), regT0);
@@ -938,6 +932,12 @@ void JIT::emitSlow_op_loop_hint(Instruction*, Vector<SlowCaseEntry>::iterator& i
 #endif
 }
 
+void JIT::emit_op_throw_static_error(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_throw_static_error);
+    slowPathCall.call();
+}
+
 void JIT::emit_op_watchdog(Instruction*)
 {
     ASSERT(m_vm->watchdog());
index 87c6a7d..def3136 100644 (file)
@@ -919,12 +919,6 @@ void JIT::emit_op_switch_string(Instruction* currentInstruction)
     jump(returnValueGPR);
 }
 
-void JIT::emit_op_throw_static_error(Instruction* currentInstruction)
-{
-    emitLoad(m_codeBlock->getConstant(currentInstruction[1].u.operand), regT1, regT0);
-    callOperation(operationThrowStaticError, regT1, regT0, currentInstruction[2].u.operand);
-}
-
 void JIT::emit_op_debug(Instruction* currentInstruction)
 {
     load32(codeBlock()->debuggerRequestsAddress(), regT0);
index f1ff5ed..37ed9b6 100644 (file)
@@ -1164,21 +1164,6 @@ UnusedPtr JIT_OPERATION operationHandleWatchdogTimer(ExecState* exec)
     return nullptr;
 }
 
-void JIT_OPERATION operationThrowStaticError(ExecState* exec, EncodedJSValue encodedValue, int32_t referenceErrorFlag)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSValue errorMessageValue = JSValue::decode(encodedValue);
-    RELEASE_ASSERT(errorMessageValue.isString());
-    String errorMessage = asString(errorMessageValue)->value(exec);
-    if (referenceErrorFlag)
-        throwException(exec, scope, createReferenceError(exec, errorMessage));
-    else
-        throwTypeError(exec, scope, errorMessage);
-}
-
 void JIT_OPERATION operationDebug(ExecState* exec, int32_t debugHookType)
 {
     VM& vm = exec->vm();
index 8065177..5810e2d 100644 (file)
@@ -376,7 +376,6 @@ void JIT_OPERATION operationSetFunctionName(ExecState*, JSCell*, EncodedJSValue)
 JSCell* JIT_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL;
 UnusedPtr JIT_OPERATION operationHandleWatchdogTimer(ExecState*) WTF_INTERNAL;
-void JIT_OPERATION operationThrowStaticError(ExecState*, EncodedJSValue, int32_t) WTF_INTERNAL;
 void JIT_OPERATION operationThrow(ExecState*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationDebug(ExecState*, int32_t) WTF_INTERNAL;
 #if ENABLE(DFG_JIT)
index 2dad569..4cb8da2 100644 (file)
@@ -1474,18 +1474,6 @@ LLINT_SLOW_PATH_DECL(slow_path_throw)
     LLINT_THROW(LLINT_OP_C(1).jsValue());
 }
 
-LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
-{
-    LLINT_BEGIN();
-    JSValue errorMessageValue = LLINT_OP_C(1).jsValue();
-    RELEASE_ASSERT(errorMessageValue.isString());
-    String errorMessage = asString(errorMessageValue)->value(exec);
-    if (pc[2].u.operand)
-        LLINT_THROW(createReferenceError(exec, errorMessage));
-    else
-        LLINT_THROW(createTypeError(exec, errorMessage));
-}
-
 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
 {
     LLINT_BEGIN_NO_SET_PC();
index b3b06d7..984e9cc 100644 (file)
@@ -116,7 +116,6 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_arguments);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_strcat);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw_static_error);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_watchdog_timer);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_debug);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_exception);
index 97f42b2..fb0c470 100644 (file)
@@ -1741,7 +1741,7 @@ _llint_op_throw:
 
 _llint_op_throw_static_error:
     traceExecution()
-    callOpcodeSlowPath(_llint_slow_path_throw_static_error)
+    callOpcodeSlowPath(_slow_path_throw_static_error)
     dispatch(3)
 
 
index f25ee81..2223b65 100644 (file)
@@ -966,4 +966,14 @@ SLOW_PATH_DECL(slow_path_define_accessor_property)
     END();
 }
 
+SLOW_PATH_DECL(slow_path_throw_static_error)
+{
+    BEGIN();
+    JSValue errorMessageValue = OP_C(1).jsValue();
+    RELEASE_ASSERT(errorMessageValue.isString());
+    String errorMessage = asString(errorMessageValue)->value(exec);
+    ErrorType errorType = static_cast<ErrorType>(pc[2].u.unsignedValue);
+    THROW(createError(exec, errorType, errorMessage));
+}
+
 } // namespace JSC
index f8830d4..682c9b1 100644 (file)
@@ -258,5 +258,6 @@ SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id_with_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_put_by_val_with_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_define_data_property);
 SLOW_PATH_HIDDEN_DECL(slow_path_define_accessor_property);
+SLOW_PATH_HIDDEN_DECL(slow_path_throw_static_error);
 
 } // namespace JSC
index 029ac47..bdc2905 100644 (file)
@@ -98,6 +98,28 @@ JSObject* createURIError(ExecState* exec, const String& message, ErrorInstance::
     return ErrorInstance::create(exec, globalObject->vm(), globalObject->URIErrorConstructor()->errorStructure(), message, appender, TypeNothing, true);
 }
 
+JSObject* createError(ExecState* exec, ErrorType errorType, const String& message)
+{
+    switch (errorType) {
+    case ErrorType::Error:
+        return createError(exec, message);
+    case ErrorType::EvalError:
+        return createEvalError(exec, message);
+    case ErrorType::RangeError:
+        return createRangeError(exec, message);
+    case ErrorType::ReferenceError:
+        return createReferenceError(exec, message);
+    case ErrorType::SyntaxError:
+        return createSyntaxError(exec, message);
+    case ErrorType::TypeError:
+        return createTypeError(exec, message);
+    case ErrorType::URIError:
+        return createURIError(exec, message);
+    }
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
 class FindFirstCallerFrameWithCodeblockFunctor {
 public:
     FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame)
@@ -282,3 +304,36 @@ void StrictModeTypeErrorFunction::destroy(JSCell* cell)
 }
 
 } // namespace JSC
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream& out, JSC::ErrorType errorType)
+{
+    switch (errorType) {
+    case JSC::ErrorType::Error:
+        out.print("Error");
+        break;
+    case JSC::ErrorType::EvalError:
+        out.print("EvalError");
+        break;
+    case JSC::ErrorType::RangeError:
+        out.print("RangeError");
+        break;
+    case JSC::ErrorType::ReferenceError:
+        out.print("ReferenceError");
+        break;
+    case JSC::ErrorType::SyntaxError:
+        out.print("SyntaxError");
+        break;
+    case JSC::ErrorType::TypeError:
+        out.print("TypeError");
+        break;
+    case JSC::ErrorType::URIError:
+        out.print("URIError");
+        break;
+    }
+}
+
+} // namespace WTF
index 85837b7..e748eed 100644 (file)
@@ -38,6 +38,16 @@ class JSObject;
 class SourceCode;
 class Structure;
 
+enum class ErrorType : uint8_t {
+    Error,
+    EvalError,
+    RangeError,
+    ReferenceError,
+    SyntaxError,
+    TypeError,
+    URIError,
+};
+
 // ExecState wrappers.
 JSObject* createError(ExecState*, const String&, ErrorInstance::SourceAppender);
 JSObject* createEvalError(ExecState*, const String&, ErrorInstance::SourceAppender);
@@ -60,6 +70,8 @@ JS_EXPORT_PRIVATE JSObject* createNotEnoughArgumentsError(ExecState*);
 JS_EXPORT_PRIVATE JSObject* createURIError(ExecState*, const String&);
 JS_EXPORT_PRIVATE JSObject* createOutOfMemoryError(ExecState*);
 
+JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorType, const String&);
+
 
 bool addErrorInfoAndGetBytecodeOffset(ExecState*, VM&, JSObject*, bool, CallFrame*&, unsigned* = nullptr);
 
@@ -146,3 +158,11 @@ private:
 };
 
 } // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&, JSC::ErrorType);
+
+} // namespace WTF