OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/contexts.h" | 5 #include "src/contexts.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 } | 54 } |
55 return false; | 55 return false; |
56 } | 56 } |
57 | 57 |
58 | 58 |
59 bool Context::is_declaration_context() { | 59 bool Context::is_declaration_context() { |
60 if (IsFunctionContext() || IsNativeContext() || IsScriptContext() || | 60 if (IsFunctionContext() || IsNativeContext() || IsScriptContext() || |
61 IsModuleContext()) { | 61 IsModuleContext()) { |
62 return true; | 62 return true; |
63 } | 63 } |
64 if (IsEvalContext()) return closure()->shared()->language_mode() == STRICT; | |
64 if (!IsBlockContext()) return false; | 65 if (!IsBlockContext()) return false; |
65 Object* ext = extension(); | 66 Object* ext = extension(); |
66 // If we have the special extension, we immediately know it must be a | 67 // If we have the special extension, we immediately know it must be a |
67 // declaration scope. That's just a small performance shortcut. | 68 // declaration scope. That's just a small performance shortcut. |
68 return ext->IsContextExtension() || | 69 return ext->IsContextExtension() || |
69 ScopeInfo::cast(ext)->is_declaration_scope(); | 70 ScopeInfo::cast(ext)->is_declaration_scope(); |
70 } | 71 } |
71 | 72 |
72 | 73 |
73 Context* Context::declaration_context() { | 74 Context* Context::declaration_context() { |
74 Context* current = this; | 75 Context* current = this; |
75 while (!current->is_declaration_context()) { | 76 while (!current->is_declaration_context()) { |
76 current = current->previous(); | 77 current = current->previous(); |
77 DCHECK(current->closure() == closure()); | 78 // Note: the closure may change while finding the declaration context, |
adamk
2016/11/12 00:26:05
Seems like this comment won't be as useful after t
Dan Ehrenberg
2016/12/07 05:41:26
Done.
| |
79 // e.g., for sloppy direct eval | |
78 } | 80 } |
79 return current; | 81 return current; |
80 } | 82 } |
81 | 83 |
82 Context* Context::closure_context() { | 84 Context* Context::closure_context() { |
83 Context* current = this; | 85 Context* current = this; |
84 while (!current->IsFunctionContext() && !current->IsScriptContext() && | 86 while (!current->IsFunctionContext() && !current->IsScriptContext() && |
85 !current->IsModuleContext() && !current->IsNativeContext()) { | 87 !current->IsModuleContext() && !current->IsNativeContext() && |
88 !current->IsEvalContext()) { | |
86 current = current->previous(); | 89 current = current->previous(); |
87 DCHECK(current->closure() == closure()); | 90 DCHECK(current->closure() == closure()); |
88 } | 91 } |
89 return current; | 92 return current; |
90 } | 93 } |
91 | 94 |
92 JSObject* Context::extension_object() { | 95 JSObject* Context::extension_object() { |
93 DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext()); | 96 DCHECK(IsNativeContext() || IsFunctionContext() || IsBlockContext() || |
97 IsEvalContext()); | |
94 HeapObject* object = extension(); | 98 HeapObject* object = extension(); |
95 if (object->IsTheHole(GetIsolate())) return nullptr; | 99 if (object->IsTheHole(GetIsolate())) return nullptr; |
96 if (IsBlockContext()) { | 100 if (IsBlockContext()) { |
97 if (!object->IsContextExtension()) return nullptr; | 101 if (!object->IsContextExtension()) return nullptr; |
98 object = JSObject::cast(ContextExtension::cast(object)->extension()); | 102 object = JSObject::cast(ContextExtension::cast(object)->extension()); |
99 } | 103 } |
100 DCHECK(object->IsJSContextExtensionObject() || | 104 DCHECK(object->IsJSContextExtensionObject() || |
101 (IsNativeContext() && object->IsJSGlobalObject())); | 105 (IsNativeContext() && object->IsJSGlobalObject())); |
102 return JSObject::cast(object); | 106 return JSObject::cast(object); |
103 } | 107 } |
104 | 108 |
105 JSReceiver* Context::extension_receiver() { | 109 JSReceiver* Context::extension_receiver() { |
106 DCHECK(IsNativeContext() || IsWithContext() || | 110 DCHECK(IsNativeContext() || IsWithContext() || IsEvalContext() || |
107 IsFunctionContext() || IsBlockContext()); | 111 IsFunctionContext() || IsBlockContext()); |
108 return IsWithContext() ? JSReceiver::cast( | 112 return IsWithContext() ? JSReceiver::cast( |
109 ContextExtension::cast(extension())->extension()) | 113 ContextExtension::cast(extension())->extension()) |
110 : extension_object(); | 114 : extension_object(); |
111 } | 115 } |
112 | 116 |
113 ScopeInfo* Context::scope_info() { | 117 ScopeInfo* Context::scope_info() { |
114 DCHECK(!IsNativeContext()); | 118 DCHECK(!IsNativeContext()); |
115 if (IsFunctionContext() || IsModuleContext()) { | 119 if (IsFunctionContext() || IsModuleContext() || IsEvalContext()) { |
116 return closure()->shared()->scope_info(); | 120 return closure()->shared()->scope_info(); |
117 } | 121 } |
118 HeapObject* object = extension(); | 122 HeapObject* object = extension(); |
119 if (object->IsContextExtension()) { | 123 if (object->IsContextExtension()) { |
120 DCHECK(IsBlockContext() || IsCatchContext() || IsWithContext() || | 124 DCHECK(IsBlockContext() || IsCatchContext() || IsWithContext() || |
121 IsDebugEvaluateContext()); | 125 IsDebugEvaluateContext()); |
122 object = ContextExtension::cast(object)->scope_info(); | 126 object = ContextExtension::cast(object)->scope_info(); |
123 } | 127 } |
124 return ScopeInfo::cast(object); | 128 return ScopeInfo::cast(object); |
125 } | 129 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 if (FLAG_trace_contexts) { | 222 if (FLAG_trace_contexts) { |
219 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); | 223 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); |
220 if (context->IsScriptContext()) PrintF(" (script context)"); | 224 if (context->IsScriptContext()) PrintF(" (script context)"); |
221 if (context->IsNativeContext()) PrintF(" (native context)"); | 225 if (context->IsNativeContext()) PrintF(" (native context)"); |
222 PrintF("\n"); | 226 PrintF("\n"); |
223 } | 227 } |
224 | 228 |
225 // 1. Check global objects, subjects of with, and extension objects. | 229 // 1. Check global objects, subjects of with, and extension objects. |
226 if ((context->IsNativeContext() || | 230 if ((context->IsNativeContext() || |
227 (context->IsWithContext() && ((flags & SKIP_WITH_CONTEXT) == 0)) || | 231 (context->IsWithContext() && ((flags & SKIP_WITH_CONTEXT) == 0)) || |
228 context->IsFunctionContext() || context->IsBlockContext()) && | 232 context->IsFunctionContext() || context->IsEvalContext() || |
233 context->IsBlockContext()) && | |
229 context->extension_receiver() != nullptr) { | 234 context->extension_receiver() != nullptr) { |
230 Handle<JSReceiver> object(context->extension_receiver()); | 235 Handle<JSReceiver> object(context->extension_receiver()); |
231 | 236 |
232 if (context->IsNativeContext()) { | 237 if (context->IsNativeContext()) { |
233 if (FLAG_trace_contexts) { | 238 if (FLAG_trace_contexts) { |
234 PrintF(" - trying other script contexts\n"); | 239 PrintF(" - trying other script contexts\n"); |
235 } | 240 } |
236 // Try other script contexts. | 241 // Try other script contexts. |
237 Handle<ScriptContextTable> script_contexts( | 242 Handle<ScriptContextTable> script_contexts( |
238 context->global_object()->native_context()->script_context_table()); | 243 context->global_object()->native_context()->script_context_table()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 if (FLAG_trace_contexts) { | 299 if (FLAG_trace_contexts) { |
295 PrintF("=> found property in context object %p\n", | 300 PrintF("=> found property in context object %p\n", |
296 reinterpret_cast<void*>(*object)); | 301 reinterpret_cast<void*>(*object)); |
297 } | 302 } |
298 return object; | 303 return object; |
299 } | 304 } |
300 } | 305 } |
301 | 306 |
302 // 2. Check the context proper if it has slots. | 307 // 2. Check the context proper if it has slots. |
303 if (context->IsFunctionContext() || context->IsBlockContext() || | 308 if (context->IsFunctionContext() || context->IsBlockContext() || |
304 context->IsScriptContext()) { | 309 context->IsScriptContext() || context->IsEvalContext()) { |
305 // Use serialized scope information of functions and blocks to search | 310 // Use serialized scope information of functions and blocks to search |
306 // for the context index. | 311 // for the context index. |
307 Handle<ScopeInfo> scope_info(context->IsFunctionContext() | 312 Handle<ScopeInfo> scope_info( |
308 ? context->closure()->shared()->scope_info() | 313 (context->IsFunctionContext() || context->IsEvalContext()) |
adamk
2016/11/12 00:26:05
Isn't this logic already present in Context::scope
Dan Ehrenberg
2016/12/07 05:41:26
Done.
| |
309 : context->scope_info()); | 314 ? context->closure()->shared()->scope_info() |
315 : context->scope_info()); | |
310 VariableMode mode; | 316 VariableMode mode; |
311 InitializationFlag flag; | 317 InitializationFlag flag; |
312 MaybeAssignedFlag maybe_assigned_flag; | 318 MaybeAssignedFlag maybe_assigned_flag; |
313 int slot_index = ScopeInfo::ContextSlotIndex(scope_info, name, &mode, | 319 int slot_index = ScopeInfo::ContextSlotIndex(scope_info, name, &mode, |
314 &flag, &maybe_assigned_flag); | 320 &flag, &maybe_assigned_flag); |
315 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); | 321 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); |
316 if (slot_index >= 0) { | 322 if (slot_index >= 0) { |
317 if (FLAG_trace_contexts) { | 323 if (FLAG_trace_contexts) { |
318 PrintF("=> found local in context slot %d (mode = %d)\n", | 324 PrintF("=> found local in context slot %d (mode = %d)\n", |
319 slot_index, mode); | 325 slot_index, mode); |
320 } | 326 } |
321 *index = slot_index; | 327 *index = slot_index; |
322 *variable_mode = mode; | 328 *variable_mode = mode; |
323 *init_flag = flag; | 329 *init_flag = flag; |
324 *attributes = GetAttributesForMode(mode); | 330 *attributes = GetAttributesForMode(mode); |
325 return context; | 331 return context; |
326 } | 332 } |
327 | 333 |
328 // Check the slot corresponding to the intermediate context holding | 334 // Check the slot corresponding to the intermediate context holding |
329 // only the function name variable. It's conceptually (and spec-wise) | 335 // only the function name variable. It's conceptually (and spec-wise) |
330 // in an outer scope of the function's declaration scope. | 336 // in an outer scope of the function's declaration scope. |
331 if (follow_context_chain && (flags & STOP_AT_DECLARATION_SCOPE) == 0 && | 337 if (follow_context_chain && (flags & STOP_AT_DECLARATION_SCOPE) == 0 && |
332 context->IsFunctionContext()) { | 338 (context->IsFunctionContext() || context->IsEvalContext())) { |
adamk
2016/11/12 00:26:05
I don't think it makes sense to add IsEvalContext
Dan Ehrenberg
2016/12/07 05:41:26
Done.
| |
333 int function_index = scope_info->FunctionContextSlotIndex(*name); | 339 int function_index = scope_info->FunctionContextSlotIndex(*name); |
334 if (function_index >= 0) { | 340 if (function_index >= 0) { |
335 if (FLAG_trace_contexts) { | 341 if (FLAG_trace_contexts) { |
336 PrintF("=> found intermediate function in context slot %d\n", | 342 PrintF("=> found intermediate function in context slot %d\n", |
337 function_index); | 343 function_index); |
338 } | 344 } |
339 *index = function_index; | 345 *index = function_index; |
340 *attributes = READ_ONLY; | 346 *attributes = READ_ONLY; |
341 *init_flag = kCreatedInitialized; | 347 *init_flag = kCreatedInitialized; |
342 *variable_mode = CONST; | 348 *variable_mode = CONST; |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
588 | 594 |
589 int previous_value = errors_thrown()->value(); | 595 int previous_value = errors_thrown()->value(); |
590 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 596 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
591 } | 597 } |
592 | 598 |
593 | 599 |
594 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 600 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
595 | 601 |
596 } // namespace internal | 602 } // namespace internal |
597 } // namespace v8 | 603 } // namespace v8 |
OLD | NEW |