Changeset 224280 in webkit


Ignore:
Timestamp:
Nov 1, 2017 10:32:08 AM (6 years ago)
Author:
Yusuke Suzuki
Message:

[JSC] Introduce @toObject
https://bugs.webkit.org/show_bug.cgi?id=178726

Reviewed by Saam Barati.

JSTests:

  • stress/array-copywithin.js:

(shouldThrow):

  • stress/object-constructor-boolean-edge.js: Added.

(shouldBe):
(test):

  • stress/object-constructor-global.js: Added.

(shouldBe):

  • stress/object-constructor-null-edge.js: Added.

(shouldBe):
(test):

  • stress/object-constructor-number-edge.js: Added.

(shouldBe):
(test):

  • stress/object-constructor-object-edge.js: Added.

(shouldBe):
(test):
(i.arg):

  • stress/object-constructor-string-edge.js: Added.

(shouldBe):
(test):

  • stress/object-constructor-symbol-edge.js: Added.

(shouldBe):
(test):

  • stress/object-constructor-undefined-edge.js: Added.

(shouldBe):
(test):

  • stress/symbol-array-from.js: Added.

(shouldBe):

  • stress/to-object-intrinsic-boolean-edge.js: Added.

(shouldBe):
(builtin.createBuiltin):

  • stress/to-object-intrinsic-null-or-undefined-edge.js: Added.

(shouldThrow):

  • stress/to-object-intrinsic-number-edge.js: Added.

(shouldBe):
(builtin.createBuiltin):

  • stress/to-object-intrinsic-object-edge.js: Added.

(shouldBe):
(builtin.createBuiltin):
(i.arg):

  • stress/to-object-intrinsic-string-edge.js: Added.

(shouldBe):
(builtin.createBuiltin):

  • stress/to-object-intrinsic-symbol-edge.js: Added.

(shouldBe):
(builtin.createBuiltin):

  • stress/to-object-intrinsic.js: Added.

(shouldBe):
(shouldThrow):
(builtin.createBuiltin):

Source/JavaScriptCore:

This patch introduces @toObject intrinsic. And we introduce op_to_object bytecode and DFG ToObject node.
Previously we emulated @toObject behavior in builtin JS. But it consumes much bytecode size while @toObject
is frequently seen and defined clearly in the spec. Furthermore, the emulated @toObject always calls
ObjectConstructor in LLInt and Baseline.

We add a new intrinsic @toObject(target, "error message"). It takes an error message string constant to
offer understandable messages in builtin JS. We can change the frequently seen "emulated ToObject" operation

if (this === @undefined
this === null)

@throwTypeError("error message");

var object = @Object(this);

with

var object = @toObject(this, "error message");

And we handle op_to_object in DFG as ToObject node. While CallObjectConstructor does not throw an error for null/undefined,
ToObject needs to throw an error for null/undefined. So it is marked as MustGenerate and it clobbers the world.
In fixup phase, we attempt to convert ToObject to CallObjectConstructor with edge filters to relax its side effect.

It also fixes a bug that CallObjectConstructor DFG node uses Node's semantic GlobalObject instead of function's one.

  • builtins/ArrayConstructor.js:

(from):

  • builtins/ArrayPrototype.js:

(values):
(keys):
(entries):
(reduce):
(reduceRight):
(every):
(forEach):
(filter):
(map):
(some):
(fill):
(find):
(findIndex):
(includes):
(sort):
(globalPrivate.concatSlowPath):
(copyWithin):

  • builtins/DatePrototype.js:

(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):
(toLocaleDateString.toDateTimeOptionsDateDate):
(toLocaleDateString):
(toLocaleTimeString.toDateTimeOptionsTimeTime):
(toLocaleTimeString):

  • builtins/GlobalOperations.js:

(globalPrivate.copyDataProperties):
(globalPrivate.copyDataPropertiesNoExclusions):

  • builtins/ObjectConstructor.js:

(entries):

  • builtins/StringConstructor.js:

(raw):

  • builtins/TypedArrayConstructor.js:

(from):

  • builtins/TypedArrayPrototype.js:

(map):
(filter):

  • bytecode/BytecodeDumper.cpp:

(JSC::BytecodeDumper<Block>::dumpBytecode):

  • bytecode/BytecodeIntrinsicRegistry.h:
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitToObject):

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

(JSC::BytecodeIntrinsicNode::emit_intrinsic_toObject):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupToObject):
(JSC::DFG::FixupPhase::fixupCallObjectConstructor):

  • dfg/DFGNode.h:

(JSC::DFG::Node::convertToCallObjectConstructor):
(JSC::DFG::Node::convertToNewStringObject):
(JSC::DFG::Node::convertToNewObject):
(JSC::DFG::Node::hasIdentifier):
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasCellOperand):

  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:
  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileToObjectOrCallObjectConstructor):
(JSC::DFG::SpeculativeJIT::compileCallObjectConstructor): Deleted.

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • 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):
(JSC::FTL::DFG::LowerDFGToB3::compileToObjectOrCallObjectConstructor):
(JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor): Deleted.

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):

  • jit/JIT.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_to_object):
(JSC::JIT::emitSlow_op_to_object):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_to_object):
(JSC::JIT::emitSlow_op_to_object):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:

Source/WebCore:

Use @isObject instead. It is more efficient.

  • Modules/mediastream/NavigatorUserMedia.js:

(getUserMedia):

