1/* 2 * Copyright (C) 2013 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 CallFrameInlines_h 27#define CallFrameInlines_h 28 29#include "CallFrame.h" 30#include "CodeBlock.h" 31 32namespace JSC { 33 34inline uint32_t CallFrame::Location::encode(CallFrame::Location::TypeTag tag, uint32_t bits) 35{ 36#if USE(JSVALUE64) 37 ASSERT(!(bits & s_shiftedMask)); 38 ASSERT(!(tag & ~s_mask)); 39 return bits | (tag << s_shift); 40#else 41 ASSERT(!(tag & ~s_mask)); 42 if (tag & CodeOriginIndexTag) 43 bits = (bits << s_shift); 44 ASSERT(!(bits & s_mask)); 45 bits |= tag; 46 return bits; 47#endif 48} 49 50inline uint32_t CallFrame::Location::decode(uint32_t bits) 51{ 52#if USE(JSVALUE64) 53 return bits & ~s_shiftedMask; 54#else 55 if (isCodeOriginIndex(bits)) 56 return bits >> s_shift; 57 return bits & ~s_mask; 58#endif 59} 60 61#if USE(JSVALUE64) 62inline uint32_t CallFrame::Location::encodeAsBytecodeOffset(uint32_t bits) 63{ 64 uint32_t encodedBits = encode(BytecodeLocationTag, bits); 65 ASSERT(isBytecodeLocation(encodedBits)); 66 return encodedBits; 67} 68#else 69inline uint32_t CallFrame::Location::encodeAsBytecodeInstruction(Instruction* instruction) 70{ 71 uint32_t encodedBits = encode(BytecodeLocationTag, reinterpret_cast<uint32_t>(instruction)); 72 ASSERT(isBytecodeLocation(encodedBits)); 73 return encodedBits; 74} 75#endif 76 77inline uint32_t CallFrame::Location::encodeAsCodeOriginIndex(uint32_t bits) 78{ 79 uint32_t encodedBits = encode(CodeOriginIndexTag, bits); 80 ASSERT(isCodeOriginIndex(encodedBits)); 81 return encodedBits; 82} 83 84inline bool CallFrame::Location::isBytecodeLocation(uint32_t bits) 85{ 86 return !isCodeOriginIndex(bits); 87} 88 89inline bool CallFrame::Location::isCodeOriginIndex(uint32_t bits) 90{ 91#if USE(JSVALUE64) 92 TypeTag tag = static_cast<TypeTag>(bits >> s_shift); 93 return !!(tag & CodeOriginIndexTag); 94#else 95 return !!(bits & CodeOriginIndexTag); 96#endif 97} 98 99inline bool CallFrame::hasLocationAsBytecodeOffset() const 100{ 101 return Location::isBytecodeLocation(locationAsRawBits()); 102} 103 104inline bool CallFrame::hasLocationAsCodeOriginIndex() const 105{ 106 return Location::isCodeOriginIndex(locationAsRawBits()); 107} 108 109inline unsigned CallFrame::locationAsRawBits() const 110{ 111 return this[JSStack::ArgumentCount].tag(); 112} 113 114inline void CallFrame::setLocationAsRawBits(unsigned bits) 115{ 116 this[JSStack::ArgumentCount].tag() = static_cast<int32_t>(bits); 117} 118 119#if USE(JSVALUE64) 120inline unsigned CallFrame::locationAsBytecodeOffset() const 121{ 122 ASSERT(hasLocationAsBytecodeOffset()); 123 ASSERT(codeBlock()); 124 return Location::decode(locationAsRawBits()); 125} 126 127inline void CallFrame::setLocationAsBytecodeOffset(unsigned offset) 128{ 129 ASSERT(codeBlock()); 130 setLocationAsRawBits(Location::encodeAsBytecodeOffset(offset)); 131 ASSERT(hasLocationAsBytecodeOffset()); 132} 133#endif // USE(JSVALUE64) 134 135inline unsigned CallFrame::locationAsCodeOriginIndex() const 136{ 137 ASSERT(hasLocationAsCodeOriginIndex()); 138 ASSERT(codeBlock()); 139 return Location::decode(locationAsRawBits()); 140} 141 142inline JSValue CallFrame::uncheckedActivation() const 143{ 144 CodeBlock* codeBlock = this->codeBlock(); 145 RELEASE_ASSERT(codeBlock->needsActivation()); 146 VirtualRegister activationRegister = codeBlock->activationRegister(); 147 return registers()[activationRegister.offset()].jsValue(); 148} 149 150} // namespace JSC 151 152#endif // CallFrameInlines_h 153