package org.dynjs.runtime;
import jnr.posix.util.Platform;
import org.dynjs.Config;
import org.dynjs.cli.Options;
import org.dynjs.compiler.JSCompiler;
import org.dynjs.exception.DynJSException;
import org.dynjs.ir.JITCompiler;
import org.dynjs.runtime.source.ClassLoaderSourceProvider;
import org.dynjs.runtime.source.FileSourceProvider;
import org.dynjs.runtime.util.SafePropertyAccessor;
import java.io.*;
import java.util.Properties;
public class DynJS {
public static final String VERSION;
public static final String VERSION_STRING;
private final JITCompiler jitCompiler;
private Config config;
private JSCompiler compiler;
private GlobalContext globalContext;
private ExecutionContext defaultExecutionContext;
public DynJS() {
this(new Config());
}
public DynJS(Config config) {
this(config, new DynObject());
}
public DynJS(Config config, JSObject globalObject) {
this.config = config;
this.compiler = new JSCompiler(config);
this.jitCompiler = new JITCompiler();
this.globalContext = GlobalContext.newGlobalContext(this, globalObject);
this.defaultExecutionContext = ExecutionContext.createDefaultGlobalExecutionContext(this);
loadKernel();
}
private void loadKernel() {
// FIXME only works for non-IR atm
if (!Config.CompileMode.IR.equals(this.config.getCompileMode())) {
try {
switch (this.config.getKernelMode()) {
case INTERNAL:
// Load pure-JS kernel
//this.evaluate(getClass().getResourceAsStream("/dynjs/kernel.js"));
this.evaluate(new ClassLoaderSourceProvider(getClass().getClassLoader(), "dynjs/kernel.js"));
break;
case EXTERNAL:
this.evaluate(new FileSourceProvider(new File("src/main/resources/dynjs/kernel.js")));
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public GlobalContext getGlobalContext() {
return this.globalContext;
}
public Config getConfig() {
return this.config;
}
public JSCompiler getCompiler() {
return this.compiler;
}
public JITCompiler getJitCompiler() {
return jitCompiler;
}
public Runner newRunner(boolean debug) {
return new Runner(this).debug(debug);
}
public Runner newRunner() {
return new Runner(this);
}
public Compiler newCompiler() {
return new Compiler(this.config);
}
// ----------------------------------------------------------------------
public Object execute(String source) {
return newRunner().withContext(this.defaultExecutionContext).withSource(source).execute();
}
public Object evaluate(String source) {
return newRunner().withContext(this.defaultExecutionContext).withSource(source).evaluate();
}
public Object evaluate(SourceProvider source) {
return newRunner().withContext(this.defaultExecutionContext).withSource(source).evaluate();
}
public ExecutionContext getDefaultExecutionContext() {
return this.defaultExecutionContext;
}
public Object evaluate(String... sourceLines) {
StringBuilder buffer = new StringBuilder();
for (String line : sourceLines) {
buffer.append(line).append("\n");
}
return evaluate(buffer.toString());
}
static {
String version = "undefined";
String fullVersion = "";
try {
Properties properties = new Properties();
InputStream stream = DynJS.class.getClassLoader().getResourceAsStream("version.properties");
if (stream != null) {
properties.load(stream);
version = properties.getProperty("git.commit.id.describe");
}
fullVersion = String.format(
"dynjs %s on %s %s%s [%s-%s]",
version,
SafePropertyAccessor.getProperty("java.vm.name", "Unknown JVM"),
SafePropertyAccessor.getProperty("java.runtime.version", SafePropertyAccessor.getProperty("java.version", "Unknown version")),
Options.INVOKEDYNAMIC.load() ? " +indy" : "",
Platform.getOSName(),
SafePropertyAccessor.getProperty("os.arch", "Unknown arch")
);
} catch (IOException e) {
// intentionally suppressed
} finally {
VERSION = version;
VERSION_STRING = fullVersion;
}
}
}