The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / frames.h @ 40c0f755

History | View | Annotate | Download (19.6 KB)

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_H_
29
#define V8_FRAMES_H_
30

    
31
namespace v8 { namespace internal {
32

    
33
typedef uint32_t RegList;
34

    
35
// Get the number of registers in a given register list.
36
int NumRegs(RegList list);
37

    
38
// Return the code of the n-th saved register available to JavaScript.
39
int JSCallerSavedCode(int n);
40

    
41

    
42
// Forward declarations.
43
class StackFrameIterator;
44
class Top;
45
class ThreadLocalTop;
46

    
47

    
48
class StackHandler BASE_EMBEDDED {
49
 public:
50
  enum State {
51
    ENTRY,
52
    TRY_CATCH,
53
    TRY_FINALLY
54
  };
55

    
56
  // Get the address of this stack handler.
57
  inline Address address() const;
58

    
59
  // Get the next stack handler in the chain.
60
  inline StackHandler* next() const;
61

    
62
  // Tells whether the given address is inside this handler.
63
  inline bool includes(Address address) const;
64

    
65
  // Garbage collection support.
66
  inline void Iterate(ObjectVisitor* v) const;
67

    
68
  // Conversion support.
69
  static inline StackHandler* FromAddress(Address address);
70

    
71
  // Testers
72
  bool is_entry() { return state() == ENTRY; }
73
  bool is_try_catch() { return state() == TRY_CATCH; }
74
  bool is_try_finally() { return state() == TRY_FINALLY; }
75

    
76
  // Garbage collection support.
77
  void Cook(Code* code);
78
  void Uncook(Code* code);
79

    
80
  // TODO(1233780): Get rid of the code slot in stack handlers.
81
  static const int kCodeNotPresent = 0;
82

    
83
 private:
84
  // Accessors.
85
  inline State state() const;
86

    
87
  inline Address pc() const;
88
  inline void set_pc(Address value);
89

    
90
  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
91
};
92

    
93

    
94
#define STACK_FRAME_TYPE_LIST(V)              \
95
  V(ENTRY,             EntryFrame)            \
96
  V(ENTRY_CONSTRUCT,   EntryConstructFrame)   \
97
  V(EXIT,              ExitFrame)             \
98
  V(EXIT_DEBUG,        ExitDebugFrame)        \
99
  V(JAVA_SCRIPT,       JavaScriptFrame)       \
100
  V(INTERNAL,          InternalFrame)         \
101
  V(CONSTRUCT,         ConstructFrame)        \
102
  V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
103

    
104

    
105
// Abstract base class for all stack frames.
106
class StackFrame BASE_EMBEDDED {
107
 public:
108
#define DECLARE_TYPE(type, ignore) type,
109
  enum Type {
110
    NONE = 0,
111
    STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
112
    NUMBER_OF_TYPES
113
  };
114
#undef DECLARE_TYPE
115

    
116
  // Opaque data type for identifying stack frames. Used extensively
117
  // by the debugger.
118
  enum Id { NO_ID = 0 };
119

    
120
  // Type testers.
121
  bool is_entry() const { return type() == ENTRY; }
122
  bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
123
  bool is_exit() const { return type() == EXIT; }
124
  bool is_exit_debug() const { return type() == EXIT_DEBUG; }
125
  bool is_java_script() const { return type() == JAVA_SCRIPT; }
126
  bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
127
  bool is_internal() const { return type() == INTERNAL; }
128
  bool is_construct() const { return type() == CONSTRUCT; }
129
  virtual bool is_standard() const { return false; }
130

    
131
  // Accessors.
132
  Address sp() const { return state_.sp; }
133
  Address fp() const { return state_.fp; }
134
  Address pp() const { return GetCallerStackPointer(); }
135

    
136
  Address pc() const { return *pc_address(); }
137
  void set_pc(Address pc) { *pc_address() = pc; }
138

    
139
  Address* pc_address() const { return state_.pc_address; }
140

    
141
  // Get the id of this stack frame.
142
  Id id() const { return static_cast<Id>(OffsetFrom(pp())); }
143

    
144
  // Checks if this frame includes any stack handlers.
145
  bool HasHandler() const;
146

    
147
  // Get the type of this frame.
148
  virtual Type type() const = 0;
149

    
150
  // Get the code associated with this frame.
151
  virtual Code* code() const = 0;
152

    
153
  // Garbage collection support.
154
  static void CookFramesForThread(ThreadLocalTop* thread);
155
  static void UncookFramesForThread(ThreadLocalTop* thread);
156

    
157
  virtual void Iterate(ObjectVisitor* v) const { }
158

    
159
  // Printing support.
160
  enum PrintMode { OVERVIEW, DETAILS };
161
  virtual void Print(StringStream* accumulator,
162
                     PrintMode mode,
163
                     int index) const { }
164

    
165
 protected:
166
  struct State {
167
    Address sp;
168
    Address fp;
169
    Address* pc_address;
170
  };
171

    
172
  explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { }
173
  virtual ~StackFrame() { }
174

    
175
  // Compute the stack pointer for the calling frame.
176
  virtual Address GetCallerStackPointer() const = 0;
177

    
178
  // Printing support.
179
  static void PrintIndex(StringStream* accumulator,
180
                         PrintMode mode,
181
                         int index);
182

    
183
  // Get the top handler from the current stack iterator.
184
  inline StackHandler* top_handler() const;
185

    
186
  // Compute the stack frame type for the given state.
187
  static Type ComputeType(State* state);
188

    
189
 private:
190
  const StackFrameIterator* iterator_;
191
  State state_;
192

    
193
  // Fill in the state of the calling frame.
194
  virtual void ComputeCallerState(State* state) const = 0;
195

    
196
  // Get the type and the state of the calling frame.
197
  virtual Type GetCallerState(State* state) const;
198

    
199
  // Cooking/uncooking support.
200
  void Cook();
201
  void Uncook();
202

    
203
  friend class StackFrameIterator;
204
  friend class StackHandlerIterator;
205
  friend class SafeStackFrameIterator;
206

    
207
  DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrame);
208
};
209

    
210

    
211
// Entry frames are used to enter JavaScript execution from C.
212
class EntryFrame: public StackFrame {
213
 public:
214
  virtual Type type() const { return ENTRY; }
215

    
216
  virtual Code* code() const;
217

    
218
  // Garbage collection support.
219
  virtual void Iterate(ObjectVisitor* v) const;
220

    
221
  static EntryFrame* cast(StackFrame* frame) {
222
    ASSERT(frame->is_entry());
223
    return static_cast<EntryFrame*>(frame);
224
  }
225

    
226
 protected:
227
  explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
228

    
229
  // The caller stack pointer for entry frames is always zero. The
230
  // real information about the caller frame is available through the
231
  // link to the top exit frame.
232
  virtual Address GetCallerStackPointer() const { return 0; }
233

    
234
 private:
235
  virtual void ComputeCallerState(State* state) const;
236
  virtual Type GetCallerState(State* state) const;
237

    
238
  friend class StackFrameIterator;
239
};
240

    
241

    
242
class EntryConstructFrame: public EntryFrame {
243
 public:
244
  virtual Type type() const { return ENTRY_CONSTRUCT; }
245

    
246
  virtual Code* code() const;
247

    
248
  static EntryConstructFrame* cast(StackFrame* frame) {
249
    ASSERT(frame->is_entry_construct());
250
    return static_cast<EntryConstructFrame*>(frame);
251
  }
252

    
253
 protected:
254
  explicit EntryConstructFrame(StackFrameIterator* iterator)
255
      : EntryFrame(iterator) { }
256

    
257
 private:
258
  friend class StackFrameIterator;
259
};
260

    
261

    
262
// Exit frames are used to exit JavaScript execution and go to C.
263
class ExitFrame: public StackFrame {
264
 public:
265
  virtual Type type() const { return EXIT; }
266

    
267
  virtual Code* code() const;
268

    
269
  // Garbage collection support.
270
  virtual void Iterate(ObjectVisitor* v) const;
271

    
272
  static ExitFrame* cast(StackFrame* frame) {
273
    ASSERT(frame->is_exit());
274
    return static_cast<ExitFrame*>(frame);
275
  }
276

    
277
  // Compute the state and type of an exit frame given a frame
278
  // pointer. Used when constructing the first stack frame seen by an
279
  // iterator and the frames following entry frames.
280
  static Type GetStateForFramePointer(Address fp, State* state);
281

    
282
 protected:
283
  explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
284

    
285
  virtual Address GetCallerStackPointer() const;
286

    
287
 private:
288
  virtual void ComputeCallerState(State* state) const;
289

    
290
  friend class StackFrameIterator;
291
};
292

    
293

    
294
class ExitDebugFrame: public ExitFrame {
295
 public:
296
  virtual Type type() const { return EXIT_DEBUG; }
297

    
298
  virtual Code* code() const;
299

    
300
  static ExitDebugFrame* cast(StackFrame* frame) {
301
    ASSERT(frame->is_exit_debug());
302
    return static_cast<ExitDebugFrame*>(frame);
303
  }
304

    
305
 protected:
306
  explicit ExitDebugFrame(StackFrameIterator* iterator)
307
      : ExitFrame(iterator) { }
308

    
309
 private:
310
  friend class StackFrameIterator;
311
};
312

    
313

    
314
class StandardFrame: public StackFrame {
315
 public:
316
  // Testers.
317
  virtual bool is_standard() const { return true; }
318

    
319
  // Accessors.
320
  inline Object* context() const;
321

    
322
  // Access the expressions in the stack frame including locals.
323
  inline Object* GetExpression(int index) const;
324
  inline void SetExpression(int index, Object* value);
325
  int ComputeExpressionsCount() const;
326

    
327
  static StandardFrame* cast(StackFrame* frame) {
328
    ASSERT(frame->is_standard());
329
    return static_cast<StandardFrame*>(frame);
330
  }
331

    
332
 protected:
333
  explicit StandardFrame(StackFrameIterator* iterator)
334
      : StackFrame(iterator) { }
335

    
336
  virtual void ComputeCallerState(State* state) const;
337

    
338
  // Accessors.
339
  inline Address caller_sp() const;
340
  inline Address caller_fp() const;
341
  inline Address caller_pc() const;
342

    
343
  // Computes the address of the PC field in the standard frame given
344
  // by the provided frame pointer.
345
  static inline Address ComputePCAddress(Address fp);
346

    
347
  // Iterate over expression stack including stack handlers, locals,
348
  // and parts of the fixed part including context and code fields.
349
  void IterateExpressions(ObjectVisitor* v) const;
350

    
351
  // Returns the address of the n'th expression stack element.
352
  Address GetExpressionAddress(int n) const;
353

    
354
  // Determines if the n'th expression stack element is in a stack
355
  // handler or not. Requires traversing all handlers in this frame.
356
  bool IsExpressionInsideHandler(int n) const;
357

    
358
  // Determines if the standard frame for the given frame pointer is
359
  // an arguments adaptor frame.
360
  static inline bool IsArgumentsAdaptorFrame(Address fp);
361

    
362
  // Determines if the standard frame for the given frame pointer is a
363
  // construct frame.
364
  static inline bool IsConstructFrame(Address fp);
365

    
366
 private:
367
  friend class StackFrame;
368
};
369

    
370

    
371
class JavaScriptFrame: public StandardFrame {
372
 public:
373
  virtual Type type() const { return JAVA_SCRIPT; }
374

    
375
  // Accessors.
376
  inline Object* function() const;
377
  inline Object* receiver() const;
378
  inline void set_receiver(Object* value);
379

    
380
  // Access the parameters.
381
  Object* GetParameter(int index) const;
382
  int ComputeParametersCount() const;
383

    
384
  // Temporary way of getting access to the number of parameters
385
  // passed on the stack by the caller. Once argument adaptor frames
386
  // has been introduced on ARM, this number will always match the
387
  // computed parameters count.
388
  int GetProvidedParametersCount() const;
389

    
390
  // Check if this frame is a constructor frame invoked through 'new'.
391
  bool IsConstructor() const;
392

    
393
  // Check if this frame has "adapted" arguments in the sense that the
394
  // actual passed arguments are available in an arguments adaptor
395
  // frame below it on the stack.
396
  inline bool has_adapted_arguments() const;
397

    
398
  // Garbage collection support.
399
  virtual void Iterate(ObjectVisitor* v) const;
400

    
401
  // Printing support.
402
  virtual void Print(StringStream* accumulator,
403
                     PrintMode mode,
404
                     int index) const;
405

    
406
  // Determine the code for the frame.
407
  virtual Code* code() const;
408

    
409
  static JavaScriptFrame* cast(StackFrame* frame) {
410
    ASSERT(frame->is_java_script());
411
    return static_cast<JavaScriptFrame*>(frame);
412
  }
413

    
414
 protected:
415
  explicit JavaScriptFrame(StackFrameIterator* iterator)
416
      : StandardFrame(iterator), disable_heap_access_(false) { }
417

    
418
  virtual Address GetCallerStackPointer() const;
419

    
420
  // When this mode is enabled it is not allowed to access heap objects.
421
  // This is a special mode used when gathering stack samples in profiler.
422
  // A shortcoming is that caller's SP value will be calculated incorrectly
423
  // (see GetCallerStackPointer implementation), but it is not used for stack
424
  // sampling.
425
  void DisableHeapAccess() { disable_heap_access_ = true; }
426

    
427
 private:
428
  bool disable_heap_access_;
429
  inline Object* function_slot_object() const;
430

    
431
  friend class StackFrameIterator;
432
};
433

    
434

    
435
// Arguments adaptor frames are automatically inserted below
436
// JavaScript frames when the actual number of parameters does not
437
// match the formal number of parameters.
438
class ArgumentsAdaptorFrame: public JavaScriptFrame {
439
 public:
440
  // This sentinel value is temporarily used to distinguish arguments
441
  // adaptor frames from ordinary JavaScript frames. If a frame has
442
  // the sentinel as its context, it is an arguments adaptor frame. It
443
  // must be tagged as a small integer to avoid GC issues. Crud.
444
  enum {
445
    SENTINEL = (1 << kSmiTagSize) | kSmiTag
446
  };
447

    
448
  virtual Type type() const { return ARGUMENTS_ADAPTOR; }
449

    
450
  // Determine the code for the frame.
451
  virtual Code* code() const;
452

    
453
  static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
454
    ASSERT(frame->is_arguments_adaptor());
455
    return static_cast<ArgumentsAdaptorFrame*>(frame);
456
  }
457

    
458
  // Printing support.
459
  virtual void Print(StringStream* accumulator,
460
                     PrintMode mode,
461
                     int index) const;
462
 protected:
463
  explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator)
