183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions of source code must retain the above copyright
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       notice, this list of conditions and the following disclaimer.
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions in binary form must reproduce the above
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       copyright notice, this list of conditions and the following
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       disclaimer in the documentation and/or other materials provided
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       with the distribution.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Neither the name of Google Inc. nor the names of its
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       contributors may be used to endorse or promote products derived
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       from this software without specific prior written permission.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h"
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
309fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org#include "bootstrapper.h"
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h"
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "scopeinfo.h"
3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgContext* Context::declaration_context() {
383cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  Context* current = this;
3946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  while (!current->IsFunctionContext() && !current->IsNativeContext()) {
403cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    current = current->previous();
413cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    ASSERT(current->closure() == closure());
423cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  }
433cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  return current;
443cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org}
453cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
463cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenJSBuiltinsObject* Context::builtins() {
4846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  GlobalObject* object = global_object();
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsJSGlobalObject()) {
5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return JSGlobalObject::cast(object)->builtins();
5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(object->IsJSBuiltinsObject());
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return JSBuiltinsObject::cast(object);
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgContext* Context::global_context() {
598e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Context* current = this;
608e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  while (!current->IsGlobalContext()) {
618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    current = current->previous();
628e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
638e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return current;
648e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
658e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
668e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
6746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgContext* Context::native_context() {
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fast case: the global object for this context has been set.  In
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // that case, the global object has a direct pointer to the global
7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // context.
7146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (global_object()->IsGlobalObject()) {
7246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    return global_object()->native_context();
7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
747b9eafd3a796ae40fdd9b130bb931c71c8a622d2kasperl@chromium.org
7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // During bootstrapping, the global object might not be set and we
7646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // have to search the context chain to find the native context.
77ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(Isolate::Current()->bootstrapper()->IsActive());
7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Context* current = this;
7946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  while (!current->IsNativeContext()) {
807b9eafd3a796ae40fdd9b130bb931c71c8a622d2kasperl@chromium.org    JSFunction* closure = JSFunction::cast(current->closure());
817b9eafd3a796ae40fdd9b130bb931c71c8a622d2kasperl@chromium.org    current = Context::cast(closure->context());
8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return current;
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
875a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgJSObject* Context::global_proxy() {
8846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return native_context()->global_proxy_object();
895a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
91e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
925a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgvoid Context::set_global_proxy(JSObject* object) {
9346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  native_context()->set_global_proxy_object(object);
945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
965a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgHandle<Object> Context::Lookup(Handle<String> name,
987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                               ContextLookupFlags flags,
99c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               int* index,
10080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                               PropertyAttributes* attributes,
10180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                               BindingFlags* binding_flags) {
102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = GetIsolate();
103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Context> context(this, isolate);
10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0;
106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  *index = -1;
10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  *attributes = ABSENT;
10880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  *binding_flags = MISSING_BINDING;
10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_trace_contexts) {
11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("Context::Lookup(");
11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    name->ShortPrint();
11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF(")\n");
11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  do {
11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (FLAG_trace_contexts) {
118f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org      PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
11946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      if (context->IsNativeContext()) PrintF(" (native context)");
12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("\n");
12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // 1. Check global objects, subjects of with, and extension objects.
12446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (context->IsNativeContext() ||
125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        context->IsWithContext() ||
126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        (context->IsFunctionContext() && context->has_extension())) {
127ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Handle<JSReceiver> object(
128ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org          JSReceiver::cast(context->extension()), isolate);
129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Context extension objects needs to behave as if they have no
130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // prototype.  So even if we want to follow prototype chains, we need
131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // to only do a local lookup for context extension objects.
132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          object->IsJSContextExtensionObject()) {
134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *attributes = object->GetLocalPropertyAttribute(*name);
13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *attributes = object->GetPropertyAttribute(*name);
137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
138ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      if (isolate->has_pending_exception()) return Handle<Object>();
139ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (*attributes != ABSENT) {
141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (FLAG_trace_contexts) {
142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          PrintF("=> found property in context object %p\n",
143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 reinterpret_cast<void*>(*object));
14443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        return object;
14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
14743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
14843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // 2. Check the context proper if it has slots.
1504acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (context->IsFunctionContext() || context->IsBlockContext()) {
151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Use serialized scope information of functions and blocks to search
152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // for the context index.
153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<ScopeInfo> scope_info;
1544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      if (context->IsFunctionContext()) {
155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        scope_info = Handle<ScopeInfo>(
1564acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org            context->closure()->shared()->scope_info(), isolate);
1574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      } else {
158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        scope_info = Handle<ScopeInfo>(
159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            ScopeInfo::cast(context->extension()), isolate);
1604acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      }
161b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      VariableMode mode;
162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      InitializationFlag init_flag;
163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      int slot_index = scope_info->ContextSlotIndex(*name, &mode, &init_flag);
164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS);
165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (slot_index >= 0) {
16643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (FLAG_trace_contexts) {
16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          PrintF("=> found local in context slot %d (mode = %d)\n",
168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 slot_index, mode);
16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *index = slot_index;
17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Note: Fixed context slots are statically allocated by the compiler.
17243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Statically allocated variables always have a statically known mode,
17343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // which is the mode with which they were declared when added to the
17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // scope. Thus, the DYNAMIC mode (which corresponds to dynamically
17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // declared variables that were introduced through declaration nodes)
17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // must not appear here.
17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        switch (mode) {
178b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case INTERNAL:  // Fall through.
179b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case VAR:
18080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org            *attributes = NONE;
18180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org            *binding_flags = MUTABLE_IS_INITIALIZED;
18280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org            break;
183b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case LET:
1847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            *attributes = NONE;
185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            *binding_flags = (init_flag == kNeedsInitialization)
186c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                ? MUTABLE_CHECK_INITIALIZED : MUTABLE_IS_INITIALIZED;
1877b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            break;
188b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case CONST:
1897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            *attributes = READ_ONLY;
190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            *binding_flags = (init_flag == kNeedsInitialization)
191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                ? IMMUTABLE_CHECK_INITIALIZED : IMMUTABLE_IS_INITIALIZED;
1927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            break;
193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          case CONST_HARMONY:
194394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com            *attributes = READ_ONLY;
195c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            *binding_flags = (init_flag == kNeedsInitialization)
196c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                ? IMMUTABLE_CHECK_INITIALIZED_HARMONY :
197c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                IMMUTABLE_IS_INITIALIZED_HARMONY;
198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com            break;
1998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          case MODULE:
2008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org            *attributes = READ_ONLY;
2018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org            *binding_flags = IMMUTABLE_IS_INITIALIZED_HARMONY;
2028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org            break;
203b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case DYNAMIC:
204b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case DYNAMIC_GLOBAL:
205b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case DYNAMIC_LOCAL:
206b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          case TEMPORARY:
2077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            UNREACHABLE();
2087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            break;
20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return context;
21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Check the slot corresponding to the intermediate context holding
2147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // only the function name variable.
215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (follow_context_chain && context->IsFunctionContext()) {
216394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        VariableMode mode;
217394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        int function_index = scope_info->FunctionContextSlotIndex(*name, &mode);
218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (function_index >= 0) {
21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          if (FLAG_trace_contexts) {
22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            PrintF("=> found intermediate function in context slot %d\n",
221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   function_index);
22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          *index = function_index;
22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          *attributes = READ_ONLY;
225394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          ASSERT(mode == CONST || mode == CONST_HARMONY);
226394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          *binding_flags = (mode == CONST)
227394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              ? IMMUTABLE_IS_INITIALIZED : IMMUTABLE_IS_INITIALIZED_HARMONY;
22843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          return context;
22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else if (context->IsCatchContext()) {
233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Catch contexts have the variable name in the extension slot.
234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (name->Equals(String::cast(context->extension()))) {
235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (FLAG_trace_contexts) {
236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          PrintF("=> found in catch context\n");
237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *index = Context::THROWN_OBJECT_INDEX;
239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *attributes = NONE;
240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *binding_flags = MUTABLE_IS_INITIALIZED;
241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        return context;
242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // 3. Prepare to continue with the previous (next outermost) context.
24646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (context->IsNativeContext()) {
24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      follow_context_chain = false;
2489fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    } else {
249ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      context = Handle<Context>(context->previous(), isolate);
25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } while (follow_context_chain);
25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_trace_contexts) {
25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("=> no property/slot found\n");
25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
2569fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  return Handle<Object>::null();
25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Context::AddOptimizedFunction(JSFunction* function) {
26146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(IsNativeContext());
262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
263619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org  if (FLAG_enable_slow_asserts) {
264619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org    Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
265619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org    while (!element->IsUndefined()) {
266619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org      CHECK(element != function);
267619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org      element = JSFunction::cast(element)->next_function_link();
268619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org    }
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Check that the context belongs to the weak native contexts list.
272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool found = false;
27346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Object* context = GetHeap()->native_contexts_list();
274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  while (!context->IsUndefined()) {
275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (context == this) {
276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      found = true;
277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CHECK(found);
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
283e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
284e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // If the function link field is already used then the function was
285e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // enqueued as a code flushing candidate and we remove it now.
286e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (!function->next_function_link()->IsUndefined()) {
287e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
288e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    flusher->EvictCandidate(function);
289e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
290e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
291e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  ASSERT(function->next_function_link()->IsUndefined());
292e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  function->set_next_function_link(get(OPTIMIZED_FUNCTIONS_LIST));
294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  set(OPTIMIZED_FUNCTIONS_LIST, function);
295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Context::RemoveOptimizedFunction(JSFunction* function) {
29946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(IsNativeContext());
300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Object* element = get(OPTIMIZED_FUNCTIONS_LIST);
301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  JSFunction* prev = NULL;
302a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  while (!element->IsUndefined()) {
303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    JSFunction* element_function = JSFunction::cast(element);
304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(element_function->next_function_link()->IsUndefined() ||
305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           element_function->next_function_link()->IsJSFunction());
306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (element_function == function) {
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (prev == NULL) {
308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        set(OPTIMIZED_FUNCTIONS_LIST, element_function->next_function_link());
309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        prev->set_next_function_link(element_function->next_function_link());
311a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
312ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      element_function->set_next_function_link(GetHeap()->undefined_value());
313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    prev = element_function;
316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    element = element_function->next_function_link();
317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UNREACHABLE();
319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgObject* Context::OptimizedFunctionsListHead() {
32346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(IsNativeContext());
324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return get(OPTIMIZED_FUNCTIONS_LIST);
325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Context::ClearOptimizedFunctions() {
329ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  set(OPTIMIZED_FUNCTIONS_LIST, GetHeap()->undefined_value());
330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
33356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.orgHandle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
33409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> result(error_message_for_code_gen_from_strings(),
33509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                        GetIsolate());
33609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (!result->IsUndefined()) return result;
33709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  return GetIsolate()->factory()->NewStringFromAscii(i::CStrVector(
33809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      "Code generation from strings disallowed for this context"));
33956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org}
34056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
34156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
3429fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org#ifdef DEBUG
34381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.orgbool Context::IsBootstrappingOrValidParentContext(
34481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    Object* object, Context* child) {
3459fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // During bootstrapping we allow all objects to pass as
3469fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // contexts. This is necessary to fix circular dependencies.
34709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (child->GetIsolate()->bootstrapper()->IsActive()) return true;
34881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  if (!object->IsContext()) return false;
34981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  Context* context = Context::cast(object);
35046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return context->IsNativeContext() || context->IsGlobalContext() ||
35146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org         context->IsModuleContext() || !child->IsModuleContext();
3529fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org}
3539fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
3549fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
3559fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.orgbool Context::IsBootstrappingOrGlobalObject(Object* object) {
3569fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // During bootstrapping we allow all objects to pass as global
3579fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // objects. This is necessary to fix circular dependencies.
358ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = Isolate::Current();
359ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->gc_state() != Heap::NOT_IN_GC ||
360ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->bootstrapper()->IsActive() ||
361ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      object->IsGlobalObject();
3629fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org}
3639fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org#endif
3649fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
366