1e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_HANDLES_H_
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_HANDLES_H_
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/objects.h"
9ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
1071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org// A Handle can be converted into a MaybeHandle. Converting a MaybeHandle
14255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org// into a Handle requires checking that it does not point to NULL.  This
15255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org// ensures NULL checks before use.
16255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org// Do not use MaybeHandle as argument type.
17255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
18255043f8054e713a64509c707cfabadd42344683machenbach@chromium.orgtemplate<typename T>
19255043f8054e713a64509c707cfabadd42344683machenbach@chromium.orgclass MaybeHandle {
20255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org public:
21255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  INLINE(MaybeHandle()) : location_(NULL) { }
22255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
23255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // Constructor for handling automatic up casting from Handle.
24255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected.
25255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  template <class S> MaybeHandle(Handle<S> handle) {
26255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org#ifdef DEBUG
27255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    T* a = NULL;
28255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    S* b = NULL;
29255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    a = b;  // Fake assignment to enforce type checks.
30255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    USE(a);
31255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org#endif
32255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    this->location_ = reinterpret_cast<T**>(handle.location());
33255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  }
34255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
35255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // Constructor for handling automatic up casting.
36255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected.
37255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  template <class S> MaybeHandle(MaybeHandle<S> maybe_handle) {
38255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org#ifdef DEBUG
39255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    T* a = NULL;
40255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    S* b = NULL;
41255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    a = b;  // Fake assignment to enforce type checks.
42255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    USE(a);
43255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org#endif
44255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    location_ = reinterpret_cast<T**>(maybe_handle.location_);
45255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  }
46255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
47e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  INLINE(void Assert() const) { DCHECK(location_ != NULL); }
488ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  INLINE(void Check() const) { CHECK(location_ != NULL); }
498f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
508ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  INLINE(Handle<T> ToHandleChecked()) const {
518f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Check();
52255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    return Handle<T>(location_);
53255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  }
54255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
55255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // Convert to a Handle with a type that can be upcasted to.
56255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  template <class S> INLINE(bool ToHandle(Handle<S>* out)) {
57255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    if (location_ == NULL) {
58255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      *out = Handle<T>::null();
59255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      return false;
60255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    } else {
61255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      *out = Handle<T>(location_);
62255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      return true;
63255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    }
64255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  }
65255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
66255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  bool is_null() const { return location_ == NULL; }
67255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
68255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org protected:
69255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  T** location_;
70255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
71255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // MaybeHandles of different classes are allowed to access each
72255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // other's location_.
73255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  template<class S> friend class MaybeHandle;
74255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org};
75255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A Handle provides a reference to an object that survives relocation by
7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the garbage collector.
79ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Handles are only valid within a HandleScope.
8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// When a handle is created for an object a cell is allocated in the heap.
8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgtemplate<typename T>
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Handle {
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
85ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  INLINE(explicit Handle(T** location)) { location_ = location; }
8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(explicit Handle(T* obj));
87ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  INLINE(Handle(T* obj, Isolate* isolate));
8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // TODO(yangguo): Values that contain empty handles should be declared as
90255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // MaybeHandle to force validation before being used as handles.
91255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  INLINE(Handle()) : location_(NULL) { }
9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Constructor for handling automatic up casting.
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  template <class S> Handle(Handle<S> handle) {
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    T* a = NULL;
9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    S* b = NULL;
9943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    a = b;  // Fake assignment to enforce type checks.
10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    USE(a);
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
102003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    location_ = reinterpret_cast<T**>(handle.location_);
10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  INLINE(T* operator->() const) { return operator*(); }
10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if this handle refers to the exact same object as the other handle.
1082bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  INLINE(bool is_identical_to(const Handle<T> other) const);
10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Provides the C++ dereference operator.
11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  INLINE(T* operator*() const);
11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns the address to where the raw pointer is stored.
114003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  INLINE(T** location() const);
11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  template <class S> static Handle<T> cast(Handle<S> that) {
11732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    T::cast(*reinterpret_cast<T**>(that.location_));
11832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    return Handle<T>(reinterpret_cast<T**>(that.location_));
11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
121255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // TODO(yangguo): Values that contain empty handles should be declared as
122255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  // MaybeHandle to force validation before being used as handles.
12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static Handle<T> null() { return Handle<T>(); }
124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool is_null() const { return location_ == NULL; }
12543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Closes the given scope, but lets this handle escape. See
12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // implementation in api.h.
128ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  inline Handle<T> EscapeFrom(v8::EscapableHandleScope* scope);
12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org#ifdef DEBUG
131dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK };
132dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
133dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool IsDereferenceAllowed(DereferenceCheckMode mode) const;
13432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org#endif  // DEBUG
13532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
13743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  T** location_;
138003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
139003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Handles of different classes are allowed to access each other's location_.
140003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  template<class S> friend class Handle;
14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
14243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
144e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org// Convenience wrapper.
145e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgtemplate<class T>
146fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orginline Handle<T> handle(T* t, Isolate* isolate) {
147fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  return Handle<T>(t, isolate);
148e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
149e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
150e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
151e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org// Convenience wrapper.
152e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgtemplate<class T>
153e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orginline Handle<T> handle(T* t) {
154e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  return Handle<T>(t, t->GetIsolate());
155e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
156e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
157e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
158c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org// Key comparison function for Map handles.
159c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orginline bool operator<(const Handle<Map>& lhs, const Handle<Map>& rhs) {
160c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  // This is safe because maps don't move.
161c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return *lhs < *rhs;
162c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
163c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
164c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
165304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgclass DeferredHandles;
16699aa490225c81012235659d9a183226b286178c8yangguo@chromium.orgclass HandleScopeImplementer;
16799aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
16899aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
169ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// A stack-allocated class that governs a number of local handles.
170ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// After a handle scope has been created, all local handles will be
171ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// allocated within that handle scope until either the handle scope is
172ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// deleted or another handle scope is created.  If there is already a
173ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// handle scope and a new one is created, all allocations will take
174ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// place in the new handle scope until it is deleted.  After that,
175ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// new handles will again be allocated in the original handle scope.
176ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//
177ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// After the handle scope of a local handle has been deleted the
178ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// garbage collector will no longer track the object stored in the
179ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// handle and may deallocate it.  The behavior of accessing a handle
180ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// for which the handle scope has been deleted is undefined.
181ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgclass HandleScope {
182ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org public:
183ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit inline HandleScope(Isolate* isolate);
184ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  inline ~HandleScope();
186ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
187ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Counts the number of allocated handles.
18809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static int NumberOfHandles(Isolate* isolate);
189ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
190ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Creates a new handle with the given value.
191911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  template <typename T>
19209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static inline T** CreateHandle(Isolate* isolate, T* value);
193ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
194c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Deallocates any extensions used by the current scope.
195ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  static void DeleteExtensions(Isolate* isolate);
196c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
19709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static Address current_next_address(Isolate* isolate);
19809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static Address current_limit_address(Isolate* isolate);
19909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static Address current_level_address(Isolate* isolate);
200c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2019ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // Closes the HandleScope (invalidating all handles
2029ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // created in the scope of the HandleScope) and returns
2039ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // a Handle backed by the parent scope holding the
2049ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // value of the argument handle.
2059ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  template <typename T>
206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<T> CloseAndEscape(Handle<T> handle_value);
207ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
208ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate() { return isolate_; }
2099ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
210ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org private:
211ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Prevent heap allocation or illegal handle scopes.
212ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  HandleScope(const HandleScope&);
213ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  void operator=(const HandleScope&);
214ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  void* operator new(size_t size);
215ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  void operator delete(void* size_t);
216ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
217ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
2189ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  Object** prev_next_;
2199ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  Object** prev_limit_;
220ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
221b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  // Close the handle scope resetting limits to a previous state.
222b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  static inline void CloseScope(Isolate* isolate,
223b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org                                Object** prev_next,
224b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org                                Object** prev_limit);
225b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
2263b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // Extend the handle scope making room for more handles.
22709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  static internal::Object** Extend(Isolate* isolate);
2283b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org
229c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org#ifdef ENABLE_HANDLE_ZAPPING
230ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Zaps the handles in the half-open interval [start, end).
231b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  static void ZapRange(Object** start, Object** end);
232f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org#endif
233ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
234ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  friend class v8::HandleScope;
235f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  friend class v8::internal::DeferredHandles;
23699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  friend class v8::internal::HandleScopeImplementer;
237304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  friend class v8::internal::Isolate;
238ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org};
239ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
240ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
24199aa490225c81012235659d9a183226b286178c8yangguo@chromium.orgclass DeferredHandles;
24299aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
24399aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
24499aa490225c81012235659d9a183226b286178c8yangguo@chromium.orgclass DeferredHandleScope {
24599aa490225c81012235659d9a183226b286178c8yangguo@chromium.org public:
24699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  explicit DeferredHandleScope(Isolate* isolate);
24799aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  // The DeferredHandles object returned stores the Handles created
24899aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  // since the creation of this DeferredHandleScope.  The Handles are
24999aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  // alive as long as the DeferredHandles object is alive.
25099aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  DeferredHandles* Detach();
25199aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  ~DeferredHandleScope();
25299aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
25399aa490225c81012235659d9a183226b286178c8yangguo@chromium.org private:
25499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  Object** prev_limit_;
25599aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  Object** prev_next_;
25699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  HandleScopeImplementer* impl_;
25799aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
25899aa490225c81012235659d9a183226b286178c8yangguo@chromium.org#ifdef DEBUG
25999aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  bool handles_detached_;
26099aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  int prev_level_;
26199aa490225c81012235659d9a183226b286178c8yangguo@chromium.org#endif
26299aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
26399aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  friend class HandleScopeImplementer;
26499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org};
26599aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
26699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
26779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org// Seal off the current HandleScope so that new handles can only be created
26879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org// if a new HandleScope is entered.
26979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.orgclass SealHandleScope BASE_EMBEDDED {
27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef DEBUG
27279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  explicit SealHandleScope(Isolate* isolate) {}
27379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ~SealHandleScope() {}
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else
27579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  explicit inline SealHandleScope(Isolate* isolate);
27679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  inline ~SealHandleScope();
27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
27809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Isolate* isolate_;
279b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  Object** limit_;
280303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  int level_;
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgstruct HandleScopeData {
28526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  internal::Object** next;
28626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  internal::Object** limit;
28726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  int level;
28826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
28926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  void Initialize() {
29026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    next = limit = NULL;
29126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    level = 0;
29226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  }
29326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org};
29426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // V8_HANDLES_H_
298