464
      : JavaScriptFrame(iterator) { }
465

    
466
  virtual Address GetCallerStackPointer() const;
467

    
468
 private:
469
  friend class StackFrameIterator;
470
};
471

    
472

    
473
class InternalFrame: public StandardFrame {
474
 public:
475
  virtual Type type() const { return INTERNAL; }
476

    
477
  // Garbage collection support.
478
  virtual void Iterate(ObjectVisitor* v) const;
479

    
480
  // Determine the code for the frame.
481
  virtual Code* code() const;
482

    
483
  static InternalFrame* cast(StackFrame* frame) {
484
    ASSERT(frame->is_internal());
485
    return static_cast<InternalFrame*>(frame);
486
  }
487

    
488
 protected:
489
  explicit InternalFrame(StackFrameIterator* iterator)
490
      : StandardFrame(iterator) { }
491

    
492
  virtual Address GetCallerStackPointer() const;
493

    
494
 private:
495
  friend class StackFrameIterator;
496
};
497

    
498

    
499
// Construct frames are special trampoline frames introduced to handle
500
// function invocations through 'new'.
501
class ConstructFrame: public InternalFrame {
502
 public:
503
  virtual Type type() const { return CONSTRUCT; }
504

    
505
  static ConstructFrame* cast(StackFrame* frame) {
506
    ASSERT(frame->is_construct());
507
    return static_cast<ConstructFrame*>(frame);
508
  }
509

    
510
 protected:
511
  explicit ConstructFrame(StackFrameIterator* iterator)
512
      : InternalFrame(iterator) { }
513

    
514
 private:
515
  friend class StackFrameIterator;
516
};
517

    
518

    
519
class StackFrameIterator BASE_EMBEDDED {
520
 public:
521
  // An iterator that iterates over the current thread's stack.
522
  StackFrameIterator();
523

    
524
  // An iterator that iterates over a given thread's stack.
525
  explicit StackFrameIterator(ThreadLocalTop* thread);
526

    
527
  // An iterator that can start from a given FP address.
528
  // If use_top, then work as usual, if fp isn't NULL, use it,
529
  // otherwise, do nothing.
530
  StackFrameIterator(bool use_top, Address fp, Address sp);
531

    
532
  StackFrame* frame() const {
533
    ASSERT(!done());
534
    return frame_;
535
  }
536

    
537
  bool done() const { return frame_ == NULL; }
538
  void Advance() { (this->*advance_)(); }
539

    
540
  // Go back to the first frame.
541
  void Reset();
542

    
543
 private:
544
#define DECLARE_SINGLETON(ignore, type) type type##_;
545
  STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
546
#undef DECLARE_SINGLETON
547
  StackFrame* frame_;
548
  StackHandler* handler_;
549
  ThreadLocalTop* thread_;
550
  Address fp_;
551
  Address sp_;
552
  void (StackFrameIterator::*advance_)();
553

    
554
  StackHandler* handler() const {
555
    ASSERT(!done());
556
    return handler_;
557
  }
558

    
559
  // Get the type-specific frame singleton in a given state.
560
  StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
561
  // A helper function, can return a NULL pointer.
562
  StackFrame* SingletonFor(StackFrame::Type type);
563

    
564
  void AdvanceWithHandler();
565
  void AdvanceWithoutHandler();
566

    
567
  friend class StackFrame;
568
  friend class SafeStackFrameIterator;
569
  DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
570
};
571

    
572

    
573
// Iterator that supports iterating through all JavaScript frames.
574
template<typename Iterator>
575
class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
576
 public:
