19258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// Copyright 2007-2008 the V8 project authors. All rights reserved.
29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Redistribution and use in source and binary forms, with or without
39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// modification, are permitted provided that the following conditions are
49a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// met:
59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Redistributions of source code must retain the above copyright
79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       notice, this list of conditions and the following disclaimer.
89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Redistributions in binary form must reproduce the above
99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       copyright notice, this list of conditions and the following
109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       disclaimer in the documentation and/or other materials provided
119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       with the distribution.
129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Neither the name of Google Inc. nor the names of its
139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       contributors may be used to endorse or promote products derived
149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       from this software without specific prior written permission.
159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include <stdlib.h>
299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/heap.h"
33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h"
349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
359a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comusing namespace v8;
369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
379a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comenum Expectations {
399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  EXPECT_RESULT,
4046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  EXPECT_EXCEPTION,
4146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  EXPECT_ERROR
429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// A DeclarationContext holds a reference to a v8::Context and keeps
469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// track of various declaration related counters to make it easier to
479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// track if global declarations in the presence of interceptors behave
489a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// the right way.
499a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comclass DeclarationContext {
509a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com public:
519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  DeclarationContext();
529a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  virtual ~DeclarationContext() {
549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (is_initialized_) {
55528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Isolate* isolate = CcTest::isolate();
56c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      HandleScope scope(isolate);
57c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      Local<Context> context = Local<Context>::New(isolate, context_);
58c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      context->Exit();
59f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      context_.Reset();
609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  void Check(const char* source,
649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com             int get, int set, int has,
659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com             Expectations expectations,
669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com             v8::Handle<Value> value = Local<Value>());
679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int get_count() const { return get_count_; }
699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int set_count() const { return set_count_; }
701af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  int query_count() const { return query_count_; }
719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com protected:
739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  virtual v8::Handle<Value> Get(Local<String> key);
749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  virtual v8::Handle<Value> Set(Local<String> key, Local<Value> value);
751af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  virtual v8::Handle<Integer> Query(Local<String> key);
769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  void InitializeIfNeeded();
789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
79de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // Perform optional initialization steps on the context after it has
80de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // been created. Defaults to none but may be overwritten.
81de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  virtual void PostInitializeContext(Handle<Context> context) {}
82de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Get the holder for the interceptor. Default to the instance template
849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // but may be overwritten.
859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    return function->InstanceTemplate();
879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // The handlers are called as static functions that forward
909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // to the instance specific virtual methods.
911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void HandleGet(Local<String> key,
921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                        const v8::PropertyCallbackInfo<v8::Value>& info);
931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void HandleSet(Local<String> key,
941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                        Local<Value> value,
951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                        const v8::PropertyCallbackInfo<v8::Value>& info);
961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static void HandleQuery(Local<String> key,
971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                          const v8::PropertyCallbackInfo<v8::Integer>& info);
989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
990f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  v8::Isolate* isolate() const { return CcTest::isolate(); }
1000f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
1019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com private:
1029a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  bool is_initialized_;
1039a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Persistent<Context> context_;
1049a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1059a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int get_count_;
1069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int set_count_;
1071af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  int query_count_;
1089a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  static DeclarationContext* GetInstance(Local<Value> data);
1109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
1119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comDeclarationContext::DeclarationContext()
1141af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) {
1159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Do nothing.
1169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comvoid DeclarationContext::InitializeIfNeeded() {
1209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (is_initialized_) return;
121528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = CcTest::isolate();
12257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  HandleScope scope(isolate);
1234f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Local<FunctionTemplate> function = FunctionTemplate::New(isolate);
1240cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  Local<Value> data = External::New(CcTest::isolate(), this);
1259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  GetHolder(function)->SetNamedPropertyHandler(&HandleGet,
1269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                               &HandleSet,
1271af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org                                               &HandleQuery,
1289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                               0, 0,
1299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                               data);
130c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  Local<Context> context = Context::New(isolate,
131c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                        0,
132c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                        function->InstanceTemplate(),
133c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                        Local<Value>());
134c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  context_.Reset(isolate, context);
135c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  context->Enter();
1369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  is_initialized_ = true;
137c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  PostInitializeContext(context);
1389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comvoid DeclarationContext::Check(const char* source,
1421af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org                               int get, int set, int query,
1439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                               Expectations expectations,
1449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                               v8::Handle<Value> value) {
1459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  InitializeIfNeeded();
1469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // A retry after a GC may pollute the counts, so perform gc now
1479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // to avoid that.
148528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE);
149528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(CcTest::isolate());
1509a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  TryCatch catcher;
1519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  catcher.SetVerbose(true);
152f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Local<Script> script =
153f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      Script::Compile(String::NewFromUtf8(CcTest::isolate(), source));
15446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (expectations == EXPECT_ERROR) {
15546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    CHECK(script.IsEmpty());
15646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    return;
15746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
15846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  CHECK(!script.IsEmpty());
15946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Local<Value> result = script->Run();
1609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  CHECK_EQ(get, get_count());
1619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  CHECK_EQ(set, set_count());
1621af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  CHECK_EQ(query, query_count());
1639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (expectations == EXPECT_RESULT) {
1649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    CHECK(!catcher.HasCaught());
1659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (!value.IsEmpty()) {
1669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      CHECK_EQ(value, result);
1679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
1689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  } else {
1699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    CHECK(expectations == EXPECT_EXCEPTION);
1709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    CHECK(catcher.HasCaught());
1719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (!value.IsEmpty()) {
1729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      CHECK_EQ(value, catcher.Exception());
1739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
1749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
175528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Clean slate for the next test.
176528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest::heap()->CollectAllAvailableGarbage();
1779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1799a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DeclarationContext::HandleGet(
1811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Local<String> key,
1821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    const v8::PropertyCallbackInfo<v8::Value>& info) {
1831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  DeclarationContext* context = GetInstance(info.Data());
1849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  context->get_count_++;
1851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  info.GetReturnValue().Set(context->Get(key));
1869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DeclarationContext::HandleSet(
1901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Local<String> key,
1911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Local<Value> value,
1921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    const v8::PropertyCallbackInfo<v8::Value>& info) {
1931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  DeclarationContext* context = GetInstance(info.Data());
1949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  context->set_count_++;
1951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  info.GetReturnValue().Set(context->Set(key, value));
1969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid DeclarationContext::HandleQuery(
2001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Local<String> key,
2011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    const v8::PropertyCallbackInfo<v8::Integer>& info) {
2021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  DeclarationContext* context = GetInstance(info.Data());
2031af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  context->query_count_++;
2041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  info.GetReturnValue().Set(context->Query(key));
2059a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2079a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDeclarationContext* DeclarationContext::GetInstance(Local<Value> data) {
2091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void* value = Local<External>::Cast(data)->Value();
210eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  return static_cast<DeclarationContext*>(value);
2119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comv8::Handle<Value> DeclarationContext::Get(Local<String> key) {
2159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return v8::Handle<Value>();
2169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comv8::Handle<Value> DeclarationContext::Set(Local<String> key,
2209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                          Local<Value> value) {
2219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return v8::Handle<Value>();
2229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2251af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgv8::Handle<Integer> DeclarationContext::Query(Local<String> key) {
2261af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  return v8::Handle<Integer>();
2279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Test global declaration of a property the interceptor doesn't know
2319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// about and doesn't handle.
2329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(Unknown) {
233528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(CcTest::isolate());
234cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  v8::V8::Initialize();
2359a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { DeclarationContext context;
2379a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x; x",
2389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
2399bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
2409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { DeclarationContext context;
2439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x = 0; x",
2449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
2459bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  1,  // initialization
2469bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
2479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2489a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2499a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { DeclarationContext context;
2509a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("function x() { }; x",
2519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
2523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                  0,
2539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
2549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  EXPECT_RESULT);
2559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { DeclarationContext context;
2589a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x; x",
2599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
2609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
2619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { DeclarationContext context;
2649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x = 0; x",
2659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
2663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                  0,
2679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
2680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
2699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comclass AbsentPropertyContext: public DeclarationContext {
2749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com protected:
2751af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  virtual v8::Handle<Integer> Query(Local<String> key) {
2761af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    return v8::Handle<Integer>();
2779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
2799a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2809a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(Absent) {
282cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  v8::Isolate* isolate = CcTest::isolate();
283cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  v8::V8::Initialize();
284cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  HandleScope scope(isolate);
2859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AbsentPropertyContext context;
2879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x; x",
2889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
2899bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Undefined(isolate));
2909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2919a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2929a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AbsentPropertyContext context;
2939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x = 0; x",
2949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
2959bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  1,  // initialization
2969bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, EXPECT_RESULT, Number::New(isolate, 0));
2979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
2989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AbsentPropertyContext context;
3009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("function x() { }; x",
3019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
3023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                  0,
3039a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
3049a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  EXPECT_RESULT);
3059a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3079a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AbsentPropertyContext context;
3089a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x; x",
3099a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
3109bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Undefined(isolate));
3119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AbsentPropertyContext context;
3149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x = 0; x",
3159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
3169bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Number::New(isolate, 0));
3179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AbsentPropertyContext context;
3209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("if (false) { var x = 0 }; x",
3219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
3229bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Undefined(isolate));
3239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
3259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comclass AppearingPropertyContext: public DeclarationContext {
3299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com public:
3309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  enum State {
3319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    DECLARE,
3329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    INITIALIZE_IF_ASSIGN,
3339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    UNKNOWN
3349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  };
3359a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  AppearingPropertyContext() : state_(DECLARE) { }
3379a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com protected:
3391af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  virtual v8::Handle<Integer> Query(Local<String> key) {
3409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    switch (state_) {
3419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      case DECLARE:
3429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        // Force declaration by returning that the
3439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        // property is absent.
3449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        state_ = INITIALIZE_IF_ASSIGN;
3451af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org        return Handle<Integer>();
3469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      case INITIALIZE_IF_ASSIGN:
3479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        // Return that the property is present so we only get the
3489a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        // setter called when initializing with a value.
3499a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        state_ = UNKNOWN;
3500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        return Integer::New(isolate(), v8::None);
3519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      default:
3523a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org        CHECK(state_ == UNKNOWN);
3539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        break;
3549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
3559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    // Do the lookup in the object.
3561af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    return v8::Handle<Integer>();
3579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3589a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com private:
3609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  State state_;
3619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
3629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(Appearing) {
365cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  v8::V8::Initialize();
366528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(CcTest::isolate());
3679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AppearingPropertyContext context;
3699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x; x",
3709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
3719bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
3729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AppearingPropertyContext context;
3759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x = 0; x",
3769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
3779bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  1,  // initialization
3789bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
3799a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3809a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AppearingPropertyContext context;
3829a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("function x() { }; x",
3839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  1,  // access
3843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                  0,
3859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
3869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  EXPECT_RESULT);
3879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AppearingPropertyContext context;
3909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x; x",
391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  1,  // access
3929bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
3939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3959a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AppearingPropertyContext context;
3969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x = 0; x",
397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  1,  // access
3989bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  0, 0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
3999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
4019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4029a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4039a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4049a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comclass ExistsInPrototypeContext: public DeclarationContext {
4050f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org public:
4060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  ExistsInPrototypeContext() { InitializeIfNeeded(); }
4079a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com protected:
4081af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  virtual v8::Handle<Integer> Query(Local<String> key) {
4099a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    // Let it seem that the property exists in the prototype object.
4100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    return Integer::New(isolate(), v8::None);
4119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Use the prototype as the holder for the interceptors.
4149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
4159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    return function->PrototypeTemplate();
4169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
4189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(ExistsInPrototype) {
421528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(CcTest::isolate());
4229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Sanity check to make sure that the holder of the interceptor
4249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // really is the prototype object.
4259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { ExistsInPrototypeContext context;
426474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    context.Check("this.x = 87; this.x", 0, 0, 1, EXPECT_RESULT,
427474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                  Number::New(CcTest::isolate(), 87));
4289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { ExistsInPrototypeContext context;
4319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x; x",
4329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
433de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
434de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
435cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org                  EXPECT_RESULT, Undefined(CcTest::isolate()));
4369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4379a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { ExistsInPrototypeContext context;
4399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("var x = 0; x",
4409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
4419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
442de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
4430f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
4449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { ExistsInPrototypeContext context;
4479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x; x",
4489a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
4499a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
450de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
451cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org                  EXPECT_RESULT, Undefined(CcTest::isolate()));
4529a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { ExistsInPrototypeContext context;
4559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("const x = 0; x",
4569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
4579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
458de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
4590f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
4609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
4629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comclass AbsentInPrototypeContext: public DeclarationContext {
4669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com protected:
4671af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  virtual v8::Handle<Integer> Query(Local<String> key) {
4689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    // Let it seem that the property is absent in the prototype object.
4691af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    return Handle<Integer>();
4709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Use the prototype as the holder for the interceptors.
4739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
4749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    return function->PrototypeTemplate();
4759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
4779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4799a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(AbsentInPrototype) {
480cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  v8::V8::Initialize();
481528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(CcTest::isolate());
4829a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  { AbsentInPrototypeContext context;
4849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    context.Check("if (false) { var x = 0; }; x",
4859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
4869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                  0,
487de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
488cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org                  EXPECT_RESULT, Undefined(CcTest::isolate()));
4899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
4909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
491de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
492de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
493de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
494de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.orgclass ExistsInHiddenPrototypeContext: public DeclarationContext {
495de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org public:
496de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  ExistsInHiddenPrototypeContext() {
4974f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    hidden_proto_ = FunctionTemplate::New(CcTest::isolate());
498de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    hidden_proto_->SetHiddenPrototype(true);
499de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
500de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
501de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org protected:
502de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  virtual v8::Handle<Integer> Query(Local<String> key) {
503de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // Let it seem that the property exists in the hidden prototype object.
5040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    return Integer::New(isolate(), v8::None);
505de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
506de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
507de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // Install the hidden prototype after the global object has been created.
508de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  virtual void PostInitializeContext(Handle<Context> context) {
509de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    Local<Object> global_object = context->Global();
510de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance();
511113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org    Local<Object> inner_global =
512113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org        Local<Object>::Cast(global_object->GetPrototype());
513113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org    inner_global->SetPrototype(hidden_proto);
514de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
515de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
516de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // Use the hidden prototype as the holder for the interceptors.
517de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
518de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    return hidden_proto_->InstanceTemplate();
519de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
520de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
521de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org private:
522de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  Local<FunctionTemplate> hidden_proto_;
523de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org};
524de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
525de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
526de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.orgTEST(ExistsInHiddenPrototype) {
527528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(CcTest::isolate());
528de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
529de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  { ExistsInHiddenPrototypeContext context;
5309bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    context.Check("var x; x", 0, 0, 0, EXPECT_RESULT,
5319bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  Undefined(CcTest::isolate()));
532de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
533de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
534de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  { ExistsInHiddenPrototypeContext context;
5359bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    context.Check("var x = 0; x", 0, 0, 0, EXPECT_RESULT,
5369bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  Number::New(CcTest::isolate(), 0));
537de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
538de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
539de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  { ExistsInHiddenPrototypeContext context;
540de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    context.Check("function x() { }; x",
541de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
542de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
543de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  0,
544de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org                  EXPECT_RESULT);
545de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
546de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
547de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // TODO(mstarzinger): The semantics of global const is vague.
548de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  { ExistsInHiddenPrototypeContext context;
5499bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    context.Check("const x; x", 0, 0, 0, EXPECT_RESULT,
5509bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  Undefined(CcTest::isolate()));
551de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
552de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
553de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  // TODO(mstarzinger): The semantics of global const is vague.
554de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  { ExistsInHiddenPrototypeContext context;
5559bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    context.Check("const x = 0; x", 0, 0, 0, EXPECT_RESULT,
5569bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                  Number::New(CcTest::isolate(), 0));
557de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  }
558de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org}
55946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
56046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
56146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
56246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgclass SimpleContext {
56346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org public:
56457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  SimpleContext()
565528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      : handle_scope_(CcTest::isolate()),
566528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        context_(Context::New(CcTest::isolate())) {
56746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context_->Enter();
56846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
56946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
57057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ~SimpleContext() {
57146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context_->Exit();
57246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
57346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
57446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void Check(const char* source,
57546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org             Expectations expectations,
57646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org             v8::Handle<Value> value = Local<Value>()) {
5772bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    HandleScope scope(context_->GetIsolate());
57846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    TryCatch catcher;
57946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    catcher.SetVerbose(true);
580f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Local<Script> script =
581f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        Script::Compile(String::NewFromUtf8(context_->GetIsolate(), source));
58246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (expectations == EXPECT_ERROR) {
58346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      CHECK(script.IsEmpty());
58446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return;
58546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
58646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    CHECK(!script.IsEmpty());
58746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    Local<Value> result = script->Run();
58846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (expectations == EXPECT_RESULT) {
58946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      CHECK(!catcher.HasCaught());
59046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      if (!value.IsEmpty()) {
59146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        CHECK_EQ(value, result);
59246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
59346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    } else {
59446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      CHECK(expectations == EXPECT_EXCEPTION);
59546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      CHECK(catcher.HasCaught());
59646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      if (!value.IsEmpty()) {
59746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        CHECK_EQ(value, catcher.Exception());
59846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
59946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
60046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
60146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
60246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org private:
60357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  HandleScope handle_scope_;
60457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Local<Context> context_;
60546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org};
60646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
60746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
6088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgTEST(CrossScriptReferences) {
6090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  v8::Isolate* isolate = CcTest::isolate();
6100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HandleScope scope(isolate);
61146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
61246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  { SimpleContext context;
61346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("var x = 1; x",
6140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 1));
61546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("var x = 2; x",
6160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 2));
6179bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    context.Check("const x = 3; x", EXPECT_EXCEPTION);
6189bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    context.Check("const x = 4; x", EXPECT_EXCEPTION);
61946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("x = 5; x",
6200f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 5));
62146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("var x = 6; x",
6220f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 6));
62346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("this.x",
6240f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 6));
62546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("function x() { return 7 }; x()",
6260f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 7));
62746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
62846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
62946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  { SimpleContext context;
63046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("const x = 1; x",
6310f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 1));
63246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("var x = 2; x",  // assignment ignored
6330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 1));
6349bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    context.Check("const x = 3; x", EXPECT_EXCEPTION);
63546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("x = 4; x",  // assignment ignored
6360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 1));
63746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("var x = 5; x",  // assignment ignored
6380f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 1));
63946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("this.x",
6400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  EXPECT_RESULT, Number::New(isolate, 1));
64146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    context.Check("function x() { return 7 }; x",
64246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                  EXPECT_EXCEPTION);
64346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
6448e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
6458e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
64646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
6478e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgTEST(CrossScriptReferencesHarmony) {
64846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  i::FLAG_use_strict = true;
64946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  i::FLAG_harmony_scoping = true;
6508e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  i::FLAG_harmony_modules = true;
65146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
6520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  v8::Isolate* isolate = CcTest::isolate();
6530f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HandleScope scope(isolate);
654355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
6558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  const char* decs[] = {
6568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "var x = 1; x", "x", "this.x",
6578e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "function x() { return 1 }; x()", "x()", "this.x()",
6588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "let x = 1; x", "x", "this.x",
6598e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "const x = 1; x", "x", "this.x",
6608e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "module x { export let a = 1 }; x.a", "x.a", "this.x.a",
6618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    NULL
6628e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  };
66346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
6648e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  for (int i = 0; decs[i] != NULL; i += 3) {
6658e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    SimpleContext context;
6660f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    context.Check(decs[i], EXPECT_RESULT, Number::New(isolate, 1));
6670f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    context.Check(decs[i+1], EXPECT_RESULT, Number::New(isolate, 1));
668355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // TODO(rossberg): The current ES6 draft spec does not reflect lexical
669355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // bindings on the global object. However, this will probably change, in
670355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // which case we reactivate the following test.
6710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (i/3 < 2) {
6720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      context.Check(decs[i+2], EXPECT_RESULT, Number::New(isolate, 1));
6730f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
67446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
6758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
67646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
67746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
6788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgTEST(CrossScriptConflicts) {
6798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  i::FLAG_use_strict = true;
6808e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  i::FLAG_harmony_scoping = true;
6818e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  i::FLAG_harmony_modules = true;
68246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
683528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(CcTest::isolate());
68446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
6858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  const char* firsts[] = {
6868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "var x = 1; x",
6878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "function x() { return 1 }; x()",
6888e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "let x = 1; x",
6898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "const x = 1; x",
6908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "module x { export let a = 1 }; x.a",
6918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    NULL
6928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  };
6938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  const char* seconds[] = {
6948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "var x = 2; x",
6958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "function x() { return 2 }; x()",
6968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "let x = 2; x",
6978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "const x = 2; x",
6988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    "module x { export let a = 2 }; x.a",
6998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    NULL
7008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  };
70146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
7028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  for (int i = 0; firsts[i] != NULL; ++i) {
7038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    for (int j = 0; seconds[j] != NULL; ++j) {
7048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      SimpleContext context;
7050f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      context.Check(firsts[i], EXPECT_RESULT,
7060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    Number::New(CcTest::isolate(), 1));
7078e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      // TODO(rossberg): All tests should actually be errors in Harmony,
7088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      // but we currently do not detect the cases where the first declaration
7098e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      // is not lexical.
7108e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      context.Check(seconds[j],
7110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    i < 2 ? EXPECT_RESULT : EXPECT_ERROR,
7120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    Number::New(CcTest::isolate(), 2));
7138e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
71446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
71546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
716