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 / api.h @ f230a1cf

History | View | Annotate | Download (24.2 KB)

1
// Copyright 2012 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_API_H_
29
#define V8_API_H_
30

    
31
#include "v8.h"
32

    
33
#include "../include/v8-testing.h"
34
#include "apiutils.h"
35
#include "contexts.h"
36
#include "factory.h"
37
#include "isolate.h"
38
#include "list-inl.h"
39

    
40
namespace v8 {
41

    
42
// Constants used in the implementation of the API.  The most natural thing
43
// would usually be to place these with the classes that use them, but
44
// we want to keep them out of v8.h because it is an externally
45
// visible file.
46
class Consts {
47
 public:
48
  enum TemplateType {
49
    FUNCTION_TEMPLATE = 0,
50
    OBJECT_TEMPLATE = 1
51
  };
52
};
53

    
54

    
55
// Utilities for working with neander-objects, primitive
56
// env-independent JSObjects used by the api.
57
class NeanderObject {
58
 public:
59
  explicit NeanderObject(int size);
60
  explicit inline NeanderObject(v8::internal::Handle<v8::internal::Object> obj);
61
  explicit inline NeanderObject(v8::internal::Object* obj);
62
  inline v8::internal::Object* get(int index);
63
  inline void set(int index, v8::internal::Object* value);
64
  inline v8::internal::Handle<v8::internal::JSObject> value() { return value_; }
65
  int size();
66
 private:
67
  v8::internal::Handle<v8::internal::JSObject> value_;
68
};
69

    
70

    
71
// Utilities for working with neander-arrays, a simple extensible
72
// array abstraction built on neander-objects.
73
class NeanderArray {
74
 public:
75
  NeanderArray();
76
  explicit inline NeanderArray(v8::internal::Handle<v8::internal::Object> obj);
77
  inline v8::internal::Handle<v8::internal::JSObject> value() {
78
    return obj_.value();
79
  }
80

    
81
  void add(v8::internal::Handle<v8::internal::Object> value);
82

    
83
  int length();
84

    
85
  v8::internal::Object* get(int index);
86
  // Change the value at an index to undefined value. If the index is
87
  // out of bounds, the request is ignored. Returns the old value.
88
  void set(int index, v8::internal::Object* value);
89
 private:
90
  NeanderObject obj_;
91
};
92

    
93

    
94
NeanderObject::NeanderObject(v8::internal::Handle<v8::internal::Object> obj)
95
    : value_(v8::internal::Handle<v8::internal::JSObject>::cast(obj)) { }
96

    
97

    
98
NeanderObject::NeanderObject(v8::internal::Object* obj)
99
    : value_(v8::internal::Handle<v8::internal::JSObject>(
100
        v8::internal::JSObject::cast(obj))) { }
101

    
102

    
103
NeanderArray::NeanderArray(v8::internal::Handle<v8::internal::Object> obj)
104
    : obj_(obj) { }
105

    
106

    
107
v8::internal::Object* NeanderObject::get(int offset) {
108
  ASSERT(value()->HasFastObjectElements());
109
  return v8::internal::FixedArray::cast(value()->elements())->get(offset);
110
}
111

    
112

    
113
void NeanderObject::set(int offset, v8::internal::Object* value) {
114
  ASSERT(value_->HasFastObjectElements());
115
  v8::internal::FixedArray::cast(value_->elements())->set(offset, value);
116
}
117

    
118

    
119
template <typename T> inline T ToCData(v8::internal::Object* obj) {
120
  STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
121
  return reinterpret_cast<T>(
122
      reinterpret_cast<intptr_t>(
123
          v8::internal::Foreign::cast(obj)->foreign_address()));
124
}
125

    
126

    
127
template <typename T>
128
inline v8::internal::Handle<v8::internal::Object> FromCData(
129
    v8::internal::Isolate* isolate, T obj) {
130
  STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
131
  return isolate->factory()->NewForeign(
132
      reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
133
}
134

    
135

    
136
class ApiFunction {
137
 public:
138
  explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { }
139
  v8::internal::Address address() { return addr_; }
140
 private:
141
  v8::internal::Address addr_;
142
};
143

    
144

    
145

    
146
class RegisteredExtension {
147
 public:
148
  explicit RegisteredExtension(Extension* extension);
149
  static void Register(RegisteredExtension* that);
150
  static void UnregisterAll();
151
  Extension* extension() { return extension_; }
152
  RegisteredExtension* next() { return next_; }
153
  static RegisteredExtension* first_extension() { return first_extension_; }
154
 private:
155
  Extension* extension_;
156
  RegisteredExtension* next_;
157
  static RegisteredExtension* first_extension_;
158
};
159

    
160

    
161
#define OPEN_HANDLE_LIST(V)                    \
162
  V(Template, TemplateInfo)                    \
163
  V(FunctionTemplate, FunctionTemplateInfo)    \
164
  V(ObjectTemplate, ObjectTemplateInfo)        \
165
  V(Signature, SignatureInfo)                  \
166
  V(AccessorSignature, FunctionTemplateInfo)   \
167
  V(TypeSwitch, TypeSwitchInfo)                \
168
  V(Data, Object)                              \
169
  V(RegExp, JSRegExp)                          \
170
  V(Object, JSObject)                          \
171
  V(Array, JSArray)                            \
172
  V(ArrayBuffer, JSArrayBuffer)                \
173
  V(ArrayBufferView, JSArrayBufferView)        \
174
  V(TypedArray, JSTypedArray)                  \
175
  V(Uint8Array, JSTypedArray)                  \
176
  V(Uint8ClampedArray, JSTypedArray)           \
177
  V(Int8Array, JSTypedArray)                   \
178
  V(Uint16Array, JSTypedArray)                 \
179
  V(Int16Array, JSTypedArray)                  \
180
  V(Uint32Array, JSTypedArray)                 \
181
  V(Int32Array, JSTypedArray)                  \
182
  V(Float32Array, JSTypedArray)                \
183
  V(Float64Array, JSTypedArray)                \
184
  V(DataView, JSDataView)                      \
185
  V(String, String)                            \
186
  V(Symbol, Symbol)                            \
187
  V(Script, Object)                            \
188
  V(Function, JSFunction)                      \
189
  V(Message, JSObject)                         \
190
  V(Context, Context)                          \
191
  V(External, Foreign)                         \
192
  V(StackTrace, JSArray)                       \
193
  V(StackFrame, JSObject)                      \
194
  V(DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
195

    
196

    
197
class Utils {
198
 public:
199
  static bool ReportApiFailure(const char* location, const char* message);
200

    
201
  static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj);
202
  static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj);
203

    
204
  static inline Local<Context> ToLocal(
205
      v8::internal::Handle<v8::internal::Context> obj);
206
  static inline Local<Value> ToLocal(
207
      v8::internal::Handle<v8::internal::Object> obj);
208
  static inline Local<Function> ToLocal(
209
      v8::internal::Handle<v8::internal::JSFunction> obj);
210
  static inline Local<String> ToLocal(
211
      v8::internal::Handle<v8::internal::String> obj);
212
  static inline Local<Symbol> ToLocal(
213
      v8::internal::Handle<v8::internal::Symbol> obj);
214
  static inline Local<RegExp> ToLocal(
215
      v8::internal::Handle<v8::internal::JSRegExp> obj);
216
  static inline Local<Object> ToLocal(
217
      v8::internal::Handle<v8::internal::JSObject> obj);
218
  static inline Local<Array> ToLocal(
219
      v8::internal::Handle<v8::internal::JSArray> obj);
220
  static inline Local<ArrayBuffer> ToLocal(
221
      v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
222
  static inline Local<ArrayBufferView> ToLocal(
223
      v8::internal::Handle<v8::internal::JSArrayBufferView> obj);
224
  static inline Local<DataView> ToLocal(
225
      v8::internal::Handle<v8::internal::JSDataView> obj);
226

    
227
  static inline Local<TypedArray> ToLocal(
228
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
229
  static inline Local<Uint8Array> ToLocalUint8Array(
230
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
231
  static inline Local<Uint8ClampedArray> ToLocalUint8ClampedArray(
232
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
233
  static inline Local<Int8Array> ToLocalInt8Array(
234
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
235
  static inline Local<Uint16Array> ToLocalUint16Array(
236
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
237
  static inline Local<Int16Array> ToLocalInt16Array(
238
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
239
  static inline Local<Uint32Array> ToLocalUint32Array(
240
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
241
  static inline Local<Int32Array> ToLocalInt32Array(
242
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
243
  static inline Local<Float32Array> ToLocalFloat32Array(
244
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
245
  static inline Local<Float64Array> ToLocalFloat64Array(
246
      v8::internal::Handle<v8::internal::JSTypedArray> obj);
247

    
248
  static inline Local<Message> MessageToLocal(
249
      v8::internal::Handle<v8::internal::Object> obj);
250
  static inline Local<StackTrace> StackTraceToLocal(
251
      v8::internal::Handle<v8::internal::JSArray> obj);
252
  static inline Local<StackFrame> StackFrameToLocal(
253
      v8::internal::Handle<v8::internal::JSObject> obj);
254
  static inline Local<Number> NumberToLocal(
255
      v8::internal::Handle<v8::internal::Object> obj);
256
  static inline Local<Integer> IntegerToLocal(
257
      v8::internal::Handle<v8::internal::Object> obj);
258
  static inline Local<Uint32> Uint32ToLocal(
259
      v8::internal::Handle<v8::internal::Object> obj);
260
  static inline Local<FunctionTemplate> ToLocal(
261
      v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
262
  static inline Local<ObjectTemplate> ToLocal(
263
      v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj);
264
  static inline Local<Signature> ToLocal(
265
      v8::internal::Handle<v8::internal::SignatureInfo> obj);
266
  static inline Local<AccessorSignature> AccessorSignatureToLocal(
267
      v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
268
  static inline Local<TypeSwitch> ToLocal(
269
      v8::internal::Handle<v8::internal::TypeSwitchInfo> obj);
270
  static inline Local<External> ExternalToLocal(
271
      v8::internal::Handle<v8::internal::JSObject> obj);
272
  static inline Local<DeclaredAccessorDescriptor> ToLocal(
273
      v8::internal::Handle<v8::internal::DeclaredAccessorDescriptor> obj);
274

    
275
#define DECLARE_OPEN_HANDLE(From, To) \
276
  static inline v8::internal::Handle<v8::internal::To> \
277
      OpenHandle(const From* that, bool allow_empty_handle = false);
278

    
279
OPEN_HANDLE_LIST(DECLARE_OPEN_HANDLE)
280

    
281
#undef DECLARE_OPEN_HANDLE
282

    
283
  template<class From, class To>
284
  static inline Local<To> Convert(v8::internal::Handle<From> obj) {
285
    ASSERT(obj.is_null() || !obj->IsTheHole());
286
    return Local<To>(reinterpret_cast<To*>(obj.location()));
287
  }
288

    
289
  template <class T>
290
  static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
291
      const v8::Persistent<T>& persistent) {
292
    return v8::internal::Handle<v8::internal::Object>(
293
        reinterpret_cast<v8::internal::Object**>(persistent.val_));
294
  }
295

    
296
  template <class T>
297
  static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
298
      v8::Persistent<T>* persistent) {
299
    return OpenPersistent(*persistent);
300
  }
301

    
302
  template <class From, class To>
303
  static inline v8::internal::Handle<To> OpenHandle(v8::Local<From> handle) {
304
    return OpenHandle(*handle);
305
  }
306
};
307

    
308

    
309
template <class T>
310
v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
311
    v8::HandleScope* scope) {
312
  v8::internal::Handle<T> handle;
313
  if (!is_null()) {
314
    handle = *this;
315
  }
316
  return Utils::OpenHandle(*scope->Close(Utils::ToLocal(handle)), true);
317
}
318

    
319

    
320
template <class T>
321
inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
322
  return reinterpret_cast<T*>(obj.location());
323
}
324

    
325
template <class T>
326
inline v8::Local<T> ToApiHandle(
327
    v8::internal::Handle<v8::internal::Object> obj) {
328
  return Utils::Convert<v8::internal::Object, T>(obj);
329
}
330

    
331

    
332
// Implementations of ToLocal
333

    
334
#define MAKE_TO_LOCAL(Name, From, To)                                       \
335
  Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
336
    return Convert<v8::internal::From, v8::To>(obj);  \
337
  }
338

    
339

    
340
#define MAKE_TO_LOCAL_TYPED_ARRAY(TypedArray, typeConst)                    \
341
  Local<v8::TypedArray> Utils::ToLocal##TypedArray(                         \
342
      v8::internal::Handle<v8::internal::JSTypedArray> obj) {               \
343
    ASSERT(obj->type() == typeConst);                                       \
344
    return Convert<v8::internal::JSTypedArray, v8::TypedArray>(obj);        \
345
  }
346

    
347

    
348
MAKE_TO_LOCAL(ToLocal, Context, Context)
349
MAKE_TO_LOCAL(ToLocal, Object, Value)
350
MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
351
MAKE_TO_LOCAL(ToLocal, String, String)
352
MAKE_TO_LOCAL(ToLocal, Symbol, Symbol)
353
MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
354
MAKE_TO_LOCAL(ToLocal, JSObject, Object)
355
MAKE_TO_LOCAL(ToLocal, JSArray, Array)
356
MAKE_TO_LOCAL(ToLocal, JSArrayBuffer, ArrayBuffer)
357
MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView)
358
MAKE_TO_LOCAL(ToLocal, JSDataView, DataView)
359
MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray)
360

    
361
MAKE_TO_LOCAL_TYPED_ARRAY(Uint8Array, kExternalUnsignedByteArray)
362
MAKE_TO_LOCAL_TYPED_ARRAY(Uint8ClampedArray, kExternalPixelArray)
363
MAKE_TO_LOCAL_TYPED_ARRAY(Int8Array, kExternalByteArray)
364
MAKE_TO_LOCAL_TYPED_ARRAY(Uint16Array, kExternalUnsignedShortArray)
365
MAKE_TO_LOCAL_TYPED_ARRAY(Int16Array, kExternalShortArray)
366
MAKE_TO_LOCAL_TYPED_ARRAY(Uint32Array, kExternalUnsignedIntArray)
367
MAKE_TO_LOCAL_TYPED_ARRAY(Int32Array, kExternalIntArray)
368
MAKE_TO_LOCAL_TYPED_ARRAY(Float32Array, kExternalFloatArray)
369
MAKE_TO_LOCAL_TYPED_ARRAY(Float64Array, kExternalDoubleArray)
370

    
371
MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
372
MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
373
MAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature)
374
MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
375
MAKE_TO_LOCAL(ToLocal, TypeSwitchInfo, TypeSwitch)
376
MAKE_TO_LOCAL(MessageToLocal, Object, Message)
377
MAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace)
378
MAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame)
379
MAKE_TO_LOCAL(NumberToLocal, Object, Number)
380
MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
381
MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
382
MAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
383
MAKE_TO_LOCAL(ToLocal, DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
384

    
385
#undef MAKE_TO_LOCAL_TYPED_ARRAY
386
#undef MAKE_TO_LOCAL
387

    
388

    
389
// Implementations of OpenHandle
390

    
391
#define MAKE_OPEN_HANDLE(From, To)                                          \
392
  v8::internal::Handle<v8::internal::To> Utils::OpenHandle(                 \
393
    const v8::From* that, bool allow_empty_handle) {                        \
394
    EXTRA_CHECK(allow_empty_handle || that != NULL);                        \
395
    EXTRA_CHECK(that == NULL ||                                             \
396
        !(*reinterpret_cast<v8::internal::To**>(                            \
397
            const_cast<v8::From*>(that)))->IsFailure());                    \
398
    return v8::internal::Handle<v8::internal::To>(                          \
399
        reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \
400
  }
401

    
402
OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
403

    
404
#undef MAKE_OPEN_HANDLE
405
#undef OPEN_HANDLE_LIST
406

    
407

    
408
namespace internal {
409

    
410
// Tracks string usage to help make better decisions when
411
// externalizing strings.
412
//
413
// Implementation note: internally this class only tracks fresh
414
// strings and keeps a single use counter for them.
415
class StringTracker {
416
 public:
417
  // Records that the given string's characters were copied to some
418
  // external buffer. If this happens often we should honor
419
  // externalization requests for the string.
420
  void RecordWrite(Handle<String> string) {
421
    Address address = reinterpret_cast<Address>(*string);
422
    Address top = isolate_->heap()->NewSpaceTop();
423
    if (IsFreshString(address, top)) {
424
      IncrementUseCount(top);
425
    }
426
  }
427

    
428
  // Estimates freshness and use frequency of the given string based
429
  // on how close it is to the new space top and the recorded usage
430
  // history.
431
  inline bool IsFreshUnusedString(Handle<String> string) {
432
    Address address = reinterpret_cast<Address>(*string);
433
    Address top = isolate_->heap()->NewSpaceTop();
434
    return IsFreshString(address, top) && IsUseCountLow(top);
435
  }
436

    
437
 private:
438
  StringTracker() : use_count_(0), last_top_(NULL), isolate_(NULL) { }
439

    
440
  static inline bool IsFreshString(Address string, Address top) {
441
    return top - kFreshnessLimit <= string && string <= top;
442
  }
443

    
444
  inline bool IsUseCountLow(Address top) {
445
    if (last_top_ != top) return true;
446
    return use_count_ < kUseLimit;
447
  }
448

    
449
  inline void IncrementUseCount(Address top) {
450
    if (last_top_ != top) {
451
      use_count_ = 0;
452
      last_top_ = top;
453
    }
454
    ++use_count_;
455
  }
456

    
457
  // Single use counter shared by all fresh strings.
458
  int use_count_;
459

    
460
  // Last new space top when the use count above was valid.
461
  Address last_top_;
462

    
463
  Isolate* isolate_;
464

    
465
  // How close to the new space top a fresh string has to be.
466
  static const int kFreshnessLimit = 1024;
467

    
468
  // The number of uses required to consider a string useful.
469
  static const int kUseLimit = 32;
470

    
471
  friend class Isolate;
472

    
473
  DISALLOW_COPY_AND_ASSIGN(StringTracker);
474
};
475

    
476

    
477
class DeferredHandles {
478
 public:
479
  ~DeferredHandles();
480

    
481
 private:
482
  DeferredHandles(Object** first_block_limit, Isolate* isolate)
483
      : next_(NULL),
484
        previous_(NULL),
485
        first_block_limit_(first_block_limit),
486
        isolate_(isolate) {
487
    isolate->LinkDeferredHandles(this);
488
  }
489

    
490
  void Iterate(ObjectVisitor* v);
491

    
492
  List<Object**> blocks_;
493
  DeferredHandles* next_;
494
  DeferredHandles* previous_;
495
  Object** first_block_limit_;
496
  Isolate* isolate_;
497

    
498
  friend class HandleScopeImplementer;
499
  friend class Isolate;
500
};
501

    
502

    
503
// This class is here in order to be able to declare it a friend of
504
// HandleScope.  Moving these methods to be members of HandleScope would be
505
// neat in some ways, but it would expose internal implementation details in
506
// our public header file, which is undesirable.
507
//
508
// An isolate has a single instance of this class to hold the current thread's
509
// data. In multithreaded V8 programs this data is copied in and out of storage
510
// so that the currently executing thread always has its own copy of this
511
// data.
512
class HandleScopeImplementer {
513
 public:
514
  explicit HandleScopeImplementer(Isolate* isolate)
515
      : isolate_(isolate),
516
        blocks_(0),
517
        entered_contexts_(0),
518
        saved_contexts_(0),
519
        spare_(NULL),
520
        call_depth_(0),
521
        last_handle_before_deferred_block_(NULL) { }
522

    
523
  ~HandleScopeImplementer() {
524
    DeleteArray(spare_);
525
  }
526

    
527
  // Threading support for handle data.
528
  static int ArchiveSpacePerThread();
529
  char* RestoreThread(char* from);
530
  char* ArchiveThread(char* to);
531
  void FreeThreadResources();
532

    
533
  // Garbage collection support.
534
  void Iterate(v8::internal::ObjectVisitor* v);
535
  static char* Iterate(v8::internal::ObjectVisitor* v, char* data);
536

    
537

    
538
  inline internal::Object** GetSpareOrNewBlock();
539
  inline void DeleteExtensions(internal::Object** prev_limit);
540

    
541
  inline void IncrementCallDepth() {call_depth_++;}
542
  inline void DecrementCallDepth() {call_depth_--;}
543
  inline bool CallDepthIsZero() { return call_depth_ == 0; }
544

    
545
  inline void EnterContext(Handle<Context> context);
546
  inline bool LeaveContext(Handle<Context> context);
547

    
548
  // Returns the last entered context or an empty handle if no
549
  // contexts have been entered.
550
  inline Handle<Context> LastEnteredContext();
551

    
552
  inline void SaveContext(Context* context);
553
  inline Context* RestoreContext();
554
  inline bool HasSavedContexts();
555

    
556
  inline List<internal::Object**>* blocks() { return &blocks_; }
557
  Isolate* isolate() const { return isolate_; }
558

    
559
  void ReturnBlock(Object** block) {
560
    ASSERT(block != NULL);
561
    if (spare_ != NULL) DeleteArray(spare_);
562
    spare_ = block;
563
  }
564

    
565
 private:
566
  void ResetAfterArchive() {
567
    blocks_.Initialize(0);
568
    entered_contexts_.Initialize(0);
569
    saved_contexts_.Initialize(0);
570
    spare_ = NULL;
571
    last_handle_before_deferred_block_ = NULL;
572
    call_depth_ = 0;
573
  }
574

    
575
  void Free() {
576
    ASSERT(blocks_.length() == 0);
577
    ASSERT(entered_contexts_.length() == 0);
578
    ASSERT(saved_contexts_.length() == 0);
579
    blocks_.Free();
580
    entered_contexts_.Free();
581
    saved_contexts_.Free();
582
    if (spare_ != NULL) {
583
      DeleteArray(spare_);
584
      spare_ = NULL;
585
    }
586
    ASSERT(call_depth_ == 0);
587
  }
588

    
589
  void BeginDeferredScope();
590
  DeferredHandles* Detach(Object** prev_limit);
591

    
592
  Isolate* isolate_;
593
  List<internal::Object**> blocks_;
594
  // Used as a stack to keep track of entered contexts.
595
  List<Context*> entered_contexts_;
596
  // Used as a stack to keep track of saved contexts.
597
  List<Context*> saved_contexts_;
598
  Object** spare_;
599
  int call_depth_;
600
  Object** last_handle_before_deferred_block_;
601
  // This is only used for threading support.
602
  v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
603

    
604
  void IterateThis(ObjectVisitor* v);
605
  char* RestoreThreadHelper(char* from);
606
  char* ArchiveThreadHelper(char* to);
607

    
608
  friend class DeferredHandles;
609
  friend class DeferredHandleScope;
610

    
611
  DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
612
};
613

    
614

    
615
const int kHandleBlockSize = v8::internal::KB - 2;  // fit in one page
616

    
617

    
618
void HandleScopeImplementer::SaveContext(Context* context) {
619
  saved_contexts_.Add(context);
620
}
621

    
622

    
623
Context* HandleScopeImplementer::RestoreContext() {
624
  return saved_contexts_.RemoveLast();
625
}
626

    
627

    
628
bool HandleScopeImplementer::HasSavedContexts() {
629
  return !saved_contexts_.is_empty();
630
}
631

    
632

    
633
void HandleScopeImplementer::EnterContext(Handle<Context> context) {
634
  entered_contexts_.Add(*context);
635
}
636

    
637

    
638
bool HandleScopeImplementer::LeaveContext(Handle<Context> context) {
639
  if (entered_contexts_.is_empty()) return false;
640
  // TODO(dcarney): figure out what's wrong here
641
  // if (entered_contexts_.last() != *context) return false;
642
  entered_contexts_.RemoveLast();
643
  return true;
644
}
645

    
646

    
647
Handle<Context> HandleScopeImplementer::LastEnteredContext() {
648
  if (entered_contexts_.is_empty()) return Handle<Context>::null();
649
  return Handle<Context>(entered_contexts_.last());
650
}
651

    
652

    
653
// If there's a spare block, use it for growing the current scope.
654
internal::Object** HandleScopeImplementer::GetSpareOrNewBlock() {
655
  internal::Object** block = (spare_ != NULL) ?
656
      spare_ :
657
      NewArray<internal::Object*>(kHandleBlockSize);
658
  spare_ = NULL;
659
  return block;
660
}
661

    
662

    
663
void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) {
664
  while (!blocks_.is_empty()) {
665
    internal::Object** block_start = blocks_.last();
666
    internal::Object** block_limit = block_start + kHandleBlockSize;
667
#ifdef DEBUG
668
    // SealHandleScope may make the prev_limit to point inside the block.
669
    if (block_start <= prev_limit && prev_limit <= block_limit) {
670
#ifdef ENABLE_HANDLE_ZAPPING
671
      internal::HandleScope::ZapRange(prev_limit, block_limit);
672
#endif
673
      break;
674
    }
675
#else
676
    if (prev_limit == block_limit) break;
677
#endif
678

    
679
    blocks_.RemoveLast();
680
#ifdef ENABLE_HANDLE_ZAPPING
681
    internal::HandleScope::ZapRange(block_start, block_limit);
682
#endif
683
    if (spare_ != NULL) {
684
      DeleteArray(spare_);
685
    }
686
    spare_ = block_start;
687
  }
688
  ASSERT((blocks_.is_empty() && prev_limit == NULL) ||
689
         (!blocks_.is_empty() && prev_limit != NULL));
690
}
691

    
692

    
693
// Interceptor functions called from generated inline caches to notify
694
// CPU profiler that external callbacks are invoked.
695
void InvokeAccessorGetterCallback(
696
    v8::Local<v8::String> property,
697
    const v8::PropertyCallbackInfo<v8::Value>& info,
698
    v8::AccessorGetterCallback getter);
699

    
700
void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
701
                            v8::FunctionCallback callback);
702

    
703
class Testing {
704
 public:
705
  static v8::Testing::StressType stress_type() { return stress_type_; }
706
  static void set_stress_type(v8::Testing::StressType stress_type) {
707
    stress_type_ = stress_type;
708
  }
709

    
710
 private:
711
  static v8::Testing::StressType stress_type_;
712
};
713

    
714
} }  // namespace v8::internal
715

    
716
#endif  // V8_API_H_