Home | History | Annotate | Download | only in src
      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_HANDLES_H_
     29 #define V8_HANDLES_H_
     30 
     31 #include "apiutils.h"
     32 
     33 namespace v8 {
     34 namespace internal {
     35 
     36 // ----------------------------------------------------------------------------
     37 // A Handle provides a reference to an object that survives relocation by
     38 // the garbage collector.
     39 // Handles are only valid within a HandleScope.
     40 // When a handle is created for an object a cell is allocated in the heap.
     41 
     42 template<typename T>
     43 class Handle {
     44  public:
     45   INLINE(explicit Handle(T** location)) { location_ = location; }
     46   INLINE(explicit Handle(T* obj));
     47   INLINE(Handle(T* obj, Isolate* isolate));
     48 
     49   INLINE(Handle()) : location_(NULL) {}
     50 
     51   // Constructor for handling automatic up casting.
     52   // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
     53   template <class S> Handle(Handle<S> handle) {
     54 #ifdef DEBUG
     55     T* a = NULL;
     56     S* b = NULL;
     57     a = b;  // Fake assignment to enforce type checks.
     58     USE(a);
     59 #endif
     60     location_ = reinterpret_cast<T**>(handle.location());
     61   }
     62 
     63   INLINE(T* operator ->() const) { return operator*(); }
     64 
     65   // Check if this handle refers to the exact same object as the other handle.
     66   bool is_identical_to(const Handle<T> other) const {
     67     return operator*() == *other;
     68   }
     69 
     70   // Provides the C++ dereference operator.
     71   INLINE(T* operator*() const);
     72 
     73   // Returns the address to where the raw pointer is stored.
     74   T** location() const {
     75     ASSERT(location_ == NULL ||
     76            reinterpret_cast<Address>(*location_) != kZapValue);
     77     return location_;
     78   }
     79 
     80   template <class S> static Handle<T> cast(Handle<S> that) {
     81     T::cast(*that);
     82     return Handle<T>(reinterpret_cast<T**>(that.location()));
     83   }
     84 
     85   static Handle<T> null() { return Handle<T>(); }
     86   bool is_null() const { return location_ == NULL; }
     87 
     88   // Closes the given scope, but lets this handle escape. See
     89   // implementation in api.h.
     90   inline Handle<T> EscapeFrom(v8::HandleScope* scope);
     91 
     92  private:
     93   T** location_;
     94 };
     95 
     96 
     97 // A stack-allocated class that governs a number of local handles.
     98 // After a handle scope has been created, all local handles will be
     99 // allocated within that handle scope until either the handle scope is
    100 // deleted or another handle scope is created.  If there is already a
    101 // handle scope and a new one is created, all allocations will take
    102 // place in the new handle scope until it is deleted.  After that,
    103 // new handles will again be allocated in the original handle scope.
    104 //
    105 // After the handle scope of a local handle has been deleted the
    106 // garbage collector will no longer track the object stored in the
    107 // handle and may deallocate it.  The behavior of accessing a handle
    108 // for which the handle scope has been deleted is undefined.
    109 class HandleScope {
    110  public:
    111   inline HandleScope();
    112   explicit inline HandleScope(Isolate* isolate);
    113 
    114   inline ~HandleScope();
    115 
    116   // Counts the number of allocated handles.
    117   static int NumberOfHandles();
    118 
    119   // Creates a new handle with the given value.
    120   template <typename T>
    121   static inline T** CreateHandle(T* value, Isolate* isolate);
    122 
    123   // Deallocates any extensions used by the current scope.
    124   static void DeleteExtensions(Isolate* isolate);
    125 
    126   static Address current_next_address();
    127   static Address current_limit_address();
    128   static Address current_level_address();
    129 
    130   // Closes the HandleScope (invalidating all handles
    131   // created in the scope of the HandleScope) and returns
    132   // a Handle backed by the parent scope holding the
    133   // value of the argument handle.
    134   template <typename T>
    135   Handle<T> CloseAndEscape(Handle<T> handle_value);
    136 
    137   Isolate* isolate() { return isolate_; }
    138 
    139  private:
    140   // Prevent heap allocation or illegal handle scopes.
    141   HandleScope(const HandleScope&);
    142   void operator=(const HandleScope&);
    143   void* operator new(size_t size);
    144   void operator delete(void* size_t);
    145 
    146   inline void CloseScope();
    147 
    148   Isolate* isolate_;
    149   Object** prev_next_;
    150   Object** prev_limit_;
    151 
    152   // Extend the handle scope making room for more handles.
    153   static internal::Object** Extend();
    154 
    155   // Zaps the handles in the half-open interval [start, end).
    156   static void ZapRange(internal::Object** start, internal::Object** end);
    157 
    158   friend class v8::HandleScope;
    159   friend class v8::ImplementationUtilities;
    160 };
    161 
    162 
    163 // ----------------------------------------------------------------------------
    164 // Handle operations.
    165 // They might invoke garbage collection. The result is an handle to
    166 // an object of expected type, or the handle is an error if running out
    167 // of space or encountering an internal error.
    168 
    169 void NormalizeProperties(Handle<JSObject> object,
    170                          PropertyNormalizationMode mode,
    171                          int expected_additional_properties);
    172 void NormalizeElements(Handle<JSObject> object);
    173 void TransformToFastProperties(Handle<JSObject> object,
    174                                int unused_property_fields);
    175 void NumberDictionarySet(Handle<NumberDictionary> dictionary,
    176                          uint32_t index,
    177                          Handle<Object> value,
    178                          PropertyDetails details);
    179 
    180 // Flattens a string.
    181 void FlattenString(Handle<String> str);
    182 
    183 // Flattens a string and returns the underlying external or sequential
    184 // string.
    185 Handle<String> FlattenGetString(Handle<String> str);
    186 
    187 Handle<Object> SetProperty(Handle<JSObject> object,
    188                            Handle<String> key,
    189                            Handle<Object> value,
    190                            PropertyAttributes attributes,
    191                            StrictModeFlag strict_mode);
    192 
    193 Handle<Object> SetProperty(Handle<Object> object,
    194                            Handle<Object> key,
    195                            Handle<Object> value,
    196                            PropertyAttributes attributes,
    197                            StrictModeFlag strict_mode);
    198 
    199 Handle<Object> ForceSetProperty(Handle<JSObject> object,
    200                                 Handle<Object> key,
    201                                 Handle<Object> value,
    202                                 PropertyAttributes attributes);
    203 
    204 Handle<Object> SetNormalizedProperty(Handle<JSObject> object,
    205                                      Handle<String> key,
    206                                      Handle<Object> value,
    207                                      PropertyDetails details);
    208 
    209 Handle<Object> ForceDeleteProperty(Handle<JSObject> object,
    210                                    Handle<Object> key);
    211 
    212 Handle<Object> SetLocalPropertyIgnoreAttributes(
    213     Handle<JSObject> object,
    214     Handle<String> key,
    215     Handle<Object> value,
    216     PropertyAttributes attributes);
    217 
    218 // Used to set local properties on the object we totally control
    219 // and which therefore has no accessors and alikes.
    220 void SetLocalPropertyNoThrow(Handle<JSObject> object,
    221                              Handle<String> key,
    222                              Handle<Object> value,
    223                              PropertyAttributes attributes = NONE);
    224 
    225 Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
    226                                           Handle<String> key,
    227                                           Handle<Object> value,
    228                                           PropertyAttributes attributes,
    229                                           StrictModeFlag strict_mode);
    230 
    231 MUST_USE_RESULT Handle<Object> SetElement(Handle<JSObject> object,
    232                                           uint32_t index,
    233                                           Handle<Object> value,
    234                                           StrictModeFlag strict_mode);
    235 
    236 Handle<Object> SetOwnElement(Handle<JSObject> object,
    237                              uint32_t index,
    238                              Handle<Object> value,
    239                              StrictModeFlag strict_mode);
    240 
    241 Handle<Object> GetProperty(Handle<JSObject> obj,
    242                            const char* name);
    243 
    244 Handle<Object> GetProperty(Handle<Object> obj,
    245                            Handle<Object> key);
    246 
    247 Handle<Object> GetProperty(Handle<JSObject> obj,
    248                            Handle<String> name,
    249                            LookupResult* result);
    250 
    251 
    252 Handle<Object> GetElement(Handle<Object> obj,
    253                           uint32_t index);
    254 
    255 Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
    256                                           Handle<JSObject> holder,
    257                                           Handle<String> name,
    258                                           PropertyAttributes* attributes);
    259 
    260 Handle<Object> GetPrototype(Handle<Object> obj);
    261 
    262 Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value);
    263 
    264 // Return the object's hidden properties object. If the object has no hidden
    265 // properties and create_if_needed is true, then a new hidden property object
    266 // will be allocated. Otherwise the Heap::undefined_value is returned.
    267 Handle<Object> GetHiddenProperties(Handle<JSObject> obj, bool create_if_needed);
    268 
    269 Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
    270 Handle<Object> DeleteProperty(Handle<JSObject> obj, Handle<String> prop);
    271 
    272 Handle<Object> LookupSingleCharacterStringFromCode(uint32_t index);
    273 
    274 Handle<JSObject> Copy(Handle<JSObject> obj);
    275 
    276 Handle<Object> SetAccessor(Handle<JSObject> obj, Handle<AccessorInfo> info);
    277 
    278 Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray>,
    279                                       Handle<JSArray> array);
    280 
    281 // Get the JS object corresponding to the given script; create it
    282 // if none exists.
    283 Handle<JSValue> GetScriptWrapper(Handle<Script> script);
    284 
    285 // Script line number computations.
    286 void InitScriptLineEnds(Handle<Script> script);
    287 // For string calculates an array of line end positions. If the string
    288 // does not end with a new line character, this character may optionally be
    289 // imagined.
    290 Handle<FixedArray> CalculateLineEnds(Handle<String> string,
    291                                      bool with_imaginary_last_new_line);
    292 int GetScriptLineNumber(Handle<Script> script, int code_position);
    293 // The safe version does not make heap allocations but may work much slower.
    294 int GetScriptLineNumberSafe(Handle<Script> script, int code_position);
    295 
    296 // Computes the enumerable keys from interceptors. Used for debug mirrors and
    297 // by GetKeysInFixedArrayFor below.
    298 v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver,
    299                                                  Handle<JSObject> object);
    300 v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver,
    301                                                    Handle<JSObject> object);
    302 
    303 enum KeyCollectionType { LOCAL_ONLY, INCLUDE_PROTOS };
    304 
    305 // Computes the enumerable keys for a JSObject. Used for implementing
    306 // "for (n in object) { }".
    307 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object,
    308                                           KeyCollectionType type);
    309 Handle<JSArray> GetKeysFor(Handle<JSObject> object);
    310 Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
    311                                        bool cache_result);
    312 
    313 // Computes the union of keys and return the result.
    314 // Used for implementing "for (n in object) { }"
    315 Handle<FixedArray> UnionOfKeys(Handle<FixedArray> first,
    316                                Handle<FixedArray> second);
    317 
    318 Handle<String> SubString(Handle<String> str,
    319                          int start,
    320                          int end,
    321                          PretenureFlag pretenure = NOT_TENURED);
    322 
    323 
    324 // Sets the expected number of properties for the function's instances.
    325 void SetExpectedNofProperties(Handle<JSFunction> func, int nof);
    326 
    327 // Sets the prototype property for a function instance.
    328 void SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value);
    329 
    330 // Sets the expected number of properties based on estimate from compiler.
    331 void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
    332                                           int estimate);
    333 
    334 
    335 Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
    336     Handle<JSFunction> constructor,
    337     Handle<JSGlobalProxy> global);
    338 
    339 Handle<Object> SetPrototype(Handle<JSFunction> function,
    340                             Handle<Object> prototype);
    341 
    342 Handle<Object> PreventExtensions(Handle<JSObject> object);
    343 
    344 // Does lazy compilation of the given function. Returns true on success and
    345 // false if the compilation resulted in a stack overflow.
    346 enum ClearExceptionFlag { KEEP_EXCEPTION, CLEAR_EXCEPTION };
    347 
    348 bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
    349                     ClearExceptionFlag flag);
    350 
    351 bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
    352                        ClearExceptionFlag flag);
    353 
    354 bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag);
    355 
    356 bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag flag);
    357 
    358 bool CompileOptimized(Handle<JSFunction> function,
    359                       int osr_ast_id,
    360                       ClearExceptionFlag flag);
    361 
    362 class NoHandleAllocation BASE_EMBEDDED {
    363  public:
    364 #ifndef DEBUG
    365   NoHandleAllocation() {}
    366   ~NoHandleAllocation() {}
    367 #else
    368   inline NoHandleAllocation();
    369   inline ~NoHandleAllocation();
    370  private:
    371   int level_;
    372 #endif
    373 };
    374 
    375 } }  // namespace v8::internal
    376 
    377 #endif  // V8_HANDLES_H_
    378