1/* 2 * Copyright (C) 2008, 2009 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 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#ifndef Register_h 30#define Register_h 31 32#include "JSCJSValue.h" 33#include <wtf/Assertions.h> 34#include <wtf/VectorTraits.h> 35 36namespace JSC { 37 38 class CodeBlock; 39 class ExecState; 40 class JSActivation; 41 class JSObject; 42 class JSPropertyNameIterator; 43 class JSScope; 44 45 typedef ExecState CallFrame; 46 47 class Register { 48 WTF_MAKE_FAST_ALLOCATED; 49 public: 50 Register(); 51 52 Register(const JSValue&); 53 Register& operator=(const JSValue&); 54 JSValue jsValue() const; 55 EncodedJSValue encodedJSValue() const; 56 57 Register& operator=(CallFrame*); 58 Register& operator=(CodeBlock*); 59 Register& operator=(JSScope*); 60 61 int32_t i() const; 62 JSActivation* activation() const; 63 CallFrame* callFrame() const; 64 CodeBlock* codeBlock() const; 65 JSObject* function() const; 66 JSPropertyNameIterator* propertyNameIterator() const; 67 JSScope* scope() const; 68 int32_t unboxedInt32() const; 69 int64_t unboxedInt52() const; 70 int64_t unboxedStrictInt52() const; 71 bool unboxedBoolean() const; 72 double unboxedDouble() const; 73 JSCell* unboxedCell() const; 74 int32_t payload() const; 75 int32_t tag() const; 76 int32_t& payload(); 77 int32_t& tag(); 78 79 static Register withInt(int32_t i) 80 { 81 Register r = jsNumber(i); 82 return r; 83 } 84 85 static Register withCallee(JSObject* callee); 86 87 private: 88 union { 89 EncodedJSValue value; 90 CallFrame* callFrame; 91 CodeBlock* codeBlock; 92 EncodedValueDescriptor encodedValue; 93 double number; 94 int64_t integer; 95 } u; 96 }; 97 98 ALWAYS_INLINE Register::Register() 99 { 100#ifndef NDEBUG 101 *this = JSValue(); 102#endif 103 } 104 105 ALWAYS_INLINE Register::Register(const JSValue& v) 106 { 107 u.value = JSValue::encode(v); 108 } 109 110 ALWAYS_INLINE Register& Register::operator=(const JSValue& v) 111 { 112 u.value = JSValue::encode(v); 113 return *this; 114 } 115 116 ALWAYS_INLINE JSValue Register::jsValue() const 117 { 118 return JSValue::decode(u.value); 119 } 120 121 ALWAYS_INLINE EncodedJSValue Register::encodedJSValue() const 122 { 123 return u.value; 124 } 125 126 // Interpreter functions 127 128 ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame) 129 { 130 u.callFrame = callFrame; 131 return *this; 132 } 133 134 ALWAYS_INLINE Register& Register::operator=(CodeBlock* codeBlock) 135 { 136 u.codeBlock = codeBlock; 137 return *this; 138 } 139 140 ALWAYS_INLINE int32_t Register::i() const 141 { 142 return jsValue().asInt32(); 143 } 144 145 ALWAYS_INLINE CallFrame* Register::callFrame() const 146 { 147 return u.callFrame; 148 } 149 150 ALWAYS_INLINE CodeBlock* Register::codeBlock() const 151 { 152 return u.codeBlock; 153 } 154 155 ALWAYS_INLINE int32_t Register::unboxedInt32() const 156 { 157 return payload(); 158 } 159 160 ALWAYS_INLINE int64_t Register::unboxedInt52() const 161 { 162 return u.integer >> JSValue::int52ShiftAmount; 163 } 164 165 ALWAYS_INLINE int64_t Register::unboxedStrictInt52() const 166 { 167 return u.integer; 168 } 169 170 ALWAYS_INLINE bool Register::unboxedBoolean() const 171 { 172 return !!payload(); 173 } 174 175 ALWAYS_INLINE double Register::unboxedDouble() const 176 { 177 return u.number; 178 } 179 180 ALWAYS_INLINE JSCell* Register::unboxedCell() const 181 { 182#if USE(JSVALUE64) 183 return u.encodedValue.ptr; 184#else 185 return bitwise_cast<JSCell*>(payload()); 186#endif 187 } 188 189 ALWAYS_INLINE int32_t Register::payload() const 190 { 191 return u.encodedValue.asBits.payload; 192 } 193 194 ALWAYS_INLINE int32_t Register::tag() const 195 { 196 return u.encodedValue.asBits.tag; 197 } 198 199 ALWAYS_INLINE int32_t& Register::payload() 200 { 201 return u.encodedValue.asBits.payload; 202 } 203 204 ALWAYS_INLINE int32_t& Register::tag() 205 { 206 return u.encodedValue.asBits.tag; 207 } 208 209} // namespace JSC 210 211namespace WTF { 212 213 template<> struct VectorTraits<JSC::Register> : VectorTraitsBase<true, JSC::Register> { }; 214 215} // namespace WTF 216 217#endif // Register_h 218