Array.prototype.flat/flatMap have a minor bug in ArraySpeciesCreate
https://bugs.webkit.org/show_bug.cgi?id=193127
Reviewed by Saam Barati.
JSTests:
- stress/array-species-create-should-handle-masquerader.js: Added.
(shouldThrow):
- stress/is-undefined-or-null-builtin.js: Added.
(shouldBe):
(isUndefinedOrNull.vm.createBuiltin):
Source/JavaScriptCore:
== null
is frequently used idiom to check null
or undefined
in JS.
However, it has a problem in terms of the builtin JS implementation: it
returns true if masquerade-as-undefined objects (e.g. document.all) come.
In this patch, we introduce a convenient builtin intrinsic @isUndefinedOrNull,
which is equivalent to C++ JSValue::isUndefinedOrNull
. It does not consider
about masquerade-as-undefined objects, so that we can use it instead of
value === null || value === @undefined
. We introduce is_undefined_or_null
bytecode, IsUndefinedOrNull DFG node and its DFG and FTL backends. Since
Null and Undefined have some bit patterns, we can implement this query
very efficiently.
- builtins/ArrayIteratorPrototype.js:
(next):
- builtins/ArrayPrototype.js:
(globalPrivate.arraySpeciesCreate):
- builtins/GlobalOperations.js:
(globalPrivate.speciesConstructor):
(globalPrivate.copyDataProperties):
(globalPrivate.copyDataPropertiesNoExclusions):
- builtins/MapIteratorPrototype.js:
(next):
- builtins/SetIteratorPrototype.js:
(next):
- builtins/StringIteratorPrototype.js:
(next):
- builtins/StringPrototype.js:
(match):
(repeat):
(padStart):
(padEnd):
(intrinsic.StringPrototypeReplaceIntrinsic.replace):
(search):
(split):
(concat):
(globalPrivate.createHTML):
- builtins/TypedArrayPrototype.js:
(globalPrivate.typedArraySpeciesConstructor):
(map):
(filter):
- bytecode/BytecodeIntrinsicRegistry.h:
- bytecode/BytecodeList.rb:
- bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
- bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitIsUndefinedOrNull):
- bytecompiler/BytecodeGenerator.h:
- bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_isUndefinedOrNull):
- dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
- dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::capabilityLevel):
(JSC::DFG::clobberize):
(JSC::DFG::doesGC):
(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):
(JSC::FTL::canCompile):
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileIsUndefinedOrNull):
(JSC::JIT::privateCompileMainPass):
- jit/JIT.h:
- jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_is_undefined_or_null):
(JSC::JIT::emit_op_is_undefined_or_null):
- llint/LowLevelInterpreter32_64.asm:
- llint/LowLevelInterpreter64.asm: