2 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef CallFrameInlines_h
27 #define CallFrameInlines_h
29 #include "CallFrame.h"
30 #include "CodeBlock.h"
34 inline uint32_t CallFrame::Location::encode(CallFrame::Location::TypeTag tag
, uint32_t bits
)
37 ASSERT(!(bits
& s_shiftedMask
));
38 ASSERT(!(tag
& ~s_mask
));
39 return bits
| (tag
<< s_shift
);
41 ASSERT(!(tag
& ~s_mask
));
42 if (tag
& CodeOriginIndexTag
)
43 bits
= (bits
<< s_shift
);
44 ASSERT(!(bits
& s_mask
));
50 inline uint32_t CallFrame::Location::decode(uint32_t bits
)
53 return bits
& ~s_shiftedMask
;
55 if (isCodeOriginIndex(bits
))
56 return bits
>> s_shift
;
57 return bits
& ~s_mask
;
62 inline uint32_t CallFrame::Location::encodeAsBytecodeOffset(uint32_t bits
)
64 uint32_t encodedBits
= encode(BytecodeLocationTag
, bits
);
65 ASSERT(isBytecodeLocation(encodedBits
));
69 inline uint32_t CallFrame::Location::encodeAsBytecodeInstruction(Instruction
* instruction
)
71 uint32_t encodedBits
= encode(BytecodeLocationTag
, reinterpret_cast<uint32_t>(instruction
));
72 ASSERT(isBytecodeLocation(encodedBits
));
77 inline uint32_t CallFrame::Location::encodeAsCodeOriginIndex(uint32_t bits
)
79 uint32_t encodedBits
= encode(CodeOriginIndexTag
, bits
);
80 ASSERT(isCodeOriginIndex(encodedBits
));
84 inline bool CallFrame::Location::isBytecodeLocation(uint32_t bits
)
86 return !isCodeOriginIndex(bits
);
89 inline bool CallFrame::Location::isCodeOriginIndex(uint32_t bits
)
92 TypeTag tag
= static_cast<TypeTag
>(bits
>> s_shift
);
93 return !!(tag
& CodeOriginIndexTag
);
95 return !!(bits
& CodeOriginIndexTag
);
99 inline bool CallFrame::hasLocationAsBytecodeOffset() const
101 return Location::isBytecodeLocation(locationAsRawBits());
104 inline bool CallFrame::hasLocationAsCodeOriginIndex() const
106 return Location::isCodeOriginIndex(locationAsRawBits());
109 inline unsigned CallFrame::locationAsRawBits() const
111 return this[JSStack::ArgumentCount
].tag();
114 inline void CallFrame::setLocationAsRawBits(unsigned bits
)
116 this[JSStack::ArgumentCount
].tag() = static_cast<int32_t>(bits
);
120 inline unsigned CallFrame::locationAsBytecodeOffset() const
122 ASSERT(hasLocationAsBytecodeOffset());
124 return Location::decode(locationAsRawBits());
127 inline void CallFrame::setLocationAsBytecodeOffset(unsigned offset
)
130 setLocationAsRawBits(Location::encodeAsBytecodeOffset(offset
));
131 ASSERT(hasLocationAsBytecodeOffset());
133 #endif // USE(JSVALUE64)
135 inline unsigned CallFrame::locationAsCodeOriginIndex() const
137 ASSERT(hasLocationAsCodeOriginIndex());
139 return Location::decode(locationAsRawBits());
142 inline bool CallFrame::hasActivation() const
144 JSValue activation
= uncheckedActivation();
145 return !!activation
&& activation
.isCell();
148 inline JSValue
CallFrame::uncheckedActivation() const
150 CodeBlock
* codeBlock
= this->codeBlock();
151 RELEASE_ASSERT(codeBlock
->needsActivation());
152 VirtualRegister activationRegister
= codeBlock
->activationRegister();
153 return registers()[activationRegister
.offset()].jsValue();
158 #endif // CallFrameInlines_h