OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); | 181 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); |
182 } | 182 } |
183 } | 183 } |
184 | 184 |
185 RETURN_FAILURE_ON_EXCEPTION( | 185 RETURN_FAILURE_ON_EXCEPTION( |
186 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); | 186 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); |
187 | 187 |
188 return *value; | 188 return *value; |
189 } | 189 } |
190 | 190 |
191 | 191 static Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, |
Michael Starzinger
2016/06/14 14:47:32
nit: Please use an anonymous namespace again inste
adamk
2016/06/14 14:59:43
Done.
| |
192 namespace { | 192 Handle<Object> value) { |
193 | 193 // Declarations are always made in a function, native, or script context, or |
194 Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name, | 194 // a declaration block scope. Since this is called from eval, the context |
195 Handle<Object> initial_value, | 195 // passed is the context of the caller, which may be some nested context and |
196 PropertyAttributes attr) { | 196 // not the declaration context. |
197 // Declarations are always made in a function, eval or script context, or | |
198 // a declaration block scope. | |
199 // In the case of eval code, the context passed is the context of the caller, | |
200 // which may be some nested context and not the declaration context. | |
201 Handle<Context> context_arg(isolate->context(), isolate); | 197 Handle<Context> context_arg(isolate->context(), isolate); |
202 Handle<Context> context(context_arg->declaration_context(), isolate); | 198 Handle<Context> context(context_arg->declaration_context(), isolate); |
203 | 199 |
204 // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals. | 200 DCHECK(context->IsFunctionContext() || context->IsNativeContext() || |
205 bool is_var = *initial_value == NULL; | 201 context->IsScriptContext() || |
206 bool is_function = initial_value->IsJSFunction(); | 202 (context->IsBlockContext() && context->has_extension())); |
207 DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function)); | 203 |
204 bool is_function = value->IsJSFunction(); | |
205 bool is_var = !is_function; | |
206 DCHECK(!is_var || value->IsUndefined(isolate)); | |
208 | 207 |
209 int index; | 208 int index; |
210 PropertyAttributes attributes; | 209 PropertyAttributes attributes; |
211 BindingFlags binding_flags; | 210 BindingFlags binding_flags; |
212 | 211 |
213 if ((attr & EVAL_DECLARED) != 0) { | 212 // Check for a conflict with a lexically scoped variable |
214 // Check for a conflict with a lexically scoped variable | 213 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &binding_flags); |
215 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, | 214 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { |
216 &binding_flags); | 215 return ThrowRedeclarationError(isolate, name); |
217 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { | |
218 return ThrowRedeclarationError(isolate, name); | |
219 } | |
220 attr = static_cast<PropertyAttributes>(attr & ~EVAL_DECLARED); | |
221 } | 216 } |
222 | 217 |
223 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, | 218 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, |
224 &attributes, &binding_flags); | 219 &attributes, &binding_flags); |
225 if (holder.is_null()) { | 220 DCHECK(!isolate->has_pending_exception()); |
226 // In case of JSProxy, an exception might have been thrown. | |
227 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | |
228 } | |
229 | 221 |
230 Handle<JSObject> object; | 222 Handle<JSObject> object; |
231 Handle<Object> value = | |
232 is_function ? initial_value | |
233 : Handle<Object>::cast(isolate->factory()->undefined_value()); | |
234 | 223 |
235 // TODO(verwaest): This case should probably not be covered by this function, | |
236 // but by DeclareGlobals instead. | |
237 if (attributes != ABSENT && holder->IsJSGlobalObject()) { | 224 if (attributes != ABSENT && holder->IsJSGlobalObject()) { |
238 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, | 225 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, |
239 value, attr, is_var, is_function); | 226 value, NONE, is_var, is_function); |
240 } | 227 } |
241 if (context_arg->extension()->IsJSGlobalObject()) { | 228 if (context_arg->extension()->IsJSGlobalObject()) { |
242 Handle<JSGlobalObject> global( | 229 Handle<JSGlobalObject> global( |
243 JSGlobalObject::cast(context_arg->extension()), isolate); | 230 JSGlobalObject::cast(context_arg->extension()), isolate); |
244 return DeclareGlobals(isolate, global, name, value, attr, is_var, | 231 return DeclareGlobals(isolate, global, name, value, NONE, is_var, |
245 is_function); | 232 is_function); |
246 } else if (context->IsScriptContext()) { | 233 } else if (context->IsScriptContext()) { |
247 DCHECK(context->global_object()->IsJSGlobalObject()); | 234 DCHECK(context->global_object()->IsJSGlobalObject()); |
248 Handle<JSGlobalObject> global( | 235 Handle<JSGlobalObject> global( |
249 JSGlobalObject::cast(context->global_object()), isolate); | 236 JSGlobalObject::cast(context->global_object()), isolate); |
250 return DeclareGlobals(isolate, global, name, value, attr, is_var, | 237 return DeclareGlobals(isolate, global, name, value, NONE, is_var, |
251 is_function); | 238 is_function); |
252 } | 239 } |
253 | 240 |
254 if (attributes != ABSENT) { | 241 if (attributes != ABSENT) { |
255 // The name was declared before; check for conflicting re-declarations. | 242 DCHECK_EQ(NONE, attributes); |
256 if ((attributes & READ_ONLY) != 0) { | |
257 return ThrowRedeclarationError(isolate, name); | |
258 } | |
259 | 243 |
260 // Skip var re-declarations. | 244 // Skip var re-declarations. |
261 if (is_var) return isolate->heap()->undefined_value(); | 245 if (is_var) return isolate->heap()->undefined_value(); |
262 | 246 |
263 DCHECK(is_function); | 247 DCHECK(is_function); |
264 if (index != Context::kNotFound) { | 248 if (index != Context::kNotFound) { |
265 DCHECK(holder.is_identical_to(context)); | 249 DCHECK(holder.is_identical_to(context)); |
266 context->set(index, *initial_value); | 250 context->set(index, *value); |
267 return isolate->heap()->undefined_value(); | 251 return isolate->heap()->undefined_value(); |
268 } | 252 } |
269 | 253 |
270 object = Handle<JSObject>::cast(holder); | 254 object = Handle<JSObject>::cast(holder); |
271 | 255 |
272 } else if (context->has_extension()) { | 256 } else if (context->has_extension()) { |
273 // Sloppy varblock contexts might not have an extension object yet, | 257 // Sloppy varblock contexts might not have an extension object yet, |
274 // in which case their extension is a ScopeInfo. | 258 // in which case their extension is a ScopeInfo. |
275 if (context->extension()->IsScopeInfo()) { | 259 if (context->extension()->IsScopeInfo()) { |
276 DCHECK(context->IsBlockContext()); | 260 DCHECK(context->IsBlockContext()); |
277 object = isolate->factory()->NewJSObject( | 261 object = isolate->factory()->NewJSObject( |
278 isolate->context_extension_function()); | 262 isolate->context_extension_function()); |
279 Handle<HeapObject> extension = | 263 Handle<HeapObject> extension = |
280 isolate->factory()->NewSloppyBlockWithEvalContextExtension( | 264 isolate->factory()->NewSloppyBlockWithEvalContextExtension( |
281 handle(context->scope_info()), object); | 265 handle(context->scope_info()), object); |
282 context->set_extension(*extension); | 266 context->set_extension(*extension); |
283 } else { | 267 } else { |
284 object = handle(context->extension_object(), isolate); | 268 object = handle(context->extension_object(), isolate); |
285 } | 269 } |
286 DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); | 270 DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); |
287 } else { | 271 } else { |
288 DCHECK(context->IsFunctionContext()); | 272 DCHECK(context->IsFunctionContext()); |
289 object = | 273 object = |
290 isolate->factory()->NewJSObject(isolate->context_extension_function()); | 274 isolate->factory()->NewJSObject(isolate->context_extension_function()); |
291 context->set_extension(*object); | 275 context->set_extension(*object); |
292 } | 276 } |
293 | 277 |
294 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( | 278 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
295 object, name, value, attr)); | 279 object, name, value, NONE)); |
296 | 280 |
297 return isolate->heap()->undefined_value(); | 281 return isolate->heap()->undefined_value(); |
298 } | 282 } |
299 | 283 |
300 } // namespace | 284 RUNTIME_FUNCTION(Runtime_DeclareEvalFunction) { |
301 | |
302 | |
303 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) { | |
304 HandleScope scope(isolate); | 285 HandleScope scope(isolate); |
305 DCHECK_EQ(3, args.length()); | 286 DCHECK_EQ(2, args.length()); |
306 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 287 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
307 CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 1); | 288 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
308 CONVERT_ARG_HANDLE_CHECKED(Smi, property_attributes, 2); | 289 return DeclareEvalHelper(isolate, name, value); |
309 | |
310 PropertyAttributes attributes = | |
311 static_cast<PropertyAttributes>(property_attributes->value()); | |
312 return DeclareLookupSlot(isolate, name, initial_value, attributes); | |
313 } | 290 } |
314 | 291 |
292 RUNTIME_FUNCTION(Runtime_DeclareEvalVar) { | |
293 HandleScope scope(isolate); | |
294 DCHECK_EQ(1, args.length()); | |
295 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | |
296 return DeclareEvalHelper(isolate, name, | |
297 isolate->factory()->undefined_value()); | |
298 } | |
315 | 299 |
316 namespace { | 300 namespace { |
317 | 301 |
318 // Find the arguments of the JavaScript function invocation that called | 302 // Find the arguments of the JavaScript function invocation that called |
319 // into C++ code. Collect these in a newly allocated array of handles. | 303 // into C++ code. Collect these in a newly allocated array of handles. |
320 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, | 304 base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, |
321 int* total_argc) { | 305 int* total_argc) { |
322 // Find frame containing arguments passed to the caller. | 306 // Find frame containing arguments passed to the caller. |
323 JavaScriptFrameIterator it(isolate); | 307 JavaScriptFrameIterator it(isolate); |
324 JavaScriptFrame* frame = it.frame(); | 308 JavaScriptFrame* frame = it.frame(); |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1002 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { | 986 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { |
1003 HandleScope scope(isolate); | 987 HandleScope scope(isolate); |
1004 DCHECK_EQ(2, args.length()); | 988 DCHECK_EQ(2, args.length()); |
1005 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 989 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
1006 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 990 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
1007 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); | 991 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); |
1008 } | 992 } |
1009 | 993 |
1010 } // namespace internal | 994 } // namespace internal |
1011 } // namespace v8 | 995 } // namespace v8 |
OLD | NEW |