Location:
trunk
Files:
16 added
49 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r224276 r224280  
     12017-11-01  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] Introduce @toObject
     4        https://bugs.webkit.org/show_bug.cgi?id=178726
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/array-copywithin.js:
     9        (shouldThrow):
     10        * stress/object-constructor-boolean-edge.js: Added.
     11        (shouldBe):
     12        (test):
     13        * stress/object-constructor-global.js: Added.
     14        (shouldBe):
     15        * stress/object-constructor-null-edge.js: Added.
     16        (shouldBe):
     17        (test):
     18        * stress/object-constructor-number-edge.js: Added.
     19        (shouldBe):
     20        (test):
     21        * stress/object-constructor-object-edge.js: Added.
     22        (shouldBe):
     23        (test):
     24        (i.arg):
     25        * stress/object-constructor-string-edge.js: Added.
     26        (shouldBe):
     27        (test):
     28        * stress/object-constructor-symbol-edge.js: Added.
     29        (shouldBe):
     30        (test):
     31        * stress/object-constructor-undefined-edge.js: Added.
     32        (shouldBe):
     33        (test):
     34        * stress/symbol-array-from.js: Added.
     35        (shouldBe):
     36        * stress/to-object-intrinsic-boolean-edge.js: Added.
     37        (shouldBe):
     38        (builtin.createBuiltin):
     39        * stress/to-object-intrinsic-null-or-undefined-edge.js: Added.
     40        (shouldThrow):
     41        * stress/to-object-intrinsic-number-edge.js: Added.
     42        (shouldBe):
     43        (builtin.createBuiltin):
     44        * stress/to-object-intrinsic-object-edge.js: Added.
     45        (shouldBe):
     46        (builtin.createBuiltin):
     47        (i.arg):
     48        * stress/to-object-intrinsic-string-edge.js: Added.
     49        (shouldBe):
     50        (builtin.createBuiltin):
     51        * stress/to-object-intrinsic-symbol-edge.js: Added.
     52        (shouldBe):
     53        (builtin.createBuiltin):
     54        * stress/to-object-intrinsic.js: Added.
     55        (shouldBe):
     56        (shouldThrow):
     57        (builtin.createBuiltin):
     58
    1592017-10-27  Yusuke Suzuki  <utatane.tea@gmail.com>
    260
  • trunk/JSTests/stress/array-copywithin.js

    r184871 r224280  
    239239shouldThrow(function () {
    240240    Array.prototype.copyWithin.call(undefined);
    241 }, 'TypeError: Array.copyWithin requires that |this| not be null or undefined');
     241}, 'TypeError: Array.prototype.copyWithin requires that |this| not be null or undefined');
    242242
    243243shouldThrow(function () {
    244244    Array.prototype.copyWithin.call(null);
    245 }, 'TypeError: Array.copyWithin requires that |this| not be null or undefined');
     245}, 'TypeError: Array.prototype.copyWithin requires that |this| not be null or undefined');
    246246
    247247
  • trunk/Source/JavaScriptCore/ChangeLog

    r224277 r224280  
     12017-11-01  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] Introduce @toObject
     4        https://bugs.webkit.org/show_bug.cgi?id=178726
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch introduces @toObject intrinsic. And we introduce op_to_object bytecode and DFG ToObject node.
     9        Previously we emulated @toObject behavior in builtin JS. But it consumes much bytecode size while @toObject
     10        is frequently seen and defined clearly in the spec. Furthermore, the emulated @toObject always calls
     11        ObjectConstructor in LLInt and Baseline.
     12
     13        We add a new intrinsic `@toObject(target, "error message")`. It takes an error message string constant to
     14        offer understandable messages in builtin JS. We can change the frequently seen "emulated ToObject" operation
     15
     16            if (this === @undefined || this === null)
     17                @throwTypeError("error message");
     18            var object = @Object(this);
     19
     20        with
     21
     22            var object = @toObject(this, "error message");
     23
     24        And we handle op_to_object in DFG as ToObject node. While CallObjectConstructor does not throw an error for null/undefined,
     25        ToObject needs to throw an error for null/undefined. So it is marked as MustGenerate and it clobbers the world.
     26        In fixup phase, we attempt to convert ToObject to CallObjectConstructor with edge filters to relax its side effect.
     27
     28        It also fixes a bug that CallObjectConstructor DFG node uses Node's semantic GlobalObject instead of function's one.
     29
     30        * builtins/ArrayConstructor.js:
     31        (from):
     32        * builtins/ArrayPrototype.js:
     33        (values):
     34        (keys):
     35        (entries):
     36        (reduce):
     37        (reduceRight):
     38        (every):
     39        (forEach):
     40        (filter):
     41        (map):
     42        (some):
     43        (fill):
     44        (find):
     45        (findIndex):
     46        (includes):
     47        (sort):
     48        (globalPrivate.concatSlowPath):
     49        (copyWithin):
     50        * builtins/DatePrototype.js:
     51        (toLocaleString.toDateTimeOptionsAnyAll):
     52        (toLocaleString):
     53        (toLocaleDateString.toDateTimeOptionsDateDate):
     54        (toLocaleDateString):
     55        (toLocaleTimeString.toDateTimeOptionsTimeTime):
     56        (toLocaleTimeString):
     57        * builtins/GlobalOperations.js:
     58        (globalPrivate.copyDataProperties):
     59        (globalPrivate.copyDataPropertiesNoExclusions):
     60        * builtins/ObjectConstructor.js:
     61        (entries):
     62        * builtins/StringConstructor.js:
     63        (raw):
     64        * builtins/TypedArrayConstructor.js:
     65        (from):
     66        * builtins/TypedArrayPrototype.js:
     67        (map):
     68        (filter):
     69        * bytecode/BytecodeDumper.cpp:
     70        (JSC::BytecodeDumper<Block>::dumpBytecode):
     71        * bytecode/BytecodeIntrinsicRegistry.h:
     72        * bytecode/BytecodeList.json:
     73        * bytecode/BytecodeUseDef.h:
     74        (JSC::computeUsesForBytecodeOffset):
     75        (JSC::computeDefsForBytecodeOffset):
     76        * bytecode/CodeBlock.cpp:
     77        (JSC::CodeBlock::finishCreation):
     78        * bytecompiler/BytecodeGenerator.cpp:
     79        (JSC::BytecodeGenerator::emitToObject):
     80        * bytecompiler/BytecodeGenerator.h:
     81        * bytecompiler/NodesCodegen.cpp:
     82        (JSC::BytecodeIntrinsicNode::emit_intrinsic_toObject):
     83        * dfg/DFGAbstractInterpreterInlines.h:
     84        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     85        * dfg/DFGByteCodeParser.cpp:
     86        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
     87        (JSC::DFG::ByteCodeParser::parseBlock):
     88        * dfg/DFGCapabilities.cpp:
     89        (JSC::DFG::capabilityLevel):
     90        * dfg/DFGClobberize.h:
     91        (JSC::DFG::clobberize):
     92        * dfg/DFGDoesGC.cpp:
     93        (JSC::DFG::doesGC):
     94        * dfg/DFGFixupPhase.cpp:
     95        (JSC::DFG::FixupPhase::fixupNode):
     96        (JSC::DFG::FixupPhase::fixupToObject):
     97        (JSC::DFG::FixupPhase::fixupCallObjectConstructor):
     98        * dfg/DFGNode.h:
     99        (JSC::DFG::Node::convertToCallObjectConstructor):
     100        (JSC::DFG::Node::convertToNewStringObject):
     101        (JSC::DFG::Node::convertToNewObject):
     102        (JSC::DFG::Node::hasIdentifier):
     103        (JSC::DFG::Node::hasHeapPrediction):
     104        (JSC::DFG::Node::hasCellOperand):
     105        * dfg/DFGNodeType.h:
     106        * dfg/DFGOperations.cpp:
     107        * dfg/DFGOperations.h:
     108        * dfg/DFGPredictionPropagationPhase.cpp:
     109        * dfg/DFGSafeToExecute.h:
     110        (JSC::DFG::safeToExecute):
     111        * dfg/DFGSpeculativeJIT.cpp:
     112        (JSC::DFG::SpeculativeJIT::compileToObjectOrCallObjectConstructor):
     113        (JSC::DFG::SpeculativeJIT::compileCallObjectConstructor): Deleted.
     114        * dfg/DFGSpeculativeJIT.h:
     115        (JSC::DFG::SpeculativeJIT::callOperation):
     116        * dfg/DFGSpeculativeJIT32_64.cpp:
     117        (JSC::DFG::SpeculativeJIT::compile):
     118        * dfg/DFGSpeculativeJIT64.cpp:
     119        (JSC::DFG::SpeculativeJIT::compile):
     120        * ftl/FTLCapabilities.cpp:
     121        (JSC::FTL::canCompile):
     122        * ftl/FTLLowerDFGToB3.cpp:
     123        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     124        (JSC::FTL::DFG::LowerDFGToB3::compileToObjectOrCallObjectConstructor):
     125        (JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor): Deleted.
     126        * jit/JIT.cpp:
     127        (JSC::JIT::privateCompileMainPass):
     128        (JSC::JIT::privateCompileSlowCases):
     129        * jit/JIT.h:
     130        * jit/JITOpcodes.cpp:
     131        (JSC::JIT::emit_op_to_object):
     132        (JSC::JIT::emitSlow_op_to_object):
     133        * jit/JITOpcodes32_64.cpp:
     134        (JSC::JIT::emit_op_to_object):
     135        (JSC::JIT::emitSlow_op_to_object):
     136        * jit/JITOperations.cpp:
     137        * jit/JITOperations.h:
     138        * llint/LowLevelInterpreter32_64.asm:
     139        * llint/LowLevelInterpreter64.asm:
     140        * runtime/CommonSlowPaths.cpp:
     141        (JSC::SLOW_PATH_DECL):
     142        * runtime/CommonSlowPaths.h:
     143
    11442017-11-01  Fujii Hironori  <Hironori.Fujii@sony.com>
    2145
  • trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js

    r208524 r224280  
    5353    }
    5454
    55     if (items == null)
    56         @throwTypeError("Array.from requires an array-like object - not null or undefined");
     55    var arrayLike = @toObject(items, "Array.from requires an array-like object - not null or undefined");
    5756
    5857    var iteratorMethod = items.@iteratorSymbol;
     
    8483    }
    8584
    86     var arrayLike = @Object(items);
    8785    var arrayLikeLength = @toLength(arrayLike.length);
    8886
  • trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js

    r221110 r224280  
    4242    "use strict";
    4343
    44     if (this === null || this === @undefined)
    45         @throwTypeError("Array.prototype.values requires that |this| not be null or undefined");
    46 
    47     return new @createArrayIterator(@Object(this), "value", @arrayIteratorValueNext);
     44    return new @createArrayIterator(@toObject(this, "Array.prototype.values requires that |this| not be null or undefined"), "value", @arrayIteratorValueNext);
    4845}
    4946
     
    5249    "use strict";
    5350
    54     if (this === null || this === @undefined)
    55         @throwTypeError("Array.prototype.keys requires that |this| not be null or undefined");
    56 
    57     return new @createArrayIterator(@Object(this), "key", @arrayIteratorKeyNext);
     51    return new @createArrayIterator(@toObject(this, "Array.prototype.keys requires that |this| not be null or undefined"), "key", @arrayIteratorKeyNext);
    5852}
    5953
     
    6256    "use strict";
    6357
    64     if (this === null || this === @undefined)
    65         @throwTypeError("Array.prototype.entries requires that |this| not be null or undefined");
    66 
    67     return new @createArrayIterator(@Object(this), "key+value", @arrayIteratorKeyValueNext);
     58    return new @createArrayIterator(@toObject(this, "Array.prototype.entries requires that |this| not be null or undefined"), "key+value", @arrayIteratorKeyValueNext);
    6859}
    6960
     
    7263    "use strict";
    7364
    74     if (this === null || this === @undefined)
    75         @throwTypeError("Array.prototype.reduce requires that |this| not be null or undefined");
    76 
    77     var array = @Object(this);
     65    var array = @toObject(this, "Array.prototype.reduce requires that |this| not be null or undefined");
    7866    var length = @toLength(array.length);
    7967
     
    10896    "use strict";
    10997
    110     if (this === null || this === @undefined)
    111         @throwTypeError("Array.prototype.reduceRight requires that |this| not be null or undefined");
    112 
    113     var array = @Object(this);
     98    var array = @toObject(this, "Array.prototype.reduceRight requires that |this| not be null or undefined");
    11499    var length = @toLength(array.length);
    115100
     
    144129    "use strict";
    145130
    146     if (this === null || this === @undefined)
    147         @throwTypeError("Array.prototype.every requires that |this| not be null or undefined");
    148    
    149     var array = @Object(this);
     131    var array = @toObject(this, "Array.prototype.every requires that |this| not be null or undefined");
    150132    var length = @toLength(array.length);
    151133
     
    169151    "use strict";
    170152
    171     if (this === null || this === @undefined)
    172         @throwTypeError("Array.prototype.forEach requires that |this| not be null or undefined");
    173    
    174     var array = @Object(this);
     153    var array = @toObject(this, "Array.prototype.forEach requires that |this| not be null or undefined");
    175154    var length = @toLength(array.length);
    176155
     
    190169    "use strict";
    191170
    192     if (this === null || this === @undefined)
    193         @throwTypeError("Array.prototype.filter requires that |this| not be null or undefined");
    194    
    195     var array = @Object(this);
     171    var array = @toObject(this, "Array.prototype.filter requires that |this| not be null or undefined");
    196172    var length = @toLength(array.length);
    197173
     
    239215    "use strict";
    240216
    241     if (this === null || this === @undefined)
    242         @throwTypeError("Array.prototype.map requires that |this| not be null or undefined");
    243    
    244     var array = @Object(this);
     217    var array = @toObject(this, "Array.prototype.map requires that |this| not be null or undefined");
    245218    var length = @toLength(array.length);
    246219
     
    284257    "use strict";
    285258
    286     if (this === null || this === @undefined)
    287         @throwTypeError("Array.prototype.some requires that |this| not be null or undefined");
    288    
    289     var array = @Object(this);
     259    var array = @toObject(this, "Array.prototype.some requires that |this| not be null or undefined");
    290260    var length = @toLength(array.length);
    291261
     
    307277    "use strict";
    308278
    309     if (this === null || this === @undefined)
    310         @throwTypeError("Array.prototype.fill requires that |this| not be null or undefined");
    311 
    312     var array = @Object(this);
     279    var array = @toObject(this, "Array.prototype.fill requires that |this| not be null or undefined");
    313280    var length = @toLength(array.length);
    314281
     
    347314    "use strict";
    348315
    349     if (this === null || this === @undefined)
    350         @throwTypeError("Array.prototype.find requires that |this| not be null or undefined");
    351    
    352     var array = @Object(this);
     316    var array = @toObject(this, "Array.prototype.find requires that |this| not be null or undefined");
    353317    var length = @toLength(array.length);
    354318
     
    369333    "use strict";
    370334
    371     if (this === null || this === @undefined)
    372         @throwTypeError("Array.prototype.findIndex requires that |this| not be null or undefined");
    373    
    374     var array = @Object(this);
     335    var array = @toObject(this, "Array.prototype.findIndex requires that |this| not be null or undefined");
    375336    var length = @toLength(array.length);
    376337
     
    390351    "use strict";
    391352
    392     if (this === null || this === @undefined)
    393         @throwTypeError("Array.prototype.includes requires that |this| not be null or undefined");
    394 
    395     var array = @Object(this);
     353    var array = @toObject(this, "Array.prototype.includes requires that |this| not be null or undefined");
    396354    var length = @toLength(array.length);
    397355
     
    634592    }
    635593
    636     if (this === null || this === @undefined)
    637         @throwTypeError("Array.prototype.sort requires that |this| not be null or undefined");
    638 
    639     var array = @Object(this);
     594    var array = @toObject(this, "Array.prototype.sort requires that |this| not be null or undefined");
    640595
    641596    var length = array.length >>> 0;
     
    661616    "use strict";
    662617
    663     if (this === null || this === @undefined)
    664         @throwTypeError("Array.prototype.concat requires that |this| not be null or undefined");
    665 
    666     var currentElement = @Object(this);
     618    var currentElement = @toObject(this, "Array.prototype.concat requires that |this| not be null or undefined");
    667619
    668620    var constructor;
     
    751703    }
    752704
    753     if (this === null || this === @undefined)
    754         @throwTypeError("Array.copyWithin requires that |this| not be null or undefined");
    755 
    756     var array = @Object(this);
     705    var array = @toObject(this, "Array.prototype.copyWithin requires that |this| not be null or undefined");
    757706    var length = @toLength(array.length);
    758707
  • trunk/Source/JavaScriptCore/builtins/DatePrototype.js

    r208524 r224280  
    4141            @throwTypeError("null is not an object");
    4242        else
    43             options = @Object(opts);
     43            options = @toObject(opts);
    4444
    4545        // Check original instead of descendant to reduce lookups up the prototype chain.
     
    9898            @throwTypeError("null is not an object");
    9999        else
    100             options = @Object(opts);
     100            options = @toObject(opts);
    101101
    102102        // Check original instead of descendant to reduce lookups up the prototype chain.
     
    148148            @throwTypeError("null is not an object");
    149149        else
    150             options = @Object(opts);
     150            options = @toObject(opts);
    151151
    152152        // Check original instead of descendant to reduce lookups up the prototype chain.
  • trunk/Source/JavaScriptCore/builtins/GlobalOperations.js

    r221417 r224280  
    9191        return target;
    9292
    93     let from = @Object(source);
     93    let from = @toObject(source);
    9494    let keys = @Reflect.@ownKeys(from);
    9595    let keysLength = keys.length;
     
    116116        return target;
    117117
    118     let from = @Object(source);
     118    let from = @toObject(source);
    119119    let keys = @Reflect.@ownKeys(from);
    120120    let keysLength = keys.length;
  • trunk/Source/JavaScriptCore/builtins/ObjectConstructor.js

    r218790 r224280  
    2929    "use strict";
    3030
    31     if (object == null)
    32         @throwTypeError("Object.entries requires that input parameter not be null or undefined");
    33 
    34     var obj = @Object(object);
     31    var obj = @toObject(object, "Object.entries requires that input parameter not be null or undefined");
    3532    var names = @getOwnPropertyNames(obj);
    3633    var properties = [];
  • trunk/Source/JavaScriptCore/builtins/StringConstructor.js

    r206853 r224280  
    2828    "use strict";
    2929
    30     if (template === null || template === @undefined)
    31         @throwTypeError("String.raw requires template not be null or undefined");
    32     var cookedSegments = @Object(template);
     30    var cookedSegments = @toObject(template, "String.raw requires template not be null or undefined");
    3331
    34     var rawValue = cookedSegments.raw;
    35     if (rawValue === null || rawValue === @undefined)
    36         @throwTypeError("String.raw requires template.raw not be null or undefined");
    37     var rawSegments = @Object(rawValue);
     32    var rawSegments = @toObject(cookedSegments.raw, "String.raw requires template.raw not be null or undefined");
    3833
    3934    var numberOfSubstitutions = arguments.length - 1;
  • trunk/Source/JavaScriptCore/builtins/TypedArrayConstructor.js

    r208524 r224280  
    6060    }
    6161
    62     if (items == null)
    63         @throwTypeError("TypedArray.from requires an array-like object - not null or undefined");
     62    let arrayLike = @toObject(items, "TypedArray.from requires an array-like object - not null or undefined");
    6463
    6564    let iteratorMethod = items.@iteratorSymbol;
     
    10099    }
    101100
    102     let arrayLike = @Object(items);
    103101    let arrayLikeLength = @toLength(arrayLike.length);
    104102
  • trunk/Source/JavaScriptCore/builtins/TypedArrayPrototype.js

    r208524 r224280  
    340340        result = new (@typedArrayGetOriginalConstructor(this))(length);
    341341    else {
    342         var speciesConstructor = @Object(constructor).@speciesSymbol;
     342        var speciesConstructor = constructor.@speciesSymbol;
    343343        if (speciesConstructor === null || speciesConstructor === @undefined)
    344344            result = new (@typedArrayGetOriginalConstructor(this))(length);
     
    381381        result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
    382382    else {
    383         var speciesConstructor = @Object(constructor).@speciesSymbol;
     383        var speciesConstructor = constructor.@speciesSymbol;
    384384        if (speciesConstructor === null || speciesConstructor === @undefined)
    385385            result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
  • trunk/Source/JavaScriptCore/bytecode/BytecodeDumper.cpp

    r223318 r224280  
    872872        break;
    873873    }
     874    case op_to_object: {
     875        printUnaryOp(out, location, it, "to_object");
     876        int id0 = (++it)->u.operand;
     877        out.printf(" %s", idName(id0, identifier(id0)).data());
     878        dumpValueProfiling(out, it, hasPrintedProfiling);
     879        break;
     880    }
    874881    case op_negate: {
    875882        printUnaryOp(out, location, it, "negate");
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h

    r221110 r224280  
    5858    macro(toNumber) \
    5959    macro(toString) \
     60    macro(toObject) \
    6061    macro(newArrayWithSize) \
    6162    macro(defineEnumerableWritableConfigurableDataProperty) \
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r223318 r224280  
    4343            { "name" : "op_to_number", "length" : 4 },
    4444            { "name" : "op_to_string", "length" : 3 },
     45            { "name" : "op_to_object", "length" : 5 },
    4546            { "name" : "op_negate", "length" : 4 },
    4647            { "name" : "op_add", "length" : 5 },
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r223318 r224280  
    194194    case op_to_number:
    195195    case op_to_string:
     196    case op_to_object:
    196197    case op_negate:
    197198    case op_neq_null:
     
    447448    case op_to_number:
    448449    case op_to_string:
     450    case op_to_object:
    449451    case op_negate:
    450452    case op_add:
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r224217 r224280  
    577577        case op_get_from_arguments:
    578578        case op_to_number:
     579        case op_to_object:
    579580        case op_get_argument: {
    580581            linkValueProfile(i, opLength);
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r223989 r224280  
    16831683    instructions().append(dst->index());
    16841684    instructions().append(src->index());
     1685    instructions().append(profile);
     1686    return dst;
     1687}
     1688
     1689RegisterID* BytecodeGenerator::emitToObject(RegisterID* dst, RegisterID* src, const Identifier& message)
     1690{
     1691    UnlinkedValueProfile profile = emitProfiledOpcode(op_to_object);
     1692    instructions().append(dst->index());
     1693    instructions().append(src->index());
     1694    instructions().append(addConstant(message));
    16851695    instructions().append(profile);
    16861696    return dst;
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r222473 r224280  
    665665        RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOpProfiled(op_to_number, dst, src); }
    666666        RegisterID* emitToString(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_string, dst, src); }
     667        RegisterID* emitToObject(RegisterID* dst, RegisterID* src, const Identifier& message);
    667668        RegisterID* emitInc(RegisterID* srcDst);
    668669        RegisterID* emitDec(RegisterID* srcDst);
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r223745 r224280  
    10301030
    10311031    return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
     1032}
     1033
     1034RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toObject(BytecodeGenerator& generator, RegisterID* dst)
     1035{
     1036    ArgumentListNode* node = m_args->m_listNode;
     1037    RefPtr<RegisterID> src = generator.emitNode(node);
     1038    node = node->m_next;
     1039
     1040    RefPtr<RegisterID> temp = generator.tempDestination(dst);
     1041    if (node) {
     1042        ASSERT(node->m_expr->isString());
     1043        const Identifier& message = static_cast<StringNode*>(node->m_expr)->value();
     1044        ASSERT(!node->m_next);
     1045        return generator.moveToDestinationIfNeeded(dst, generator.emitToObject(temp.get(), src.get(), message));
     1046    }
     1047    return generator.moveToDestinationIfNeeded(dst, generator.emitToObject(temp.get(), src.get(), generator.vm()->propertyNames->emptyIdentifier));
    10321048}
    10331049
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r224276 r224280  
    21882188        break;
    21892189
     2190    case ToObject:
    21902191    case CallObjectConstructor: {
    21912192        AbstractValue& source = forNode(node->child1());
     
    21982199        }
    21992200
     2201        if (node->op() == ToObject)
     2202            clobberWorld(node->origin.semantic, clobberLimit);
    22002203        forNode(node).setType(m_graph, SpecObject);
    22012204        break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r224276 r224280  
    33003300            result = addToGraph(NewObject, OpInfo(m_graph.registerStructure(function->globalObject()->objectStructureForObjectConstructor())));
    33013301        else
    3302             result = addToGraph(CallObjectConstructor, get(virtualRegisterForArgument(1, registerOffset)));
     3302            result = addToGraph(CallObjectConstructor, OpInfo(m_graph.freeze(function->globalObject())), OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));
    33033303        set(VirtualRegister(resultOperand), result);
    33043304        return true;
     
    60706070        }
    60716071
     6072        case op_to_object: {
     6073            SpeculatedType prediction = getPrediction();
     6074            Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
     6075            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
     6076            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ToObject, OpInfo(identifierNumber), OpInfo(prediction), value));
     6077            NEXT_OPCODE(op_to_object);
     6078        }
     6079
    60726080        case op_in: {
    60736081            ArrayMode arrayMode = getArrayMode(currentInstruction[OPCODE_LENGTH(op_in) - 1].u.arrayProfile);
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r223318 r224280  
    229229    case op_to_number:
    230230    case op_to_string:
     231    case op_to_object:
    231232    case op_switch_imm:
    232233    case op_switch_char:
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r224276 r224280  
    523523        return;
    524524
     525    case ToObject:
     526        read(World);
     527        write(Heap);
     528        return;
     529
    525530    case CallObjectConstructor:
     531        read(HeapObjectCount);
     532        write(HeapObjectCount);
     533        return;
     534
    526535    case ToThis:
    527536    case CreateThis:
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r224276 r224280  
    302302    case CreateClonedArguments:
    303303    case CallObjectConstructor:
     304    case ToObject:
    304305    case ToThis:
    305306    case CreateThis:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r224276 r224280  
    12941294        }
    12951295
     1296        case ToObject: {
     1297            fixupToObject(node);
     1298            break;
     1299        }
     1300
    12961301        case CallObjectConstructor: {
    1297             if (node->child1()->shouldSpeculateObject()) {
    1298                 fixEdge<ObjectUse>(node->child1());
    1299                 node->convertToIdentity();
    1300                 break;
    1301             }
    1302 
    1303             fixEdge<UntypedUse>(node->child1());
     1302            fixupCallObjectConstructor(node);
    13041303            break;
    13051304        }
     
    25102509        node->setResult(NodeResultJS);
    25112510    }
     2511
     2512    void fixupToObject(Node* node)
     2513    {
     2514        if (node->child1()->shouldSpeculateObject()) {
     2515            fixEdge<ObjectUse>(node->child1());
     2516            node->convertToIdentity();
     2517            return;
     2518        }
     2519
     2520        // ToObject(Null/Undefined) can throw an error. We can emit filters to convert ToObject to CallObjectConstructor.
     2521
     2522        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
     2523
     2524        if (node->child1()->shouldSpeculateString()) {
     2525            insertCheck<StringUse>(node->child1().node());
     2526            fixEdge<KnownStringUse>(node->child1());
     2527            node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
     2528            return;
     2529        }
     2530
     2531        if (node->child1()->shouldSpeculateSymbol()) {
     2532            insertCheck<SymbolUse>(node->child1().node());
     2533            node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
     2534            return;
     2535        }
     2536
     2537        if (node->child1()->shouldSpeculateNumber()) {
     2538            insertCheck<NumberUse>(node->child1().node());
     2539            node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
     2540            return;
     2541        }
     2542
     2543        if (node->child1()->shouldSpeculateBoolean()) {
     2544            insertCheck<BooleanUse>(node->child1().node());
     2545            node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
     2546            return;
     2547        }
     2548
     2549        fixEdge<UntypedUse>(node->child1());
     2550    }
     2551
     2552    void fixupCallObjectConstructor(Node* node)
     2553    {
     2554        if (node->child1()->shouldSpeculateObject()) {
     2555            fixEdge<ObjectUse>(node->child1());
     2556            node->convertToIdentity();
     2557            return;
     2558        }
     2559
     2560        if (node->child1()->shouldSpeculateString()) {
     2561            auto* globalObject = jsCast<JSGlobalObject*>(node->cellOperand()->cell());
     2562            insertCheck<StringUse>(node->child1().node());
     2563            fixEdge<KnownStringUse>(node->child1());
     2564            node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
     2565            return;
     2566        }
     2567
     2568        // While ToObject(Null/Undefined) throws an error, CallObjectConstructor(Null/Undefined) generates a new empty object.
     2569        if (node->child1()->shouldSpeculateOther()) {
     2570            insertCheck<OtherUse>(node->child1().node());
     2571            node->convertToNewObject(m_graph.registerStructure(jsCast<JSGlobalObject*>(node->cellOperand()->cell())->objectStructureForObjectConstructor()));
     2572            return;
     2573        }
     2574
     2575        fixEdge<UntypedUse>(node->child1());
     2576    }
    25122577   
    25132578    void fixupToStringOrCallStringConstructor(Node* node)
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r223594 r224280  
    719719        children.setChild1(Edge());
    720720    }
     721
     722    void convertToCallObjectConstructor(FrozenValue* globalObject)
     723    {
     724        ASSERT(m_op == ToObject);
     725        setOpAndDefaultFlags(CallObjectConstructor);
     726        m_opInfo = globalObject;
     727    }
     728
     729    void convertToNewStringObject(RegisteredStructure structure)
     730    {
     731        ASSERT(m_op == CallObjectConstructor || m_op == ToObject);
     732        setOpAndDefaultFlags(NewStringObject);
     733        m_opInfo = structure;
     734        m_opInfo2 = OpInfoWrapper();
     735    }
     736
     737    void convertToNewObject(RegisteredStructure structure)
     738    {
     739        ASSERT(m_op == CallObjectConstructor);
     740        setOpAndDefaultFlags(NewObject);
     741        children.reset();
     742        m_opInfo = structure;
     743        m_opInfo2 = OpInfoWrapper();
     744    }
    721745   
    722746    void convertToDirectCall(FrozenValue*);
     
    10041028        case ResolveScopeForHoistingFuncDeclInEval:
    10051029        case ResolveScope:
     1030        case ToObject:
    10061031            return true;
    10071032        default:
     
    15791604        case StringReplaceRegExp:
    15801605        case ToNumber:
     1606        case ToObject:
     1607        case CallObjectConstructor:
    15811608        case LoadKeyFromMapBucket:
    15821609        case LoadValueFromMapBucket:
     
    16441671        case NewRegexp:
    16451672        case CompareEqPtr:
     1673        case CallObjectConstructor:
    16461674        case DirectCall:
    16471675        case DirectTailCall:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r224276 r224280  
    357357    macro(ToString, NodeResultJS | NodeMustGenerate) \
    358358    macro(ToNumber, NodeResultJS | NodeMustGenerate) \
     359    macro(ToObject, NodeResultJS | NodeMustGenerate) \
    359360    macro(CallObjectConstructor, NodeResultJS) \
    360361    macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r224276 r224280  
    264264}
    265265
    266 JSCell* JIT_OPERATION operationObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
     266JSCell* JIT_OPERATION operationCallObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
    267267{
    268268    VM* vm = &exec->vm();
     
    274274    if (value.isUndefinedOrNull())
    275275        return constructEmptyObject(exec, globalObject->objectPrototype());
     276    return value.toObject(exec, globalObject);
     277}
     278
     279JSCell* JIT_OPERATION operationToObject(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget, UniquedStringImpl* errorMessage)
     280{
     281    VM* vm = &exec->vm();
     282    NativeCallFrameTracer tracer(vm, exec);
     283    auto scope = DECLARE_THROW_SCOPE(*vm);
     284
     285    JSValue value = JSValue::decode(encodedTarget);
     286    ASSERT(!value.isObject());
     287
     288    if (UNLIKELY(value.isUndefinedOrNull())) {
     289        if (errorMessage->length()) {
     290            throwVMTypeError(exec, scope, errorMessage);
     291            return nullptr;
     292        }
     293    }
     294
    276295    return value.toObject(exec, globalObject);
    277296}
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r224276 r224280  
    4242
    4343// These routines provide callbacks out to C++ implementations of operations too complex to JIT.
    44 JSCell* JIT_OPERATION operationObjectConstructor(ExecState*, JSGlobalObject*, EncodedJSValue encodedTarget) WTF_INTERNAL;
     44JSCell* JIT_OPERATION operationCallObjectConstructor(ExecState*, JSGlobalObject*, EncodedJSValue encodedTarget) WTF_INTERNAL;
     45JSCell* JIT_OPERATION operationToObject(ExecState*, JSGlobalObject*, EncodedJSValue encodedTarget, UniquedStringImpl*) WTF_INTERNAL;
    4546JSCell* JIT_OPERATION operationCreateThis(ExecState*, JSObject* constructor, int32_t inlineCapacity) WTF_INTERNAL;
    4647EncodedJSValue JIT_OPERATION operationToThis(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r224276 r224280  
    721721        case LoadValueFromMapBucket:
    722722        case ToNumber:
     723        case ToObject:
     724        case CallObjectConstructor:
    723725        case GetArgument:
    724726        case CallDOMGetter:
     
    858860            break;
    859861
    860         case CallObjectConstructor: {
    861             setPrediction(SpecObject);
    862             break;
    863         }
    864862        case SkipScope:
    865863        case GetGlobalObject: {
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r224276 r224280  
    315315    case ToString:
    316316    case ToNumber:
     317    case ToObject:
    317318    case NumberToStringWithRadix:
    318319    case NumberToStringWithValidRadixConstant:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r224276 r224280  
    40894089}
    40904090
    4091 void SpeculativeJIT::compileCallObjectConstructor(Node* node)
     4091void SpeculativeJIT::compileToObjectOrCallObjectConstructor(Node* node)
    40924092{
    40934093    RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
     4094
    40944095    JSValueOperand value(this, node->child1());
    40954096#if USE(JSVALUE64)
     
    41074108    m_jit.move(valueRegs.payloadGPR(), resultGPR);
    41084109
    4109     addSlowPathGenerator(slowPathCall(slowCases, this, operationObjectConstructor, resultGPR, m_jit.globalObjectFor(node->origin.semantic), valueRegs));
     4110    if (node->op() == ToObject)
     4111        addSlowPathGenerator(slowPathCall(slowCases, this, operationToObject, resultGPR, m_jit.graph().globalObjectFor(node->origin.semantic), valueRegs, identifierUID(node->identifierNumber())));
     4112    else
     4113        addSlowPathGenerator(slowPathCall(slowCases, this, operationCallObjectConstructor, resultGPR, TrustedImmPtr(node->cellOperand()), valueRegs));
     4114
    41104115    cellResult(resultGPR, node);
    41114116}
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r224276 r224280  
    11901190    }
    11911191
     1192    JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, TrustedImmPtr globalObject, GPRReg arg2)
     1193    {
     1194        m_jit.setupArgumentsWithExecState(globalObject, arg2);
     1195        return appendCallSetResult(operation, result);
     1196    }
     1197
    11921198    JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
    11931199    {
     
    16831689    }
    16841690
     1691    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, TrustedImmPtr globalObject, GPRReg arg1)
     1692    {
     1693        m_jit.setupArgumentsWithExecState(globalObject, arg1);
     1694        return appendCallSetResult(operation, result);
     1695    }
     1696
     1697    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, TrustedImmPtr globalObject, JSValueRegs arg1)
     1698    {
     1699        return callOperation(operation, result, globalObject, arg1.gpr());
     1700    }
     1701
    16851702    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg1)
    16861703    {
    1687         m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1);
    1688         return appendCallSetResult(operation, result);
     1704        return callOperation(operation, result, TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1);
    16891705    }
    16901706
     
    16921708    {
    16931709        return callOperation(operation, result, globalObject, arg1.gpr());
     1710    }
     1711
     1712    JITCompiler::Call callOperation(C_JITOperation_EGJI operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1, UniquedStringImpl* arg2)
     1713    {
     1714        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1.gpr(), TrustedImmPtr(arg2));
     1715        return appendCallSetResult(operation, result);
    16941716    }
    16951717
     
    23392361    }
    23402362
     2363    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, TrustedImmPtr globalObject, JSValueRegs arg1)
     2364    {
     2365        m_jit.setupArgumentsWithExecState(globalObject, arg1.payloadGPR(), arg1.tagGPR());
     2366        return appendCallSetResult(operation, result);
     2367    }
     2368
    23412369    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1)
    23422370    {
    23432371        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1.payloadGPR(), arg1.tagGPR());
     2372        return appendCallSetResult(operation, result);
     2373    }
     2374
     2375    JITCompiler::Call callOperation(C_JITOperation_EGJI operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1, UniquedStringImpl* arg2)
     2376    {
     2377        m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), arg1.payloadGPR(), arg1.tagGPR(), TrustedImmPtr(arg2));
    23442378        return appendCallSetResult(operation, result);
    23452379    }
     
    29763010    void compileMaterializeNewObject(Node*);
    29773011    void compileRecordRegExpCachedResult(Node*);
    2978     void compileCallObjectConstructor(Node*);
     3012    void compileToObjectOrCallObjectConstructor(Node*);
    29793013    void compileResolveScope(Node*);
    29803014    void compileResolveScopeForHoistingFuncDeclInEval(Node*);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r224276 r224280  
    40294029    }
    40304030
     4031    case ToObject:
    40314032    case CallObjectConstructor: {
    4032         compileCallObjectConstructor(node);
     4033        compileToObjectOrCallObjectConstructor(node);
    40334034        break;
    40344035    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r224276 r224280  
    42384238    }
    42394239
     4240    case ToObject:
    42404241    case CallObjectConstructor: {
    4241         compileCallObjectConstructor(node);
     4242        compileToObjectOrCallObjectConstructor(node);
    42424243        break;
    42434244    }
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r224276 r224280  
    181181    case ToNumber:
    182182    case ToString:
     183    case ToObject:
    183184    case CallObjectConstructor:
    184185    case CallStringConstructor:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r224276 r224280  
    556556            compileNoOp();
    557557            break;
     558        case ToObject:
    558559        case CallObjectConstructor:
    559             compileCallObjectConstructor();
     560            compileToObjectOrCallObjectConstructor();
    560561            break;
    561562        case ToThis:
     
    16621663    }
    16631664
    1664     void compileCallObjectConstructor()
    1665     {
    1666         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
     1665    void compileToObjectOrCallObjectConstructor()
     1666    {
    16671667        LValue value = lowJSValue(m_node->child1());
    16681668
     
    16781678
    16791679        m_out.appendTo(slowCase, continuation);
    1680         ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationObjectConstructor), m_callFrame, weakPointer(globalObject), value));
     1680
     1681        ValueFromBlock slowResult;
     1682        if (m_node->op() == ToObject) {
     1683            auto* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
     1684            slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationToObject), m_callFrame, weakPointer(globalObject), value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
     1685        } else
     1686            slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationCallObjectConstructor), m_callFrame, frozenPointer(m_node->cellOperand()), value));
    16811687        m_out.jump(continuation);
    16821688
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r224138 r224280  
    398398        DEFINE_OP(op_to_number)
    399399        DEFINE_OP(op_to_string)
     400        DEFINE_OP(op_to_object)
    400401        DEFINE_OP(op_to_primitive)
    401402
     
    533534        DEFINE_SLOWCASE_OP(op_to_number)
    534535        DEFINE_SLOWCASE_OP(op_to_string)
     536        DEFINE_SLOWCASE_OP(op_to_object)
    535537        DEFINE_SLOWCASE_OP(op_to_primitive)
    536538        DEFINE_SLOWCASE_OP(op_has_indexed_property)
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r223824 r224280  
    576576        void emit_op_to_number(Instruction*);
    577577        void emit_op_to_string(Instruction*);
     578        void emit_op_to_object(Instruction*);
    578579        void emit_op_to_primitive(Instruction*);
    579580        void emit_op_unexpected_load(Instruction*);
     
    642643        void emitSlow_op_to_number(Instruction*, Vector<SlowCaseEntry>::iterator&);
    643644        void emitSlow_op_to_string(Instruction*, Vector<SlowCaseEntry>::iterator&);
     645        void emitSlow_op_to_object(Instruction*, Vector<SlowCaseEntry>::iterator&);
    644646        void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
    645647        void emitSlow_op_unsigned(Instruction*, Vector<SlowCaseEntry>::iterator&);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r223824 r224280  
    520520}
    521521
     522void JIT::emit_op_to_object(Instruction* currentInstruction)
     523{
     524    int dstVReg = currentInstruction[1].u.operand;
     525    int srcVReg = currentInstruction[2].u.operand;
     526    emitGetVirtualRegister(srcVReg, regT0);
     527
     528    addSlowCase(emitJumpIfNotJSCell(regT0));
     529    addSlowCase(branch8(Below, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType)));
     530
     531    emitValueProfilingSite();
     532    if (srcVReg != dstVReg)
     533        emitPutVirtualRegister(dstVReg);
     534}
     535
    522536void JIT::emit_op_catch(Instruction* currentInstruction)
    523537{
     
    898912
    899913    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_string);
     914    slowPathCall.call();
     915}
     916
     917void JIT::emitSlow_op_to_object(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     918{
     919    linkAllSlowCases(iter);
     920
     921    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_object);
    900922    slowPathCall.call();
    901923}
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r223824 r224280  
    724724}
    725725
     726void JIT::emit_op_to_object(Instruction* currentInstruction)
     727{
     728    int dst = currentInstruction[1].u.operand;
     729    int src = currentInstruction[2].u.operand;
     730
     731    emitLoad(src, regT1, regT0);
     732
     733    addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
     734    addSlowCase(branch8(Below, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType)));
     735
     736    emitValueProfilingSite();
     737    if (src != dst)
     738        emitStore(dst, regT1, regT0);
     739}
     740
     741void JIT::emitSlow_op_to_object(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     742{
     743    linkAllSlowCases(iter);
     744
     745    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_object);
     746    slowPathCall.call();
     747}
     748
    726749void JIT::emit_op_catch(Instruction* currentInstruction)
    727750{
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r223738 r224280  
    21362136}
    21372137
    2138 EncodedJSValue JIT_OPERATION operationToObject(ExecState* exec, EncodedJSValue value)
    2139 {
    2140     VM& vm = exec->vm();
    2141     NativeCallFrameTracer tracer(&vm, exec);
    2142     JSObject* obj = JSValue::decode(value).toObject(exec);
    2143     if (!obj)
    2144         return JSValue::encode(JSValue());
    2145     return JSValue::encode(obj);
    2146 }
    2147 
    21482138char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState* exec, EncodedJSValue encodedKey, size_t tableIndex)
    21492139{
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r224276 r224280  
    189189typedef JSCell* (JIT_OPERATION *C_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
    190190typedef JSCell* (JIT_OPERATION *C_JITOperation_EGJ)(ExecState*, JSGlobalObject*, EncodedJSValue);
     191typedef JSCell* (JIT_OPERATION *C_JITOperation_EGJI)(ExecState*, JSGlobalObject*, EncodedJSValue, UniquedStringImpl*);
    191192typedef JSCell* (JIT_OPERATION *C_JITOperation_EIcf)(ExecState*, InlineCallFrame*);
    192193typedef JSCell* (JIT_OPERATION *C_JITOperation_EJ)(ExecState*, EncodedJSValue);
     
    440441CallFrame* JIT_OPERATION operationSetupForwardArgumentsFrame(ExecState*, CallFrame*, EncodedJSValue, int32_t, int32_t length) WTF_INTERNAL;
    441442CallFrame* JIT_OPERATION operationSetupVarargsFrame(ExecState*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset, int32_t length) WTF_INTERNAL;
    442 EncodedJSValue JIT_OPERATION operationToObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
    443443
    444444char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(ExecState*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r223891 r224280  
    943943    callOpcodeSlowPath(_slow_path_to_string)
    944944    dispatch(constexpr op_to_string_length)
     945
     946
     947_llint_op_to_object:
     948    traceExecution()
     949    loadi 8[PC], t0
     950    loadi 4[PC], t1
     951    loadConstantOrVariable(t0, t2, t3)
     952    bineq t2, CellTag, .opToObjectSlow
     953    bbb JSCell::m_type[t3], ObjectType, .opToObjectSlow
     954    storei t2, TagOffset[cfr, t1, 8]
     955    storei t3, PayloadOffset[cfr, t1, 8]
     956    valueProfile(t2, t3, 16, t1)
     957    dispatch(constexpr op_to_object_length)
     958
     959.opToObjectSlow:
     960    callOpcodeSlowPath(_slow_path_to_object)
     961    dispatch(constexpr op_to_object_length)
    945962
    946963
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r223891 r224280  
    848848
    849849
     850_llint_op_to_object:
     851    traceExecution()
     852    loadisFromInstruction(2, t0)
     853    loadisFromInstruction(1, t1)
     854    loadConstantOrVariable(t0, t2)
     855    btqnz t2, tagMask, .opToObjectSlow
     856    bbb JSCell::m_type[t2], ObjectType, .opToObjectSlow
     857    storeq t2, [cfr, t1, 8]
     858    valueProfile(t2, 4, t0)
     859    dispatch(constexpr op_to_object_length)
     860
     861.opToObjectSlow:
     862    callOpcodeSlowPath(_slow_path_to_object)
     863    dispatch(constexpr op_to_object_length)
     864
     865
    850866_llint_op_negate:
    851867    traceExecution()
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r223891 r224280  
    436436}
    437437
     438SLOW_PATH_DECL(slow_path_to_object)
     439{
     440    BEGIN();
     441    JSValue argument = OP_C(2).jsValue();
     442    if (UNLIKELY(argument.isUndefinedOrNull())) {
     443        const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
     444        if (!ident.isEmpty())
     445            THROW(createTypeError(exec, ident.impl()));
     446    }
     447    JSObject* result = argument.toObject(exec);
     448    RETURN_PROFILED(op_to_object, result);
     449}
     450
    438451SLOW_PATH_DECL(slow_path_add)
    439452{
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r223891 r224280  
    235235SLOW_PATH_HIDDEN_DECL(slow_path_to_number);
    236236SLOW_PATH_HIDDEN_DECL(slow_path_to_string);
     237SLOW_PATH_HIDDEN_DECL(slow_path_to_object);
    237238SLOW_PATH_HIDDEN_DECL(slow_path_negate);
    238239SLOW_PATH_HIDDEN_DECL(slow_path_add);
  • trunk/Source/WebCore/ChangeLog

    r224279 r224280  
     12017-11-01  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] Introduce @toObject
     4        https://bugs.webkit.org/show_bug.cgi?id=178726
     5
     6        Reviewed by Saam Barati.
     7
     8        Use @isObject instead. It is more efficient.
     9
     10        * Modules/mediastream/NavigatorUserMedia.js:
     11        (getUserMedia):
     12
    1132017-11-01  Commit Queue  <commit-queue@webkit.org>
    214
  • trunk/Source/WebCore/Modules/mediastream/NavigatorUserMedia.js

    r212323 r224280  
    3838        @throwTypeError("Not enough arguments");
    3939
    40     if (options !== @Object(options))
     40    if (!@isObject(options))
    4141        @throwTypeError("Argument 1 (options) to Navigator.getUserMedia must be an object");
    4242
Note: See TracChangeset for help on using the changeset viewer.