Files
sdk/compiler/java/com/google/dart/runner/V8Launcher.java
T
2012-02-08 10:22:07 +00:00

179 lines
5.3 KiB
Java

// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.google.dart.runner;
import com.google.common.collect.Lists;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Runs a given JS-script in d8 (part of V8).
*/
public class V8Launcher implements JavaScriptLauncher {
private static class Drainer implements Runnable {
private final InputStream stream;
private final List<String> lines;
private final PrintStream out;
public Drainer(InputStream stream, PrintStream out, List<String> lines) {
this.stream = stream;
this.lines = lines;
this.out = out;
}
@Override
public void run() {
BufferedReader r = new BufferedReader(new InputStreamReader(stream));
String str;
try {
while ((str = r.readLine()) != null) {
if (lines != null) {
lines.add(str);
}
out.println(str);
}
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
private static final String D8_ENVIRONMENT_VARIABLE = "D8_EXEC";
private static final String EOL = System.getProperty("line.separator");
public V8Launcher() {
}
@Override
public void execute(String jsScript, String sourceName, String[] args, RunnerOptions options,
PrintStream stdout, PrintStream stderr)
throws RunnerError {
if (!isConfigured()) {
throw new RunnerError("Please set the " + D8_ENVIRONMENT_VARIABLE + " environment variable.");
}
File sourceFile;
try {
sourceFile = writeTempFile(sourceName, jsScript);
} catch (IOException e) {
throw new RunnerError(e);
}
try {
ArrayList<String> command = new ArrayList<String>();
command.add(v8Executable().getAbsolutePath());
command.add(sourceFile.getAbsolutePath());
if (options.shouldProfile()) {
command.add("--prof");
}
command.add("--");
command.addAll(Arrays.asList(args));
int exitValue;
Process p = null;
List<String> stdOutLines = Lists.newArrayList();
Thread stdOutDrain = null;
Thread stdErrDrain = null;
try {
p = Runtime.getRuntime().exec(command.toArray(new String[0]));
// TODO(floitsch): we should handle timeouts (but how long should we wait?).
stdOutDrain = new Thread(new Drainer(p.getInputStream(), stdout, stdOutLines));
stdErrDrain = new Thread(new Drainer(p.getErrorStream(), stderr, null));
stdOutDrain.start();
stdErrDrain.start();
try {
exitValue = p.waitFor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} catch (IOException e) {
throw new RunnerError(e);
} finally {
try {
if (stdOutDrain != null) {
stdOutDrain.join();
}
if (stdErrDrain != null) {
stdErrDrain.join();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
p.getInputStream().close();
p.getOutputStream().close();
p.getOutputStream().close();
} catch (IOException e) {
throw new RunnerError(e);
}
p.destroy();
}
if (exitValue != 0) {
StringWriter stringWriter = new StringWriter();
PrintWriter out = new PrintWriter(stringWriter);
if (options.verbose()) {
out.println(jsScript);
}
out.println("Execution failed.");
out.println("V8 execution returned non-zero exit-code: " + p.exitValue());
out.flush();
throw new RunnerError(stringWriter.toString());
}
} finally {
sourceFile.delete();
}
}
private File writeTempFile(String name, String content) throws IOException {
// The first argument to createTempFile must be at least three characters long, and be a
// valid file-name.
name = name.replace('/', '_');
File file = File.createTempFile("dart_" + name, ".js");
FileWriter writer = new FileWriter(file);
try {
writer.write(content);
} finally {
writer.close();
}
return file;
}
private static File v8Executable() {
String d8Path = System.getProperty("com.google.dart.runner.d8",
System.getenv(D8_ENVIRONMENT_VARIABLE));
if (d8Path == null) {
String testSrcDir = System.getenv("TEST_SRCDIR");
if (testSrcDir == null) {
return null;
}
return new File(new File(new File(new File(testSrcDir, "google3"),
"third_party"), "v8"), "d8");
} else {
return new File(d8Path);
}
}
/**
* @return true if the D8_EXEC environment variable is correctly set up.
*/
public static boolean isConfigured() {
File file = v8Executable();
if (file == null) {
return false;
}
return file.canExecute();
}
}