| /* |
| * Copyright (C) 2013-2016 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #pragma once |
| |
| #if ENABLE(DFG_JIT) |
| |
| #include "DFGNodeFlags.h" |
| #include "SpeculatedType.h" |
| #include <wtf/PrintStream.h> |
| |
| namespace JSC { namespace DFG { |
| |
| enum UseKind { |
| // The DFG has 3 representations of values used: |
| |
| // 1. The JSValue representation for a JSValue that must be stored in a GP |
| // register (or a GP register pair), and follows rules for boxing and unboxing |
| // that allow the JSValue to be stored as either fully boxed JSValues, or |
| // unboxed Int32, Booleans, Cells, etc. in 32-bit as appropriate. |
| UntypedUse, // UntypedUse must come first (value 0). |
| Int32Use, |
| KnownInt32Use, |
| AnyIntUse, |
| NumberUse, |
| RealNumberUse, |
| BooleanUse, |
| KnownBooleanUse, |
| CellUse, |
| KnownCellUse, |
| CellOrOtherUse, |
| ObjectUse, |
| ArrayUse, |
| FunctionUse, |
| FinalObjectUse, |
| PromiseObjectUse, |
| RegExpObjectUse, |
| ProxyObjectUse, |
| DerivedArrayUse, |
| ObjectOrOtherUse, |
| StringIdentUse, |
| StringUse, |
| StringOrOtherUse, |
| KnownStringUse, |
| KnownPrimitiveUse, // This bizarre type arises for op_strcat, which has a bytecode guarantee that it will only see primitives (i.e. not objects). |
| SymbolUse, |
| BigIntUse, |
| DateObjectUse, |
| MapObjectUse, |
| SetObjectUse, |
| WeakMapObjectUse, |
| WeakSetObjectUse, |
| DataViewObjectUse, |
| StringObjectUse, |
| StringOrStringObjectUse, |
| NotStringVarUse, |
| NotSymbolUse, |
| NotCellUse, |
| KnownOtherUse, |
| OtherUse, |
| MiscUse, |
| |
| // 2. The Double representation for an unboxed double value that must be stored |
| // in an FP register. |
| DoubleRepUse, |
| DoubleRepRealUse, |
| DoubleRepAnyIntUse, |
| |
| // 3. The Int52 representation for an unboxed integer value that must be stored |
| // in a GP register. |
| Int52RepUse, |
| |
| LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements. |
| }; |
| |
| inline SpeculatedType typeFilterFor(UseKind useKind) |
| { |
| switch (useKind) { |
| case UntypedUse: |
| return SpecBytecodeTop; |
| case Int32Use: |
| case KnownInt32Use: |
| return SpecInt32Only; |
| case Int52RepUse: |
| return SpecInt52Any; |
| case AnyIntUse: |
| return SpecInt32Only | SpecAnyIntAsDouble; |
| case NumberUse: |
| return SpecBytecodeNumber; |
| case RealNumberUse: |
| return SpecBytecodeRealNumber; |
| case DoubleRepUse: |
| return SpecFullDouble; |
| case DoubleRepRealUse: |
| return SpecDoubleReal; |
| case DoubleRepAnyIntUse: |
| return SpecAnyIntAsDouble; |
| case BooleanUse: |
| case KnownBooleanUse: |
| return SpecBoolean; |
| case CellUse: |
| case KnownCellUse: |
| return SpecCellCheck; |
| case CellOrOtherUse: |
| return SpecCellCheck | SpecOther; |
| case ObjectUse: |
| return SpecObject; |
| case ArrayUse: |
| return SpecArray; |
| case FunctionUse: |
| return SpecFunction; |
| case FinalObjectUse: |
| return SpecFinalObject; |
| case RegExpObjectUse: |
| return SpecRegExpObject; |
| case ProxyObjectUse: |
| return SpecProxyObject; |
| case DerivedArrayUse: |
| return SpecDerivedArray; |
| case ObjectOrOtherUse: |
| return SpecObject | SpecOther; |
| case StringIdentUse: |
| return SpecStringIdent; |
| case StringUse: |
| case KnownStringUse: |
| return SpecString; |
| case StringOrOtherUse: |
| return SpecString | SpecOther; |
| case KnownPrimitiveUse: |
| return SpecHeapTop & ~SpecObject; |
| case SymbolUse: |
| return SpecSymbol; |
| case BigIntUse: |
| return SpecBigInt; |
| case PromiseObjectUse: |
| return SpecPromiseObject; |
| case DateObjectUse: |
| return SpecDateObject; |
| case MapObjectUse: |
| return SpecMapObject; |
| case SetObjectUse: |
| return SpecSetObject; |
| case WeakMapObjectUse: |
| return SpecWeakMapObject; |
| case WeakSetObjectUse: |
| return SpecWeakSetObject; |
| case DataViewObjectUse: |
| return SpecDataViewObject; |
| case StringObjectUse: |
| return SpecStringObject; |
| case StringOrStringObjectUse: |
| return SpecString | SpecStringObject; |
| case NotStringVarUse: |
| return ~SpecStringVar; |
| case NotSymbolUse: |
| return ~SpecSymbol; |
| case NotCellUse: |
| return ~SpecCellCheck; |
| case KnownOtherUse: |
| case OtherUse: |
| return SpecOther; |
| case MiscUse: |
| return SpecMisc; |
| default: |
| RELEASE_ASSERT_NOT_REACHED(); |
| return SpecFullTop; |
| } |
| } |
| |
| inline bool shouldNotHaveTypeCheck(UseKind kind) |
| { |
| switch (kind) { |
| case UntypedUse: |
| case KnownInt32Use: |
| case KnownCellUse: |
| case KnownStringUse: |
| case KnownPrimitiveUse: |
| case KnownBooleanUse: |
| case KnownOtherUse: |
| case Int52RepUse: |
| case DoubleRepUse: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| inline bool mayHaveTypeCheck(UseKind kind) |
| { |
| return !shouldNotHaveTypeCheck(kind); |
| } |
| |
| inline bool isNumerical(UseKind kind) |
| { |
| switch (kind) { |
| case Int32Use: |
| case KnownInt32Use: |
| case NumberUse: |
| case RealNumberUse: |
| case Int52RepUse: |
| case DoubleRepUse: |
| case DoubleRepRealUse: |
| case AnyIntUse: |
| case DoubleRepAnyIntUse: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| inline bool isDouble(UseKind kind) |
| { |
| switch (kind) { |
| case DoubleRepUse: |
| case DoubleRepRealUse: |
| case DoubleRepAnyIntUse: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| // Returns true if the use kind only admits cells, and is therefore appropriate for |
| // SpeculateCellOperand in the DFG or lowCell() in the FTL. |
| inline bool isCell(UseKind kind) |
| { |
| switch (kind) { |
| case CellUse: |
| case KnownCellUse: |
| case ObjectUse: |
| case ArrayUse: |
| case FunctionUse: |
| case FinalObjectUse: |
| case RegExpObjectUse: |
| case PromiseObjectUse: |
| case ProxyObjectUse: |
| case DerivedArrayUse: |
| case StringIdentUse: |
| case StringUse: |
| case KnownStringUse: |
| case SymbolUse: |
| case BigIntUse: |
| case StringObjectUse: |
| case StringOrStringObjectUse: |
| case DateObjectUse: |
| case MapObjectUse: |
| case SetObjectUse: |
| case WeakMapObjectUse: |
| case WeakSetObjectUse: |
| case DataViewObjectUse: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| // Returns true if we've already guaranteed the type |
| inline bool alreadyChecked(UseKind kind, SpeculatedType type) |
| { |
| return !(type & ~typeFilterFor(kind)); |
| } |
| |
| inline UseKind useKindForResult(NodeFlags result) |
| { |
| ASSERT(!(result & ~NodeResultMask)); |
| switch (result) { |
| case NodeResultInt52: |
| return Int52RepUse; |
| case NodeResultDouble: |
| return DoubleRepUse; |
| default: |
| return UntypedUse; |
| } |
| } |
| |
| inline bool checkMayCrashIfInputIsEmpty(UseKind kind) |
| { |
| #if USE(JSVALUE64) |
| switch (kind) { |
| case UntypedUse: |
| case Int32Use: |
| case KnownInt32Use: |
| case AnyIntUse: |
| case NumberUse: |
| case BooleanUse: |
| case KnownBooleanUse: |
| case CellUse: |
| case KnownCellUse: |
| case CellOrOtherUse: |
| case KnownOtherUse: |
| case OtherUse: |
| case MiscUse: |
| case NotCellUse: |
| return false; |
| default: |
| return true; |
| } |
| #else |
| UNUSED_PARAM(kind); |
| return true; |
| #endif |
| } |
| |
| } } // namespace JSC::DFG |
| |
| namespace WTF { |
| |
| void printInternal(PrintStream&, JSC::DFG::UseKind); |
| |
| } // namespace WTF |
| |
| #endif // ENABLE(DFG_JIT) |