1// Copyright 2018 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5type FrameType extends Smi constexpr 'StackFrame::Type'; 6const STUB_FRAME: constexpr FrameType 7 generates 'StackFrame::STUB'; 8const kFrameTypeCount: 9 constexpr int31 generates 'StackFrame::NUMBER_OF_TYPES'; 10 11FromConstexpr<FrameType, constexpr FrameType>(t: constexpr FrameType): 12 FrameType { 13 // Note that althought FrameTypes sometimes masquerade as Smis (their 14 // LSB is a zero), they are not. For efficiency in storing them as a 15 // constant into a frame, they are simply the FrameType value shifted 16 // up by a single bit. 17 const i: constexpr uintptr = %RawConstexprCast<constexpr uintptr>(t) 18 << kSmiTagSize; 19 return %RawDownCast<FrameType>(BitcastWordToTaggedSigned(i)); 20} 21Cast<FrameType>(o: Object): FrameType 22 labels CastError { 23 if (TaggedIsNotSmi(o)) goto CastError; 24 dcheck( 25 Convert<int32>(BitcastTaggedToWordForTagAndSmiBits(o)) < 26 Convert<int32>(kFrameTypeCount << kSmiTagSize)); 27 return %RawDownCast<FrameType>(o); 28} 29 30type FrameBase extends RawPtr constexpr 'void*'; 31type StandardFrame extends FrameBase constexpr 'void*'; 32type StubFrame extends FrameBase constexpr 'void*'; 33type FrameWithArguments = StandardFrame; 34type Frame = FrameWithArguments|StubFrame; 35 36extern macro LoadFramePointer(): Frame; 37extern macro LoadParentFramePointer(): Frame; 38 39// Load values from a specified frame by given offset in bytes. 40macro LoadObjectFromFrame(f: Frame, o: constexpr int32): Object { 41 return LoadBufferObject(f, o); 42} 43macro LoadPointerFromFrame(f: Frame, o: constexpr int32): RawPtr { 44 return LoadBufferPointer(f, o); 45} 46macro LoadIntptrFromFrame(f: Frame, o: constexpr int32): intptr { 47 return LoadBufferIntptr(f, o); 48} 49 50const kStandardFrameFunctionOffset: constexpr int31 51 generates 'StandardFrameConstants::kFunctionOffset'; 52operator '.function' macro LoadFunctionFromFrame(f: Frame): JSFunction { 53 // TODO(danno): Use RawDownCast here in order to avoid passing the implicit 54 // context, since this accessor is used in legacy CSA code through 55 // LoadTargetFromFrame 56 const result: Object = LoadObjectFromFrame(f, kStandardFrameFunctionOffset); 57 return %RawDownCast<JSFunction>(result); 58} 59 60const kStandardFrameCallerFPOffset: constexpr int31 61 generates 'StandardFrameConstants::kCallerFPOffset'; 62operator '.caller' macro LoadCallerFromFrame(f: Frame): Frame { 63 const result: RawPtr = LoadPointerFromFrame(f, kStandardFrameCallerFPOffset); 64 return %RawDownCast<Frame>(result); 65} 66 67const kStandardFrameArgCOffset: constexpr int31 68 generates 'StandardFrameConstants::kArgCOffset'; 69const kJSArgcReceiverSlots: constexpr int31 70 generates 'kJSArgcReceiverSlots'; 71 72operator '.argument_count' macro LoadArgCFromFrame(f: Frame): intptr { 73 return LoadIntptrFromFrame(f, kStandardFrameArgCOffset) - 74 kJSArgcReceiverSlots; 75} 76 77type ContextOrFrameType = Context|FrameType; 78Cast<ContextOrFrameType>(implicit context: Context)(o: Object): 79 ContextOrFrameType 80 labels CastError { 81 typeswitch (o) { 82 case (c: Context): { 83 return c; 84 } 85 case (t: FrameType): { 86 return t; 87 } 88 case (Object): { 89 goto CastError; 90 } 91 } 92} 93 94const kStandardFrameContextOrFrameTypeOffset: constexpr int31 95 generates 'StandardFrameConstants::kContextOrFrameTypeOffset'; 96operator '.context_or_frame_type' 97macro LoadContextOrFrameTypeFromFrame(implicit context: Context)(f: Frame): 98 ContextOrFrameType { 99 return UnsafeCast<ContextOrFrameType>( 100 LoadObjectFromFrame(f, kStandardFrameContextOrFrameTypeOffset)); 101} 102 103operator '==' macro FrameTypeEquals(f1: FrameType, f2: FrameType): bool { 104 return TaggedEqual(f1, f2); 105} 106 107macro Cast<A : type extends Frame>(implicit context: Context)(o: Frame): 108 A labels CastError; 109Cast<StandardFrame>(implicit context: Context)(f: Frame): 110 StandardFrame labels CastError { 111 const o: HeapObject = 112 Cast<HeapObject>(f.context_or_frame_type) otherwise CastError; 113 // StandardFrames (which include interpreted and JIT-compiled frames), 114 // unlike other frame types, don't have their own type marker stored in 115 // the frame, but rather have the function's context stored where the 116 // type marker is stored for other frame types. From Torque, it would 117 // be quite expensive to do the test required to distinguish interpreter 118 // frames from JITted ones (and other StandardFrame types), so 119 // StandardFrame is the level of granularity support when iterating the 120 // stack from generated code. 121 // See the descriptions and frame layouts in src/frame-constants.h. 122 if (IsContext(o)) { 123 return %RawDownCast<StandardFrame>(f); 124 } 125 goto CastError; 126} 127 128// Load target function from the current JS frame. 129// This is an alternative way of getting the target function in addition to 130// Parameter(Descriptor::kJSTarget). The latter should be used near the 131// beginning of builtin code while the target value is still in the register 132// and the former should be used in slow paths in order to reduce register 133// pressure on the fast path. 134@export 135macro LoadTargetFromFrame(): JSFunction { 136 return LoadFramePointer().function; 137} 138