// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/flags/flags.h"

#include "test/cctest/cctest.h"

namespace {

using v8::Context;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::MaybeLocal;
using v8::Module;
using v8::Promise;
using v8::ScriptCompiler;
using v8::ScriptOrigin;
using v8::String;
using v8::Value;

ScriptOrigin ModuleOrigin(Local<v8::Value> resource_name, Isolate* isolate) {
  ScriptOrigin origin(resource_name, Local<v8::Integer>(), Local<v8::Integer>(),
                      Local<v8::Boolean>(), Local<v8::Integer>(),
                      Local<v8::Value>(), Local<v8::Boolean>(),
                      Local<v8::Boolean>(), True(isolate));
  return origin;
}

static Local<Module> dep1;
static Local<Module> dep2;
MaybeLocal<Module> ResolveCallback(Local<Context> context,
                                   Local<String> specifier,
                                   Local<Module> referrer) {
  Isolate* isolate = CcTest::isolate();
  if (specifier->StrictEquals(v8_str("./dep1.js"))) {
    return dep1;
  } else if (specifier->StrictEquals(v8_str("./dep2.js"))) {
    return dep2;
  } else {
    isolate->ThrowException(v8_str("boom"));
    return MaybeLocal<Module>();
  }
}

TEST(ModuleInstantiationFailures1) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;
    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    Local<Module> module;
    {
      Local<String> source_text = v8_str(
          "import './foo.js';\n"
          "export {} from './bar.js';");
      ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      module = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
      CHECK_EQ(Module::kUninstantiated, module->GetStatus());
      CHECK_EQ(2, module->GetModuleRequestsLength());
      CHECK(v8_str("./foo.js")->StrictEquals(module->GetModuleRequest(0)));
      v8::Location loc = module->GetModuleRequestLocation(0);
      CHECK_EQ(0, loc.GetLineNumber());
      CHECK_EQ(7, loc.GetColumnNumber());
      CHECK(v8_str("./bar.js")->StrictEquals(module->GetModuleRequest(1)));
      loc = module->GetModuleRequestLocation(1);
      CHECK_EQ(1, loc.GetLineNumber());
      CHECK_EQ(15, loc.GetColumnNumber());
    }

    // Instantiation should fail.
    {
      v8::TryCatch inner_try_catch(isolate);
      CHECK(
          module->InstantiateModule(env.local(), ResolveCallback).IsNothing());
      CHECK(inner_try_catch.HasCaught());
      CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
      CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    }

    // Start over again...
    {
      Local<String> source_text = v8_str(
          "import './dep1.js';\n"
          "export {} from './bar.js';");
      ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      module = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    }

