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:
adamk 2015-02-10 11:11:44 -08:00 committed by Commit bot
parent 661668f7ab
commit a18b797fd9
7 changed files with 112 additions and 104 deletions

View File

@ -225,13 +225,16 @@ ScriptCompiler::CachedData* CompileForCachedData(
// Compile a string within the current v8 context. // Compile a string within the current v8 context.
Local<UnboundScript> Shell::CompileString( Local<Script> Shell::CompileString(
Isolate* isolate, Local<String> source, Local<Value> name, Isolate* isolate, Local<String> source, Local<Value> name,
ScriptCompiler::CompileOptions compile_options) { ScriptCompiler::CompileOptions compile_options, SourceType source_type) {
ScriptOrigin origin(name); ScriptOrigin origin(name);
if (compile_options == ScriptCompiler::kNoCompileOptions) { if (compile_options == ScriptCompiler::kNoCompileOptions) {
ScriptCompiler::Source script_source(source, origin); ScriptCompiler::Source script_source(source, origin);
return ScriptCompiler::CompileUnbound(isolate, &script_source, return source_type == SCRIPT
? ScriptCompiler::Compile(isolate, &script_source,
compile_options)
: ScriptCompiler::CompileModule(isolate, &script_source,
compile_options); compile_options);
} }
@ -246,17 +249,17 @@ Local<UnboundScript> Shell::CompileString(
DCHECK(false); // A new compile option? DCHECK(false); // A new compile option?
} }
if (data == NULL) compile_options = ScriptCompiler::kNoCompileOptions; if (data == NULL) compile_options = ScriptCompiler::kNoCompileOptions;
return ScriptCompiler::CompileUnbound(isolate, &cached_source, return source_type == SCRIPT
? ScriptCompiler::Compile(isolate, &cached_source, compile_options)
: ScriptCompiler::CompileModule(isolate, &cached_source,
compile_options); compile_options);
} }
// Executes a string within the current v8 context. // Executes a string within the current v8 context.
bool Shell::ExecuteString(Isolate* isolate, bool Shell::ExecuteString(Isolate* isolate, Handle<String> source,
Handle<String> source, Handle<Value> name, bool print_result,
Handle<Value> name, bool report_exceptions, SourceType source_type) {
bool print_result,
bool report_exceptions) {
#ifndef V8_SHARED #ifndef V8_SHARED
bool FLAG_debugger = i::FLAG_debugger; bool FLAG_debugger = i::FLAG_debugger;
#else #else
@ -270,28 +273,30 @@ bool Shell::ExecuteString(Isolate* isolate,
try_catch.SetVerbose(true); try_catch.SetVerbose(true);
} }
Handle<UnboundScript> script = Handle<Value> result;
Shell::CompileString(isolate, source, name, options.compile_options); {
PerIsolateData* data = PerIsolateData::Get(isolate);
Local<Context> realm =
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
Context::Scope context_scope(realm);
Handle<Script> script = Shell::CompileString(
isolate, source, name, options.compile_options, source_type);
if (script.IsEmpty()) { if (script.IsEmpty()) {
// Print errors that happened during compilation. // Print errors that happened during compilation.
if (report_exceptions && !FLAG_debugger) if (report_exceptions && !FLAG_debugger)
ReportException(isolate, &try_catch); ReportException(isolate, &try_catch);
return false; return false;
} else { }
PerIsolateData* data = PerIsolateData::Get(isolate); result = script->Run();
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_; data->realm_current_ = data->realm_switch_;
}
if (result.IsEmpty()) { if (result.IsEmpty()) {
DCHECK(try_catch.HasCaught()); DCHECK(try_catch.HasCaught());
// Print errors that happened during execution. // Print errors that happened during execution.
if (report_exceptions && !FLAG_debugger) if (report_exceptions && !FLAG_debugger)
ReportException(isolate, &try_catch); ReportException(isolate, &try_catch);
return false; return false;
} else { }
DCHECK(!try_catch.HasCaught()); DCHECK(!try_catch.HasCaught());
if (print_result) { if (print_result) {
#if !defined(V8_SHARED) #if !defined(V8_SHARED)
@ -313,7 +318,7 @@ bool Shell::ExecuteString(Isolate* isolate,
Handle<Object> global = context->Global(); Handle<Object> global = context->Global();
Handle<Value> fun = Handle<Value> fun =
global->Get(String::NewFromUtf8(isolate, "Stringify")); global->Get(String::NewFromUtf8(isolate, "Stringify"));
Handle<Value> argv[1] = { result }; Handle<Value> argv[1] = {result};
Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv); Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv);
if (try_catch.HasCaught()) return true; if (try_catch.HasCaught()) return true;
v8::String::Utf8Value str(s); v8::String::Utf8Value str(s);
@ -323,8 +328,6 @@ bool Shell::ExecuteString(Isolate* isolate,
#endif #endif
} }
return true; return true;
}
}
} }
@ -1193,6 +1196,7 @@ void SourceGroup::Execute(Isolate* isolate) {
bool exception_was_thrown = false; bool exception_was_thrown = false;
for (int i = begin_offset_; i < end_offset_; ++i) { for (int i = begin_offset_; i < end_offset_; ++i) {
const char* arg = argv_[i]; const char* arg = argv_[i];
Shell::SourceType source_type = Shell::SCRIPT;
if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) { if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
// Execute argument given to -e option directly. // Execute argument given to -e option directly.
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
@ -1203,9 +1207,16 @@ void SourceGroup::Execute(Isolate* isolate) {
break; break;
} }
++i; ++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] == '-') { } else if (arg[0] == '-') {
// Ignore other options. They have been parsed already. // Ignore other options. They have been parsed already.
} else { continue;
}
// Use all other arguments as names of files to load and run. // Use all other arguments as names of files to load and run.
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
Handle<String> file_name = String::NewFromUtf8(isolate, arg); Handle<String> file_name = String::NewFromUtf8(isolate, arg);
@ -1214,12 +1225,12 @@ void SourceGroup::Execute(Isolate* isolate) {
printf("Error reading '%s'\n", arg); printf("Error reading '%s'\n", arg);
Shell::Exit(1); Shell::Exit(1);
} }
if (!Shell::ExecuteString(isolate, source, file_name, false, true)) { if (!Shell::ExecuteString(isolate, source, file_name, false, true,
source_type)) {
exception_was_thrown = true; exception_was_thrown = true;
break; break;
} }
} }
}
if (exception_was_thrown != Shell::options.expected_to_throw) { if (exception_was_thrown != Shell::options.expected_to_throw) {
Shell::Exit(1); Shell::Exit(1);
} }
@ -1402,6 +1413,8 @@ bool Shell::SetOptions(int argc, char* argv[]) {
v8::V8::SetFlagsFromCommandLine(&argc, argv, true); v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
bool enable_harmony_modules = false;
// Set up isolated source groups. // Set up isolated source groups.
options.isolate_sources = new SourceGroup[options.num_isolates]; options.isolate_sources = new SourceGroup[options.num_isolates];
SourceGroup* current = options.isolate_sources; SourceGroup* current = options.isolate_sources;
@ -1412,6 +1425,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
current->End(i); current->End(i);
current++; current++;
current->Begin(argv, i + 1); 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) { } else if (strncmp(argv[i], "--", 2) == 0) {
printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]); 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"); SetFlagsFromString("--nologfile_per_isolate");
} }
if (enable_harmony_modules) {
SetFlagsFromString("--harmony-modules");
}
return true; return true;
} }

