OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 } else { | 395 } else { |
396 // If a property with this name does not already exist on the | 396 // If a property with this name does not already exist on the |
397 // global object add the property locally. We take special | 397 // global object add the property locally. We take special |
398 // precautions to always add it as a local property even in case | 398 // precautions to always add it as a local property even in case |
399 // of callbacks in the prototype chain (this rules out using | 399 // of callbacks in the prototype chain (this rules out using |
400 // SetProperty). Also, we must use the handle-based version to | 400 // SetProperty). Also, we must use the handle-based version to |
401 // avoid GC issues. | 401 // avoid GC issues. |
402 IgnoreAttributesAndSetLocalProperty(global, name, value, attributes); | 402 IgnoreAttributesAndSetLocalProperty(global, name, value, attributes); |
403 } | 403 } |
404 } | 404 } |
405 // Done. | 405 |
406 return Heap::undefined_value(); | 406 return Heap::undefined_value(); |
407 } | 407 } |
408 | 408 |
409 | 409 |
410 static Object* Runtime_DeclareContextSlot(Arguments args) { | 410 static Object* Runtime_DeclareContextSlot(Arguments args) { |
411 HandleScope scope; | 411 HandleScope scope; |
412 ASSERT(args.length() == 5); | 412 ASSERT(args.length() == 4); |
413 | 413 |
414 // args[0] is result (TOS) | 414 CONVERT_ARG_CHECKED(Context, context, 0); |
415 CONVERT_ARG_CHECKED(Context, context, 1); | 415 Handle<String> name(String::cast(args[1])); |
416 Handle<String> name(String::cast(args[2])); | |
417 PropertyAttributes mode = | 416 PropertyAttributes mode = |
418 static_cast<PropertyAttributes>(Smi::cast(args[3])->value()); | 417 static_cast<PropertyAttributes>(Smi::cast(args[2])->value()); |
419 ASSERT(mode == READ_ONLY || mode == NONE); | 418 ASSERT(mode == READ_ONLY || mode == NONE); |
420 Handle<Object> initial_value(args[4]); | 419 Handle<Object> initial_value(args[3]); |
421 | 420 |
422 // Declarations are always done in the function context. | 421 // Declarations are always done in the function context. |
423 context = Handle<Context>(context->fcontext()); | 422 context = Handle<Context>(context->fcontext()); |
424 | 423 |
425 int index; | 424 int index; |
426 PropertyAttributes attributes; | 425 PropertyAttributes attributes; |
427 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; | 426 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; |
428 Handle<Object> context_obj = | 427 Handle<Object> context_obj = |
429 context->Lookup(name, flags, &index, &attributes); | 428 context->Lookup(name, flags, &index, &attributes); |
430 | 429 |
(...skipping 18 matching lines...) Expand all Loading... |
449 if (((attributes & READ_ONLY) == 0) || | 448 if (((attributes & READ_ONLY) == 0) || |
450 context->get(index)->IsTheHole()) { | 449 context->get(index)->IsTheHole()) { |
451 context->set(index, *initial_value); | 450 context->set(index, *initial_value); |
452 } | 451 } |
453 } else { | 452 } else { |
454 // Slow case: The property is not in the FixedArray part of the context. | 453 // Slow case: The property is not in the FixedArray part of the context. |
455 Handle<JSObject> context_ext = Handle<JSObject>::cast(context_obj); | 454 Handle<JSObject> context_ext = Handle<JSObject>::cast(context_obj); |
456 SetProperty(context_ext, name, initial_value, mode); | 455 SetProperty(context_ext, name, initial_value, mode); |
457 } | 456 } |
458 } | 457 } |
459 return args[0]; // return TOS | 458 |
| 459 } else { |
| 460 // The property is not in the function context. It needs to be |
| 461 // "declared" in the function context's extension context, or in the |
| 462 // global context. |
| 463 Handle<JSObject> context_ext; |
| 464 if (context->extension() != NULL) { |
| 465 // The function context's extension context exists - use it. |
| 466 context_ext = Handle<JSObject>(context->extension()); |
| 467 } else { |
| 468 // The function context's extension context does not exists - allocate |
| 469 // it. |
| 470 context_ext = Factory::NewJSObject(Top::context_extension_function()); |
| 471 // And store it in the extension slot. |
| 472 context->set_extension(*context_ext); |
| 473 } |
| 474 ASSERT(*context_ext != NULL); |
| 475 |
| 476 // Declare the property by setting it to the initial value if provided, |
| 477 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for |
| 478 // constant declarations). |
| 479 ASSERT(!context_ext->HasLocalProperty(*name)); |
| 480 Handle<Object> value(Heap::undefined_value()); |
| 481 if (*initial_value != NULL) value = initial_value; |
| 482 SetProperty(context_ext, name, value, mode); |
| 483 ASSERT(context_ext->GetLocalPropertyAttribute(*name) == mode); |
460 } | 484 } |
461 | 485 |
462 // The property is not in the function context. It needs to be "declared" | 486 return Heap::undefined_value(); |
463 // in the function context's extension context, or in the global context. | |
464 Handle<JSObject> context_ext; | |
465 if (context->extension() != NULL) { | |
466 // The function context's extension context exists - use it. | |
467 context_ext = Handle<JSObject>(context->extension()); | |
468 } else { | |
469 // The function context's extension context does not exists - allocate it. | |
470 context_ext = Factory::NewJSObject(Top::context_extension_function()); | |
471 // And store it in the extension slot. | |
472 context->set_extension(*context_ext); | |
473 } | |
474 ASSERT(*context_ext != NULL); | |
475 | |
476 // Declare the property by setting it to the initial value if provided, | |
477 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for | |
478 // constant declarations). | |
479 ASSERT(!context_ext->HasLocalProperty(*name)); | |
480 Handle<Object> value(Heap::undefined_value()); | |
481 if (*initial_value != NULL) value = initial_value; | |
482 SetProperty(context_ext, name, value, mode); | |
483 ASSERT(context_ext->GetLocalPropertyAttribute(*name) == mode); | |
484 return args[0]; // return TOS | |
485 } | 487 } |
486 | 488 |
487 | 489 |
488 static Object* Runtime_InitializeVarGlobal(Arguments args) { | 490 static Object* Runtime_InitializeVarGlobal(Arguments args) { |
489 NoHandleAllocation nha; | 491 NoHandleAllocation nha; |
490 | 492 |
491 // Determine if we need to assign to the variable if it already | 493 // Determine if we need to assign to the variable if it already |
492 // exists (based on the number of arguments). | 494 // exists (based on the number of arguments). |
493 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); | 495 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); |
494 bool assign = args.length() == 2; | 496 bool assign = args.length() == 2; |
(...skipping 4561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5056 | 5058 |
5057 void Runtime::PerformGC(Object* result) { | 5059 void Runtime::PerformGC(Object* result) { |
5058 Failure* failure = Failure::cast(result); | 5060 Failure* failure = Failure::cast(result); |
5059 // Try to do a garbage collection; ignore it if it fails. The C | 5061 // Try to do a garbage collection; ignore it if it fails. The C |
5060 // entry stub will throw an out-of-memory exception in that case. | 5062 // entry stub will throw an out-of-memory exception in that case. |
5061 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); | 5063 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); |
5062 } | 5064 } |
5063 | 5065 |
5064 | 5066 |
5065 } } // namespace v8::internal | 5067 } } // namespace v8::internal |
OLD | NEW |