1// Copyright 2006-2008 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#ifndef V8_FRAMES_INL_H_ 29#define V8_FRAMES_INL_H_ 30 31#include "frames.h" 32 33#if V8_TARGET_ARCH_IA32 34#include "ia32/frames-ia32.h" 35#elif V8_TARGET_ARCH_X64 36#include "x64/frames-x64.h" 37#elif V8_TARGET_ARCH_ARM 38#include "arm/frames-arm.h" 39#elif V8_TARGET_ARCH_MIPS 40#include "mips/frames-mips.h" 41#else 42#error Unsupported target architecture. 43#endif 44 45namespace v8 { 46namespace internal { 47 48 49inline Address StackHandler::address() const { 50 return reinterpret_cast<Address>(const_cast<StackHandler*>(this)); 51} 52 53 54inline StackHandler* StackHandler::next() const { 55 const int offset = StackHandlerConstants::kNextOffset; 56 return FromAddress(Memory::Address_at(address() + offset)); 57} 58 59 60inline bool StackHandler::includes(Address address) const { 61 Address start = this->address(); 62 Address end = start + StackHandlerConstants::kSize; 63 return start <= address && address <= end; 64} 65 66 67inline void StackHandler::Iterate(ObjectVisitor* v) const { 68 // Stack handlers do not contain any pointers that need to be 69 // traversed. 70} 71 72 73inline StackHandler* StackHandler::FromAddress(Address address) { 74 return reinterpret_cast<StackHandler*>(address); 75} 76 77 78inline StackHandler::State StackHandler::state() const { 79 const int offset = StackHandlerConstants::kStateOffset; 80 return static_cast<State>(Memory::int_at(address() + offset)); 81} 82 83 84inline Address StackHandler::pc() const { 85 const int offset = StackHandlerConstants::kPCOffset; 86 return Memory::Address_at(address() + offset); 87} 88 89 90inline void StackHandler::set_pc(Address value) { 91 const int offset = StackHandlerConstants::kPCOffset; 92 Memory::Address_at(address() + offset) = value; 93} 94 95 96inline StackHandler* StackFrame::top_handler() const { 97 return iterator_->handler(); 98} 99 100 101inline Object* StandardFrame::GetExpression(int index) const { 102 return Memory::Object_at(GetExpressionAddress(index)); 103} 104 105 106inline void StandardFrame::SetExpression(int index, Object* value) { 107 Memory::Object_at(GetExpressionAddress(index)) = value; 108} 109 110 111inline Object* StandardFrame::context() const { 112 const int offset = StandardFrameConstants::kContextOffset; 113 return Memory::Object_at(fp() + offset); 114} 115 116 117inline Address StandardFrame::caller_fp() const { 118 return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset); 119} 120 121 122inline Address StandardFrame::caller_pc() const { 123 return Memory::Address_at(ComputePCAddress(fp())); 124} 125 126 127inline Address StandardFrame::ComputePCAddress(Address fp) { 128 return fp + StandardFrameConstants::kCallerPCOffset; 129} 130 131 132inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) { 133 Object* marker = 134 Memory::Object_at(fp + StandardFrameConstants::kContextOffset); 135 return marker == Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR); 136} 137 138 139inline bool StandardFrame::IsConstructFrame(Address fp) { 140 Object* marker = 141 Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset); 142 return marker == Smi::FromInt(CONSTRUCT); 143} 144 145 146inline Object* JavaScriptFrame::receiver() const { 147 const int offset = JavaScriptFrameConstants::kReceiverOffset; 148 return Memory::Object_at(caller_sp() + offset); 149} 150 151 152inline void JavaScriptFrame::set_receiver(Object* value) { 153 const int offset = JavaScriptFrameConstants::kReceiverOffset; 154 Memory::Object_at(caller_sp() + offset) = value; 155} 156 157 158inline bool JavaScriptFrame::has_adapted_arguments() const { 159 return IsArgumentsAdaptorFrame(caller_fp()); 160} 161 162 163inline Object* JavaScriptFrame::function() const { 164 Object* result = function_slot_object(); 165 ASSERT(result->IsJSFunction()); 166 return result; 167} 168 169 170template<typename Iterator> 171inline JavaScriptFrame* JavaScriptFrameIteratorTemp<Iterator>::frame() const { 172 // TODO(1233797): The frame hierarchy needs to change. It's 173 // problematic that we can't use the safe-cast operator to cast to 174 // the JavaScript frame type, because we may encounter arguments 175 // adaptor frames. 176 StackFrame* frame = iterator_.frame(); 177 ASSERT(frame->is_java_script() || frame->is_arguments_adaptor()); 178 return static_cast<JavaScriptFrame*>(frame); 179} 180 181 182template<typename Iterator> 183JavaScriptFrameIteratorTemp<Iterator>::JavaScriptFrameIteratorTemp( 184 StackFrame::Id id) { 185 while (!done()) { 186 Advance(); 187 if (frame()->id() == id) return; 188 } 189} 190 191 192template<typename Iterator> 193void JavaScriptFrameIteratorTemp<Iterator>::Advance() { 194 do { 195 iterator_.Advance(); 196 } while (!iterator_.done() && !iterator_.frame()->is_java_script()); 197} 198 199 200template<typename Iterator> 201void JavaScriptFrameIteratorTemp<Iterator>::AdvanceToArgumentsFrame() { 202 if (!frame()->has_adapted_arguments()) return; 203 iterator_.Advance(); 204 ASSERT(iterator_.frame()->is_arguments_adaptor()); 205} 206 207 208template<typename Iterator> 209void JavaScriptFrameIteratorTemp<Iterator>::Reset() { 210 iterator_.Reset(); 211 if (!done()) Advance(); 212} 213 214 215} } // namespace v8::internal 216 217#endif // V8_FRAMES_INL_H_ 218