577
  JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
578

    
579
  explicit JavaScriptFrameIteratorTemp(ThreadLocalTop* thread) :
580
      iterator_(thread) {
581
    if (!done()) Advance();
582
  }
583

    
584
  // Skip frames until the frame with the given id is reached.
585
  explicit JavaScriptFrameIteratorTemp(StackFrame::Id id);
586

    
587
  JavaScriptFrameIteratorTemp(Address fp, Address sp,
588
                              Address low_bound, Address high_bound) :
589
      iterator_(fp, sp, low_bound, high_bound) {
590
    if (!done()) Advance();
591
  }
592

    
593
  inline JavaScriptFrame* frame() const;
594

    
595
  bool done() const { return iterator_.done(); }
596
  void Advance();
597

    
598
  // Advance to the frame holding the arguments for the current
599
  // frame. This only affects the current frame if it has adapted
600
  // arguments.
601
  void AdvanceToArgumentsFrame();
602

    
603
  // Go back to the first frame.
604
  void Reset();
605

    
606
 private:
607
  Iterator iterator_;
608
};
609

    
610

    
611
typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
612

    
613

    
614
// NOTE: The stack trace frame iterator is an iterator that only
615
// traverse proper JavaScript frames; that is JavaScript frames that
616
// have proper JavaScript functions. This excludes the problematic
617
// functions in runtime.js.
618
class StackTraceFrameIterator: public JavaScriptFrameIterator {
619
 public:
620
  StackTraceFrameIterator();
621
  void Advance();
622
};
623

    
624

    
625
class SafeStackFrameIterator BASE_EMBEDDED {
626
 public:
627
  SafeStackFrameIterator(Address fp, Address sp,
628
                         Address low_bound, Address high_bound);
629

    
630
  StackFrame* frame() const {
631
    ASSERT(is_working_iterator_);
632
    return iterator_.frame();
633
  }
634

    
635
  bool done() const { return iteration_done_ ? true : iterator_.done(); }
636

    
637
  void Advance();
638
  void Reset();
639

    
640
 private:
641
  static bool IsWithinBounds(
642
      Address low_bound, Address high_bound, Address addr) {
643
    return low_bound <= addr && addr <= high_bound;
644
  }
645
  bool IsValidStackAddress(Address addr) const {
646
    return IsWithinBounds(low_bound_, high_bound_, addr);
647
  }
648
  bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
649
  bool IsValidFrame(StackFrame* frame) const;
650
  bool IsValidCaller(StackFrame* frame);
651

    
652
  Address low_bound_;
653
  Address high_bound_;
654
  const bool is_valid_top_;
655
  const bool is_valid_fp_;
656
  const bool is_working_iterator_;
657
  bool iteration_done_;
658
  StackFrameIterator iterator_;
659
};
660

    
661

    
662
#ifdef ENABLE_LOGGING_AND_PROFILING
663
typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
664
    SafeJavaScriptFrameIterator;
665

    
666

    
667
class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator {
668
 public:
669
  explicit SafeStackTraceFrameIterator(Address fp, Address sp,
670
                                       Address low_bound, Address high_bound);
671
  void Advance();
672
};
673
#endif
674

    
675

    
676
class StackFrameLocator BASE_EMBEDDED {
677
 public:
678
  // Find the nth JavaScript frame on the stack. The caller must
679
  // guarantee that such a frame exists.
680
  JavaScriptFrame* FindJavaScriptFrame(int n);
681

    
682
 private:
683
  StackFrameIterator iterator_;
684
};
685

    
686

    
687
} }  // namespace v8::internal
688

    
689
#endif  // V8_FRAMES_H_