[V8] Introduce a QML compilation mode
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / contexts.h
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_CONTEXTS_H_
29 #define V8_CONTEXTS_H_
30
31 #include "heap.h"
32 #include "objects.h"
33
34 namespace v8 {
35 namespace internal {
36
37
38 enum ContextLookupFlags {
39   FOLLOW_CONTEXT_CHAIN = 1,
40   FOLLOW_PROTOTYPE_CHAIN = 2,
41
42   DONT_FOLLOW_CHAINS = 0,
43   FOLLOW_CHAINS = FOLLOW_CONTEXT_CHAIN | FOLLOW_PROTOTYPE_CHAIN
44 };
45
46
47 // ES5 10.2 defines lexical environments with mutable and immutable bindings.
48 // Immutable bindings have two states, initialized and uninitialized, and
49 // their state is changed by the InitializeImmutableBinding method. The
50 // BindingFlags enum represents information if a binding has definitely been
51 // initialized. A mutable binding does not need to be checked and thus has
52 // the BindingFlag MUTABLE_IS_INITIALIZED.
53 //
54 // There are two possibilities for immutable bindings
55 //  * 'const' declared variables. They are initialized when evaluating the
56 //    corresponding declaration statement. They need to be checked for being
57 //    initialized and thus get the flag IMMUTABLE_CHECK_INITIALIZED.
58 //  * The function name of a named function literal. The binding is immediately
59 //    initialized when entering the function and thus does not need to be
60 //    checked. it gets the BindingFlag IMMUTABLE_IS_INITIALIZED.
61 // Accessing an uninitialized binding produces the undefined value.
62 //
63 // The harmony proposal for block scoped bindings also introduces the
64 // uninitialized state for mutable bindings.
65 //  * A 'let' declared variable. They are initialized when evaluating the
66 //    corresponding declaration statement. They need to be checked for being
67 //    initialized and thus get the flag MUTABLE_CHECK_INITIALIZED.
68 //  * A 'var' declared variable. It is initialized immediately upon creation
69 //    and thus doesn't need to be checked. It gets the flag
70 //    MUTABLE_IS_INITIALIZED.
71 //  * Catch bound variables, function parameters and variables introduced by
72 //    function declarations are initialized immediately and do not need to be
73 //    checked. Thus they get the flag MUTABLE_IS_INITIALIZED.
74 // Immutable bindings in harmony mode get the _HARMONY flag variants. Accessing
75 // an uninitialized binding produces a reference error.
76 //
77 // In V8 uninitialized bindings are set to the hole value upon creation and set
78 // to a different value upon initialization.
79 enum BindingFlags {
80   MUTABLE_IS_INITIALIZED,
81   MUTABLE_CHECK_INITIALIZED,
82   IMMUTABLE_IS_INITIALIZED,
83   IMMUTABLE_CHECK_INITIALIZED,
84   IMMUTABLE_IS_INITIALIZED_HARMONY,
85   IMMUTABLE_CHECK_INITIALIZED_HARMONY,
86   MISSING_BINDING
87 };
88
89
90 // Heap-allocated activation contexts.
91 //
92 // Contexts are implemented as FixedArray objects; the Context
93 // class is a convenience interface casted on a FixedArray object.
94 //
95 // Note: Context must have no virtual functions and Context objects
96 // must always be allocated via Heap::AllocateContext() or
97 // Factory::NewContext.
98
99 #define GLOBAL_CONTEXT_FIELDS(V) \
100   V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
101   V(SECURITY_TOKEN_INDEX, Object, security_token) \
102   V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function) \
103   V(NUMBER_FUNCTION_INDEX, JSFunction, number_function) \
104   V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
105   V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \
106   V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
107   V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
108   V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
109   V(SMI_JS_ARRAY_MAP_INDEX, Object, smi_js_array_map) \
110   V(DOUBLE_JS_ARRAY_MAP_INDEX, Object, double_js_array_map) \
111   V(OBJECT_JS_ARRAY_MAP_INDEX, Object, object_js_array_map) \
112   V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
113   V(JSON_OBJECT_INDEX, JSObject, json_object) \
114   V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \
115   V(INITIAL_OBJECT_PROTOTYPE_INDEX, JSObject, initial_object_prototype) \
116   V(CREATE_DATE_FUN_INDEX, JSFunction,  create_date_fun) \
117   V(TO_NUMBER_FUN_INDEX, JSFunction, to_number_fun) \
118   V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun) \
119   V(TO_DETAIL_STRING_FUN_INDEX, JSFunction, to_detail_string_fun) \
120   V(TO_OBJECT_FUN_INDEX, JSFunction, to_object_fun) \
121   V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun) \
122   V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun) \
123   V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun) \
124   V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \
125   V(INSTANTIATE_FUN_INDEX, JSFunction, instantiate_fun) \
126   V(CONFIGURE_INSTANCE_FUN_INDEX, JSFunction, configure_instance_fun) \
127   V(FUNCTION_MAP_INDEX, Map, function_map) \
128   V(STRICT_MODE_FUNCTION_MAP_INDEX, Map, strict_mode_function_map) \
129   V(FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, function_without_prototype_map) \
130   V(STRICT_MODE_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
131     strict_mode_function_without_prototype_map) \
132   V(FUNCTION_INSTANCE_MAP_INDEX, Map, function_instance_map) \
133   V(STRICT_MODE_FUNCTION_INSTANCE_MAP_INDEX, Map, \
134     strict_mode_function_instance_map) \
135   V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)\
136   V(ARGUMENTS_BOILERPLATE_INDEX, JSObject, arguments_boilerplate) \
137   V(ALIASED_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
138     aliased_arguments_boilerplate) \
139   V(STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX, JSObject, \
140     strict_mode_arguments_boilerplate) \
141   V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
142   V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
143   V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun) \
144   V(CONFIGURE_GLOBAL_INDEX, JSFunction, configure_global_fun) \
145   V(FUNCTION_CACHE_INDEX, JSObject, function_cache) \
146   V(JSFUNCTION_RESULT_CACHES_INDEX, FixedArray, jsfunction_result_caches) \
147   V(NORMALIZED_MAP_CACHE_INDEX, NormalizedMapCache, normalized_map_cache) \
148   V(RUNTIME_CONTEXT_INDEX, Context, runtime_context) \
149   V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate) \
150   V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
151     call_as_constructor_delegate) \
152   V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
153   V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function) \
154   V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
155   V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \
156   V(MAP_CACHE_INDEX, Object, map_cache) \
157   V(CONTEXT_DATA_INDEX, Object, data) \
158   V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
159   V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
160     to_complete_property_descriptor) \
161   V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
162   V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
163   V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap) \
164   V(PROXY_ENUMERATE, JSFunction, proxy_enumerate) \
165   V(RANDOM_SEED_INDEX, ByteArray, random_seed)
166
167 // JSFunctions are pairs (context, function code), sometimes also called
168 // closures. A Context object is used to represent function contexts and
169 // dynamically pushed 'with' contexts (or 'scopes' in ECMA-262 speak).
170 //
171 // At runtime, the contexts build a stack in parallel to the execution
172 // stack, with the top-most context being the current context. All contexts
173 // have the following slots:
174 //
175 // [ closure   ]  This is the current function. It is the same for all
176 //                contexts inside a function. It provides access to the
177 //                incoming context (i.e., the outer context, which may
178 //                or may not become the current function's context), and
179 //                it provides access to the functions code and thus it's
180 //                scope information, which in turn contains the names of
181 //                statically allocated context slots. The names are needed
182 //                for dynamic lookups in the presence of 'with' or 'eval'.
183 //
184 // [ previous  ]  A pointer to the previous context. It is NULL for
185 //                function contexts, and non-NULL for 'with' contexts.
186 //                Used to implement the 'with' statement.
187 //
188 // [ extension ]  A pointer to an extension JSObject, or NULL. Used to
189 //                implement 'with' statements and dynamic declarations
190 //                (through 'eval'). The object in a 'with' statement is
191 //                stored in the extension slot of a 'with' context.
192 //                Dynamically declared variables/functions are also added
193 //                to lazily allocated extension object. Context::Lookup
194 //                searches the extension object for properties.
195 //
196 // [ global    ]  A pointer to the global object. Provided for quick
197 //                access to the global object from inside the code (since
198 //                we always have a context pointer).
199 //
200 // In addition, function contexts may have statically allocated context slots
201 // to store local variables/functions that are accessed from inner functions
202 // (via static context addresses) or through 'eval' (dynamic context lookups).
203 // Finally, the global context contains additional slots for fast access to
204 // global properties.
205
206 class Context: public FixedArray {
207  public:
208   // Conversions.
209   static Context* cast(Object* context) {
210     ASSERT(context->IsContext());
211     return reinterpret_cast<Context*>(context);
212   }
213
214   // The default context slot layout; indices are FixedArray slot indices.
215   enum {
216     // These slots are in all contexts.
217     CLOSURE_INDEX,
218     PREVIOUS_INDEX,
219     // The extension slot is used for either the global object (in global
220     // contexts), eval extension object (function contexts), subject of with
221     // (with contexts), or the variable name (catch contexts), the serialized
222     // scope info (block contexts).
223     EXTENSION_INDEX,
224     QML_GLOBAL_INDEX,
225     GLOBAL_INDEX,
226     MIN_CONTEXT_SLOTS,
227
228     // This slot holds the thrown value in catch contexts.
229     THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS,
230
231     // These slots are only in global contexts.
232     GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
233     SECURITY_TOKEN_INDEX,
234     ARGUMENTS_BOILERPLATE_INDEX,
235     ALIASED_ARGUMENTS_BOILERPLATE_INDEX,
236     STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX,
237     REGEXP_RESULT_MAP_INDEX,
238     FUNCTION_MAP_INDEX,
239     STRICT_MODE_FUNCTION_MAP_INDEX,
240     FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
241     STRICT_MODE_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
242     FUNCTION_INSTANCE_MAP_INDEX,
243     STRICT_MODE_FUNCTION_INSTANCE_MAP_INDEX,
244     INITIAL_OBJECT_PROTOTYPE_INDEX,
245     BOOLEAN_FUNCTION_INDEX,
246     NUMBER_FUNCTION_INDEX,
247     STRING_FUNCTION_INDEX,
248     STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
249     OBJECT_FUNCTION_INDEX,
250     INTERNAL_ARRAY_FUNCTION_INDEX,
251     ARRAY_FUNCTION_INDEX,
252     SMI_JS_ARRAY_MAP_INDEX,
253     DOUBLE_JS_ARRAY_MAP_INDEX,
254     OBJECT_JS_ARRAY_MAP_INDEX,
255     DATE_FUNCTION_INDEX,
256     JSON_OBJECT_INDEX,
257     REGEXP_FUNCTION_INDEX,
258     CREATE_DATE_FUN_INDEX,
259     TO_NUMBER_FUN_INDEX,
260     TO_STRING_FUN_INDEX,
261     TO_DETAIL_STRING_FUN_INDEX,
262     TO_OBJECT_FUN_INDEX,
263     TO_INTEGER_FUN_INDEX,
264     TO_UINT32_FUN_INDEX,
265     TO_INT32_FUN_INDEX,
266     TO_BOOLEAN_FUN_INDEX,
267     GLOBAL_EVAL_FUN_INDEX,
268     INSTANTIATE_FUN_INDEX,
269     CONFIGURE_INSTANCE_FUN_INDEX,
270     MESSAGE_LISTENERS_INDEX,
271     MAKE_MESSAGE_FUN_INDEX,
272     GET_STACK_TRACE_LINE_INDEX,
273     CONFIGURE_GLOBAL_INDEX,
274     FUNCTION_CACHE_INDEX,
275     JSFUNCTION_RESULT_CACHES_INDEX,
276     NORMALIZED_MAP_CACHE_INDEX,
277     RUNTIME_CONTEXT_INDEX,
278     CALL_AS_FUNCTION_DELEGATE_INDEX,
279     CALL_AS_CONSTRUCTOR_DELEGATE_INDEX,
280     SCRIPT_FUNCTION_INDEX,
281     OPAQUE_REFERENCE_FUNCTION_INDEX,
282     CONTEXT_EXTENSION_FUNCTION_INDEX,
283     OUT_OF_MEMORY_INDEX,
284     CONTEXT_DATA_INDEX,
285     ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
286     TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
287     DERIVED_HAS_TRAP_INDEX,
288     DERIVED_GET_TRAP_INDEX,
289     DERIVED_SET_TRAP_INDEX,
290     PROXY_ENUMERATE,
291     RANDOM_SEED_INDEX,
292
293     // Properties from here are treated as weak references by the full GC.
294     // Scavenge treats them as strong references.
295     OPTIMIZED_FUNCTIONS_LIST,  // Weak.
296     MAP_CACHE_INDEX,  // Weak.
297     NEXT_CONTEXT_LINK,  // Weak.
298
299     // Total number of slots.
300     GLOBAL_CONTEXT_SLOTS,
301
302     FIRST_WEAK_SLOT = OPTIMIZED_FUNCTIONS_LIST
303   };
304
305   // Direct slot access.
306   JSFunction* closure() { return JSFunction::cast(get(CLOSURE_INDEX)); }
307   void set_closure(JSFunction* closure) { set(CLOSURE_INDEX, closure); }
308
309   Context* previous() {
310     Object* result = unchecked_previous();
311     ASSERT(IsBootstrappingOrContext(result));
312     return reinterpret_cast<Context*>(result);
313   }
314   void set_previous(Context* context) { set(PREVIOUS_INDEX, context); }
315
316   bool has_extension() { return extension() != NULL; }
317   Object* extension() { return get(EXTENSION_INDEX); }
318   void set_extension(Object* object) { set(EXTENSION_INDEX, object); }
319
320   // Get the context where var declarations will be hoisted to, which
321   // may be the context itself.
322   Context* declaration_context();
323
324   GlobalObject* global() {
325     Object* result = get(GLOBAL_INDEX);
326     ASSERT(IsBootstrappingOrGlobalObject(result));
327     return reinterpret_cast<GlobalObject*>(result);
328   }
329   void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); }
330
331   JSObject *qml_global() { return reinterpret_cast<JSObject *>(get(QML_GLOBAL_INDEX)); }
332   void set_qml_global(JSObject *qml_global) { set(QML_GLOBAL_INDEX, qml_global); }
333
334   // Returns a JSGlobalProxy object or null.
335   JSObject* global_proxy();
336   void set_global_proxy(JSObject* global);
337
338   // The builtins object.
339   JSBuiltinsObject* builtins();
340
341   // Compute the global context by traversing the context chain.
342   Context* global_context();
343
344   // Predicates for context types.  IsGlobalContext is defined on Object
345   // because we frequently have to know if arbitrary objects are global
346   // contexts.
347   bool IsFunctionContext() {
348     Map* map = this->map();
349     return map == map->GetHeap()->function_context_map();
350   }
351   bool IsCatchContext() {
352     Map* map = this->map();
353     return map == map->GetHeap()->catch_context_map();
354   }
355   bool IsWithContext() {
356     Map* map = this->map();
357     return map == map->GetHeap()->with_context_map();
358   }
359   bool IsBlockContext() {
360     Map* map = this->map();
361     return map == map->GetHeap()->block_context_map();
362   }
363   bool IsModuleContext() {
364     Map* map = this->map();
365     return map == map->GetHeap()->module_context_map();
366   }
367
368   // Tells whether the global context is marked with out of memory.
369   inline bool has_out_of_memory();
370
371   // Mark the global context with out of memory.
372   inline void mark_out_of_memory();
373
374   // A global context hold a list of all functions which have been optimized.
375   void AddOptimizedFunction(JSFunction* function);
376   void RemoveOptimizedFunction(JSFunction* function);
377   Object* OptimizedFunctionsListHead();
378   void ClearOptimizedFunctions();
379
380   static int GetContextMapIndexFromElementsKind(
381       ElementsKind elements_kind) {
382     if (elements_kind == FAST_DOUBLE_ELEMENTS) {
383       return Context::DOUBLE_JS_ARRAY_MAP_INDEX;
384     } else if (elements_kind == FAST_ELEMENTS) {
385       return Context::OBJECT_JS_ARRAY_MAP_INDEX;
386     } else {
387       ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS);
388       return Context::SMI_JS_ARRAY_MAP_INDEX;
389     }
390   }
391
392 #define GLOBAL_CONTEXT_FIELD_ACCESSORS(index, type, name) \
393   void  set_##name(type* value) {                         \
394     ASSERT(IsGlobalContext());                            \
395     set(index, value);                                    \
396   }                                                       \
397   type* name() {                                          \
398     ASSERT(IsGlobalContext());                            \
399     return type::cast(get(index));                        \
400   }
401   GLOBAL_CONTEXT_FIELDS(GLOBAL_CONTEXT_FIELD_ACCESSORS)
402 #undef GLOBAL_CONTEXT_FIELD_ACCESSORS
403
404   // Lookup the slot called name, starting with the current context.
405   // There are three possibilities:
406   //
407   // 1) result->IsContext():
408   //    The binding was found in a context.  *index is always the
409   //    non-negative slot index.  *attributes is NONE for var and let
410   //    declarations, READ_ONLY for const declarations (never ABSENT).
411   //
412   // 2) result->IsJSObject():
413   //    The binding was found as a named property in a context extension
414   //    object (i.e., was introduced via eval), as a property on the subject
415   //    of with, or as a property of the global object.  *index is -1 and
416   //    *attributes is not ABSENT.
417   //
418   // 3) result.is_null():
419   //    There was no binding found, *index is always -1 and *attributes is
420   //    always ABSENT.
421   Handle<Object> Lookup(Handle<String> name,
422                         ContextLookupFlags flags,
423                         int* index,
424                         PropertyAttributes* attributes,
425                         BindingFlags* binding_flags);
426
427   // Code generation support.
428   static int SlotOffset(int index) {
429     return kHeaderSize + index * kPointerSize - kHeapObjectTag;
430   }
431
432   static const int kSize = kHeaderSize + GLOBAL_CONTEXT_SLOTS * kPointerSize;
433
434   // GC support.
435   typedef FixedBodyDescriptor<
436       kHeaderSize, kSize, kSize> ScavengeBodyDescriptor;
437
438   typedef FixedBodyDescriptor<
439       kHeaderSize,
440       kHeaderSize + FIRST_WEAK_SLOT * kPointerSize,
441       kSize> MarkCompactBodyDescriptor;
442
443  private:
444   // Unchecked access to the slots.
445   Object* unchecked_previous() { return get(PREVIOUS_INDEX); }
446
447 #ifdef DEBUG
448   // Bootstrapping-aware type checks.
449   static bool IsBootstrappingOrContext(Object* object);
450   static bool IsBootstrappingOrGlobalObject(Object* object);
451 #endif
452 };
453
454 } }  // namespace v8::internal
455
456 #endif  // V8_CONTEXTS_H_