    // dep1.js
    {
      Local<String> source_text = v8_str("");
      ScriptOrigin origin = ModuleOrigin(v8_str("dep1.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      dep1 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    }

    // Instantiation should fail because a sub-module fails to resolve.
    {
      v8::TryCatch inner_try_catch(isolate);
      CHECK(
          module->InstantiateModule(env.local(), ResolveCallback).IsNothing());
      CHECK(inner_try_catch.HasCaught());
      CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
      CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    }

    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

TEST(ModuleInstantiationFailures2) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;

    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    // root1.js
    Local<Module> root;
    {
      Local<String> source_text =
          v8_str("import './dep1.js'; import './dep2.js'");
      ScriptOrigin origin = ModuleOrigin(v8_str("root1.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      root = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    }

    // dep1.js
    {
      Local<String> source_text = v8_str("export let x = 42");
      ScriptOrigin origin = ModuleOrigin(v8_str("dep1.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      dep1 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    }

    // dep2.js
    {
      Local<String> source_text = v8_str("import {foo} from './dep3.js'");
      ScriptOrigin origin = ModuleOrigin(v8_str("dep2.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      dep2 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    }

    {
      v8::TryCatch inner_try_catch(isolate);
      CHECK(root->InstantiateModule(env.local(), ResolveCallback).IsNothing());
      CHECK(inner_try_catch.HasCaught());
      CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
      CHECK_EQ(Module::kUninstantiated, root->GetStatus());
      CHECK_EQ(Module::kUninstantiated, dep1->GetStatus());
      CHECK_EQ(Module::kUninstantiated, dep2->GetStatus());
    }

    // Change dep2.js
    {
      Local<String> source_text = v8_str("import {foo} from './dep2.js'");
      ScriptOrigin origin = ModuleOrigin(v8_str("dep2.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      dep2 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    }

    {
      v8::TryCatch inner_try_catch(isolate);
      CHECK(root->InstantiateModule(env.local(), ResolveCallback).IsNothing());
      CHECK(inner_try_catch.HasCaught());
      CHECK(!inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
      CHECK_EQ(Module::kUninstantiated, root->GetStatus());
      CHECK_EQ(Module::kInstantiated, dep1->GetStatus());
      CHECK_EQ(Module::kUninstantiated, dep2->GetStatus());
    }

    // Change dep2.js again
    {
      Local<String> source_text = v8_str("import {foo} from './dep3.js'");
      ScriptOrigin origin = ModuleOrigin(v8_str("dep2.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      dep2 = ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    }

    {
      v8::TryCatch inner_try_catch(isolate);
      CHECK(root->InstantiateModule(env.local(), ResolveCallback).IsNothing());
      CHECK(inner_try_catch.HasCaught());
      CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
      CHECK_EQ(Module::kUninstantiated, root->GetStatus());
      CHECK_EQ(Module::kInstantiated, dep1->GetStatus());
      CHECK_EQ(Module::kUninstantiated, dep2->GetStatus());
    }
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

static MaybeLocal<Module> CompileSpecifierAsModuleResolveCallback(
    Local<Context> context, Local<String> specifier, Local<Module> referrer) {
  ScriptOrigin origin = ModuleOrigin(v8_str("module.js"), CcTest::isolate());
  ScriptCompiler::Source source(specifier, origin);
  return ScriptCompiler::CompileModule(CcTest::isolate(), &source)
      .ToLocalChecked();
}

TEST(ModuleEvaluation) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;

    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    Local<String> source_text = v8_str(
        "import 'Object.expando = 5';"
        "import 'Object.expando *= 2';");
    ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    CHECK(module
              ->InstantiateModule(env.local(),
                                  CompileSpecifierAsModuleResolveCallback)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());

    MaybeLocal<Value> result = module->Evaluate(env.local());
    CHECK_EQ(Module::kEvaluated, module->GetStatus());
    if (i::FLAG_harmony_top_level_await) {
      Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked());
      CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
      CHECK(promise->Result()->IsUndefined());
    } else {
      CHECK(!result.IsEmpty());
      ExpectInt32("Object.expando", 10);
    }
    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

TEST(ModuleEvaluationError1) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;

    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    Local<String> source_text =
        v8_str("Object.x = (Object.x || 0) + 1; throw 'boom';");
    ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    CHECK(module
              ->InstantiateModule(env.local(),
                                  CompileSpecifierAsModuleResolveCallback)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());

    {
      v8::TryCatch inner_try_catch(isolate);
      MaybeLocal<Value> result = module->Evaluate(env.local());
      CHECK_EQ(Module::kErrored, module->GetStatus());
      Local<Value> exception = module->GetException();
      CHECK(exception->StrictEquals(v8_str("boom")));
      ExpectInt32("Object.x", 1);

      if (i::FLAG_harmony_top_level_await) {
        // With top level await, we do not throw and errored evaluation returns
        // a rejected promise with the exception.
        CHECK(!inner_try_catch.HasCaught());
        Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked());
        CHECK_EQ(promise->State(), v8::Promise::kRejected);
        CHECK_EQ(promise->Result(), module->GetException());
      } else {
        CHECK(inner_try_catch.HasCaught());
        CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
        CHECK(result.IsEmpty());
      }
    }

    {
      v8::TryCatch inner_try_catch(isolate);
      MaybeLocal<Value> result = module->Evaluate(env.local());
      CHECK_EQ(Module::kErrored, module->GetStatus());
      Local<Value> exception = module->GetException();
      CHECK(exception->StrictEquals(v8_str("boom")));
      ExpectInt32("Object.x", 1);

      if (i::FLAG_harmony_top_level_await) {
        // With top level await, we do not throw and errored evaluation returns
        // a rejected promise with the exception.
        CHECK(!inner_try_catch.HasCaught());
        Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked());
        CHECK_EQ(promise->State(), v8::Promise::kRejected);
        CHECK_EQ(promise->Result(), module->GetException());
      } else {
        CHECK(inner_try_catch.HasCaught());
        CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
        CHECK(result.IsEmpty());
      }
    }

    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

static Local<Module> failure_module;
static Local<Module> dependent_module;
MaybeLocal<Module> ResolveCallbackForModuleEvaluationError2(
    Local<Context> context, Local<String> specifier, Local<Module> referrer) {
  if (specifier->StrictEquals(v8_str("./failure.js"))) {
    return failure_module;
  } else {
    CHECK(specifier->StrictEquals(v8_str("./dependent.js")));
    return dependent_module;
  }
}

TEST(ModuleEvaluationError2) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;

    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    Local<String> failure_text = v8_str("throw 'boom';");
    ScriptOrigin failure_origin =
        ModuleOrigin(v8_str("failure.js"), CcTest::isolate());
    ScriptCompiler::Source failure_source(failure_text, failure_origin);
    failure_module = ScriptCompiler::CompileModule(isolate, &failure_source)
                         .ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, failure_module->GetStatus());
    CHECK(failure_module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForModuleEvaluationError2)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, failure_module->GetStatus());

    {
      v8::TryCatch inner_try_catch(isolate);
      MaybeLocal<Value> result = failure_module->Evaluate(env.local());
      CHECK_EQ(Module::kErrored, failure_module->GetStatus());
      Local<Value> exception = failure_module->GetException();
      CHECK(exception->StrictEquals(v8_str("boom")));

      if (i::FLAG_harmony_top_level_await) {
        // With top level await, we do not throw and errored evaluation returns
        // a rejected promise with the exception.
        CHECK(!inner_try_catch.HasCaught());
        Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked());
        CHECK_EQ(promise->State(), v8::Promise::kRejected);
        CHECK_EQ(promise->Result(), failure_module->GetException());
      } else {
        CHECK(inner_try_catch.HasCaught());
        CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
        CHECK(result.IsEmpty());
      }
    }

    Local<String> dependent_text =
        v8_str("import './failure.js'; export const c = 123;");
    ScriptOrigin dependent_origin =
        ModuleOrigin(v8_str("dependent.js"), CcTest::isolate());
    ScriptCompiler::Source dependent_source(dependent_text, dependent_origin);
    dependent_module = ScriptCompiler::CompileModule(isolate, &dependent_source)
                           .ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, dependent_module->GetStatus());
    CHECK(dependent_module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForModuleEvaluationError2)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, dependent_module->GetStatus());

    {
      v8::TryCatch inner_try_catch(isolate);
      MaybeLocal<Value> result = dependent_module->Evaluate(env.local());
      CHECK_EQ(Module::kErrored, dependent_module->GetStatus());
      Local<Value> exception = dependent_module->GetException();
      CHECK(exception->StrictEquals(v8_str("boom")));
      CHECK_EQ(exception, failure_module->GetException());

      if (i::FLAG_harmony_top_level_await) {
        // With top level await, we do not throw and errored evaluation returns
        // a rejected promise with the exception.
        CHECK(!inner_try_catch.HasCaught());
        Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked());
        CHECK_EQ(promise->State(), v8::Promise::kRejected);
        CHECK_EQ(promise->Result(), failure_module->GetException());
      } else {
        CHECK(inner_try_catch.HasCaught());
        CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom")));
        CHECK(result.IsEmpty());
      }
    }

    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

TEST(ModuleEvaluationCompletion1) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;

    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    const char* sources[] = {
        "",
        "var a = 1",
        "import '42'",
        "export * from '42'",
        "export {} from '42'",
        "export {}",
        "var a = 1; export {a}",
        "export function foo() {}",
        "export class C extends null {}",
        "export let a = 1",
        "export default 1",
        "export default function foo() {}",
        "export default function () {}",
        "export default (function () {})",
        "export default class C extends null {}",
        "export default (class C extends null {})",
        "for (var i = 0; i < 5; ++i) {}",
    };

    for (auto src : sources) {
      Local<String> source_text = v8_str(src);
      ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      Local<Module> module =
          ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
      CHECK_EQ(Module::kUninstantiated, module->GetStatus());
      CHECK(module
                ->InstantiateModule(env.local(),
                                    CompileSpecifierAsModuleResolveCallback)
                .FromJust());
      CHECK_EQ(Module::kInstantiated, module->GetStatus());

      // Evaluate twice.
      Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked();
      CHECK_EQ(Module::kEvaluated, module->GetStatus());
      Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked();
      CHECK_EQ(Module::kEvaluated, module->GetStatus());

      if (i::FLAG_harmony_top_level_await) {
        Local<Promise> promise = Local<Promise>::Cast(result_1);
        CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
        CHECK(promise->Result()->IsUndefined());

        // Second evaluation should return the same promise.
        Local<Promise> promise_too = Local<Promise>::Cast(result_2);
        CHECK_EQ(promise, promise_too);
        CHECK_EQ(promise_too->State(), v8::Promise::kFulfilled);
        CHECK(promise_too->Result()->IsUndefined());
      } else {
        CHECK(result_1->IsUndefined());
        CHECK(result_2->IsUndefined());
      }
    }
    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

TEST(ModuleEvaluationCompletion2) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;

    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    const char* sources[] = {
        "'gaga'; ",
        "'gaga'; var a = 1",
        "'gaga'; import '42'",
        "'gaga'; export * from '42'",
        "'gaga'; export {} from '42'",
        "'gaga'; export {}",
        "'gaga'; var a = 1; export {a}",
        "'gaga'; export function foo() {}",
        "'gaga'; export class C extends null {}",
        "'gaga'; export let a = 1",
        "'gaga'; export default 1",
        "'gaga'; export default function foo() {}",
        "'gaga'; export default function () {}",
        "'gaga'; export default (function () {})",
        "'gaga'; export default class C extends null {}",
        "'gaga'; export default (class C extends null {})",
    };

    for (auto src : sources) {
      Local<String> source_text = v8_str(src);
      ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
      ScriptCompiler::Source source(source_text, origin);
      Local<Module> module =
          ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
      CHECK_EQ(Module::kUninstantiated, module->GetStatus());
      CHECK(module
                ->InstantiateModule(env.local(),
                                    CompileSpecifierAsModuleResolveCallback)
                .FromJust());
      CHECK_EQ(Module::kInstantiated, module->GetStatus());

      Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked();
      CHECK_EQ(Module::kEvaluated, module->GetStatus());

      Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked();
      CHECK_EQ(Module::kEvaluated, module->GetStatus());
      if (i::FLAG_harmony_top_level_await) {
        Local<Promise> promise = Local<Promise>::Cast(result_1);
        CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
        CHECK(promise->Result()->IsUndefined());

        // Second Evaluation should return the same promise.
        Local<Promise> promise_too = Local<Promise>::Cast(result_2);
        CHECK_EQ(promise, promise_too);
        CHECK_EQ(promise_too->State(), v8::Promise::kFulfilled);
        CHECK(promise_too->Result()->IsUndefined());
      } else {
        CHECK(result_1->StrictEquals(v8_str("gaga")));
        CHECK(result_2->IsUndefined());
      }
    }
    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

TEST(ModuleNamespace) {
  bool prev_top_level_await = i::FLAG_harmony_top_level_await;
  for (auto top_level_await : {true, false}) {
    i::FLAG_harmony_top_level_await = top_level_await;

    Isolate* isolate = CcTest::isolate();
    HandleScope scope(isolate);
    LocalContext env;
    v8::TryCatch try_catch(isolate);

    Local<v8::Object> ReferenceError =
        CompileRun("ReferenceError")->ToObject(env.local()).ToLocalChecked();

    Local<String> source_text = v8_str(
        "import {a, b} from 'export var a = 1; export let b = 2';"
        "export function geta() {return a};"
        "export function getb() {return b};"
        "export let radio = 3;"
        "export var gaga = 4;");
    ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    CHECK(module
              ->InstantiateModule(env.local(),
                                  CompileSpecifierAsModuleResolveCallback)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());
    Local<Value> ns = module->GetModuleNamespace();
    CHECK_EQ(Module::kInstantiated, module->GetStatus());
    Local<v8::Object> nsobj = ns->ToObject(env.local()).ToLocalChecked();
    CHECK_EQ(nsobj->CreationContext(), env.local());

    // a, b
    CHECK(nsobj->Get(env.local(), v8_str("a")).ToLocalChecked()->IsUndefined());
    CHECK(nsobj->Get(env.local(), v8_str("b")).ToLocalChecked()->IsUndefined());

    // geta
    {
      auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked();
      auto a = geta.As<v8::Function>()
                   ->Call(env.local(), geta, 0, nullptr)
                   .ToLocalChecked();
      CHECK(a->IsUndefined());
    }

    // getb
    {
      v8::TryCatch inner_try_catch(isolate);
      auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked();
      CHECK(getb.As<v8::Function>()
                ->Call(env.local(), getb, 0, nullptr)
                .IsEmpty());
      CHECK(inner_try_catch.HasCaught());
      CHECK(inner_try_catch.Exception()
                ->InstanceOf(env.local(), ReferenceError)
                .FromJust());
    }

    // radio
    {
      v8::TryCatch inner_try_catch(isolate);
      // https://bugs.chromium.org/p/v8/issues/detail?id=7235
      // CHECK(nsobj->Get(env.local(), v8_str("radio")).IsEmpty());
      CHECK(nsobj->Get(env.local(), v8_str("radio"))
                .ToLocalChecked()
                ->IsUndefined());
      CHECK(inner_try_catch.HasCaught());
      CHECK(inner_try_catch.Exception()
                ->InstanceOf(env.local(), ReferenceError)
                .FromJust());
    }

    // gaga
    {
      auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked();
      CHECK(gaga->IsUndefined());
    }

    CHECK(!try_catch.HasCaught());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());
    module->Evaluate(env.local()).ToLocalChecked();
    CHECK_EQ(Module::kEvaluated, module->GetStatus());

    // geta
    {
      auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked();
      auto a = geta.As<v8::Function>()
                   ->Call(env.local(), geta, 0, nullptr)
                   .ToLocalChecked();
      CHECK_EQ(1, a->Int32Value(env.local()).FromJust());
    }

    // getb
    {
      auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked();
      auto b = getb.As<v8::Function>()
                   ->Call(env.local(), getb, 0, nullptr)
                   .ToLocalChecked();
      CHECK_EQ(2, b->Int32Value(env.local()).FromJust());
    }

    // radio
    {
      auto radio = nsobj->Get(env.local(), v8_str("radio")).ToLocalChecked();
      CHECK_EQ(3, radio->Int32Value(env.local()).FromJust());
    }

    // gaga
    {
      auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked();
      CHECK_EQ(4, gaga->Int32Value(env.local()).FromJust());
    }
    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = prev_top_level_await;
}

TEST(ModuleEvaluationTopLevelAwait) {
  bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await;
  i::FLAG_harmony_top_level_await = true;
  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  LocalContext env;
  v8::TryCatch try_catch(isolate);
  const char* sources[] = {
      "await 42",
      "import 'await 42';",
      "import '42'; import 'await 42';",
  };

  for (auto src : sources) {
    Local<String> source_text = v8_str(src);
    ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    CHECK(module
              ->InstantiateModule(env.local(),
                                  CompileSpecifierAsModuleResolveCallback)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());
    Local<Promise> promise =
        Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
    CHECK_EQ(Module::kEvaluated, module->GetStatus());
    CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
    CHECK(promise->Result()->IsUndefined());
    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value;
}

TEST(ModuleEvaluationTopLevelAwaitError) {
  bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await;
  i::FLAG_harmony_top_level_await = true;
  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  LocalContext env;
  const char* sources[] = {
      "await 42; throw 'boom';",
      "import 'await 42; throw \"boom\";';",
      "import '42'; import 'await 42; throw \"boom\";';",
  };

  for (auto src : sources) {
    v8::TryCatch try_catch(isolate);
    Local<String> source_text = v8_str(src);
    ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    CHECK(module
              ->InstantiateModule(env.local(),
                                  CompileSpecifierAsModuleResolveCallback)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());
    Local<Promise> promise =
        Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
    CHECK_EQ(Module::kErrored, module->GetStatus());
    CHECK_EQ(promise->State(), v8::Promise::kRejected);
    CHECK(promise->Result()->StrictEquals(v8_str("boom")));
    CHECK(module->GetException()->StrictEquals(v8_str("boom")));

    // TODO(cbruni) I am not sure, but this might not be supposed to throw
    // because it is async.
    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value;
}

namespace {
struct DynamicImportData {
  DynamicImportData(Isolate* isolate_, Local<Promise::Resolver> resolver_,
                    Local<Context> context_, bool should_resolve_)
      : isolate(isolate_), should_resolve(should_resolve_) {
    resolver.Reset(isolate, resolver_);
    context.Reset(isolate, context_);
  }

  Isolate* isolate;
  v8::Global<Promise::Resolver> resolver;
  v8::Global<Context> context;
  bool should_resolve;
};

void DoHostImportModuleDynamically(void* import_data) {
  std::unique_ptr<DynamicImportData> import_data_(
      static_cast<DynamicImportData*>(import_data));
  Isolate* isolate(import_data_->isolate);
  HandleScope handle_scope(isolate);

  Local<Promise::Resolver> resolver(import_data_->resolver.Get(isolate));
  Local<Context> realm(import_data_->context.Get(isolate));
  Context::Scope context_scope(realm);

  if (import_data_->should_resolve) {
    resolver->Resolve(realm, True(isolate)).ToChecked();
  } else {
    resolver->Reject(realm, v8_str("boom")).ToChecked();
  }
}

v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackResolve(
    Local<Context> context, Local<v8::ScriptOrModule> referrer,
    Local<String> specifier) {
  Isolate* isolate = context->GetIsolate();
  Local<v8::Promise::Resolver> resolver =
      v8::Promise::Resolver::New(context).ToLocalChecked();

  DynamicImportData* data =
      new DynamicImportData(isolate, resolver, context, true);
  isolate->EnqueueMicrotask(DoHostImportModuleDynamically, data);
  return resolver->GetPromise();
}

v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackReject(
    Local<Context> context, Local<v8::ScriptOrModule> referrer,
    Local<String> specifier) {
  Isolate* isolate = context->GetIsolate();
  Local<v8::Promise::Resolver> resolver =
      v8::Promise::Resolver::New(context).ToLocalChecked();

  DynamicImportData* data =
      new DynamicImportData(isolate, resolver, context, false);
  isolate->EnqueueMicrotask(DoHostImportModuleDynamically, data);
  return resolver->GetPromise();
}

}  // namespace

TEST(ModuleEvaluationTopLevelAwaitDynamicImport) {
  bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await;
  i::FLAG_harmony_top_level_await = true;
  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
  isolate->SetHostImportModuleDynamicallyCallback(
      HostImportModuleDynamicallyCallbackResolve);
  LocalContext env;
  v8::TryCatch try_catch(isolate);
  const char* sources[] = {
      "await import('foo');",
      "import 'await import(\"foo\");';",
      "import '42'; import 'await import(\"foo\");';",
  };

  for (auto src : sources) {
    Local<String> source_text = v8_str(src);
    ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    CHECK(module
              ->InstantiateModule(env.local(),
                                  CompileSpecifierAsModuleResolveCallback)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());

    Local<Promise> promise =
        Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
    CHECK_EQ(Module::kEvaluated, module->GetStatus());
    CHECK_EQ(promise->State(), v8::Promise::kPending);
    CHECK(!try_catch.HasCaught());

    isolate->PerformMicrotaskCheckpoint();
    CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
  }
  i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value;
}

TEST(ModuleEvaluationTopLevelAwaitDynamicImportError) {
  bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await;
  i::FLAG_harmony_top_level_await = true;
  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
  isolate->SetHostImportModuleDynamicallyCallback(
      HostImportModuleDynamicallyCallbackReject);
  LocalContext env;
  v8::TryCatch try_catch(isolate);
  const char* sources[] = {
      "await import('foo');",
      "import 'await import(\"foo\");';",
      "import '42'; import 'await import(\"foo\");';",
  };

  for (auto src : sources) {
    Local<String> source_text = v8_str(src);
    ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK_EQ(Module::kUninstantiated, module->GetStatus());
    CHECK(module
              ->InstantiateModule(env.local(),
                                  CompileSpecifierAsModuleResolveCallback)
              .FromJust());
    CHECK_EQ(Module::kInstantiated, module->GetStatus());

    Local<Promise> promise =
        Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
    CHECK_EQ(Module::kEvaluated, module->GetStatus());
    CHECK_EQ(promise->State(), v8::Promise::kPending);
    CHECK(!try_catch.HasCaught());

    isolate->PerformMicrotaskCheckpoint();
    CHECK_EQ(Module::kErrored, module->GetStatus());
    CHECK_EQ(promise->State(), v8::Promise::kRejected);
    CHECK(promise->Result()->StrictEquals(v8_str("boom")));
    CHECK(module->GetException()->StrictEquals(v8_str("boom")));
    CHECK(!try_catch.HasCaught());
  }
  i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value;
}

TEST(TerminateExecutionTopLevelAwaitSync) {
  bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await;
  i::FLAG_harmony_top_level_await = true;

  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  LocalContext env;
  v8::TryCatch try_catch(isolate);

  env.local()
      ->Global()
      ->Set(env.local(), v8_str("terminate"),
            v8::Function::New(env.local(),
                              [](const v8::FunctionCallbackInfo<Value>& info) {
                                info.GetIsolate()->TerminateExecution();
                              })
                .ToLocalChecked())
      .ToChecked();

  Local<String> source_text = v8_str("terminate(); while (true) {}");
  ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
  ScriptCompiler::Source source(source_text, origin);
  Local<Module> module =
      ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
  CHECK(module
            ->InstantiateModule(env.local(),
                                CompileSpecifierAsModuleResolveCallback)
            .FromJust());

  CHECK(module->Evaluate(env.local()).IsEmpty());
  CHECK(try_catch.HasCaught());
  CHECK(try_catch.HasTerminated());
  CHECK_EQ(module->GetStatus(), Module::kErrored);
  CHECK_EQ(module->GetException(), v8::Null(isolate));

  i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value;
}

TEST(TerminateExecutionTopLevelAwaitAsync) {
  bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await;
  i::FLAG_harmony_top_level_await = true;

  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  LocalContext env;
  v8::TryCatch try_catch(isolate);

  env.local()
      ->Global()
      ->Set(env.local(), v8_str("terminate"),
            v8::Function::New(env.local(),
                              [](const v8::FunctionCallbackInfo<Value>& info) {
                                info.GetIsolate()->TerminateExecution();
                              })
                .ToLocalChecked())
      .ToChecked();

  Local<Promise::Resolver> eval_promise =
      Promise::Resolver::New(env.local()).ToLocalChecked();
  env.local()
      ->Global()
      ->Set(env.local(), v8_str("evalPromise"), eval_promise)
      .ToChecked();

  Local<String> source_text =
      v8_str("await evalPromise; terminate(); while (true) {}");
  ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
  ScriptCompiler::Source source(source_text, origin);
  Local<Module> module =
      ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
  CHECK(module
            ->InstantiateModule(env.local(),
                                CompileSpecifierAsModuleResolveCallback)
            .FromJust());

  Local<Promise> promise =
      Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked());
  CHECK_EQ(module->GetStatus(), Module::kEvaluated);
  CHECK_EQ(promise->State(), Promise::PromiseState::kPending);
  CHECK(!try_catch.HasCaught());
  CHECK(!try_catch.HasTerminated());

  eval_promise->Resolve(env.local(), v8::Undefined(isolate)).ToChecked();

  CHECK(try_catch.HasCaught());
  CHECK(try_catch.HasTerminated());
  CHECK_EQ(promise->State(), Promise::PromiseState::kPending);

  // The termination exception doesn't trigger the module's
  // catch handler, so the module isn't transitioned to kErrored.
  CHECK_EQ(module->GetStatus(), Module::kEvaluated);

  i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value;
}

static Local<Module> async_leaf_module;
static Local<Module> sync_leaf_module;
static Local<Module> cycle_self_module;
static Local<Module> cycle_one_module;
static Local<Module> cycle_two_module;
MaybeLocal<Module> ResolveCallbackForIsGraphAsyncTopLevelAwait(
    Local<Context> context, Local<String> specifier, Local<Module> referrer) {
  if (specifier->StrictEquals(v8_str("./async_leaf.js"))) {
    return async_leaf_module;
  } else if (specifier->StrictEquals(v8_str("./sync_leaf.js"))) {
    return sync_leaf_module;
  } else if (specifier->StrictEquals(v8_str("./cycle_self.js"))) {
    return cycle_self_module;
  } else if (specifier->StrictEquals(v8_str("./cycle_one.js"))) {
    return cycle_one_module;
  } else {
    CHECK(specifier->StrictEquals(v8_str("./cycle_two.js")));
    return cycle_two_module;
  }
}

TEST(IsGraphAsyncTopLevelAwait) {
  bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await;
  i::FLAG_harmony_top_level_await = true;

  Isolate* isolate = CcTest::isolate();
  HandleScope scope(isolate);
  LocalContext env;

  {
    Local<String> source_text = v8_str("await notExecuted();");
    ScriptOrigin origin =
        ModuleOrigin(v8_str("async_leaf.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    async_leaf_module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK(async_leaf_module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForIsGraphAsyncTopLevelAwait)
              .FromJust());
    CHECK(async_leaf_module->IsGraphAsync());
  }

  {
    Local<String> source_text = v8_str("notExecuted();");
    ScriptOrigin origin =
        ModuleOrigin(v8_str("sync_leaf.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    sync_leaf_module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK(sync_leaf_module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForIsGraphAsyncTopLevelAwait)
              .FromJust());
    CHECK(!sync_leaf_module->IsGraphAsync());
  }

  {
    Local<String> source_text = v8_str("import './async_leaf.js'");
    ScriptOrigin origin =
        ModuleOrigin(v8_str("import_async.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK(module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForIsGraphAsyncTopLevelAwait)
              .FromJust());
    CHECK(module->IsGraphAsync());
  }

  {
    Local<String> source_text = v8_str("import './sync_leaf.js'");
    ScriptOrigin origin =
        ModuleOrigin(v8_str("import_sync.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    Local<Module> module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK(module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForIsGraphAsyncTopLevelAwait)
              .FromJust());
    CHECK(!module->IsGraphAsync());
  }

  {
    Local<String> source_text = v8_str(
        "import './cycle_self.js'\n"
        "import './async_leaf.js'");
    ScriptOrigin origin =
        ModuleOrigin(v8_str("cycle_self.js"), CcTest::isolate());
    ScriptCompiler::Source source(source_text, origin);
    cycle_self_module =
        ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
    CHECK(cycle_self_module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForIsGraphAsyncTopLevelAwait)
              .FromJust());
    CHECK(cycle_self_module->IsGraphAsync());
  }

  {
    Local<String> source_text1 = v8_str("import './cycle_two.js'");
    ScriptOrigin origin1 =
        ModuleOrigin(v8_str("cycle_one.js"), CcTest::isolate());
    ScriptCompiler::Source source1(source_text1, origin1);
    cycle_one_module =
        ScriptCompiler::CompileModule(isolate, &source1).ToLocalChecked();
    Local<String> source_text2 = v8_str(
        "import './cycle_one.js'\n"
        "import './async_leaf.js'");
    ScriptOrigin origin2 =
        ModuleOrigin(v8_str("cycle_two.js"), CcTest::isolate());
    ScriptCompiler::Source source2(source_text2, origin2);
    cycle_two_module =
        ScriptCompiler::CompileModule(isolate, &source2).ToLocalChecked();
    CHECK(cycle_one_module
              ->InstantiateModule(env.local(),
                                  ResolveCallbackForIsGraphAsyncTopLevelAwait)
              .FromJust());
    CHECK(cycle_one_module->IsGraphAsync());
    CHECK(cycle_two_module->IsGraphAsync());
  }

  i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value;
}

}  // anonymous namespace
