Changeset 238861 in webkit
- Timestamp:
- Dec 4, 2018 10:55:27 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r238835 r238861 1 2018-12-04 Caio Lima <ticaiolima@gmail.com> 2 3 [ESNext][BigInt] Support logic operations 4 https://bugs.webkit.org/show_bug.cgi?id=179903 5 6 Reviewed by Yusuke Suzuki. 7 8 * stress/big-int-branch-usage.js: Added. 9 * stress/big-int-logical-and.js: Added. 10 * stress/big-int-logical-not.js: Added. 11 * stress/big-int-logical-or.js: Added. 12 1 13 2018-12-03 Ryan Haddad <ryanhaddad@apple.com> 2 14 -
trunk/Source/JavaScriptCore/ChangeLog
r238850 r238861 1 2018-12-04 Caio Lima <ticaiolima@gmail.com> 2 3 [ESNext][BigInt] Support logic operations 4 https://bugs.webkit.org/show_bug.cgi?id=179903 5 6 Reviewed by Yusuke Suzuki. 7 8 We are introducing in this patch the ToBoolean support for JSBigInt. 9 With this change, we can implement the correct behavior of BigInt as 10 operand of logical opertions. During JIT genertion into DFG and FTL, 11 we are using JSBigInt::m_length to verify if the number is 0n or not, 12 following the same approach used by JSString. This is also safe in the case 13 of BigInt, because only 0n has m_length == 0. 14 15 We are not including BigInt speculation into Branch nodes in this 16 patch, but the plan is to implement it in further patches. 17 18 * ftl/FTLAbstractHeapRepository.h: 19 * ftl/FTLLowerDFGToB3.cpp: 20 (JSC::FTL::DFG::LowerDFGToB3::boolify): 21 (JSC::FTL::DFG::LowerDFGToB3::isBigInt): 22 * jit/AssemblyHelpers.cpp: 23 (JSC::AssemblyHelpers::emitConvertValueToBoolean): 24 (JSC::AssemblyHelpers::branchIfValue): 25 * runtime/JSBigInt.cpp: 26 (JSC::JSBigInt::isZero const): 27 (JSC::JSBigInt::offsetOfLength): 28 (JSC::JSBigInt::toBoolean const): 29 (JSC::JSBigInt::isZero): Deleted. 30 * runtime/JSBigInt.h: 31 * runtime/JSCellInlines.h: 32 (JSC::JSCell::toBoolean const): 33 (JSC::JSCell::pureToBoolean const): 34 1 35 2018-12-04 Devin Rousso <drousso@apple.com> 2 36 -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r238835 r238861 86 86 macro(JSString_length, JSString::offsetOfLength()) \ 87 87 macro(JSString_value, JSString::offsetOfValue()) \ 88 macro(JSBigInt_length, JSBigInt::offsetOfLength()) \ 88 89 macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \ 89 90 macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \ -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r238835 r238861 13579 13579 // Implements the following control flow structure: 13580 13580 // if (value is cell) { 13581 // if (value is string )13581 // if (value is string or value is BigInt) 13582 13582 // result = !!value->length 13583 13583 // else { … … 13596 13596 LBasicBlock stringCase = m_out.newBlock(); 13597 13597 LBasicBlock notStringCase = m_out.newBlock(); 13598 LBasicBlock bigIntCase = m_out.newBlock(); 13599 LBasicBlock notBigIntCase = m_out.newBlock(); 13598 13600 LBasicBlock notCellCase = m_out.newBlock(); 13599 13601 LBasicBlock int32Case = m_out.newBlock(); … … 13617 13619 results.append(m_out.anchor(nonEmptyString)); 13618 13620 m_out.jump(continuation); 13619 13620 m_out.appendTo(notStringCase, notCellCase); 13621 13622 m_out.appendTo(notStringCase, bigIntCase); 13623 m_out.branch( 13624 isBigInt(value, provenType(edge) & SpecCell), 13625 unsure(bigIntCase), unsure(notBigIntCase)); 13626 13627 m_out.appendTo(bigIntCase, notBigIntCase); 13628 LValue nonZeroBigInt = m_out.notZero32( 13629 m_out.load32NonNegative(value, m_heaps.JSBigInt_length)); 13630 results.append(m_out.anchor(nonZeroBigInt)); 13631 m_out.jump(continuation); 13632 13633 m_out.appendTo(notBigIntCase, notCellCase); 13621 13634 LValue isTruthyObject; 13622 13635 if (masqueradesAsUndefinedWatchpointIsStillValid()) … … 15612 15625 } 15613 15626 15627 LValue isBigInt(LValue cell, SpeculatedType type = SpecFullTop) 15628 { 15629 if (LValue proven = isProvenValue(type & SpecCell, SpecBigInt)) 15630 return proven; 15631 return m_out.equal( 15632 m_out.load32(cell, m_heaps.JSCell_structureID), 15633 m_out.constInt32(vm().bigIntStructure->id())); 15634 } 15635 15614 15636 LValue isArrayTypeForArrayify(LValue cell, ArrayMode arrayMode) 15615 15637 { -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp
r238835 r238861 759 759 // Implements the following control flow structure: 760 760 // if (value is cell) { 761 // if (value is string )761 // if (value is string or value is BigInt) 762 762 // result = !!value->length 763 763 // else { … … 782 782 783 783 isCellButNotString.link(this); 784 auto isCellButNotBigIntOrString = branchIfNotBigInt(value.payloadGPR()); 785 load32(Address(value.payloadGPR(), JSBigInt::offsetOfLength()), result); 786 compare32(invert ? Equal : NotEqual, result, TrustedImm32(0), result); 787 done.append(jump()); 788 789 isCellButNotBigIntOrString.link(this); 784 790 if (shouldCheckMasqueradesAsUndefined) { 785 791 ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg); … … 832 838 // Implements the following control flow structure: 833 839 // if (value is cell) { 834 // if (value is string )840 // if (value is string or value is BigInt) 835 841 // result = !!value->length 836 842 // else { … … 853 859 truthy.append(branchTest32(invert ? Zero : NonZero, Address(value.payloadGPR(), JSString::offsetOfLength()))); 854 860 done.append(jump()); 861 isCellButNotString.link(this); 862 auto isCellButNotBigIntOrString = branchIfNotBigInt(value.payloadGPR()); 863 truthy.append(branchTest32(invert ? Zero : NonZero, Address(value.payloadGPR(), JSBigInt::offsetOfLength()))); 864 done.append(jump()); 855 865 856 866 if (shouldCheckMasqueradesAsUndefined) { 857 isCellButNot String.link(this);867 isCellButNotBigIntOrString.link(this); 858 868 ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg); 859 869 JumpList isNotMasqueradesAsUndefined; … … 875 885 } else { 876 886 if (invert) 877 done.append(isCellButNot String);887 done.append(isCellButNotBigIntOrString); 878 888 else 879 truthy.append(isCellButNot String);889 truthy.append(isCellButNotBigIntOrString); 880 890 } 881 891 -
trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp
r238835 r238861 233 233 } 234 234 235 inline bool JSBigInt::isZero()236 {237 ASSERT(length() || !sign());238 return length() == 0;239 }240 241 235 // Multiplies {this} with {factor} and adds {summand} to the result. 242 236 void JSBigInt::inplaceMultiplyAdd(Digit factor, Digit summand) … … 1701 1695 } 1702 1696 1697 size_t JSBigInt::offsetOfLength() 1698 { 1699 return OBJECT_OFFSETOF(JSBigInt, m_length); 1700 } 1701 1703 1702 template <typename CharType> 1704 1703 JSBigInt* JSBigInt::parseInt(ExecState* exec, CharType* data, unsigned length, ErrorParseMode errorParseMode) … … 1819 1818 dataStorage()[n] = value; 1820 1819 } 1820 1821 1821 JSObject* JSBigInt::toObject(ExecState* exec, JSGlobalObject* globalObject) const 1822 1822 { -
trunk/Source/JavaScriptCore/runtime/JSBigInt.h
r238835 r238861 29 29 #include "ExceptionHelpers.h" 30 30 #include "JSObject.h" 31 #include "ParseInt.h"32 31 #include <wtf/CagedPtr.h> 33 32 #include <wtf/text/StringBuilder.h> … … 59 58 static JSBigInt* createFrom(VM&, int64_t value); 60 59 static JSBigInt* createFrom(VM&, bool value); 60 61 static size_t offsetOfLength(); 61 62 62 63 DECLARE_EXPORT_INFO; … … 105 106 106 107 JSObject* toObject(ExecState*, JSGlobalObject*) const; 108 inline bool toBoolean() const { return !isZero(); } 107 109 108 110 static JSBigInt* multiply(ExecState*, JSBigInt* x, JSBigInt* y); … … 195 197 static String toStringGeneric(ExecState*, JSBigInt*, unsigned radix); 196 198 197 bool isZero(); 199 inline bool isZero() const 200 { 201 ASSERT(length() || !sign()); 202 return length() == 0; 203 } 198 204 199 205 template <typename CharType> -
trunk/Source/JavaScriptCore/runtime/JSCellInlines.h
r238835 r238861 34 34 #include "Handle.h" 35 35 #include "IsoSubspaceInlines.h" 36 #include "JSBigInt.h" 36 37 #include "JSCast.h" 37 38 #include "JSDestructibleObject.h" … … 340 341 if (isString()) 341 342 return static_cast<const JSString*>(this)->toBoolean(); 343 if (isBigInt()) 344 return static_cast<const JSBigInt*>(this)->toBoolean(); 342 345 return !structure(exec->vm())->masqueradesAsUndefined(exec->lexicalGlobalObject()); 343 346 } … … 347 350 if (isString()) 348 351 return static_cast<const JSString*>(this)->toBoolean() ? TrueTriState : FalseTriState; 352 if (isBigInt()) 353 return static_cast<const JSBigInt*>(this)->toBoolean() ? TrueTriState : FalseTriState; 349 354 if (isSymbol()) 350 355 return TrueTriState;
Note: See TracChangeset
for help on using the changeset viewer.