Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(983)

Side by Side Diff: src/contexts.cc

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/contexts.h ('k') | src/conversions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 16 matching lines...) Expand all
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "bootstrapper.h" 30 #include "bootstrapper.h"
31 #include "debug.h" 31 #include "debug.h"
32 #include "scopeinfo.h" 32 #include "scopeinfo.h"
33 33
34 namespace v8 { 34 namespace v8 {
35 namespace internal { 35 namespace internal {
36 36
37 Context* Context::declaration_context() {
38 Context* current = this;
39 while (!current->IsFunctionContext() && !current->IsGlobalContext()) {
40 current = current->previous();
41 ASSERT(current->closure() == closure());
42 }
43 return current;
44 }
45
46
37 JSBuiltinsObject* Context::builtins() { 47 JSBuiltinsObject* Context::builtins() {
38 GlobalObject* object = global(); 48 GlobalObject* object = global();
39 if (object->IsJSGlobalObject()) { 49 if (object->IsJSGlobalObject()) {
40 return JSGlobalObject::cast(object)->builtins(); 50 return JSGlobalObject::cast(object)->builtins();
41 } else { 51 } else {
42 ASSERT(object->IsJSBuiltinsObject()); 52 ASSERT(object->IsJSBuiltinsObject());
43 return JSBuiltinsObject::cast(object); 53 return JSBuiltinsObject::cast(object);
44 } 54 }
45 } 55 }
46 56
(...skipping 20 matching lines...) Expand all
67 77
68 JSObject* Context::global_proxy() { 78 JSObject* Context::global_proxy() {
69 return global_context()->global_proxy_object(); 79 return global_context()->global_proxy_object();
70 } 80 }
71 81
72 void Context::set_global_proxy(JSObject* object) { 82 void Context::set_global_proxy(JSObject* object) {
73 global_context()->set_global_proxy_object(object); 83 global_context()->set_global_proxy_object(object);
74 } 84 }
75 85
76 86
77 Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, 87 Handle<Object> Context::Lookup(Handle<String> name,
78 int* index_, PropertyAttributes* attributes) { 88 ContextLookupFlags flags,
89 int* index_,
90 PropertyAttributes* attributes) {
79 Isolate* isolate = GetIsolate(); 91 Isolate* isolate = GetIsolate();
80 Handle<Context> context(this, isolate); 92 Handle<Context> context(this, isolate);
81 93
82 bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0; 94 bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0;
83 *index_ = -1; 95 *index_ = -1;
84 *attributes = ABSENT; 96 *attributes = ABSENT;
85 97
86 if (FLAG_trace_contexts) { 98 if (FLAG_trace_contexts) {
87 PrintF("Context::Lookup("); 99 PrintF("Context::Lookup(");
88 name->ShortPrint(); 100 name->ShortPrint();
89 PrintF(")\n"); 101 PrintF(")\n");
90 } 102 }
91 103
92 do { 104 do {
93 if (FLAG_trace_contexts) { 105 if (FLAG_trace_contexts) {
94 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); 106 PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
95 if (context->IsGlobalContext()) PrintF(" (global context)"); 107 if (context->IsGlobalContext()) PrintF(" (global context)");
96 PrintF("\n"); 108 PrintF("\n");
97 } 109 }
98 110
99 // check extension/with object 111 // Check extension/with/global object.
100 if (context->has_extension()) { 112 if (context->has_extension()) {
101 Handle<JSObject> extension = Handle<JSObject>(context->extension(), 113 if (context->IsCatchContext()) {
102 isolate); 114 // Catch contexts have the variable name in the extension slot.
103 // Context extension objects needs to behave as if they have no 115 if (name->Equals(String::cast(context->extension()))) {
104 // prototype. So even if we want to follow prototype chains, we 116 if (FLAG_trace_contexts) {
105 // need to only do a local lookup for context extension objects. 117 PrintF("=> found in catch context\n");
106 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 || 118 }
107 extension->IsJSContextExtensionObject()) { 119 *index_ = Context::THROWN_OBJECT_INDEX;
108 *attributes = extension->GetLocalPropertyAttribute(*name); 120 *attributes = NONE;
121 return context;
122 }
109 } else { 123 } else {
110 *attributes = extension->GetPropertyAttribute(*name); 124 // Global, function, and with contexts may have an object in the
111 } 125 // extension slot.
112 if (*attributes != ABSENT) { 126 Handle<JSObject> extension(JSObject::cast(context->extension()),
113 // property found 127 isolate);
114 if (FLAG_trace_contexts) { 128 // Context extension objects needs to behave as if they have no
115 PrintF("=> found property in context object %p\n", 129 // prototype. So even if we want to follow prototype chains, we
116 reinterpret_cast<void*>(*extension)); 130 // need to only do a local lookup for context extension objects.
131 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
132 extension->IsJSContextExtensionObject()) {
133 *attributes = extension->GetLocalPropertyAttribute(*name);
134 } else {
135 *attributes = extension->GetPropertyAttribute(*name);
117 } 136 }
118 return extension; 137 if (*attributes != ABSENT) {
138 // property found
139 if (FLAG_trace_contexts) {
140 PrintF("=> found property in context object %p\n",
141 reinterpret_cast<void*>(*extension));
142 }
143 return extension;
144 }
119 } 145 }
120 } 146 }
121 147
122 if (context->is_function_context()) { 148 // Only functions can have locals, parameters, and a function name.
123 // we have context-local slots 149 if (context->IsFunctionContext()) {
124 150 // We may have context-local slots. Check locals in the context.
125 // check non-parameter locals in context
126 Handle<SerializedScopeInfo> scope_info( 151 Handle<SerializedScopeInfo> scope_info(
127 context->closure()->shared()->scope_info(), isolate); 152 context->closure()->shared()->scope_info(), isolate);
128 Variable::Mode mode; 153 Variable::Mode mode;
129 int index = scope_info->ContextSlotIndex(*name, &mode); 154 int index = scope_info->ContextSlotIndex(*name, &mode);
130 ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS); 155 ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS);
131 if (index >= 0) { 156 if (index >= 0) {
132 // slot found
133 if (FLAG_trace_contexts) { 157 if (FLAG_trace_contexts) {
134 PrintF("=> found local in context slot %d (mode = %d)\n", 158 PrintF("=> found local in context slot %d (mode = %d)\n",
135 index, mode); 159 index, mode);
136 } 160 }
137 *index_ = index; 161 *index_ = index;
138 // Note: Fixed context slots are statically allocated by the compiler. 162 // Note: Fixed context slots are statically allocated by the compiler.
139 // Statically allocated variables always have a statically known mode, 163 // Statically allocated variables always have a statically known mode,
140 // which is the mode with which they were declared when added to the 164 // which is the mode with which they were declared when added to the
141 // scope. Thus, the DYNAMIC mode (which corresponds to dynamically 165 // scope. Thus, the DYNAMIC mode (which corresponds to dynamically
142 // declared variables that were introduced through declaration nodes) 166 // declared variables that were introduced through declaration nodes)
143 // must not appear here. 167 // must not appear here.
144 switch (mode) { 168 switch (mode) {
145 case Variable::INTERNAL: // fall through 169 case Variable::INTERNAL: // Fall through.
146 case Variable::VAR: *attributes = NONE; break; 170 case Variable::VAR:
147 case Variable::CONST: *attributes = READ_ONLY; break; 171 *attributes = NONE;
148 case Variable::DYNAMIC: UNREACHABLE(); break; 172 break;
149 case Variable::DYNAMIC_GLOBAL: UNREACHABLE(); break; 173 case Variable::CONST:
150 case Variable::DYNAMIC_LOCAL: UNREACHABLE(); break; 174 *attributes = READ_ONLY;
151 case Variable::TEMPORARY: UNREACHABLE(); break; 175 break;
176 case Variable::DYNAMIC:
177 case Variable::DYNAMIC_GLOBAL:
178 case Variable::DYNAMIC_LOCAL:
179 case Variable::TEMPORARY:
180 UNREACHABLE();
181 break;
152 } 182 }
153 return context; 183 return context;
154 } 184 }
155 185
156 // check parameter locals in context 186 // Check the slot corresponding to the intermediate context holding
157 int param_index = scope_info->ParameterIndex(*name); 187 // only the function name variable.
158 if (param_index >= 0) {
159 // slot found.
160 int index = scope_info->ContextSlotIndex(
161 isolate->heap()->arguments_shadow_symbol(), NULL);
162 ASSERT(index >= 0); // arguments must exist and be in the heap context
163 Handle<JSObject> arguments(JSObject::cast(context->get(index)),
164 isolate);
165 if (FLAG_trace_contexts) {
166 PrintF("=> found parameter %d in arguments object\n", param_index);
167 }
168 *index_ = param_index;
169 *attributes = NONE;
170 return arguments;
171 }
172
173 // check intermediate context (holding only the function name variable)
174 if (follow_context_chain) { 188 if (follow_context_chain) {
175 int index = scope_info->FunctionContextSlotIndex(*name); 189 int index = scope_info->FunctionContextSlotIndex(*name);
176 if (index >= 0) { 190 if (index >= 0) {
177 // slot found
178 if (FLAG_trace_contexts) { 191 if (FLAG_trace_contexts) {
179 PrintF("=> found intermediate function in context slot %d\n", 192 PrintF("=> found intermediate function in context slot %d\n",
180 index); 193 index);
181 } 194 }
182 *index_ = index; 195 *index_ = index;
183 *attributes = READ_ONLY; 196 *attributes = READ_ONLY;
184 return context; 197 return context;
185 } 198 }
186 } 199 }
187 } 200 }
188 201
189 // proceed with enclosing context 202 // Proceed with the previous context.
190 if (context->IsGlobalContext()) { 203 if (context->IsGlobalContext()) {
191 follow_context_chain = false; 204 follow_context_chain = false;
192 } else if (context->is_function_context()) {
193 context = Handle<Context>(Context::cast(context->closure()->context()),
194 isolate);
195 } else { 205 } else {
196 context = Handle<Context>(context->previous(), isolate); 206 context = Handle<Context>(context->previous(), isolate);
197 } 207 }
198 } while (follow_context_chain); 208 } while (follow_context_chain);
199 209
200 // slot not found
201 if (FLAG_trace_contexts) { 210 if (FLAG_trace_contexts) {
202 PrintF("=> no property/slot found\n"); 211 PrintF("=> no property/slot found\n");
203 } 212 }
204 return Handle<Object>::null(); 213 return Handle<Object>::null();
205 } 214 }
206 215
207 216
208 bool Context::GlobalIfNotShadowedByEval(Handle<String> name) { 217 bool Context::GlobalIfNotShadowedByEval(Handle<String> name) {
209 Context* context = this; 218 Context* context = this;
210 219
211 // Check that there is no local with the given name in contexts 220 // Check that there is no local with the given name in contexts
212 // before the global context and check that there are no context 221 // before the global context and check that there are no context
213 // extension objects (conservative check for with statements). 222 // extension objects (conservative check for with statements).
214 while (!context->IsGlobalContext()) { 223 while (!context->IsGlobalContext()) {
215 // Check if the context is a potentially a with context. 224 // Check if the context is a catch or with context, or has introduced
225 // bindings by calling non-strict eval.
216 if (context->has_extension()) return false; 226 if (context->has_extension()) return false;
217 227
218 // Not a with context so it must be a function context. 228 // Not a with context so it must be a function context.
219 ASSERT(context->is_function_context()); 229 ASSERT(context->IsFunctionContext());
220 230
221 // Check non-parameter locals. 231 // Check non-parameter locals.
222 Handle<SerializedScopeInfo> scope_info( 232 Handle<SerializedScopeInfo> scope_info(
223 context->closure()->shared()->scope_info()); 233 context->closure()->shared()->scope_info());
224 Variable::Mode mode; 234 Variable::Mode mode;
225 int index = scope_info->ContextSlotIndex(*name, &mode); 235 int index = scope_info->ContextSlotIndex(*name, &mode);
226 ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS); 236 ASSERT(index < 0 || index >= MIN_CONTEXT_SLOTS);
227 if (index >= 0) return false; 237 if (index >= 0) return false;
228 238
229 // Check parameter locals. 239 // Check parameter locals.
230 int param_index = scope_info->ParameterIndex(*name); 240 int param_index = scope_info->ParameterIndex(*name);
231 if (param_index >= 0) return false; 241 if (param_index >= 0) return false;
232 242
233 // Check context only holding the function name variable. 243 // Check context only holding the function name variable.
234 index = scope_info->FunctionContextSlotIndex(*name); 244 index = scope_info->FunctionContextSlotIndex(*name);
235 if (index >= 0) return false; 245 if (index >= 0) return false;
236 context = Context::cast(context->closure()->context()); 246 context = context->previous();
237 } 247 }
238 248
239 // No local or potential with statement found so the variable is 249 // No local or potential with statement found so the variable is
240 // global unless it is shadowed by an eval-introduced variable. 250 // global unless it is shadowed by an eval-introduced variable.
241 return true; 251 return true;
242 } 252 }
243 253
244 254
245 void Context::ComputeEvalScopeInfo(bool* outer_scope_calls_eval, 255 void Context::ComputeEvalScopeInfo(bool* outer_scope_calls_eval,
246 bool* outer_scope_calls_non_strict_eval) { 256 bool* outer_scope_calls_non_strict_eval) {
257 // Skip up the context chain checking all the function contexts to see
258 // whether they call eval.
247 Context* context = this; 259 Context* context = this;
248 while (true) { 260 while (!context->IsGlobalContext()) {
249 Handle<SerializedScopeInfo> scope_info( 261 if (context->IsFunctionContext()) {
250 context->closure()->shared()->scope_info()); 262 Handle<SerializedScopeInfo> scope_info(
251 if (scope_info->CallsEval()) { 263 context->closure()->shared()->scope_info());
252 *outer_scope_calls_eval = true; 264 if (scope_info->CallsEval()) {
253 if (!scope_info->IsStrictMode()) { 265 *outer_scope_calls_eval = true;
254 // No need to go further since the answers will not change 266 if (!scope_info->IsStrictMode()) {
255 // from here. 267 // No need to go further since the answers will not change from
256 *outer_scope_calls_non_strict_eval = true; 268 // here.
257 return; 269 *outer_scope_calls_non_strict_eval = true;
270 return;
271 }
258 } 272 }
259 } 273 }
260 if (context->IsGlobalContext()) break; 274 context = context->previous();
261 context = Context::cast(context->closure()->context());
262 } 275 }
263 } 276 }
264 277
265 278
266 void Context::AddOptimizedFunction(JSFunction* function) { 279 void Context::AddOptimizedFunction(JSFunction* function) {
267 ASSERT(IsGlobalContext()); 280 ASSERT(IsGlobalContext());
268 #ifdef DEBUG 281 #ifdef DEBUG
269 Object* element = get(OPTIMIZED_FUNCTIONS_LIST); 282 Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
270 while (!element->IsUndefined()) { 283 while (!element->IsUndefined()) {
271 CHECK(element != function); 284 CHECK(element != function);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 // During bootstrapping we allow all objects to pass as global 351 // During bootstrapping we allow all objects to pass as global
339 // objects. This is necessary to fix circular dependencies. 352 // objects. This is necessary to fix circular dependencies.
340 Isolate* isolate = Isolate::Current(); 353 Isolate* isolate = Isolate::Current();
341 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || 354 return isolate->heap()->gc_state() != Heap::NOT_IN_GC ||
342 isolate->bootstrapper()->IsActive() || 355 isolate->bootstrapper()->IsActive() ||
343 object->IsGlobalObject(); 356 object->IsGlobalObject();
344 } 357 }
345 #endif 358 #endif
346 359
347 } } // namespace v8::internal 360 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/contexts.h ('k') | src/conversions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698