v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
contexts.cc
Go to the documentation of this file.
1 // Copyright 2011 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 #include "v8.h"
29 
30 #include "bootstrapper.h"
31 #include "debug.h"
32 #include "scopeinfo.h"
33 
34 namespace v8 {
35 namespace internal {
36 
38  Context* current = this;
39  while (!current->IsFunctionContext() && !current->IsNativeContext()) {
40  current = current->previous();
41  ASSERT(current->closure() == closure());
42  }
43  return current;
44 }
45 
46 
48  GlobalObject* object = global_object();
49  if (object->IsJSGlobalObject()) {
50  return JSGlobalObject::cast(object)->builtins();
51  } else {
52  ASSERT(object->IsJSBuiltinsObject());
53  return JSBuiltinsObject::cast(object);
54  }
55 }
56 
57 
59  // Fast case: the global object for this context has been set. In
60  // that case, the global object has a direct pointer to the global
61  // context.
62  if (global_object()->IsGlobalObject()) {
63  return global_object()->native_context();
64  }
65 
66  // During bootstrapping, the global object might not be set and we
67  // have to search the context chain to find the native context.
68  ASSERT(Isolate::Current()->bootstrapper()->IsActive());
69  Context* current = this;
70  while (!current->IsNativeContext()) {
72  current = Context::cast(closure->context());
73  }
74  return current;
75 }
76 
77 
79  return native_context()->global_proxy_object();
80 }
81 
83  native_context()->set_global_proxy_object(object);
84 }
85 
86 
89  int* index,
90  PropertyAttributes* attributes,
91  BindingFlags* binding_flags) {
92  Isolate* isolate = GetIsolate();
93  Handle<Context> context(this, isolate);
94 
95  bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0;
96  *index = -1;
97  *attributes = ABSENT;
98  *binding_flags = MISSING_BINDING;
99 
100  if (FLAG_trace_contexts) {
101  PrintF("Context::Lookup(");
102  name->ShortPrint();
103  PrintF(")\n");
104  }
105 
106  do {
107  if (FLAG_trace_contexts) {
108  PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
109  if (context->IsNativeContext()) PrintF(" (native context)");
110  PrintF("\n");
111  }
112 
113  // 1. Check global objects, subjects of with, and extension objects.
114  if (context->IsNativeContext() ||
115  context->IsWithContext() ||
116  (context->IsFunctionContext() && context->has_extension())) {
117  Handle<JSObject> object(JSObject::cast(context->extension()), isolate);
118  // Context extension objects needs to behave as if they have no
119  // prototype. So even if we want to follow prototype chains, we need
120  // to only do a local lookup for context extension objects.
121  if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
122  object->IsJSContextExtensionObject()) {
123  *attributes = object->GetLocalPropertyAttribute(*name);
124  } else {
125  *attributes = object->GetPropertyAttribute(*name);
126  }
127  if (*attributes != ABSENT) {
128  if (FLAG_trace_contexts) {
129  PrintF("=> found property in context object %p\n",
130  reinterpret_cast<void*>(*object));
131  }
132  return object;
133  }
134  }
135 
136  // 2. Check the context proper if it has slots.
137  if (context->IsFunctionContext() || context->IsBlockContext()) {
138  // Use serialized scope information of functions and blocks to search
139  // for the context index.
140  Handle<ScopeInfo> scope_info;
141  if (context->IsFunctionContext()) {
142  scope_info = Handle<ScopeInfo>(
143  context->closure()->shared()->scope_info(), isolate);
144  } else {
145  scope_info = Handle<ScopeInfo>(
146  ScopeInfo::cast(context->extension()), isolate);
147  }
148  VariableMode mode;
149  InitializationFlag init_flag;
150  int slot_index = scope_info->ContextSlotIndex(*name, &mode, &init_flag);
151  ASSERT(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS);
152  if (slot_index >= 0) {
153  if (FLAG_trace_contexts) {
154  PrintF("=> found local in context slot %d (mode = %d)\n",
155  slot_index, mode);
156  }
157  *index = slot_index;
158  // Note: Fixed context slots are statically allocated by the compiler.
159  // Statically allocated variables always have a statically known mode,
160  // which is the mode with which they were declared when added to the
161  // scope. Thus, the DYNAMIC mode (which corresponds to dynamically
162  // declared variables that were introduced through declaration nodes)
163  // must not appear here.
164  switch (mode) {
165  case INTERNAL: // Fall through.
166  case VAR:
167  *attributes = NONE;
168  *binding_flags = MUTABLE_IS_INITIALIZED;
169  break;
170  case LET:
171  *attributes = NONE;
172  *binding_flags = (init_flag == kNeedsInitialization)
174  break;
175  case CONST:
176  *attributes = READ_ONLY;
177  *binding_flags = (init_flag == kNeedsInitialization)
179  break;
180  case CONST_HARMONY:
181  *attributes = READ_ONLY;
182  *binding_flags = (init_flag == kNeedsInitialization)
185  break;
186  case DYNAMIC:
187  case DYNAMIC_GLOBAL:
188  case DYNAMIC_LOCAL:
189  case TEMPORARY:
190  UNREACHABLE();
191  break;
192  }
193  return context;
194  }
195 
196  // Check the slot corresponding to the intermediate context holding
197  // only the function name variable.
198  if (follow_context_chain && context->IsFunctionContext()) {
199  VariableMode mode;
200  int function_index = scope_info->FunctionContextSlotIndex(*name, &mode);
201  if (function_index >= 0) {
202  if (FLAG_trace_contexts) {
203  PrintF("=> found intermediate function in context slot %d\n",
204  function_index);
205  }
206  *index = function_index;
207  *attributes = READ_ONLY;
208  ASSERT(mode == CONST || mode == CONST_HARMONY);
209  *binding_flags = (mode == CONST)
211  return context;
212  }
213  }
214 
215  } else if (context->IsCatchContext()) {
216  // Catch contexts have the variable name in the extension slot.
217  if (name->Equals(String::cast(context->extension()))) {
218  if (FLAG_trace_contexts) {
219  PrintF("=> found in catch context\n");
220  }
222  *attributes = NONE;
223  *binding_flags = MUTABLE_IS_INITIALIZED;
224  return context;
225  }
226  }
227 
228  // 3. Prepare to continue with the previous (next outermost) context.
229  if (context->IsNativeContext()) {
230  follow_context_chain = false;
231  } else {
232  context = Handle<Context>(context->previous(), isolate);
233  }
234  } while (follow_context_chain);
235 
236  if (FLAG_trace_contexts) {
237  PrintF("=> no property/slot found\n");
238  }
239  return Handle<Object>::null();
240 }
241 
242 
244  ASSERT(IsNativeContext());
245 #ifdef DEBUG
247  Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
248  while (!element->IsUndefined()) {
249  CHECK(element != function);
250  element = JSFunction::cast(element)->next_function_link();
251  }
252  }
253 
254  CHECK(function->next_function_link()->IsUndefined());
255 
256  // Check that the context belongs to the weak native contexts list.
257  bool found = false;
258  Object* context = GetHeap()->native_contexts_list();
259  while (!context->IsUndefined()) {
260  if (context == this) {
261  found = true;
262  break;
263  }
264  context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
265  }
266  CHECK(found);
267 #endif
268  function->set_next_function_link(get(OPTIMIZED_FUNCTIONS_LIST));
269  set(OPTIMIZED_FUNCTIONS_LIST, function);
270 }
271 
272 
274  ASSERT(IsNativeContext());
275  Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
276  JSFunction* prev = NULL;
277  while (!element->IsUndefined()) {
278  JSFunction* element_function = JSFunction::cast(element);
279  ASSERT(element_function->next_function_link()->IsUndefined() ||
280  element_function->next_function_link()->IsJSFunction());
281  if (element_function == function) {
282  if (prev == NULL) {
283  set(OPTIMIZED_FUNCTIONS_LIST, element_function->next_function_link());
284  } else {
285  prev->set_next_function_link(element_function->next_function_link());
286  }
287  element_function->set_next_function_link(GetHeap()->undefined_value());
288  return;
289  }
290  prev = element_function;
291  element = element_function->next_function_link();
292  }
293  UNREACHABLE();
294 }
295 
296 
298  ASSERT(IsNativeContext());
299  return get(OPTIMIZED_FUNCTIONS_LIST);
300 }
301 
302 
304  set(OPTIMIZED_FUNCTIONS_LIST, GetHeap()->undefined_value());
305 }
306 
307 
309  Handle<Object> result(error_message_for_code_gen_from_strings());
310  if (result->IsUndefined()) {
311  const char* error =
312  "Code generation from strings disallowed for this context";
313  Isolate* isolate = Isolate::Current();
314  result = isolate->factory()->NewStringFromAscii(i::CStrVector(error));
315  }
316  return result;
317 }
318 
319 
320 #ifdef DEBUG
321 bool Context::IsBootstrappingOrValidParentContext(
322  Object* object, Context* child) {
323  // During bootstrapping we allow all objects to pass as
324  // contexts. This is necessary to fix circular dependencies.
325  if (Isolate::Current()->bootstrapper()->IsActive()) return true;
326  if (!object->IsContext()) return false;
327  Context* context = Context::cast(object);
328  return context->IsNativeContext() || context->IsGlobalContext() ||
329  context->IsModuleContext() || !child->IsModuleContext();
330 }
331 
332 
333 bool Context::IsBootstrappingOrGlobalObject(Object* object) {
334  // During bootstrapping we allow all objects to pass as global
335  // objects. This is necessary to fix circular dependencies.
336  Isolate* isolate = Isolate::Current();
337  return isolate->heap()->gc_state() != Heap::NOT_IN_GC ||
338  isolate->bootstrapper()->IsActive() ||
339  object->IsGlobalObject();
340 }
341 #endif
342 
343 } } // namespace v8::internal
bool FLAG_enable_slow_asserts
void set(int index, Object *value)
Definition: objects-inl.h:1757
void PrintF(const char *format,...)
Definition: v8utils.cc:40
static String * cast(Object *obj)
Context * previous()
Definition: contexts.h:310
static JSBuiltinsObject * cast(Object *obj)
JSBuiltinsObject * builtins()
Definition: contexts.cc:47
void set_global_proxy(JSObject *global)
Definition: contexts.cc:82
#define ASSERT(condition)
Definition: checks.h:270
static Context * cast(Object *context)
Definition: contexts.h:212
#define CHECK(condition)
Definition: checks.h:56
Factory * factory()
Definition: isolate.h:992
PropertyAttributes
static ScopeInfo * cast(Object *object)
void ClearOptimizedFunctions()
Definition: contexts.cc:303
GlobalObject * global_object()
Definition: contexts.h:328
Handle< Object > Lookup(Handle< String > name, ContextLookupFlags flags, int *index, PropertyAttributes *attributes, BindingFlags *binding_flags)
Definition: contexts.cc:87
#define UNREACHABLE()
Definition: checks.h:50
Context * native_context()
Definition: contexts.cc:58
JSObject * global_proxy()
Definition: contexts.cc:78
Object * OptimizedFunctionsListHead()
Definition: contexts.cc:297
void RemoveOptimizedFunction(JSFunction *function)
Definition: contexts.cc:273
Vector< const char > CStrVector(const char *data)
Definition: utils.h:526
ContextLookupFlags
Definition: contexts.h:38
Handle< String > NewStringFromAscii(Vector< const char > str, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:199
Object * native_contexts_list()
Definition: heap.h:1189
bool IsFunctionContext()
Definition: contexts.h:350
static Handle< T > null()
Definition: handles.h:86
void AddOptimizedFunction(JSFunction *function)
Definition: contexts.cc:243
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
Object * get(int index)
Definition: objects-inl.h:1737
Handle< Object > ErrorMessageForCodeGenerationFromStrings()
Definition: contexts.cc:308
JSFunction * closure()
Definition: contexts.h:307
Context * declaration_context()
Definition: contexts.cc:37
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
Definition: flags.cc:495
static JSObject * cast(Object *obj)
static JSGlobalObject * cast(Object *obj)
static JSFunction * cast(Object *obj)