1/* 2 * Copyright (C) 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ResultType_h 27#define ResultType_h 28 29namespace JSC { 30 31 struct ResultType { 32 friend struct OperandTypes; 33 34 typedef char Type; 35 static const Type TypeInt32 = 1; 36 37 static const Type TypeMaybeNumber = 0x04; 38 static const Type TypeMaybeString = 0x08; 39 static const Type TypeMaybeNull = 0x10; 40 static const Type TypeMaybeBool = 0x20; 41 static const Type TypeMaybeOther = 0x40; 42 43 static const Type TypeBits = TypeMaybeNumber | TypeMaybeString | TypeMaybeNull | TypeMaybeBool | TypeMaybeOther; 44 45 explicit ResultType(Type type) 46 : m_type(type) 47 { 48 } 49 50 bool isInt32() 51 { 52 return m_type & TypeInt32; 53 } 54 55 bool definitelyIsNumber() 56 { 57 return (m_type & TypeBits) == TypeMaybeNumber; 58 } 59 60 bool definitelyIsString() 61 { 62 return (m_type & TypeBits) == TypeMaybeString; 63 } 64 65 bool definitelyIsBoolean() 66 { 67 return (m_type & TypeBits) == TypeMaybeBool; 68 } 69 70 bool mightBeNumber() 71 { 72 return m_type & TypeMaybeNumber; 73 } 74 75 bool isNotNumber() 76 { 77 return !mightBeNumber(); 78 } 79 80 static ResultType nullType() 81 { 82 return ResultType(TypeMaybeNull); 83 } 84 85 static ResultType booleanType() 86 { 87 return ResultType(TypeMaybeBool); 88 } 89 90 static ResultType numberType() 91 { 92 return ResultType(TypeMaybeNumber); 93 } 94 95 static ResultType numberTypeIsInt32() 96 { 97 return ResultType(TypeInt32 | TypeMaybeNumber); 98 } 99 100 static ResultType stringOrNumberType() 101 { 102 return ResultType(TypeMaybeNumber | TypeMaybeString); 103 } 104 105 static ResultType stringType() 106 { 107 return ResultType(TypeMaybeString); 108 } 109 110 static ResultType unknownType() 111 { 112 return ResultType(TypeBits); 113 } 114 115 static ResultType forAdd(ResultType op1, ResultType op2) 116 { 117 if (op1.definitelyIsNumber() && op2.definitelyIsNumber()) 118 return numberType(); 119 if (op1.definitelyIsString() || op2.definitelyIsString()) 120 return stringType(); 121 return stringOrNumberType(); 122 } 123 124 // Unlike in C, a logical op produces the value of the 125 // last expression evaluated (and not true or false). 126 static ResultType forLogicalOp(ResultType op1, ResultType op2) 127 { 128 if (op1.definitelyIsBoolean() && op2.definitelyIsBoolean()) 129 return booleanType(); 130 if (op1.definitelyIsNumber() && op2.definitelyIsNumber()) 131 return numberType(); 132 if (op1.definitelyIsString() && op2.definitelyIsString()) 133 return stringType(); 134 return unknownType(); 135 } 136 137 static ResultType forBitOp() 138 { 139 return numberTypeIsInt32(); 140 } 141 142 private: 143 Type m_type; 144 }; 145 146 struct OperandTypes 147 { 148 OperandTypes(ResultType first = ResultType::unknownType(), ResultType second = ResultType::unknownType()) 149 { 150 // We have to initialize one of the int to ensure that 151 // the entire struct is initialized. 152 m_u.i = 0; 153 m_u.rds.first = first.m_type; 154 m_u.rds.second = second.m_type; 155 } 156 157 union { 158 struct { 159 ResultType::Type first; 160 ResultType::Type second; 161 } rds; 162 int i; 163 } m_u; 164 165 ResultType first() 166 { 167 return ResultType(m_u.rds.first); 168 } 169 170 ResultType second() 171 { 172 return ResultType(m_u.rds.second); 173 } 174 175 int toInt() 176 { 177 return m_u.i; 178 } 179 static OperandTypes fromInt(int value) 180 { 181 OperandTypes types; 182 types.m_u.i = value; 183 return types; 184 } 185 }; 186 187} // namespace JSC 188 189#endif // ResultType_h 190