View File

@ -248,14 +248,16 @@ class Shell : public i::AllStatic {
#endif // V8_SHARED #endif // V8_SHARED
public: public:
static Local<UnboundScript> CompileString( enum SourceType { SCRIPT, MODULE };
static Local<Script> CompileString(
Isolate* isolate, Local<String> source, Local<Value> name, Isolate* isolate, Local<String> source, Local<Value> name,
v8::ScriptCompiler::CompileOptions compile_options); v8::ScriptCompiler::CompileOptions compile_options,
static bool ExecuteString(Isolate* isolate, SourceType source_type);
Handle<String> source, static bool ExecuteString(Isolate* isolate, Handle<String> source,
Handle<Value> name, Handle<Value> name, bool print_result,
bool print_result, bool report_exceptions,
bool report_exceptions); SourceType source_type = SCRIPT);
static const char* ToCString(const v8::String::Utf8Value& value); static const char* ToCString(const v8::String::Utf8Value& value);
static void ReportException(Isolate* isolate, TryCatch* try_catch); static void ReportException(Isolate* isolate, TryCatch* try_catch);
static Handle<String> ReadFile(Isolate* isolate, const char* name); static Handle<String> ReadFile(Isolate* isolate, const char* name);

View File

@ -138,7 +138,6 @@
'test-microtask-delivery.cc', 'test-microtask-delivery.cc',
'test-mark-compact.cc', 'test-mark-compact.cc',
'test-mementos.cc', 'test-mementos.cc',
'test-modules.cc',
'test-object-observe.cc', 'test-object-observe.cc',
'test-ordered-hash-table.cc', 'test-ordered-hash-table.cc',
'test-parsing.cc', 'test-parsing.cc',

View File

@ -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());
}

View 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);

View File

@ -34,6 +34,7 @@ from testrunner.objects import testcase
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
FILES_PATTERN = re.compile(r"//\s+Files:(.*)") FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME") SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")
MODULE_PATTERN = re.compile(r"^// MODULE$", flags=re.MULTILINE)
class MjsunitTestSuite(testsuite.TestSuite): class MjsunitTestSuite(testsuite.TestSuite):
@ -80,6 +81,9 @@ class MjsunitTestSuite(testsuite.TestSuite):
if not context.no_harness: if not context.no_harness:
files.append(os.path.join(self.root, "mjsunit.js")) files.append(os.path.join(self.root, "mjsunit.js"))
if MODULE_PATTERN.search(source):
files.append("--module")
files.append(testfilename) files.append(testfilename)
flags += files flags += files