Enable compiling mjsunit tests as ES6 modules
Adding the line "// MODULE" to an mjsunit file will now cause run-tests.py to prefix the test case with "--module" in the d8 commandline. d8 has itself been updated to treat files preceded with "--module" as modules (that is, it compiles them with ScriptCompiler::CompileModule, and turns on --harmony-modules). Review URL: https://codereview.chromium.org/902263002 Cr-Commit-Position: refs/heads/master@{#26555}
This commit is contained in:
parent
661668f7ab
commit
a18b797fd9
162
src/d8.cc
162
src/d8.cc
@ -225,14 +225,17 @@ ScriptCompiler::CachedData* CompileForCachedData(
|
||||
|
||||
|
||||
// Compile a string within the current v8 context.
|
||||
Local<UnboundScript> Shell::CompileString(
|
||||
Local<Script> Shell::CompileString(
|
||||
Isolate* isolate, Local<String> source, Local<Value> name,
|
||||
ScriptCompiler::CompileOptions compile_options) {
|
||||
ScriptCompiler::CompileOptions compile_options, SourceType source_type) {
|
||||
ScriptOrigin origin(name);
|
||||
if (compile_options == ScriptCompiler::kNoCompileOptions) {
|
||||
ScriptCompiler::Source script_source(source, origin);
|
||||
return ScriptCompiler::CompileUnbound(isolate, &script_source,
|
||||
compile_options);
|
||||
return source_type == SCRIPT
|
||||
? ScriptCompiler::Compile(isolate, &script_source,
|
||||
compile_options)
|
||||
: ScriptCompiler::CompileModule(isolate, &script_source,
|
||||
compile_options);
|
||||
}
|
||||
|
||||
ScriptCompiler::CachedData* data =
|
||||
@ -246,17 +249,17 @@ Local<UnboundScript> Shell::CompileString(
|
||||
DCHECK(false); // A new compile option?
|
||||
}
|
||||
if (data == NULL) compile_options = ScriptCompiler::kNoCompileOptions;
|
||||
return ScriptCompiler::CompileUnbound(isolate, &cached_source,
|
||||
compile_options);
|
||||
return source_type == SCRIPT
|
||||
? ScriptCompiler::Compile(isolate, &cached_source, compile_options)
|
||||
: ScriptCompiler::CompileModule(isolate, &cached_source,
|
||||
compile_options);
|
||||
}
|
||||
|
||||
|
||||
// Executes a string within the current v8 context.
|
||||
bool Shell::ExecuteString(Isolate* isolate,
|
||||
Handle<String> source,
|
||||
Handle<Value> name,
|
||||
bool print_result,
|
||||
bool report_exceptions) {
|
||||
bool Shell::ExecuteString(Isolate* isolate, Handle<String> source,
|
||||
Handle<Value> name, bool print_result,
|
||||
bool report_exceptions, SourceType source_type) {
|
||||
#ifndef V8_SHARED
|
||||
bool FLAG_debugger = i::FLAG_debugger;
|
||||
#else
|
||||
@ -270,61 +273,61 @@ bool Shell::ExecuteString(Isolate* isolate,
|
||||
try_catch.SetVerbose(true);
|
||||
}
|
||||
|
||||
Handle<UnboundScript> script =
|
||||
Shell::CompileString(isolate, source, name, options.compile_options);
|
||||
if (script.IsEmpty()) {
|
||||
// Print errors that happened during compilation.
|
||||
if (report_exceptions && !FLAG_debugger)
|
||||
ReportException(isolate, &try_catch);
|
||||
return false;
|
||||
} else {
|
||||
Handle<Value> result;
|
||||
{
|
||||
PerIsolateData* data = PerIsolateData::Get(isolate);
|
||||
Local<Context> realm =
|
||||
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
|
||||
realm->Enter();
|
||||
Handle<Value> result = script->BindToCurrentContext()->Run();
|
||||
realm->Exit();
|
||||
data->realm_current_ = data->realm_switch_;
|
||||
if (result.IsEmpty()) {
|
||||
DCHECK(try_catch.HasCaught());
|
||||
// Print errors that happened during execution.
|
||||
Context::Scope context_scope(realm);
|
||||
Handle<Script> script = Shell::CompileString(
|
||||
isolate, source, name, options.compile_options, source_type);
|
||||
if (script.IsEmpty()) {
|
||||
// Print errors that happened during compilation.
|
||||
if (report_exceptions && !FLAG_debugger)
|
||||
ReportException(isolate, &try_catch);
|
||||
return false;
|
||||
} else {
|
||||
DCHECK(!try_catch.HasCaught());
|
||||
if (print_result) {
|
||||
#if !defined(V8_SHARED)
|
||||
if (options.test_shell) {
|
||||
#endif
|
||||
if (!result->IsUndefined()) {
|
||||
// If all went well and the result wasn't undefined then print
|
||||
// the returned value.
|
||||
v8::String::Utf8Value str(result);
|
||||
fwrite(*str, sizeof(**str), str.length(), stdout);
|
||||
printf("\n");
|
||||
}
|
||||
#if !defined(V8_SHARED)
|
||||
} else {
|
||||
v8::TryCatch try_catch;
|
||||
v8::Local<v8::Context> context =
|
||||
v8::Local<v8::Context>::New(isolate, utility_context_);
|
||||
v8::Context::Scope context_scope(context);
|
||||
Handle<Object> global = context->Global();
|
||||
Handle<Value> fun =
|
||||
global->Get(String::NewFromUtf8(isolate, "Stringify"));
|
||||
Handle<Value> argv[1] = { result };
|
||||
Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv);
|
||||
if (try_catch.HasCaught()) return true;
|
||||
v8::String::Utf8Value str(s);
|
||||
fwrite(*str, sizeof(**str), str.length(), stdout);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
result = script->Run();
|
||||
data->realm_current_ = data->realm_switch_;
|
||||
}
|
||||
if (result.IsEmpty()) {
|
||||
DCHECK(try_catch.HasCaught());
|
||||
// Print errors that happened during execution.
|
||||
if (report_exceptions && !FLAG_debugger)
|
||||
ReportException(isolate, &try_catch);
|
||||
return false;
|
||||
}
|
||||
DCHECK(!try_catch.HasCaught());
|
||||
if (print_result) {
|
||||
#if !defined(V8_SHARED)
|
||||
if (options.test_shell) {
|
||||
#endif
|
||||
if (!result->IsUndefined()) {
|
||||
// If all went well and the result wasn't undefined then print
|
||||
// the returned value.
|
||||
v8::String::Utf8Value str(result);
|
||||
fwrite(*str, sizeof(**str), str.length(), stdout);
|
||||
printf("\n");
|
||||
}
|
||||
#if !defined(V8_SHARED)
|
||||
} else {
|
||||
v8::TryCatch try_catch;
|
||||
v8::Local<v8::Context> context =
|
||||
v8::Local<v8::Context>::New(isolate, utility_context_);
|
||||
v8::Context::Scope context_scope(context);
|
||||
Handle<Object> global = context->Global();
|
||||
Handle<Value> fun =
|
||||
global->Get(String::NewFromUtf8(isolate, "Stringify"));
|
||||
Handle<Value> argv[1] = {result};
|
||||
Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv);
|
||||
if (try_catch.HasCaught()) return true;
|
||||
v8::String::Utf8Value str(s);
|
||||
fwrite(*str, sizeof(**str), str.length(), stdout);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1193,6 +1196,7 @@ void SourceGroup::Execute(Isolate* isolate) {
|
||||
bool exception_was_thrown = false;
|
||||
for (int i = begin_offset_; i < end_offset_; ++i) {
|
||||
const char* arg = argv_[i];
|
||||
Shell::SourceType source_type = Shell::SCRIPT;
|
||||
if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
|
||||
// Execute argument given to -e option directly.
|
||||
HandleScope handle_scope(isolate);
|
||||
@ -1203,21 +1207,28 @@ void SourceGroup::Execute(Isolate* isolate) {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
continue;
|
||||
} else if (strcmp(arg, "--module") == 0 && i + 1 < end_offset_) {
|
||||
// Treat the next file as a module.
|
||||
source_type = Shell::MODULE;
|
||||
arg = argv_[++i];
|
||||
} else if (arg[0] == '-') {
|
||||
// Ignore other options. They have been parsed already.
|
||||
} else {
|
||||
// Use all other arguments as names of files to load and run.
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<String> file_name = String::NewFromUtf8(isolate, arg);
|
||||
Handle<String> source = ReadFile(isolate, arg);
|
||||
if (source.IsEmpty()) {
|
||||
printf("Error reading '%s'\n", arg);
|
||||
Shell::Exit(1);
|
||||
}
|
||||
if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
|
||||
exception_was_thrown = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Use all other arguments as names of files to load and run.
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<String> file_name = String::NewFromUtf8(isolate, arg);
|
||||
Handle<String> source = ReadFile(isolate, arg);
|
||||
if (source.IsEmpty()) {
|
||||
printf("Error reading '%s'\n", arg);
|
||||
Shell::Exit(1);
|
||||
}
|
||||
if (!Shell::ExecuteString(isolate, source, file_name, false, true,
|
||||
source_type)) {
|
||||
exception_was_thrown = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exception_was_thrown != Shell::options.expected_to_throw) {
|
||||
@ -1402,6 +1413,8 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
||||
|
||||
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
|
||||
bool enable_harmony_modules = false;
|
||||
|
||||
// Set up isolated source groups.
|
||||
options.isolate_sources = new SourceGroup[options.num_isolates];
|
||||
SourceGroup* current = options.isolate_sources;
|
||||
@ -1412,6 +1425,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
||||
current->End(i);
|
||||
current++;
|
||||
current->Begin(argv, i + 1);
|
||||
} else if (strcmp(str, "--module") == 0) {
|
||||
// Pass on to SourceGroup, which understands this option.
|
||||
enable_harmony_modules = true;
|
||||
} else if (strncmp(argv[i], "--", 2) == 0) {
|
||||
printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
|
||||
}
|
||||
@ -1422,6 +1438,10 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
||||
SetFlagsFromString("--nologfile_per_isolate");
|
||||
}
|
||||
|
||||
if (enable_harmony_modules) {
|
||||
SetFlagsFromString("--harmony-modules");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
16
src/d8.h
16
src/d8.h
@ -248,14 +248,16 @@ class Shell : public i::AllStatic {
|
||||
#endif // V8_SHARED
|
||||
|
||||
public:
|
||||
static Local<UnboundScript> CompileString(
|
||||
enum SourceType { SCRIPT, MODULE };
|
||||
|
||||
static Local<Script> CompileString(
|
||||
Isolate* isolate, Local<String> source, Local<Value> name,
|
||||
v8::ScriptCompiler::CompileOptions compile_options);
|
||||
static bool ExecuteString(Isolate* isolate,
|
||||
Handle<String> source,
|
||||
Handle<Value> name,
|
||||
bool print_result,
|
||||
bool report_exceptions);
|
||||
v8::ScriptCompiler::CompileOptions compile_options,
|
||||
SourceType source_type);
|
||||
static bool ExecuteString(Isolate* isolate, Handle<String> source,
|
||||
Handle<Value> name, bool print_result,
|
||||
bool report_exceptions,
|
||||
SourceType source_type = SCRIPT);
|
||||
static const char* ToCString(const v8::String::Utf8Value& value);
|
||||
static void ReportException(Isolate* isolate, TryCatch* try_catch);
|
||||
static Handle<String> ReadFile(Isolate* isolate, const char* name);
|
||||
|
@ -138,7 +138,6 @@
|
||||
'test-microtask-delivery.cc',
|
||||
'test-mark-compact.cc',
|
||||
'test-mementos.cc',
|
||||
'test-modules.cc',
|
||||
'test-object-observe.cc',
|
||||
'test-ordered-hash-table.cc',
|
||||
'test-parsing.cc',
|
||||
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2015 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 "test/cctest/cctest.h"
|
||||
|
||||
TEST(ModuleCompilation) {
|
||||
v8::internal::FLAG_harmony_modules = true;
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
LocalContext context;
|
||||
|
||||
CompileRun(
|
||||
"var data = [];"
|
||||
"function store(thing) {"
|
||||
" data.push(thing);"
|
||||
"}");
|
||||
|
||||
CompileRunModule(
|
||||
"export let a = 42;"
|
||||
"store(a)");
|
||||
|
||||
CHECK_EQ(1, CompileRun("data.length")->Int32Value());
|
||||
CHECK_EQ(42, CompileRun("data[0]")->Int32Value());
|
||||
}
|
8
test/mjsunit/harmony/modules.js
Normal file
8
test/mjsunit/harmony/modules.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// MODULE
|
||||
|
||||
export let a = 42;
|
||||
assertEquals(42, a);
|
@ -34,6 +34,7 @@ from testrunner.objects import testcase
|
||||
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
|
||||
FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
|
||||
SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")
|
||||
MODULE_PATTERN = re.compile(r"^// MODULE$", flags=re.MULTILINE)
|
||||
|
||||
|
||||
class MjsunitTestSuite(testsuite.TestSuite):
|
||||
@ -80,6 +81,9 @@ class MjsunitTestSuite(testsuite.TestSuite):
|
||||
|
||||
if not context.no_harness:
|
||||
files.append(os.path.join(self.root, "mjsunit.js"))
|
||||
|
||||
if MODULE_PATTERN.search(source):
|
||||
files.append("--module")
|
||||
files.append(testfilename)
|
||||
|
||||
flags += files
|
||||
|
Loading…
Reference in New Issue
Block a user