Changeset 193974 in webkit
- Timestamp:
- Dec 11, 2015 1:43:45 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 64 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r193973 r193974 1 2015-12-11 Keith Miller <keith_miller@apple.com> 2 3 [ES6] Add support for Symbol.hasInstance 4 https://bugs.webkit.org/show_bug.cgi?id=151839 5 6 Reviewed by Saam Barati. 7 8 Fix tests to reflect the changes to instanceof in ES6. 9 10 Added a new regression test for bound functions in instanceof 11 as the perfomance on bound functions should, to some degree, 12 reflect the performance on C-API users. 13 14 * js/Object-getOwnPropertyNames-expected.txt: 15 * js/exception-for-nonobject-expected.txt: 16 * js/exception-instanceof-expected.txt: 17 * js/instance-of-immediates-expected.txt: 18 * js/regress/instanceof-bound-expected.txt: Added. 19 * js/regress/instanceof-bound.html: Added. 20 * js/regress/script-tests/instanceof-bound.js: Added. 21 (Constructor): 22 (test): 23 * js/script-tests/Object-getOwnPropertyNames.js: 24 1 25 2015-12-11 Ryan Haddad <ryanhaddad@apple.com> 2 26 -
trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt
r191864 r193974 62 62 PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc'] 63 63 PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify'] 64 PASS getSortedOwnPropertyNames(Symbol) is ['for', ' iterator', 'keyFor', 'length', 'name', 'prototype', 'toStringTag', 'unscopables']64 PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'toStringTag', 'unscopables'] 65 65 PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf'] 66 66 PASS globalPropertyNames.indexOf('NaN') != -1 is true -
trunk/LayoutTests/js/exception-for-nonobject-expected.txt
r181889 r193974 5 5 6 6 PASS new {}.undefined threw exception TypeError: undefined is not a constructor (evaluating 'new {}.undefined'). 7 PASS 1 instanceof {}.undefined threw exception TypeError: {}.undefined is not a function. (evaluating '1 instanceof {}.undefined').7 PASS 1 instanceof {}.undefined threw exception TypeError: Right hand side of instanceof is not an object. 8 8 PASS successfullyParsed is true 9 9 -
trunk/LayoutTests/js/exception-instanceof-expected.txt
r181889 r193974 4 4 5 5 6 PASS 'instanceof' instanceof 'instanceof' threw exception TypeError: "instanceof" is not a function. (evaluating ''instanceof' instanceof 'instanceof'').7 PASS 20 instanceof 'hello' threw exception TypeError: 'hello' is not a function. (evaluating '20 instanceof 'hello'').6 PASS 'instanceof' instanceof 'instanceof' threw exception TypeError: Right hand side of instanceof is not an object. 7 PASS 20 instanceof 'hello' threw exception TypeError: Right hand side of instanceof is not an object. 8 8 PASS 20 instanceof {} threw exception TypeError: {} is not a function. (evaluating '20 instanceof {}'). 9 PASS 20 instanceof {}.foo threw exception TypeError: {}.foo is not a function. (evaluating '20 instanceof {}.foo').10 PASS 20 instanceof true threw exception TypeError: true is not a function. (evaluating '20 instanceof true').9 PASS 20 instanceof {}.foo threw exception TypeError: Right hand side of instanceof is not an object. 10 PASS 20 instanceof true threw exception TypeError: Right hand side of instanceof is not an object. 11 11 PASS successfullyParsed is true 12 12 -
trunk/LayoutTests/js/instance-of-immediates-expected.txt
r181889 r193974 4 4 5 5 6 PASS (1 instanceof 1) threw exception TypeError: 1 is not a function. (evaluating '1 instanceof 1').7 PASS ({} instanceof 1) threw exception TypeError: 1 is not a function. (evaluating '{} instanceof 1').8 PASS (obj instanceof 1) threw exception TypeError: 1 is not a function. (evaluating 'obj instanceof 1').6 PASS (1 instanceof 1) threw exception TypeError: Right hand side of instanceof is not an object. 7 PASS ({} instanceof 1) threw exception TypeError: Right hand side of instanceof is not an object. 8 PASS (obj instanceof 1) threw exception TypeError: Right hand side of instanceof is not an object. 9 9 PASS (1 instanceof {}) threw exception TypeError: {} is not a function. (evaluating '1 instanceof {}'). 10 10 PASS ({} instanceof {}) threw exception TypeError: {} is not a function. (evaluating '{} instanceof {}'). -
trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js
r191864 r193974 71 71 "Math": "['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']", 72 72 "JSON": "['parse', 'stringify']", 73 "Symbol": "['for', ' iterator', 'keyFor', 'length', 'name', 'prototype', 'toStringTag', 'unscopables']",73 "Symbol": "['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'toStringTag', 'unscopables']", 74 74 "Symbol.prototype": "['constructor', 'toString', 'valueOf']" 75 75 }; -
trunk/Source/JavaScriptCore/API/JSCallbackObject.h
r187587 r193974 128 128 public: 129 129 typedef Parent Base; 130 static const unsigned StructureFlags = Base::StructureFlags | ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesGetPropertyNames | TypeOfShouldCallGetCallData;130 static const unsigned StructureFlags = Base::StructureFlags | ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstanceFlag | OverridesGetPropertyNames | TypeOfShouldCallGetCallData; 131 131 132 132 ~JSCallbackObject(); -
trunk/Source/JavaScriptCore/ChangeLog
r193972 r193974 1 2015-12-11 Keith Miller <keith_miller@apple.com> 2 3 [ES6] Add support for Symbol.hasInstance 4 https://bugs.webkit.org/show_bug.cgi?id=151839 5 6 Reviewed by Saam Barati. 7 8 This patch adds support for Symbol.hasInstance, unfortunately in order to prevent 9 regressions several new bytecodes and DFG IR nodes were necessary. Before, Symbol.hasInstance 10 when executing an instanceof expression we would emit three bytecodes: overrides_has_instance, get_by_id, 11 then instanceof. As the spec has changed, we emit a more complicated set of bytecodes in addition to some 12 new ones. First the role of overrides_has_instance and its corresponding DFG node have changed. Now it returns 13 a js-boolean indicating whether the RHS of the instanceof expression (from here on called the constructor for simplicity) 14 needs non-default behavior for resolving the expression. i.e. The constructor has a Symbol.hasInstance that differs from the one on 15 Function.prototype[Symbol.hasInstance] or is a bound/C-API function. Once we get to the DFG this node is generally eliminated as 16 we can prove the value of Symbol.hasInstance is a constant. The second new bytecode is instanceof_custom. insntanceof_custom, just 17 emits a call to slow path code that computes the result. 18 19 In the DFG, there is also a new node, CheckTypeInfoFlags, which checks the type info flags are consistent with the ones provided and 20 OSR exits if the flags are not. Additionally, we attempt to prove that the result of CheckHasValue will be a constant and transform 21 it into a CheckTypeInfoFlags followed by a JSConstant. 22 23 * API/JSCallbackObject.h: 24 * builtins/FunctionPrototype.js: 25 (symbolHasInstance): 26 * bytecode/BytecodeBasicBlock.cpp: 27 (JSC::isBranch): Deleted. 28 * bytecode/BytecodeList.json: 29 * bytecode/BytecodeUseDef.h: 30 (JSC::computeUsesForBytecodeOffset): 31 (JSC::computeDefsForBytecodeOffset): 32 * bytecode/CodeBlock.cpp: 33 (JSC::CodeBlock::dumpBytecode): 34 * bytecode/ExitKind.cpp: 35 (JSC::exitKindToString): 36 * bytecode/ExitKind.h: 37 * bytecode/PreciseJumpTargets.cpp: 38 (JSC::getJumpTargetsForBytecodeOffset): Deleted. 39 * bytecompiler/BytecodeGenerator.cpp: 40 (JSC::BytecodeGenerator::emitOverridesHasInstance): 41 (JSC::BytecodeGenerator::emitInstanceOfCustom): 42 (JSC::BytecodeGenerator::emitCheckHasInstance): Deleted. 43 * bytecompiler/BytecodeGenerator.h: 44 * bytecompiler/NodesCodegen.cpp: 45 (JSC::InstanceOfNode::emitBytecode): 46 * dfg/DFGAbstractInterpreterInlines.h: 47 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 48 * dfg/DFGByteCodeParser.cpp: 49 (JSC::DFG::ByteCodeParser::parseBlock): 50 * dfg/DFGCapabilities.cpp: 51 (JSC::DFG::capabilityLevel): 52 * dfg/DFGClobberize.h: 53 (JSC::DFG::clobberize): 54 * dfg/DFGDoesGC.cpp: 55 (JSC::DFG::doesGC): 56 * dfg/DFGFixupPhase.cpp: 57 (JSC::DFG::FixupPhase::fixupNode): 58 * dfg/DFGHeapLocation.cpp: 59 (WTF::printInternal): 60 * dfg/DFGHeapLocation.h: 61 * dfg/DFGNode.h: 62 (JSC::DFG::Node::hasCellOperand): 63 (JSC::DFG::Node::hasTypeInfoOperand): 64 (JSC::DFG::Node::typeInfoOperand): 65 * dfg/DFGNodeType.h: 66 * dfg/DFGPredictionPropagationPhase.cpp: 67 (JSC::DFG::PredictionPropagationPhase::propagate): 68 * dfg/DFGSafeToExecute.h: 69 (JSC::DFG::safeToExecute): 70 * dfg/DFGSpeculativeJIT.cpp: 71 (JSC::DFG::SpeculativeJIT::compileCheckTypeInfoFlags): 72 (JSC::DFG::SpeculativeJIT::compileInstanceOfCustom): 73 * dfg/DFGSpeculativeJIT.h: 74 (JSC::DFG::SpeculativeJIT::callOperation): 75 * dfg/DFGSpeculativeJIT32_64.cpp: 76 (JSC::DFG::SpeculativeJIT::compile): 77 * dfg/DFGSpeculativeJIT64.cpp: 78 (JSC::DFG::SpeculativeJIT::compile): 79 * ftl/FTLCapabilities.cpp: 80 (JSC::FTL::canCompile): 81 * ftl/FTLIntrinsicRepository.h: 82 * ftl/FTLLowerDFGToLLVM.cpp: 83 (JSC::FTL::DFG::LowerDFGToLLVM::compileNode): 84 (JSC::FTL::DFG::LowerDFGToLLVM::compileOverridesHasInstance): 85 (JSC::FTL::DFG::LowerDFGToLLVM::compileCheckTypeInfoFlags): 86 (JSC::FTL::DFG::LowerDFGToLLVM::compileInstanceOfCustom): 87 (JSC::FTL::DFG::LowerDFGToLLVM::compileCheckHasInstance): Deleted. 88 * jit/JIT.cpp: 89 (JSC::JIT::privateCompileMainPass): 90 (JSC::JIT::privateCompileSlowCases): 91 * jit/JIT.h: 92 * jit/JITInlines.h: 93 (JSC::JIT::callOperation): 94 * jit/JITOpcodes.cpp: 95 (JSC::JIT::emit_op_overrides_has_instance): 96 (JSC::JIT::emit_op_instanceof): 97 (JSC::JIT::emit_op_instanceof_custom): 98 (JSC::JIT::emitSlow_op_instanceof): 99 (JSC::JIT::emitSlow_op_instanceof_custom): 100 (JSC::JIT::emit_op_check_has_instance): Deleted. 101 (JSC::JIT::emitSlow_op_check_has_instance): Deleted. 102 * jit/JITOpcodes32_64.cpp: 103 (JSC::JIT::emit_op_overrides_has_instance): 104 (JSC::JIT::emit_op_instanceof): 105 (JSC::JIT::emit_op_instanceof_custom): 106 (JSC::JIT::emitSlow_op_instanceof_custom): 107 (JSC::JIT::emit_op_check_has_instance): Deleted. 108 (JSC::JIT::emitSlow_op_check_has_instance): Deleted. 109 * jit/JITOperations.cpp: 110 * jit/JITOperations.h: 111 * llint/LLIntData.cpp: 112 (JSC::LLInt::Data::performAssertions): 113 * llint/LLIntSlowPaths.cpp: 114 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 115 * llint/LLIntSlowPaths.h: 116 * llint/LowLevelInterpreter32_64.asm: 117 * llint/LowLevelInterpreter64.asm: 118 * runtime/CommonIdentifiers.h: 119 * runtime/ExceptionHelpers.cpp: 120 (JSC::invalidParameterInstanceofSourceAppender): 121 (JSC::invalidParameterInstanceofNotFunctionSourceAppender): 122 (JSC::invalidParameterInstanceofhasInstanceValueNotFunctionSourceAppender): 123 (JSC::createInvalidInstanceofParameterErrorNotFunction): 124 (JSC::createInvalidInstanceofParameterErrorhasInstanceValueNotFunction): 125 (JSC::createInvalidInstanceofParameterError): Deleted. 126 * runtime/ExceptionHelpers.h: 127 * runtime/FunctionPrototype.cpp: 128 (JSC::FunctionPrototype::addFunctionProperties): 129 * runtime/FunctionPrototype.h: 130 * runtime/JSBoundFunction.cpp: 131 (JSC::isBoundFunction): 132 (JSC::hasInstanceBoundFunction): 133 * runtime/JSBoundFunction.h: 134 * runtime/JSGlobalObject.cpp: 135 (JSC::JSGlobalObject::init): 136 (JSC::JSGlobalObject::visitChildren): 137 * runtime/JSGlobalObject.h: 138 (JSC::JSGlobalObject::functionProtoHasInstanceSymbolFunction): 139 * runtime/JSObject.cpp: 140 (JSC::JSObject::hasInstance): 141 (JSC::objectPrivateFuncInstanceOf): 142 * runtime/JSObject.h: 143 * runtime/JSTypeInfo.h: 144 (JSC::TypeInfo::TypeInfo): 145 (JSC::TypeInfo::overridesHasInstance): 146 * runtime/WriteBarrier.h: 147 (JSC::WriteBarrierBase<Unknown>::slot): 148 * tests/es6.yaml: 149 * tests/stress/instanceof-custom-hasinstancesymbol.js: Added. 150 (Constructor): 151 (value): 152 (instanceOf): 153 (body): 154 * tests/stress/symbol-hasInstance.js: Added. 155 (Constructor): 156 (value): 157 (ObjectClass.Symbol.hasInstance): 158 (NumberClass.Symbol.hasInstance): 159 1 160 2015-12-11 Joseph Pecoraro <pecoraro@apple.com> 2 161 -
trunk/Source/JavaScriptCore/builtins/FunctionPrototype.js
r192751 r193974 37 37 return this.@apply(thisValue, argumentValues); 38 38 } 39 40 // FIXME: this should have a different name: https://bugs.webkit.org/show_bug.cgi?id=151363 41 function symbolHasInstance(value) 42 { 43 "use strict"; 44 45 if (typeof this !== "function") 46 return false; 47 48 if (@isBoundFunction(this)) 49 return @hasInstanceBoundFunction(this, value); 50 51 let target = this.prototype; 52 return @instanceOf(value, target); 53 } -
trunk/Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp
r192937 r193974 59 59 case op_switch_char: 60 60 case op_switch_string: 61 case op_check_has_instance:62 61 case op_save: 63 62 return true; -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r193766 r193974 46 46 { "name" : "op_bitxor", "length" : 5 }, 47 47 { "name" : "op_bitor", "length" : 5 }, 48 { "name" : "op_ check_has_instance", "length" : 5},48 { "name" : "op_overrides_has_instance", "length" : 4 }, 49 49 { "name" : "op_instanceof", "length" : 4 }, 50 { "name" : "op_instanceof_custom", "length" : 5 }, 50 51 { "name" : "op_typeof", "length" : 3 }, 51 52 { "name" : "op_is_undefined", "length" : 3 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r193766 r193974 170 170 case op_in: 171 171 case op_instanceof: 172 case op_check_has_instance:173 172 case op_add: 174 173 case op_mul: … … 196 195 return; 197 196 } 197 case op_overrides_has_instance: 198 case op_instanceof_custom: 198 199 case op_has_structure_property: 199 200 case op_construct_varargs: … … 351 352 case op_get_by_id: 352 353 case op_get_array_length: 353 case op_ check_has_instance:354 case op_overrides_has_instance: 354 355 case op_instanceof: 356 case op_instanceof_custom: 355 357 case op_get_by_val: 356 358 case op_typeof: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r193766 r193974 1014 1014 break; 1015 1015 } 1016 case op_ check_has_instance: {1016 case op_overrides_has_instance: { 1017 1017 int r0 = (++it)->u.operand; 1018 1018 int r1 = (++it)->u.operand; 1019 1019 int r2 = (++it)->u.operand; 1020 int offset = (++it)->u.operand; 1021 printLocationAndOp(out, exec, location, it, "check_has_instance"); 1022 out.printf("%s, %s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), offset, location + offset); 1020 printLocationAndOp(out, exec, location, it, "overrides_has_instance"); 1021 out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); 1023 1022 break; 1024 1023 } … … 1029 1028 printLocationAndOp(out, exec, location, it, "instanceof"); 1030 1029 out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); 1030 break; 1031 } 1032 case op_instanceof_custom: { 1033 int r0 = (++it)->u.operand; 1034 int r1 = (++it)->u.operand; 1035 int r2 = (++it)->u.operand; 1036 int r3 = (++it)->u.operand; 1037 printLocationAndOp(out, exec, location, it, "instanceof_custom"); 1038 out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); 1031 1039 break; 1032 1040 } -
trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp
r188299 r193974 51 51 case BadIndexingType: 52 52 return "BadIndexingType"; 53 case BadTypeInfoFlags: 54 return "BadTypeInfoFlags"; 53 55 case Overflow: 54 56 return "Overflow"; -
trunk/Source/JavaScriptCore/bytecode/ExitKind.h
r188299 r193974 38 38 BadConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong. 39 39 BadIndexingType, // We exited because an indexing type was wrong. 40 BadTypeInfoFlags, // We exited because we made an incorrect assumption about what TypeInfo flags we would see. 40 41 Overflow, // We exited because of overflow. 41 42 NegativeZero, // We exited because we encountered negative zero. -
trunk/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp
r192937 r193974 75 75 break; 76 76 } 77 case op_check_has_instance:78 out.append(bytecodeOffset + current[4].u.operand);79 break;80 77 case op_loop_hint: 81 78 out.append(bytecodeOffset); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r193842 r193974 2100 2100 } 2101 2101 2102 void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target) 2103 { 2104 size_t begin = instructions().size(); 2105 emitOpcode(op_check_has_instance); 2102 RegisterID* BytecodeGenerator::emitOverridesHasInstance(RegisterID* dst, RegisterID* constructor, RegisterID* hasInstanceValue) 2103 { 2104 emitOpcode(op_overrides_has_instance); 2106 2105 instructions().append(dst->index()); 2107 instructions().append( value->index());2108 instructions().append( base->index());2109 instructions().append(target->bind(begin, instructions().size()));2106 instructions().append(constructor->index()); 2107 instructions().append(hasInstanceValue->index()); 2108 return dst; 2110 2109 } 2111 2110 … … 2271 2270 instructions().append(value->index()); 2272 2271 instructions().append(basePrototype->index()); 2272 return dst; 2273 } 2274 2275 RegisterID* BytecodeGenerator::emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue) 2276 { 2277 emitOpcode(op_instanceof_custom); 2278 instructions().append(dst->index()); 2279 instructions().append(value->index()); 2280 instructions().append(constructor->index()); 2281 instructions().append(hasInstanceValue->index()); 2273 2282 return dst; 2274 2283 } -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r193842 r193974 535 535 RegisterID* emitDec(RegisterID* srcDst); 536 536 537 void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target);537 RegisterID* emitOverridesHasInstance(RegisterID* dst, RegisterID* constructor, RegisterID* hasInstanceValue); 538 538 RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype); 539 RegisterID* emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue); 539 540 RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); } 540 541 RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); } -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r193766 r193974 1660 1660 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1661 1661 { 1662 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 1663 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2); 1662 RefPtr<RegisterID> hasInstanceValue = generator.newTemporary(); 1663 RefPtr<RegisterID> isObject = generator.newTemporary(); 1664 RefPtr<RegisterID> isCustom = generator.newTemporary(); 1664 1665 RefPtr<RegisterID> prototype = generator.newTemporary(); 1665 RefPtr<RegisterID> dstReg = generator.finalDestination(dst, src1.get()); 1666 RefPtr<Label> target = generator.newLabel(); 1666 RefPtr<RegisterID> value = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 1667 RefPtr<RegisterID> constructor = generator.emitNode(m_expr2); 1668 RefPtr<RegisterID> dstReg = generator.finalDestination(dst, value.get()); 1669 RefPtr<Label> custom = generator.newLabel(); 1670 RefPtr<Label> done = generator.newLabel(); 1671 RefPtr<Label> typeError = generator.newLabel(); 1667 1672 1668 1673 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1669 generator.emitCheckHasInstance(dstReg.get(), src1.get(), src2.get(), target.get()); 1674 generator.emitIsObject(isObject.get(), constructor.get()); 1675 generator.emitJumpIfFalse(isObject.get(), typeError.get()); 1670 1676 1671 1677 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1672 generator.emitGetById( prototype.get(), src2.get(), generator.vm()->propertyNames->prototype);1678 generator.emitGetById(hasInstanceValue.get(), constructor.get(), generator.vm()->propertyNames->hasInstanceSymbol); 1673 1679 1674 1680 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1675 RegisterID* result = generator.emitInstanceOf(dstReg.get(), src1.get(), prototype.get()); 1676 generator.emitLabel(target.get()); 1677 return result; 1681 generator.emitOverridesHasInstance(isCustom.get(), constructor.get(), hasInstanceValue.get()); 1682 1683 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1684 generator.emitJumpIfTrue(isCustom.get(), custom.get()); 1685 1686 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1687 generator.emitGetById(prototype.get(), constructor.get(), generator.vm()->propertyNames->prototype); 1688 1689 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1690 generator.emitInstanceOf(dstReg.get(), value.get(), prototype.get()); 1691 1692 generator.emitJump(done.get()); 1693 1694 generator.emitLabel(typeError.get()); 1695 generator.emitThrowTypeError("Right hand side of instanceof is not an object"); 1696 1697 generator.emitLabel(custom.get()); 1698 1699 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1700 generator.emitInstanceOfCustom(dstReg.get(), value.get(), constructor.get(), hasInstanceValue.get()); 1701 1702 generator.emitLabel(done.get()); 1703 1704 return dstReg.get(); 1678 1705 } 1679 1706 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r193781 r193974 2449 2449 break; 2450 2450 2451 case CheckHasInstance:2452 // Sadly, we don't propagate the fact that we've done CheckHasInstance2451 case OverridesHasInstance: 2452 forNode(node).setType(SpecBoolean); 2453 2453 break; 2454 2454 2455 2455 case InstanceOf: 2456 // Again, sadly, we don't propagate the fact that we've done InstanceOf 2456 // Sadly, we don't propagate the fact that we've done InstanceOf 2457 forNode(node).setType(SpecBoolean); 2458 break; 2459 2460 case InstanceOfCustom: 2461 clobberWorld(node->origin.semantic, clobberLimit); 2457 2462 forNode(node).setType(SpecBoolean); 2458 2463 break; … … 2511 2516 case CheckTierUpInLoop: 2512 2517 case CheckTierUpAtReturn: 2518 case CheckTypeInfoFlags: 2513 2519 break; 2514 2520 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r193766 r193974 3498 3498 } 3499 3499 3500 case op_check_has_instance: 3501 addToGraph(CheckHasInstance, get(VirtualRegister(currentInstruction[3].u.operand))); 3502 NEXT_OPCODE(op_check_has_instance); 3500 case op_overrides_has_instance: { 3501 JSFunction* defaultHasInstanceSymbolFunction = m_inlineStackTop->m_codeBlock->globalObjectFor(currentCodeOrigin())->functionProtoHasInstanceSymbolFunction(); 3502 3503 Node* constructor = get(VirtualRegister(currentInstruction[2].u.operand)); 3504 Node* hasInstanceValue = get(VirtualRegister(currentInstruction[3].u.operand)); 3505 3506 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(OverridesHasInstance, OpInfo(m_graph.freeze(defaultHasInstanceSymbolFunction)), constructor, hasInstanceValue)); 3507 NEXT_OPCODE(op_overrides_has_instance); 3508 } 3503 3509 3504 3510 case op_instanceof: { … … 3508 3514 NEXT_OPCODE(op_instanceof); 3509 3515 } 3510 3516 3517 case op_instanceof_custom: { 3518 Node* value = get(VirtualRegister(currentInstruction[2].u.operand)); 3519 Node* constructor = get(VirtualRegister(currentInstruction[3].u.operand)); 3520 Node* hasInstanceValue = get(VirtualRegister(currentInstruction[4].u.operand)); 3521 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(InstanceOfCustom, value, constructor, hasInstanceValue)); 3522 NEXT_OPCODE(op_instanceof_custom); 3523 } 3524 3511 3525 case op_is_undefined: { 3512 3526 Node* value = get(VirtualRegister(currentInstruction[2].u.operand)); -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r193766 r193974 129 129 case op_profile_control_flow: 130 130 case op_mov: 131 case op_ check_has_instance:131 case op_overrides_has_instance: 132 132 case op_instanceof: 133 case op_instanceof_custom: 133 134 case op_is_undefined: 134 135 case op_is_boolean: -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r193781 r193974 728 728 return; 729 729 730 case Check HasInstance:730 case CheckTypeInfoFlags: 731 731 read(JSCell_typeInfoFlags); 732 def(HeapLocation(CheckHasInstanceLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node)); 732 def(HeapLocation(CheckTypeInfoFlagsLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node)); 733 return; 734 735 case OverridesHasInstance: 736 read(JSCell_typeInfoFlags); 737 def(HeapLocation(OverridesHasInstanceLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node)); 733 738 return; 734 739 … … 736 741 read(JSCell_structureID); 737 742 def(HeapLocation(InstanceOfLoc, JSCell_structureID, node->child1(), node->child2()), LazyNode(node)); 743 return; 744 745 case InstanceOfCustom: 746 read(World); 747 write(Heap); 738 748 return; 739 749 -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r193766 r193974 142 142 case ProfileType: 143 143 case ProfileControlFlow: 144 case CheckHasInstance:144 case OverridesHasInstance: 145 145 case InstanceOf: 146 case InstanceOfCustom: 146 147 case IsUndefined: 147 148 case IsBoolean: … … 181 182 case ConstantStoragePointer: 182 183 case Check: 184 case CheckTypeInfoFlags: 183 185 case MultiGetByOffset: 184 186 case ValueRep: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r193781 r193974 1101 1101 break; 1102 1102 } 1103 1104 case OverridesHasInstance: { 1105 if (node->child2().node()->isCellConstant()) { 1106 if (node->child2().node()->asCell() != m_graph.globalObjectFor(node->origin.semantic)->functionProtoHasInstanceSymbolFunction()) { 1107 1108 m_graph.convertToConstant(node, jsBoolean(true)); 1109 break; 1110 } 1111 1112 if (!m_graph.hasExitSite(node->origin.semantic, BadTypeInfoFlags)) { 1113 // Here we optimistically assume that we will not see an bound/C-API function here. 1114 m_insertionSet.insertNode(m_indexInBlock, SpecNone, CheckTypeInfoFlags, node->origin, OpInfo(ImplementsDefaultHasInstance), Edge(node->child1().node(), CellUse)); 1115 m_graph.convertToConstant(node, jsBoolean(false)); 1116 break; 1117 } 1118 } 1119 1120 fixEdge<CellUse>(node->child1()); 1121 break; 1122 } 1103 1123 1104 1124 case CheckStructure: 1105 1125 case CheckCell: 1106 case CheckHasInstance:1107 1126 case CreateThis: 1108 1127 case GetButterfly: … … 1165 1184 break; 1166 1185 } 1167 1186 1187 case InstanceOfCustom: 1188 fixEdge<CellUse>(node->child2()); 1189 break; 1190 1168 1191 case In: { 1169 1192 // FIXME: We should at some point have array profiling on op_in, in which … … 1411 1434 case VarInjectionWatchpoint: 1412 1435 case Call: 1436 case CheckTypeInfoFlags: 1413 1437 case TailCallInlinedCaller: 1414 1438 case Construct: -
trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
r190896 r193974 96 96 out.print("ButterflyReadOnlyLoc"); 97 97 return; 98 99 case CheckHasInstanceLoc: 100 out.print("CheckHasInstanceLoc"); 98 99 case CheckTypeInfoFlagsLoc: 100 out.print("CheckTypeInfoFlagsLoc"); 101 return; 102 103 case OverridesHasInstanceLoc: 104 out.print("OverridesHasInstanceLoc"); 101 105 return; 102 106 -
trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h
r190896 r193974 41 41 ButterflyLoc, 42 42 ButterflyReadOnlyLoc, 43 CheckHasInstanceLoc, 43 CheckTypeInfoFlagsLoc, 44 OverridesHasInstanceLoc, 44 45 ClosureVariableLoc, 45 46 DirectArgumentsLoc, -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r193470 r193974 1355 1355 switch (op()) { 1356 1356 case CheckCell: 1357 case OverridesHasInstance: 1357 1358 case NewFunction: 1358 1359 case NewArrowFunction: … … 1414 1415 ASSERT(hasUidOperand()); 1415 1416 return reinterpret_cast<UniquedStringImpl*>(m_opInfo); 1417 } 1418 1419 bool hasTypeInfoOperand() 1420 { 1421 return op() == CheckTypeInfoFlags; 1422 } 1423 1424 unsigned typeInfoOperand() 1425 { 1426 ASSERT(hasTypeInfoOperand() && m_opInfo <= UCHAR_MAX); 1427 return static_cast<unsigned>(m_opInfo); 1416 1428 } 1417 1429 -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r193766 r193974 222 222 macro(CheckInBounds, NodeMustGenerate) \ 223 223 macro(CheckIdent, NodeMustGenerate) \ 224 macro(CheckTypeInfoFlags, NodeMustGenerate) /* Takes an OpInfo with the flags you want to test are set */\ 224 225 \ 225 226 /* Optimizations for array mutation. */\ … … 279 280 macro(ProfileWillCall, NodeMustGenerate) \ 280 281 macro(ProfileDidCall, NodeMustGenerate) \ 281 macro( CheckHasInstance, NodeMustGenerate) \282 macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \ 282 283 macro(InstanceOf, NodeResultBoolean) \ 284 macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \ 283 285 macro(IsUndefined, NodeResultBoolean) \ 284 286 macro(IsBoolean, NodeResultBoolean) \ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r193781 r193974 403 403 case CompareEq: 404 404 case CompareStrictEq: 405 case OverridesHasInstance: 405 406 case InstanceOf: 407 case InstanceOfCustom: 406 408 case IsUndefined: 407 409 case IsBoolean: … … 570 572 case GetLocalUnlinked: 571 573 case CheckArray: 574 case CheckTypeInfoFlags: 572 575 case Arrayify: 573 576 case ArrayifyToStructure: … … 681 684 case ProfileType: 682 685 case ProfileControlFlow: 683 case CheckHasInstance:684 686 case ThrowReferenceError: 685 687 case ForceOSRExit: -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r193766 r193974 242 242 case ProfileType: 243 243 case ProfileControlFlow: 244 case CheckHasInstance: 244 case CheckTypeInfoFlags: 245 case OverridesHasInstance: 245 246 case InstanceOf: 247 case InstanceOfCustom: 246 248 case IsUndefined: 247 249 case IsBoolean: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r193795 r193974 2739 2739 } 2740 2740 2741 void SpeculativeJIT::compileCheckTypeInfoFlags(Node* node) 2742 { 2743 SpeculateCellOperand base(this, node->child1()); 2744 2745 GPRReg baseGPR = base.gpr(); 2746 2747 speculationCheck(BadTypeInfoFlags, JSValueRegs(), 0, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(baseGPR, JSCell::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(node->typeInfoOperand()))); 2748 2749 noResult(node); 2750 } 2751 2741 2752 void SpeculativeJIT::compileInstanceOf(Node* node) 2742 2753 { … … 2949 2960 jsValueResult(resultRegs, node); 2950 2961 return; 2962 } 2963 2964 void SpeculativeJIT::compileInstanceOfCustom(Node* node) 2965 { 2966 // We could do something smarter here but this case is currently super rare and unless 2967 // Symbol.hasInstance becomes popular will likely remain that way. 2968 2969 JSValueOperand value(this, node->child1()); 2970 SpeculateCellOperand constructor(this, node->child2()); 2971 JSValueOperand hasInstanceValue(this, node->child3()); 2972 GPRTemporary result(this); 2973 2974 JSValueRegs valueRegs = value.jsValueRegs(); 2975 GPRReg constructorGPR = constructor.gpr(); 2976 JSValueRegs hasInstanceRegs = hasInstanceValue.jsValueRegs(); 2977 GPRReg resultGPR = result.gpr(); 2978 2979 MacroAssembler::Jump slowCase = m_jit.jump(); 2980 2981 addSlowPathGenerator(slowPathCall(slowCase, this, operationInstanceOfCustom, resultGPR, valueRegs, constructorGPR, hasInstanceRegs)); 2982 2983 unblessedBooleanResult(resultGPR, node); 2951 2984 } 2952 2985 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r193795 r193974 728 728 void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg); 729 729 void compileInstanceOf(Node*); 730 void compileInstanceOfCustom(Node*); 730 731 731 732 void emitCall(Node*); … … 1512 1513 return appendCallSetResult(operation, result); 1513 1514 } 1515 1516 JITCompiler::Call callOperation(Z_JITOperation_EJOJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) 1517 { 1518 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); 1519 return appendCallSetResult(operation, result); 1520 } 1521 JITCompiler::Call callOperation(Z_JITOperation_EJOJ operation, GPRReg result, JSValueRegs arg1, GPRReg arg2, JSValueRegs arg3) 1522 { 1523 return callOperation(operation, result, arg1.payloadGPR(), arg2, arg3.payloadGPR()); 1524 } 1525 1514 1526 JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, unsigned arg2) 1515 1527 { … … 1831 1843 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag); 1832 1844 return appendCall(operation); 1845 } 1846 1847 JITCompiler::Call callOperation(Z_JITOperation_EJOJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) 1848 { 1849 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); 1850 return appendCallSetResult(operation, result); 1851 } 1852 JITCompiler::Call callOperation(Z_JITOperation_EJOJ operation, GPRReg result, JSValueRegs arg1, GPRReg arg2, JSValueRegs arg3) 1853 { 1854 return callOperation(operation, result, arg1.tagGPR(), arg1.payloadGPR(), arg2, arg3.tagGPR(), arg3.payloadGPR()); 1833 1855 } 1834 1856 … … 2205 2227 void compileGetArrayLength(Node*); 2206 2228 2229 void compileCheckTypeInfoFlags(Node*); 2207 2230 void compileCheckIdent(Node*); 2208 2231 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r193795 r193974 4160 4160 } 4161 4161 4162 case CheckHasInstance: { 4162 case CheckTypeInfoFlags: { 4163 compileCheckTypeInfoFlags(node); 4164 break; 4165 } 4166 4167 case OverridesHasInstance: { 4168 4169 Node* hasInstanceValueNode = node->child2().node(); 4170 JSFunction* defaultHasInstanceFunction = jsCast<JSFunction*>(node->cellOperand()->value()); 4171 4172 MacroAssembler::Jump notDefaulthasInstanceValue; 4173 MacroAssembler::Jump hasInstanceValueNotCell; 4163 4174 SpeculateCellOperand base(this, node->child1()); 4164 GPRTemporary structure(this); 4165 4166 // Speculate that base 'ImplementsDefaultHasInstance'. 4167 speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branchTest8( 4168 MacroAssembler::Zero, 4169 MacroAssembler::Address(base.gpr(), JSCell::typeInfoFlagsOffset()), 4170 MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance))); 4171 4172 noResult(node); 4175 JSValueOperand hasInstanceValue(this, node->child2()); 4176 GPRTemporary result(this); 4177 4178 GPRReg resultGPR = result.gpr(); 4179 4180 // If we have proven that the constructor's Symbol.hasInstance will always be the one on 4181 // Function.prototype[Symbol.hasInstance] then we don't need a runtime check here. We don't worry 4182 // about the case where the constructor's Symbol.hasInstance is a constant but is not the default 4183 // one as fixup should have converted this check to true. 4184 ASSERT(!hasInstanceValueNode->isCellConstant() || defaultHasInstanceFunction == hasInstanceValueNode->asCell()); 4185 if (!hasInstanceValueNode->isCellConstant()) { 4186 4187 JSValueRegs hasInstanceValueRegs = hasInstanceValue.jsValueRegs(); 4188 hasInstanceValueNotCell = m_jit.branchIfNotCell(hasInstanceValueRegs); 4189 notDefaulthasInstanceValue = m_jit.branchPtr(MacroAssembler::NotEqual, hasInstanceValueRegs.payloadGPR(), TrustedImmPtr(defaultHasInstanceFunction)); 4190 } 4191 4192 // Check that constructor 'ImplementsDefaultHasInstance'. 4193 m_jit.test8(MacroAssembler::Zero, MacroAssembler::Address(base.gpr(), JSCell::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance), resultGPR); 4194 MacroAssembler::Jump done = m_jit.jump(); 4195 4196 if (!hasInstanceValueNode->isCellConstant()) { 4197 hasInstanceValueNotCell.link(&m_jit); 4198 notDefaulthasInstanceValue.link(&m_jit); 4199 moveTrueTo(resultGPR); 4200 } 4201 4202 done.link(&m_jit); 4203 booleanResult(resultGPR, node); 4173 4204 break; 4174 4205 } … … 4176 4207 case InstanceOf: { 4177 4208 compileInstanceOf(node); 4209 break; 4210 } 4211 4212 case InstanceOfCustom: { 4213 compileInstanceOfCustom(node); 4178 4214 break; 4179 4215 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r193795 r193974 4150 4150 } 4151 4151 4152 case CheckHasInstance: { 4152 case CheckTypeInfoFlags: { 4153 compileCheckTypeInfoFlags(node); 4154 break; 4155 } 4156 4157 case OverridesHasInstance: { 4158 4159 Node* hasInstanceValueNode = node->child2().node(); 4160 JSFunction* defaultHasInstanceFunction = jsCast<JSFunction*>(node->cellOperand()->value()); 4161 4162 MacroAssembler::Jump notDefault; 4153 4163 SpeculateCellOperand base(this, node->child1()); 4154 GPRTemporary structure(this); 4155 4156 // Speculate that base 'ImplementsDefaultHasInstance'. 4157 speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branchTest8( 4158 MacroAssembler::Zero, 4159 MacroAssembler::Address(base.gpr(), JSCell::typeInfoFlagsOffset()), 4160 MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance))); 4161 4162 noResult(node); 4164 JSValueOperand hasInstanceValue(this, node->child2()); 4165 GPRTemporary result(this); 4166 4167 GPRReg resultGPR = result.gpr(); 4168 4169 // If we have proven that the constructor's Symbol.hasInstance will always be the one on Function.prototype[Symbol.hasInstance] 4170 // then we don't need a runtime check here. We don't worry about the case where the constructor's Symbol.hasInstance is a constant 4171 // but is not the default one as fixup should have converted this check to true. 4172 ASSERT(!hasInstanceValueNode->isCellConstant() || defaultHasInstanceFunction == hasInstanceValueNode->asCell()); 4173 if (!hasInstanceValueNode->isCellConstant()) 4174 notDefault = m_jit.branchPtr(MacroAssembler::NotEqual, hasInstanceValue.gpr(), TrustedImmPtr(defaultHasInstanceFunction)); 4175 4176 // Check that base 'ImplementsDefaultHasInstance'. 4177 m_jit.test8(MacroAssembler::Zero, MacroAssembler::Address(base.gpr(), JSCell::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance), resultGPR); 4178 m_jit.or32(TrustedImm32(ValueFalse), resultGPR); 4179 MacroAssembler::Jump done = m_jit.jump(); 4180 4181 if (notDefault.isSet()) { 4182 notDefault.link(&m_jit); 4183 moveTrueTo(resultGPR); 4184 } 4185 4186 done.link(&m_jit); 4187 jsValueResult(resultGPR, node, DataFormatJSBoolean); 4163 4188 break; 4164 4189 } … … 4166 4191 case InstanceOf: { 4167 4192 compileInstanceOf(node); 4193 break; 4194 } 4195 4196 case InstanceOfCustom: { 4197 compileInstanceOfCustom(node); 4168 4198 break; 4169 4199 } -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r193766 r193974 175 175 case IsObjectOrNull: 176 176 case IsFunction: 177 case CheckHasInstance: 177 case CheckTypeInfoFlags: 178 case OverridesHasInstance: 178 179 case InstanceOf: 180 case InstanceOfCustom: 179 181 case DoubleRep: 180 182 case ValueRep: -
trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
r192671 r193974 129 129 macro(Z_JITOperation_EC, functionType(int32, intPtr, intPtr)) \ 130 130 macro(Z_JITOperation_EGC, functionType(int32, intPtr, intPtr, intPtr)) \ 131 macro(Z_JITOperation_EJOJ, functionType(int32, intPtr, int64, intPtr, int64)) \ 131 132 macro(Z_JITOperation_EJZ, functionType(int32, intPtr, int64, int32)) \ 132 133 macro(Z_JITOperation_ESJss, functionType(int32, intPtr, intPtr, int64)) \ -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r193955 r193974 942 942 compileTypeOf(); 943 943 break; 944 case CheckHasInstance: 945 compileCheckHasInstance(); 944 case CheckTypeInfoFlags: 945 compileCheckTypeInfoFlags(); 946 break; 947 case OverridesHasInstance: 948 compileOverridesHasInstance(); 946 949 break; 947 950 case InstanceOf: 948 951 compileInstanceOf(); 952 break; 953 case InstanceOfCustom: 954 compileInstanceOfCustom(); 949 955 break; 950 956 case CountExecution: … … 5716 5722 } 5717 5723 5718 void compileCheckHasInstance() 5724 void compileOverridesHasInstance() 5725 { 5726 JSFunction* defaultHasInstanceFunction = jsCast<JSFunction*>(m_node->cellOperand()->value()); 5727 5728 LValue constructor = lowCell(m_node->child1()); 5729 LValue hasInstance = lowJSValue(m_node->child2()); 5730 5731 LBasicBlock defaultHasInstance = FTL_NEW_BLOCK(m_out, ("OverridesHasInstance Symbol.hasInstance is default")); 5732 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("OverridesHasInstance continuation")); 5733 5734 // Unlike in the DFG, we don't worry about cleaning this code up for the case where we have proven the hasInstanceValue is a constant as LLVM should fix it for us. 5735 5736 ASSERT(!m_node->child2().node()->isCellConstant() || defaultHasInstanceFunction == m_node->child2().node()->asCell()); 5737 5738 ValueFromBlock notDefaultHasInstanceResult = m_out.anchor(m_out.booleanTrue); 5739 m_out.branch(m_out.notEqual(hasInstance, m_out.constIntPtr(defaultHasInstanceFunction)), unsure(continuation), unsure(defaultHasInstance)); 5740 5741 LBasicBlock lastNext = m_out.appendTo(defaultHasInstance, continuation); 5742 ValueFromBlock implementsDefaultHasInstanceResult = m_out.anchor(m_out.testIsZero32( 5743 m_out.load8ZeroExt32(constructor, m_heaps.JSCell_typeInfoFlags), 5744 m_out.constInt32(ImplementsDefaultHasInstance))); 5745 m_out.jump(continuation); 5746 5747 m_out.appendTo(continuation, lastNext); 5748 setBoolean(m_out.phi(m_out.boolean, implementsDefaultHasInstanceResult, notDefaultHasInstanceResult)); 5749 } 5750 5751 void compileCheckTypeInfoFlags() 5719 5752 { 5720 5753 speculate( 5721 Uncountable, noValue(), 0,5754 BadTypeInfoFlags, noValue(), 0, 5722 5755 m_out.testIsZero32( 5723 5756 m_out.load8ZeroExt32(lowCell(m_node->child1()), m_heaps.JSCell_typeInfoFlags), 5724 m_out.constInt32( ImplementsDefaultHasInstance)));5757 m_out.constInt32(m_node->typeInfoOperand()))); 5725 5758 } 5726 5759 … … 5774 5807 setBoolean( 5775 5808 m_out.phi(m_out.boolean, notCellResult, isInstanceResult, notInstanceResult)); 5809 } 5810 5811 void compileInstanceOfCustom() 5812 { 5813 LValue value = lowJSValue(m_node->child1()); 5814 LValue constructor = lowCell(m_node->child2()); 5815 LValue hasInstance = lowJSValue(m_node->child3()); 5816 5817 setBoolean(m_out.bitNot(m_out.equal(m_out.constInt32(0), vmCall(m_out.int32, m_out.operation(operationInstanceOfCustom), m_callFrame, value, constructor, hasInstance)))); 5776 5818 } 5777 5819 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r193766 r193974 229 229 DEFINE_OP(op_get_by_id) 230 230 DEFINE_OP(op_get_by_val) 231 DEFINE_OP(op_ check_has_instance)231 DEFINE_OP(op_overrides_has_instance) 232 232 DEFINE_OP(op_instanceof) 233 DEFINE_OP(op_instanceof_custom) 233 234 DEFINE_OP(op_is_undefined) 234 235 DEFINE_OP(op_is_boolean) … … 400 401 DEFINE_SLOWCASE_OP(op_get_by_id) 401 402 DEFINE_SLOWCASE_OP(op_get_by_val) 402 DEFINE_SLOWCASE_OP(op_check_has_instance)403 403 DEFINE_SLOWCASE_OP(op_instanceof) 404 DEFINE_SLOWCASE_OP(op_instanceof_custom) 404 405 DEFINE_SLOWCASE_OP(op_jfalse) 405 406 DEFINE_SLOWCASE_OP(op_jless) -
trunk/Source/JavaScriptCore/jit/JIT.h
r193788 r193974 510 510 void emit_op_get_argument_by_val(Instruction*); 511 511 void emit_op_init_lazy_reg(Instruction*); 512 void emit_op_ check_has_instance(Instruction*);512 void emit_op_overrides_has_instance(Instruction*); 513 513 void emit_op_instanceof(Instruction*); 514 void emit_op_instanceof_custom(Instruction*); 514 515 void emit_op_is_undefined(Instruction*); 515 516 void emit_op_is_boolean(Instruction*); … … 617 618 void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); 618 619 void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); 619 void emitSlow_op_check_has_instance(Instruction*, Vector<SlowCaseEntry>::iterator&);620 620 void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); 621 void emitSlow_op_instanceof_custom(Instruction*, Vector<SlowCaseEntry>::iterator&); 621 622 void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); 622 623 void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&); … … 745 746 MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*); 746 747 MacroAssembler::Call callOperation(J_JITOperation_EJJBy, int, GPRReg, GPRReg, ByValInfo*); 748 MacroAssembler::Call callOperation(Z_JITOperation_EJOJ, GPRReg, GPRReg, GPRReg); 747 749 MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg); 748 750 MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*); … … 812 814 MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, GPRReg, const Identifier*); 813 815 MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg, GPRReg, GPRReg); 816 MacroAssembler::Call callOperation(Z_JITOperation_EJOJ, GPRReg, GPRReg, GPRReg, GPRReg, GPRReg); 814 817 MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, GPRReg, GPRReg, ArrayProfile*); 815 818 MacroAssembler::Call callOperation(J_JITOperation_EJJBy, int, GPRReg, GPRReg, GPRReg, GPRReg, ByValInfo*); -
trunk/Source/JavaScriptCore/jit/JITInlines.h
r192836 r193974 504 504 } 505 505 506 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJOJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) 507 { 508 setupArgumentsWithExecState(arg1, arg2, arg3); 509 return appendCallWithExceptionCheck(operation); 510 } 511 506 512 ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(V_JITOperation_EJ operation, GPRReg arg1) 507 513 { … … 595 601 updateTopCallFrame(); 596 602 return appendCall(operation); 603 } 604 605 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Z_JITOperation_EJOJ operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) 606 { 607 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); 608 return appendCallWithExceptionCheck(operation); 597 609 } 598 610 -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r193766 r193974 106 106 } 107 107 108 void JIT::emit_op_check_has_instance(Instruction* currentInstruction) 109 { 110 int baseVal = currentInstruction[3].u.operand; 111 112 emitGetVirtualRegister(baseVal, regT0); 113 114 // Check that baseVal is a cell. 115 emitJumpSlowCaseIfNotJSCell(regT0, baseVal); 116 117 // Check that baseVal 'ImplementsHasInstance'. 118 addSlowCase(branchTest8(Zero, Address(regT0, JSCell::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance))); 108 void JIT::emit_op_overrides_has_instance(Instruction* currentInstruction) 109 { 110 int dst = currentInstruction[1].u.operand; 111 int constructor = currentInstruction[2].u.operand; 112 int hasInstanceValue = currentInstruction[3].u.operand; 113 114 emitGetVirtualRegister(hasInstanceValue, regT0); 115 116 // We don't jump if we know what Symbol.hasInstance would do. 117 Jump customhasInstanceValue = branchPtr(NotEqual, regT0, TrustedImmPtr(m_codeBlock->globalObject()->functionProtoHasInstanceSymbolFunction())); 118 119 emitGetVirtualRegister(constructor, regT0); 120 121 // Check that constructor 'ImplementsHasInstance' i.e. the object is a C-API user or a bound function. 122 test8(Zero, Address(regT0, JSCell::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance), regT0); 123 emitTagBool(regT0); 124 Jump done = jump(); 125 126 customhasInstanceValue.link(this); 127 move(TrustedImm32(ValueTrue), regT0); 128 129 done.link(this); 130 emitPutVirtualRegister(dst); 119 131 } 120 132 … … 130 142 emitGetVirtualRegister(proto, regT1); 131 143 132 // Check that proto are cells. baseVal must be a cell - this is checked by op_check_has_instance.144 // Check that proto are cells. baseVal must be a cell - this is checked by the get_by_id for Symbol.hasInstance. 133 145 emitJumpSlowCaseIfNotJSCell(regT2, value); 134 146 emitJumpSlowCaseIfNotJSCell(regT1, proto); … … 156 168 isInstance.link(this); 157 169 emitPutVirtualRegister(dst); 170 } 171 172 void JIT::emit_op_instanceof_custom(Instruction*) 173 { 174 // This always goes to slow path since we expect it to be rare. 175 addSlowCase(jump()); 158 176 } 159 177 … … 830 848 } 831 849 832 void JIT::emitSlow_op_check_has_instance(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)833 {834 int dst = currentInstruction[1].u.operand;835 int value = currentInstruction[2].u.operand;836 int baseVal = currentInstruction[3].u.operand;837 838 linkSlowCaseIfNotJSCell(iter, baseVal);839 linkSlowCase(iter);840 emitGetVirtualRegister(value, regT0);841 emitGetVirtualRegister(baseVal, regT1);842 callOperation(operationCheckHasInstance, dst, regT0, regT1);843 844 emitJumpSlowToHot(jump(), currentInstruction[4].u.operand);845 }846 847 850 void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 848 851 { … … 857 860 emitGetVirtualRegister(proto, regT1); 858 861 callOperation(operationInstanceOf, dst, regT0, regT1); 862 } 863 864 void JIT::emitSlow_op_instanceof_custom(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 865 { 866 int dst = currentInstruction[1].u.operand; 867 int value = currentInstruction[2].u.operand; 868 int constructor = currentInstruction[3].u.operand; 869 int hasInstanceValue = currentInstruction[4].u.operand; 870 871 linkSlowCase(iter); 872 emitGetVirtualRegister(value, regT0); 873 emitGetVirtualRegister(constructor, regT1); 874 emitGetVirtualRegister(hasInstanceValue, regT2); 875 callOperation(operationInstanceOfCustom, regT0, regT1, regT2); 876 emitTagBool(returnValueGPR); 877 emitPutVirtualRegister(dst, returnValueGPR); 859 878 } 860 879 -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r193766 r193974 184 184 } 185 185 186 void JIT::emit_op_check_has_instance(Instruction* currentInstruction) 187 { 188 int baseVal = currentInstruction[3].u.operand; 189 190 emitLoadPayload(baseVal, regT0); 191 192 // Check that baseVal is a cell. 193 emitJumpSlowCaseIfNotJSCell(baseVal); 194 195 // Check that baseVal 'ImplementsHasInstance'. 196 addSlowCase(branchTest8(Zero, Address(regT0, JSCell::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance))); 186 void JIT::emit_op_overrides_has_instance(Instruction* currentInstruction) 187 { 188 int dst = currentInstruction[1].u.operand; 189 int constructor = currentInstruction[2].u.operand; 190 int hasInstanceValue = currentInstruction[3].u.operand; 191 192 emitLoadPayload(hasInstanceValue, regT0); 193 // We don't jump if we know what Symbol.hasInstance would do. 194 Jump hasInstanceValueNotCell = emitJumpIfNotJSCell(hasInstanceValue); 195 Jump customhasInstanceValue = branchPtr(NotEqual, regT0, TrustedImmPtr(m_codeBlock->globalObject()->functionProtoHasInstanceSymbolFunction())); 196 197 // We know that constructor is an object from the way bytecode is emitted for instanceof expressions. 198 emitLoadPayload(constructor, regT0); 199 200 // Check that constructor 'ImplementsHasInstance' i.e. the object is a C-API user or a bound function. 201 test8(Zero, Address(regT0, JSCell::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance), regT0); 202 Jump done = jump(); 203 204 hasInstanceValueNotCell.link(this); 205 customhasInstanceValue.link(this); 206 move(TrustedImm32(1), regT0); 207 208 done.link(this); 209 emitStoreBool(dst, regT0); 210 197 211 } 198 212 … … 208 222 emitLoadPayload(proto, regT1); 209 223 210 // Check that proto are cells. baseVal must be a cell - this is checked by op_check_has_instance.224 // Check that proto are cells. baseVal must be a cell - this is checked by the get_by_id for Symbol.hasInstance. 211 225 emitJumpSlowCaseIfNotJSCell(value); 212 226 emitJumpSlowCaseIfNotJSCell(proto); … … 236 250 } 237 251 238 void JIT::emitSlow_op_check_has_instance(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 239 { 240 int dst = currentInstruction[1].u.operand; 241 int value = currentInstruction[2].u.operand; 242 int baseVal = currentInstruction[3].u.operand; 243 244 linkSlowCaseIfNotJSCell(iter, baseVal); 245 linkSlowCase(iter); 246 247 emitLoad(value, regT1, regT0); 248 emitLoad(baseVal, regT3, regT2); 249 callOperation(operationCheckHasInstance, dst, regT1, regT0, regT3, regT2); 250 251 emitJumpSlowToHot(jump(), currentInstruction[4].u.operand); 252 void JIT::emit_op_instanceof_custom(Instruction*) 253 { 254 // This always goes to slow path since we expect it to be rare. 255 addSlowCase(jump()); 252 256 } 253 257 … … 265 269 emitLoad(proto, regT3, regT2); 266 270 callOperation(operationInstanceOf, dst, regT1, regT0, regT3, regT2); 271 } 272 273 void JIT::emitSlow_op_instanceof_custom(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 274 { 275 int dst = currentInstruction[1].u.operand; 276 int value = currentInstruction[2].u.operand; 277 int constructor = currentInstruction[3].u.operand; 278 int hasInstanceValue = currentInstruction[4].u.operand; 279 280 linkSlowCase(iter); 281 282 emitLoad(value, regT1, regT0); 283 emitLoadPayload(constructor, regT2); 284 emitLoad(hasInstanceValue, regT4, regT3); 285 callOperation(operationInstanceOfCustom, regT1, regT0, regT2, regT4, regT3); 286 emitStoreBool(dst, returnValueGPR); 267 287 } 268 288 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r192937 r193974 1488 1488 } 1489 1489 1490 EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBaseVal)1490 int32_t JIT_OPERATION operationInstanceOfCustom(ExecState* exec, EncodedJSValue encodedValue, JSObject* constructor, EncodedJSValue encodedHasInstance) 1491 1491 { 1492 1492 VM& vm = exec->vm(); … … 1494 1494 1495 1495 JSValue value = JSValue::decode(encodedValue); 1496 JSValue baseVal = JSValue::decode(encodedBaseVal); 1497 1498 if (baseVal.isObject()) { 1499 JSObject* baseObject = asObject(baseVal); 1500 ASSERT(!baseObject->structure(vm)->typeInfo().implementsDefaultHasInstance()); 1501 if (baseObject->structure(vm)->typeInfo().implementsHasInstance()) { 1502 bool result = baseObject->methodTable(vm)->customHasInstance(baseObject, exec, value); 1503 return JSValue::encode(jsBoolean(result)); 1504 } 1505 } 1506 1507 vm.throwException(exec, createInvalidInstanceofParameterError(exec, baseVal)); 1508 return JSValue::encode(JSValue()); 1496 JSValue hasInstanceValue = JSValue::decode(encodedHasInstance); 1497 1498 ASSERT(hasInstanceValue != exec->lexicalGlobalObject()->functionProtoHasInstanceSymbolFunction() || !constructor->structure()->typeInfo().implementsDefaultHasInstance()); 1499 1500 if (constructor->hasInstance(exec, value, hasInstanceValue)) 1501 return 1; 1502 return 0; 1509 1503 } 1510 1504 -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r192937 r193974 176 176 typedef int32_t JIT_OPERATION (*Z_JITOperation_ESJss)(ExecState*, size_t, JSString*); 177 177 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJ)(ExecState*, EncodedJSValue); 178 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJOJ)(ExecState*, EncodedJSValue, JSObject*, EncodedJSValue); 178 179 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t); 179 180 typedef int32_t JIT_OPERATION (*Z_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t); … … 329 330 void JIT_OPERATION operationProfileDidCall(ExecState*, EncodedJSValue) WTF_INTERNAL; 330 331 void JIT_OPERATION operationProfileWillCall(ExecState*, EncodedJSValue) WTF_INTERNAL; 331 EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState*, EncodedJSValue, EncodedJSValue baseVal) WTF_INTERNAL;332 332 EncodedJSValue JIT_OPERATION operationGetByValOptimize(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo*) WTF_INTERNAL; 333 333 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo*) WTF_INTERNAL; … … 358 358 359 359 int32_t JIT_OPERATION operationCheckIfExceptionIsUncatchableAndNotifyProfiler(ExecState*); 360 int32_t JIT_OPERATION operationInstanceOfCustom(ExecState*, EncodedJSValue encodedValue, JSObject* constructor, EncodedJSValue encodedHasInstance) WTF_INTERNAL; 360 361 361 362 EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*); -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r190916 r193974 35 35 #include "Opcode.h" 36 36 #include "PropertyOffset.h" 37 #include "WriteBarrier.h" 37 38 38 39 namespace JSC { namespace LLInt { … … 155 156 ASSERT(ModuleCode == 3); 156 157 158 ASSERT(!(reinterpret_cast<ptrdiff_t>((reinterpret_cast<WriteBarrier<JSCell>*>(0x4000)->slot())) - 0x4000)); 157 159 static_assert(PutByIdPrimaryTypeMask == 0x6, "LLInt assumes PutByIdPrimaryTypeMask is == 0x6"); 158 160 static_assert(PutByIdPrimaryTypeSecondary == 0x0, "LLInt assumes PutByIdPrimaryTypeSecondary is == 0x0"); -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r193766 r193974 523 523 } 524 524 525 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)526 {527 LLINT_BEGIN();528 529 JSValue value = LLINT_OP_C(2).jsValue();530 JSValue baseVal = LLINT_OP_C(3).jsValue();531 if (baseVal.isObject()) {532 JSObject* baseObject = asObject(baseVal);533 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());534 if (baseObject->structure()->typeInfo().implementsHasInstance()) {535 JSValue result = jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value));536 LLINT_RETURN_WITH_PC_ADJUSTMENT(result, pc[4].u.operand);537 }538 }539 LLINT_THROW(createInvalidInstanceofParameterError(exec, baseVal));540 }541 542 525 LLINT_SLOW_PATH_DECL(slow_path_instanceof) 543 526 { … … 547 530 ASSERT(!value.isObject() || !proto.isObject()); 548 531 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto))); 532 } 533 534 LLINT_SLOW_PATH_DECL(slow_path_instanceof_custom) 535 { 536 LLINT_BEGIN(); 537 538 JSValue value = LLINT_OP_C(2).jsValue(); 539 JSValue constructor = LLINT_OP_C(3).jsValue(); 540 JSValue hasInstanceValue = LLINT_OP_C(4).jsValue(); 541 542 ASSERT(constructor.isObject()); 543 ASSERT(hasInstanceValue != exec->lexicalGlobalObject()->functionProtoHasInstanceSymbolFunction() || !constructor.getObject()->structure()->typeInfo().implementsDefaultHasInstance()); 544 545 JSValue result = jsBoolean(constructor.getObject()->hasInstance(exec, value, hasInstanceValue)); 546 LLINT_RETURN(result); 549 547 } 550 548 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r192937 r193974 68 68 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_array_buffer); 69 69 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_regexp); 70 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_check_has_instance);71 70 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof); 71 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof_custom); 72 72 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id); 73 73 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_arguments_length); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r193766 r193974 1176 1176 1177 1177 1178 _llint_op_check_has_instance: 1179 traceExecution() 1180 loadi 12[PC], t1 1181 loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow) 1182 btbz JSCell::m_flags[t0], ImplementsDefaultHasInstance, .opCheckHasInstanceSlow 1183 dispatch(5) 1184 1185 .opCheckHasInstanceSlow: 1186 callSlowPath(_llint_slow_path_check_has_instance) 1187 dispatch(0) 1188 1178 _llint_op_overrides_has_instance: 1179 traceExecution() 1180 1181 loadisFromInstruction(1, t3) 1182 storei BooleanTag, TagOffset[cfr, t3, 8] 1183 1184 # First check if hasInstanceValue is the one on Function.prototype[Symbol.hasInstance] 1185 loadisFromInstruction(3, t0) 1186 loadConstantOrVariablePayload(t0, CellTag, t2, .opOverrideshasInstanceValueNotCell) 1187 loadConstantOrVariable(t0, t1, t2) 1188 bineq t1, CellTag, .opOverrideshasInstanceValueNotCell 1189 1190 # We don't need hasInstanceValue's tag register anymore. 1191 loadp CodeBlock[cfr], t1 1192 loadp CodeBlock::m_globalObject[t1], t1 1193 loadp JSGlobalObject::m_functionProtoHasInstanceSymbolFunction[t1], t1 1194 bineq t1, t2, .opOverrideshasInstanceValueNotDefault 1195 1196 # We know the constructor is a cell. 1197 loadisFromInstruction(2, t0) 1198 loadConstantOrVariablePayloadUnchecked(t0, t1) 1199 tbz JSCell::m_flags[t1], ImplementsDefaultHasInstance, t0 1200 storei t0, PayloadOffset[cfr, t3, 8] 1201 dispatch(4) 1202 1203 .opOverrideshasInstanceValueNotCell: 1204 .opOverrideshasInstanceValueNotDefault: 1205 storei 1, PayloadOffset[cfr, t3, 8] 1206 dispatch(4) 1189 1207 1190 1208 _llint_op_instanceof: … … 1215 1233 callSlowPath(_llint_slow_path_instanceof) 1216 1234 dispatch(4) 1235 1236 _llint_op_instanceof_custom: 1237 traceExecution() 1238 callSlowPath(_llint_slow_path_instanceof_custom) 1239 dispatch(5) 1217 1240 1218 1241 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r193766 r193974 1070 1070 1071 1071 1072 _llint_op_check_has_instance: 1073 traceExecution() 1072 _llint_op_overrides_has_instance: 1073 traceExecution() 1074 loadisFromInstruction(1, t3) 1075 1074 1076 loadisFromInstruction(3, t1) 1075 loadConstantOrVariableCell(t1, t0, .opCheckHasInstanceSlow) 1076 btbz JSCell::m_flags[t0], ImplementsDefaultHasInstance, .opCheckHasInstanceSlow 1077 dispatch(5) 1078 1079 .opCheckHasInstanceSlow: 1080 callSlowPath(_llint_slow_path_check_has_instance) 1081 dispatch(0) 1077 loadConstantOrVariable(t1, t0) 1078 loadp CodeBlock[cfr], t2 1079 loadp CodeBlock::m_globalObject[t2], t2 1080 loadp JSGlobalObject::m_functionProtoHasInstanceSymbolFunction[t2], t2 1081 bqneq t0, t2, .opOverridesHasInstanceNotDefaultSymbol 1082 1083 loadisFromInstruction(2, t1) 1084 loadConstantOrVariable(t1, t0) 1085 tbz JSCell::m_flags[t0], ImplementsDefaultHasInstance, t1 1086 orq ValueFalse, t1 1087 storeq t1, [cfr, t3, 8] 1088 dispatch(4) 1089 1090 .opOverridesHasInstanceNotDefaultSymbol: 1091 storeq ValueTrue, t1 1092 storeq t1, [cfr, t3, 8] 1093 dispatch(4) 1082 1094 1083 1095 … … 1110 1122 dispatch(4) 1111 1123 1124 _llint_op_instanceof_custom: 1125 traceExecution() 1126 callSlowPath(_llint_slow_path_instanceof_custom) 1127 dispatch(5) 1112 1128 1113 1129 _llint_op_is_undefined: -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r193899 r193974 251 251 252 252 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\ 253 macro(hasInstance) \254 253 macro(isConcatSpreadable) \ 255 254 macro(match) \ … … 261 260 262 261 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \ 262 macro(hasInstance) \ 263 263 macro(iterator) \ 264 264 macro(unscopables) \ … … 346 346 macro(newTargetLocal) \ 347 347 macro(derivedConstructor) \ 348 macro(isBoundFunction) \ 349 macro(hasInstanceBoundFunction) \ 350 macro(instanceOf) \ 348 351 349 352 -
trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
r189920 r193974 210 210 } 211 211 212 static String invalidParameterInstanceofSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)212 inline String invalidParameterInstanceofSourceAppender(const String& content, const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence) 213 213 { 214 214 if (occurrence == ErrorInstance::FoundApproximateSource) … … 223 223 static const unsigned instanceofLength = 10; 224 224 String rightHandSide = sourceText.substring(instanceofIndex + instanceofLength).simplifyWhiteSpace(); 225 return makeString(rightHandSide, " is not a function. (evaluating '", sourceText, "')"); 225 return makeString(rightHandSide, content, ". (evaluating '", sourceText, "')"); 226 } 227 228 static String invalidParameterInstanceofNotFunctionSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType runtimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence) 229 { 230 return invalidParameterInstanceofSourceAppender(WTF::makeString(" is not a function"), originalMessage, sourceText, runtimeType, occurrence); 231 } 232 233 static String invalidParameterInstanceofhasInstanceValueNotFunctionSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType runtimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence) 234 { 235 return invalidParameterInstanceofSourceAppender(WTF::makeString("[Symbol.hasInstance] is not a function, undefined, or null"), originalMessage, sourceText, runtimeType, occurrence); 226 236 } 227 237 … … 246 256 } 247 257 248 JSObject* createInvalidInstanceofParameterError(ExecState* exec, JSValue value) 249 { 250 return createError(exec, value, makeString("is not a function."), invalidParameterInstanceofSourceAppender); 258 JSObject* createInvalidInstanceofParameterErrorNotFunction(ExecState* exec, JSValue value) 259 { 260 return createError(exec, value, makeString(" is not a function"), invalidParameterInstanceofNotFunctionSourceAppender); 261 } 262 263 JSObject* createInvalidInstanceofParameterErrorhasInstanceValueNotFunction(ExecState* exec, JSValue value) 264 { 265 return createError(exec, value, makeString("[Symbol.hasInstance] is not a function, undefined, or null"), invalidParameterInstanceofhasInstanceValueNotFunctionSourceAppender); 251 266 } 252 267 -
trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.h
r186860 r193974 46 46 JSObject* createInvalidFunctionApplyParameterError(ExecState*, JSValue); 47 47 JSObject* createInvalidInParameterError(ExecState*, JSValue); 48 JSObject* createInvalidInstanceofParameterError(ExecState*, JSValue); 48 JSObject* createInvalidInstanceofParameterErrorNotFunction(ExecState*, JSValue); 49 JSObject* createInvalidInstanceofParameterErrorhasInstanceValueNotFunction(ExecState*, JSValue); 49 50 JSObject* createNotAConstructorError(ExecState*, JSValue); 50 51 JSObject* createNotAFunctionError(ExecState*, JSValue); -
trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
r190096 r193974 54 54 } 55 55 56 void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, JSFunction** callFunction, JSFunction** applyFunction )56 void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, JSFunction** callFunction, JSFunction** applyFunction, JSFunction** hasInstanceSymbolFunction) 57 57 { 58 58 VM& vm = exec->vm(); … … 63 63 *applyFunction = putDirectBuiltinFunctionWithoutTransition(vm, globalObject, vm.propertyNames->builtinNames().applyPublicName(), functionPrototypeApplyCodeGenerator(vm), DontEnum); 64 64 *callFunction = putDirectBuiltinFunctionWithoutTransition(vm, globalObject, vm.propertyNames->builtinNames().callPublicName(), functionPrototypeCallCodeGenerator(vm), DontEnum); 65 *hasInstanceSymbolFunction = putDirectBuiltinFunction(vm, globalObject, vm.propertyNames->hasInstanceSymbol, functionPrototypeSymbolHasInstanceCodeGenerator(vm), DontDelete | ReadOnly | DontEnum); 65 66 66 67 JSFunction* bindFunction = JSFunction::create(vm, globalObject, 1, vm.propertyNames->bind.string(), functionProtoFuncBind); -
trunk/Source/JavaScriptCore/runtime/FunctionPrototype.h
r173269 r193974 37 37 } 38 38 39 void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction );39 void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction, JSFunction** hasInstanceSymbolFunction); 40 40 41 41 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) -
trunk/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
r189561 r193974 75 75 } 76 76 77 EncodedJSValue JSC_HOST_CALL isBoundFunction(ExecState* exec) 78 { 79 return JSValue::encode(JSValue(static_cast<bool>(jsDynamicCast<JSBoundFunction*>(exec->uncheckedArgument(0))))); 80 } 81 82 EncodedJSValue JSC_HOST_CALL hasInstanceBoundFunction(ExecState* exec) 83 { 84 JSBoundFunction* boundObject = jsCast<JSBoundFunction*>(exec->uncheckedArgument(0)); 85 JSValue value = exec->uncheckedArgument(1); 86 87 return JSValue::encode(jsBoolean(boundObject->targetFunction()->hasInstance(exec, value))); 88 } 89 90 77 91 JSBoundFunction* JSBoundFunction::create(VM& vm, JSGlobalObject* globalObject, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int length, const String& name) 78 92 { -
trunk/Source/JavaScriptCore/runtime/JSBoundFunction.h
r182899 r193974 33 33 EncodedJSValue JSC_HOST_CALL boundFunctionCall(ExecState*); 34 34 EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState*); 35 EncodedJSValue JSC_HOST_CALL isBoundFunction(ExecState*); 36 EncodedJSValue JSC_HOST_CALL hasInstanceBoundFunction(ExecState*); 35 37 36 38 class JSBoundFunction : public JSFunction { 37 39 public: 38 40 typedef JSFunction Base; 39 const static unsigned StructureFlags = OverridesHasInstance | Base::StructureFlags;41 const static unsigned StructureFlags = OverridesHasInstanceFlag | Base::StructureFlags; 40 42 41 43 static JSBoundFunction* create(VM&, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String&); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r193766 r193974 287 287 JSFunction* callFunction = 0; 288 288 JSFunction* applyFunction = 0; 289 m_functionPrototype->addFunctionProperties(exec, this, &callFunction, &applyFunction); 289 JSFunction* hasInstanceSymbolFunction = 0; 290 m_functionPrototype->addFunctionProperties(exec, this, &callFunction, &applyFunction, &hasInstanceSymbolFunction); 290 291 m_callFunction.set(vm, this, callFunction); 291 292 m_applyFunction.set(vm, this, applyFunction); … … 293 294 m_initializePromiseFunction.set(vm, this, JSFunction::createBuiltinFunction(vm, promiseOperationsInitializePromiseCodeGenerator(vm), this)); 294 295 m_newPromiseCapabilityFunction.set(vm, this, JSFunction::createBuiltinFunction(vm, promiseOperationsNewPromiseCapabilityCodeGenerator(vm), this)); 296 m_functionProtoHasInstanceSymbolFunction.set(vm, this, hasInstanceSymbolFunction); 295 297 m_nullGetterFunction.set(vm, this, NullGetterFunction::create(vm, NullGetterFunction::createStructure(vm, this, m_functionPrototype.get()))); 296 298 m_nullSetterFunction.set(vm, this, NullSetterFunction::create(vm, NullSetterFunction::createStructure(vm, this, m_functionPrototype.get()))); … … 522 524 JSFunction* privateFuncTypedArrayLength = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncLength); 523 525 JSFunction* privateFuncTypedArraySort = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncSort); 526 JSFunction* privateFuncIsBoundFunction = JSFunction::create(vm, this, 0, String(), isBoundFunction); 527 JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction); 528 JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf); 524 529 525 530 GlobalPropertyInfo staticGlobals[] = { … … 536 541 GlobalPropertyInfo(vm.propertyNames->typedArrayLengthPrivateName, privateFuncTypedArrayLength, DontEnum | DontDelete | ReadOnly), 537 542 GlobalPropertyInfo(vm.propertyNames->typedArraySortPrivateName, privateFuncTypedArraySort, DontEnum | DontDelete | ReadOnly), 543 GlobalPropertyInfo(vm.propertyNames->isBoundFunctionPrivateName, privateFuncIsBoundFunction, DontEnum | DontDelete | ReadOnly), 544 GlobalPropertyInfo(vm.propertyNames->hasInstanceBoundFunctionPrivateName, privateFuncHasInstanceBoundFunction, DontEnum | DontDelete | ReadOnly), 545 GlobalPropertyInfo(vm.propertyNames->instanceOfPrivateName, privateFuncInstanceOf, DontEnum | DontDelete | ReadOnly), 538 546 GlobalPropertyInfo(vm.propertyNames->BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly), 539 547 GlobalPropertyInfo(vm.propertyNames->ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly), … … 833 841 visitor.append(&thisObject->m_initializePromiseFunction); 834 842 visitor.append(&thisObject->m_newPromiseCapabilityFunction); 843 visitor.append(&thisObject->m_functionProtoHasInstanceSymbolFunction); 835 844 visitor.append(&thisObject->m_throwTypeErrorGetterSetter); 836 845 visitor.append(&thisObject->m_moduleLoader); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r193766 r193974 223 223 WriteBarrier<JSFunction> m_initializePromiseFunction; 224 224 WriteBarrier<JSFunction> m_newPromiseCapabilityFunction; 225 WriteBarrier<JSFunction> m_functionProtoHasInstanceSymbolFunction; 225 226 WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter; 226 227 … … 439 440 JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(); } 440 441 JSFunction* newPromiseCapabilityFunction() const { return m_newPromiseCapabilityFunction.get(); } 442 JSFunction* functionProtoHasInstanceSymbolFunction() const { return m_functionProtoHasInstanceSymbolFunction.get(); } 441 443 GetterSetter* throwTypeErrorGetterSetter(VM& vm) 442 444 { -
trunk/Source/JavaScriptCore/runtime/JSObject.cpp
r192858 r193974 1458 1458 } 1459 1459 1460 bool JSObject::hasInstance(ExecState* exec, JSValue value )1460 bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue hasInstanceValue) 1461 1461 { 1462 1462 VM& vm = exec->vm(); 1463 1464 if (!hasInstanceValue.isUndefinedOrNull() && hasInstanceValue != exec->lexicalGlobalObject()->functionProtoHasInstanceSymbolFunction()) { 1465 CallData callData; 1466 CallType callType = JSC::getCallData(hasInstanceValue, callData); 1467 if (callType == CallTypeNone) { 1468 vm.throwException(exec, createInvalidInstanceofParameterErrorhasInstanceValueNotFunction(exec, this)); 1469 return false; 1470 } 1471 1472 MarkedArgumentBuffer args; 1473 args.append(value); 1474 JSValue result = call(exec, hasInstanceValue, callType, callData, this, args); 1475 return result.toBoolean(exec); 1476 } 1477 1463 1478 TypeInfo info = structure(vm)->typeInfo(); 1464 1479 if (info.implementsDefaultHasInstance()) … … 1466 1481 if (info.implementsHasInstance()) 1467 1482 return methodTable(vm)->customHasInstance(this, exec, value); 1468 vm.throwException(exec, createInvalidInstanceofParameterError (exec, this));1483 vm.throwException(exec, createInvalidInstanceofParameterErrorNotFunction(exec, this)); 1469 1484 return false; 1485 } 1486 1487 bool JSObject::hasInstance(ExecState* exec, JSValue value) 1488 { 1489 JSValue hasInstanceValue = get(exec, exec->propertyNames().hasInstanceSymbol); 1490 1491 return hasInstance(exec, value, hasInstanceValue); 1470 1492 } 1471 1493 … … 1486 1508 } 1487 1509 return false; 1510 } 1511 1512 EncodedJSValue JSC_HOST_CALL objectPrivateFuncInstanceOf(ExecState* exec) 1513 { 1514 JSValue value = exec->uncheckedArgument(0); 1515 JSValue proto = exec->uncheckedArgument(1); 1516 1517 return JSValue::encode(jsBoolean(JSObject::defaultHasInstance(exec, value, proto))); 1488 1518 } 1489 1519 -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r191215 r193974 486 486 JS_EXPORT_PRIVATE static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); 487 487 488 JS_EXPORT_PRIVATE bool hasInstance(ExecState*, JSValue value, JSValue hasInstanceValue); 488 489 bool hasInstance(ExecState*, JSValue); 489 490 static bool defaultHasInstance(ExecState*, JSValue, JSValue prototypeProperty); … … 974 975 } 975 976 }; 977 978 JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectPrivateFuncInstanceOf(ExecState*); 976 979 977 980 inline JSFinalObject* JSFinalObject::create( -
trunk/Source/JavaScriptCore/runtime/JSTypeInfo.h
r192693 r193974 39 39 static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable. 40 40 static const unsigned ImplementsHasInstance = 1 << 1; 41 static const unsigned OverridesHasInstance = 1 << 2;41 static const unsigned OverridesHasInstanceFlag = 1 << 2; // FIXME: This is only trivially used by the runtime and should be removed: https://bugs.webkit.org/show_bug.cgi?id=152005 42 42 static const unsigned ImplementsDefaultHasInstance = 1 << 3; 43 43 static const unsigned TypeOfShouldCallGetCallData = 1 << 4; // Need this flag if you override getCallData() and you want typeof to use this to determine if it should say "function". Currently we always set this flag when we override getCallData(). … … 69 69 { 70 70 // No object that doesn't ImplementsHasInstance should override it! 71 ASSERT((m_flags & (ImplementsHasInstance | OverridesHasInstance )) != OverridesHasInstance);71 ASSERT((m_flags & (ImplementsHasInstance | OverridesHasInstanceFlag)) != OverridesHasInstanceFlag); 72 72 // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance) 73 if ((m_flags & (ImplementsHasInstance | OverridesHasInstance )) == ImplementsHasInstance)73 if ((m_flags & (ImplementsHasInstance | OverridesHasInstanceFlag)) == ImplementsHasInstance) 74 74 m_flags |= ImplementsDefaultHasInstance; 75 75 } … … 84 84 bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); } 85 85 bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); } 86 bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstance ); }86 bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstanceFlag); } 87 87 bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); } 88 88 bool typeOfShouldCallGetCallData() const { return isSetOnFlags1(TypeOfShouldCallGetCallData); } -
trunk/Source/JavaScriptCore/runtime/WriteBarrier.h
r186860 r193974 153 153 bool isCustomGetterSetter() const { return get().isCustomGetterSetter(); } 154 154 155 JSValue* slot() 155 JSValue* slot() const 156 156 { 157 union { 158 EncodedJSValue* v; 159 JSValue* slot; 160 } u; 161 u.v = &m_value; 162 return u.slot; 157 return bitwise_cast<JSValue*>(&m_value); 163 158 } 164 159 -
trunk/Source/JavaScriptCore/tests/es6.yaml
r193766 r193974 1184 1184 cmd: runES6 :fail 1185 1185 - path: es6/well-known_symbols_Symbol.hasInstance.js 1186 cmd: runES6 : fail1186 cmd: runES6 :normal 1187 1187 - path: es6/well-known_symbols_Symbol.isConcatSpreadable.js 1188 1188 cmd: runES6 :fail
Note: See TracChangeset
for help on using the changeset viewer.