Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

compiling to .erj

  • Loading branch information...
commit 1aa836fdcb376e305890a7412b4bb2bd8f1423a7 1 parent 24d492a
@krestenkrab krestenkrab authored
View
2  .classpath
@@ -6,8 +6,6 @@
<classpathentry kind="lib" path="lib/OtpErlang.jar"/>
<classpathentry kind="lib" path="lib/antlr-3.2.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
- <classpathentry kind="lib" path="target/gen"/>
- <classpathentry kind="lib" path="lib/asm-all-2.2.3.jar"/>
<classpathentry kind="lib" path="lib/kilim-0.6-krab.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
View
103 build.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<project name="erjang" default="all">
+ <property name="erjang.version" value="0.1" />
+ <path id="erjang.classpath">
+ <pathelement location="target/classes/" />
+ <pathelement location="lib/kilim-0.6-krab.jar" />
+ <pathelement location="lib/OtpErlang.jar" />
+ <pathelement location="lib/junit.jar" />
+ <pathelement location="lib/antlr-3.2.jar" />
+ <pathelement path="${java.class.path}" />
+ </path>
+ <path id="erjang.testwovenclasspath">
+ <pathelement location="target/classes/" />
+ <pathelement location="target/test-classes/" />
+ <pathelement location="lib/kilim-0.6-krab.jar" />
+ <pathelement location="lib/OtpErlang.jar" />
+ <pathelement location="lib/junit.jar" />
+ <pathelement location="lib/antlr-3.2.jar" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="all" depends="clean,weave,jar" />
+ <target name="test" depends="all,testwoven" />
+
+ <target name="compile">
+ <mkdir dir="target" />
+ <mkdir dir="target/classes" />
+ <mkdir dir="target/test-classes" />
+ <mkdir dir="target/compiled" />
+
+ <echo message="Compiling src ===================" />
+ <javac debug="on" srcdir="src/main/java" destdir="target/classes"
+ classpathref="erjang.classpath"/>
+ </target>
+
+ <target name="testcompile" depends="compile">
+ <echo message="Compiling test ===================" />
+ <javac debug="on" srcdir="src/test/java" destdir="target/test-classes"
+ classpathref="erjang.classpath"/>
+ </target>
+
+
+ <target name="weave" depends="testcompile">
+ <echo message="Weaving files ===================" />
+ <java classname="kilim.tools.Weaver" fork ="yes">
+ <classpath refid="erjang.classpath"/>
+ <assertions>
+ <enable/>
+ </assertions>
+ <arg value="-d" />
+ <arg value="./target/classes" />
+ <arg line="./target/classes" />
+ </java>
+ <echo message="Weaving test classes ==============" />
+ <java classname="kilim.tools.Weaver" fork ="yes">
+ <classpath refid="erjang.testwovenclasspath"/>
+ <assertions>
+ <enable/>
+ </assertions>
+ <arg value="-d" />
+ <arg value="./target/test-classes" />
+ <arg line="./target/test-classes" />
+ </java>
+
+ </target>
+
+ <target name="clean">
+ <echo message="deleting files" />
+ <delete>
+ <fileset defaultexcludes="no" dir="." includes="*~,#*,foo,bar,x,y" />
+ </delete>
+ <delete dir="./target" />
+ </target>
+
+
+ <!-- This runs those tests depend on generated classes in testclasses-->
+ <target name="testwoven" >
+ <echo message="Testing Tasks ======================" />
+ <java classname="junit.textui.TestRunner" fork="yes">
+ <classpath refid="erjang.testwovenclasspath"/>
+ <assertions>
+ <enable/>
+ </assertions>
+ <arg value="erjang.AllTests" />
+ </java>
+ </target>
+
+ <target name="jar" description="generate the distribution" depends="clean,weave">
+ <copy file="License" todir="classes/erjang" />
+ <jar jarfile="erjang-${erjang.version}.jar" basedir="target/classes">
+ <zipgroupfileset dir="lib" includes="*.jar">
+ <exclude name="junit.jar" />
+ <exclude name="asm-all-2.2.3.jar" />
+ </zipgroupfileset>
+ <exclude name="erjang/test/**" />
+ <exclude name="erjang/examples/**" />
+ <exclude name="erjang/bench/**" />
+ <manifest>
+ <attribute name="Main-Class" value="erjang.Erj"/>
+ </manifest>
+ </jar>
+ </target>
+</project>
View
BIN  erjang-0.1.jar
Binary file not shown
View
3  fib_test.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+java -cp erjang-0.1.jar -Derjpath=./src/main/erl/preloaded/ebin:src/main/erl erjang.Erj fib:main
View
BIN  lib/asm-all-2.2.3.jar
Binary file not shown
View
3  ring_test.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+java -cp erjang-0.1.jar -Derjpath=./src/main/erl/preloaded/ebin:src/main/erl erjang.Erj ring:main
View
BIN  src/main/erl/fib.beam
Binary file not shown
View
BIN  src/main/erl/ring.beam
Binary file not shown
View
15 src/main/java/erjang/EBinary.java
@@ -19,6 +19,7 @@
package erjang;
import java.util.zip.Adler32;
+import java.util.zip.CRC32;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -116,6 +117,20 @@ static long adler32(long adler, int byte_value) {
}
return res;
}
+
+ public long crc() {
+ CRC32 crc = new CRC32();
+
+ int octets = bitCount() / 8;
+ if ((bitOff % 8) == 0) {
+ crc.update(data, bitOff / 8, octets);
+ } else {
+ for (int i = 0; i < octets; i++) {
+ crc.update( (byte) octetAt(i) );
+ }
+ }
+ return crc.getValue();
+ }
/**
* @return
View
7 src/main/java/erjang/EFun.java
@@ -430,4 +430,11 @@ public static void main(String[] args) {
}
}
+ /**
+ * @param arity
+ */
+ public static void ensure(int arity) {
+ get_fun_class(arity);
+ }
+
}
View
11 src/main/java/erjang/ERT.java
@@ -18,16 +18,15 @@
package erjang;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import kilim.Mailbox;
import kilim.Pausable;
+import erjang.beam.Compiler;
@Module(value="erlang")
@@ -270,6 +269,7 @@ public static EAtom guard(boolean bool) {
private static final EAtom AM_TIMEOUT = EAtom.intern("timeout");
private static final EAtom am_try_case_clause = EAtom.intern("try_case_clause");
private static final EAtom am_if_clause = EAtom.intern("if_clause");
+ public static final boolean DEBUG = false;
public EBitStringBuilder bs_init(int size, int flags) {
return new EBitStringBuilder(size, flags);
@@ -470,5 +470,8 @@ public static void timeout() {
// skip //
}
-
+ static void load(EAtom module) throws IOException {
+ File f = Compiler.find_and_compile(module.getName());
+ EModule.load_module(module, f.toURI().toURL());
+ }
}
View
26 src/main/java/erjang/Erj.java
@@ -19,8 +19,8 @@
package erjang;
import java.io.File;
+import java.io.IOException;
import java.net.MalformedURLException;
-import java.net.URL;
/**
*
@@ -33,7 +33,8 @@
"prim_zip", "zlib" };
@SuppressWarnings("unchecked")
- public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
+ public static void main(String[] args)
+ throws Exception {
String m = args[0];
String f;
@@ -49,22 +50,18 @@ public static void main(String[] args) throws ClassNotFoundException, MalformedU
EAtom fun = EAtom.intern(f);
EModule[] modules = new EModule[MODULES.length];
- File preloaded_dir = new File(PRELOADED);
for (int i = 0; i < modules.length; i++) {
String mod = MODULES[i];
- File dir = preloaded_dir;
-
- File path = new File(dir, mod + ".classes");
-
- load(path, mod);
+
+ ERT.load(EAtom.intern(mod));
}
EModule.load_module(EAtom.intern("io"), new File("target/classes").toURL());
EModule.load_module(EAtom.intern("timer"), new File("target/classes").toURL());
- load(new File("src/main/erl/" + m + ".classes"), m);
+ ERT.load(EAtom.intern(m));
ESeq env = ERT.NIL;
ESeq argv = ERT.NIL;
@@ -79,17 +76,6 @@ public static void main(String[] args) throws ClassNotFoundException, MalformedU
ERT.run(p=new EProc(null, module, fun, argv ));
p.joinb();
- System.out.println("ready for second run...");
- try {
- Thread.sleep(10000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- ERT.run(p=new EProc(null, module, fun, argv ));
- p.joinb();
-
-
System.out.println("done.");
}
View
4 src/main/java/erjang/ErjC.java
@@ -40,8 +40,8 @@ public static void main(String[] args) throws OtpAuthException, IOException {
if (args[i].endsWith(".beam")) {
File in = new File(args[i]);
int idx = args[i].lastIndexOf('.');
- File out = new File(args[i].substring(0, idx) + ".classes");
- DirClassRepo jcp = new DirClassRepo(out);
+ File out = new File(args[i].substring(0, idx) + ".jar");
+ JarClassRepo jcp = new JarClassRepo(out);
System.out.println("compining "+in+" -> "+out+" ...");
new Compiler(jcp).compile(in);
View
5 src/main/java/erjang/beam/BIFUtil.java
@@ -29,6 +29,7 @@
import erjang.EAtom;
import erjang.EBig;
import erjang.EDouble;
+import erjang.ERT;
import erjang.ESmall;
import erjang.EObject;
import erjang.EProc;
@@ -272,8 +273,8 @@ private BuiltInFunction find_bif(Type[] parmTypes) {
for (Args a : args.generalize()) {
m = found.get(a);
if (m != null) {
-
- System.err.println("missed opportunity erlang:"
+ if (ERT.DEBUG)
+ System.err.println("missed opportunity erlang:"
+ EAtom.intern(name) + "/" + parmTypes.length + " "
+ args + ", \n\tusing " + m);
View
247 src/main/java/erjang/beam/Compiler.java
@@ -18,9 +18,14 @@
package erjang.beam;
+import java.io.EOFException;
import java.io.File;
-import java.io.FileOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedInputStream;
import kilim.analysis.ClassInfo;
import kilim.analysis.ClassWeaver;
@@ -35,33 +40,39 @@
import erjang.EBinary;
import erjang.beam.analysis.BeamTypeAnalysis;
-import erjang.m.erlang.ErlBif;
public class Compiler implements Opcodes {
static ErlangBeamDisLoader loader;
private ClassRepo classRepo;
+ static {
+ try {
+ loader = new ErlangBeamDisLoader();
+ } catch (OtpAuthException e) {
+ throw new Error(e);
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ }
+
/**
- * @param repo
+ * @param repo
* @throws IOException
* @throws OtpAuthException
*
*/
public Compiler(ClassRepo repo) throws OtpAuthException, IOException {
- if (loader == null)
- loader = new ErlangBeamDisLoader();
this.classRepo = repo;
}
- public static void compile(EBinary data, ClassRepo repo) throws IOException
- {
+ public static void compile(EBinary data, ClassRepo repo) throws IOException {
// class writer, phase 4
ClassWriter cw = new ClassWriter(true);
//
CheckClassAdapter ca = new CheckClassAdapter(cw);
-
+
// the java bytecode generator, phase 3
CompilerVisitor cv = new CompilerVisitor(ca, repo);
@@ -77,29 +88,30 @@ public static void compile(EBinary data, ClassRepo repo) throws IOException
} catch (Error e) {
e.printStackTrace();
}
-
+
byte[] byteArray = cw.toByteArray();
-
- ClassWeaver cwe = new ClassWeaver(byteArray, Detector.DEFAULT);
+
+ ClassWeaver cwe = new ClassWeaver(byteArray, new ErjangDetector(
+ cv.getInternalClassName()));
for (ClassInfo ci : cwe.getClassInfos()) {
String name = ci.className;
byte[] bytes = ci.bytes;
-
+
repo.store(name.replace('.', '/'), bytes);
}
-
+
// repo.store(cv.getInternalClassName(), byteArray);
}
-
+
public void compile(File file) throws IOException {
-
+
// class writer, phase 4
ClassWriter cw = new ClassWriter(true);
//
CheckClassAdapter ca = new CheckClassAdapter(cw);
-
+
// the java bytecode generator, phase 3
CompilerVisitor cv = new CompilerVisitor(ca, classRepo);
@@ -111,26 +123,28 @@ public void compile(File file) throws IOException {
// go!
reader.accept(analysis);
-
- classRepo.store(cv.getInternalClassName(), cw.toByteArray());
-
-
- ClassWeaver cwe = new ClassWeaver(cw.toByteArray(), new ErjangDetector(cv.getInternalClassName()));
+
+ // classRepo.store(cv.getInternalClassName(), cw.toByteArray());
+
+ ClassWeaver cwe = new ClassWeaver(cw.toByteArray(), new ErjangDetector(
+ cv.getInternalClassName()));
for (ClassInfo ci : cwe.getClassInfos()) {
String name = ci.className;
byte[] bytes = ci.bytes;
-
+
+ // System.out.println("storing "+name+" in "+classRepo);
+
classRepo.store(name.replace('.', '/'), bytes);
}
}
-
+
static public class ErjangDetector extends Detector {
private final String className;
/**
- * @param className
+ * @param className
* @param mirrors
*/
public ErjangDetector(String className) {
@@ -141,49 +155,190 @@ public ErjangDetector(String className) {
@Override
public int getPausableStatus(String className, String methodName,
String desc) {
-
+
if (className.startsWith(CompilerVisitor.EFUN_NAME)) {
- if (methodName.equals("invoke_tail")) return Detector.METHOD_NOT_PAUSABLE;
- if (methodName.equals("arity")) return Detector.METHOD_NOT_PAUSABLE;
- if (methodName.equals("cast")) return Detector.METHOD_NOT_PAUSABLE;
-
- if (methodName.equals("go")) return Detector.PAUSABLE_METHOD_FOUND;
- if (methodName.equals("invoke")) return Detector.PAUSABLE_METHOD_FOUND;
+ if (methodName.equals("invoke_tail"))
+ return Detector.METHOD_NOT_PAUSABLE;
+ if (methodName.equals("arity"))
+ return Detector.METHOD_NOT_PAUSABLE;
+ if (methodName.equals("cast"))
+ return Detector.METHOD_NOT_PAUSABLE;
+
+ if (methodName.equals("go"))
+ return Detector.PAUSABLE_METHOD_FOUND;
+ if (methodName.equals("invoke"))
+ return Detector.PAUSABLE_METHOD_FOUND;
}
-
+
if (className.equals(this.className)) {
- if (methodName.endsWith("$tail")) return Detector.METHOD_NOT_PAUSABLE;
- if (methodName.endsWith("init>")) return Detector.METHOD_NOT_PAUSABLE;
- if (methodName.equals("module_name")) return Detector.METHOD_NOT_PAUSABLE;
+ if (methodName.endsWith("$tail"))
+ return Detector.METHOD_NOT_PAUSABLE;
+ if (methodName.endsWith("init>"))
+ return Detector.METHOD_NOT_PAUSABLE;
+ if (methodName.equals("module_name"))
+ return Detector.METHOD_NOT_PAUSABLE;
return Detector.PAUSABLE_METHOD_FOUND;
}
-
+
return super.getPausableStatus(className, methodName, desc);
}
}
public static String moduleClassName(String moduleName) {
String cn = EUtil.toJavaIdentifier(moduleName);
-
+
String base = "erjang/m/" + cn + "/" + cn;
-
+
return base;
-
+
}
public static void main(String[] args) throws Exception {
- File out_dir = new File("out");
- ClassRepo repo = new DirClassRepo(out_dir);
- Compiler cc = new Compiler(repo);
-
+ File out_dir = new File("target/compiled");
+ out_dir.mkdirs();
for (int i = 0; i < args.length; i++) {
- File infile = new File(args[i]);
- cc.compile(infile);
+
+ if (args[i].endsWith(".beam")) {
+ File in = new File(args[i]);
+ if (!in.exists() || !in.isFile() || !in.canRead())
+ throw new IOException("bad permissions for " + in);
+
+ int idx = args[i].lastIndexOf('.');
+ int idx0 = args[i].lastIndexOf(File.separator);
+
+ String shortName = args[i].substring(idx0 + 1, idx);
+
+ File out = new File(out_dir, shortName + "-"
+ + Long.toHexString(crcFile(in)) + ".jar");
+ JarClassRepo jcp = new JarClassRepo(out);
+
+ System.out.println("compining " + in + " -> " + out + " ...");
+ new Compiler(jcp).compile(in);
+
+ jcp.close();
+ }
}
+ }
- repo.close();
+ private static long crcFile(File file) throws IOException {
+
+ CheckedInputStream cis = null;
+ long fileSize = 0;
+ cis = new CheckedInputStream(new FileInputStream(file), new CRC32());
+ try {
+ byte[] buf = new byte[4 * 1024];
+ while (cis.read(buf) >= 0)
+ ;
+
+ return cis.getChecksum().getValue();
+ } finally {
+ cis.close();
+ }
}
+ public static File find_and_compile(String module) throws IOException {
+ File input = findBeamFile(module);
+ if (input == null)
+ throw new FileNotFoundException(module);
+ byte[] data = new byte[(int) input.length()];
+ FileInputStream fi = new FileInputStream(input);
+ try {
+ int pos = 0, left = data.length;
+ do {
+ int val = fi.read(data, pos, left);
+ if (val == -1)
+ throw new EOFException();
+ pos += val;
+ left -= val;
+ } while (left > 0);
+
+ } finally {
+ fi.close();
+ }
+
+ EBinary eb = new EBinary(data);
+
+ return compile(module, eb);
+
+ }
+
+ /**
+ * @param module
+ * @return
+ */
+ private static File findBeamFile(String module) {
+ String n = module;
+
+ for (File e : loadPath) {
+ File beam = new File(e, n + ".beam");
+ if (beam.exists())
+ return beam;
+ }
+
+ return null;
+ }
+
+ static File[] loadPath;
+
+ static {
+ ArrayList<File> lp = new ArrayList<File>();
+ String sys_path = System.getenv("ERJ_PATH");
+ if (sys_path != null)
+ add(lp, sys_path);
+
+ String path = System.getProperty("erjpath", ".");
+ add(lp, path);
+
+ loadPath = lp.toArray(new File[lp.size()]);
+ }
+
+ private static void add(ArrayList<File> out, String path) {
+ for (String s : path.split(":")) {
+ File elem = new File(s);
+ if (elem.exists() && elem.isDirectory()) {
+ out.add(elem);
+ }
+ }
+ }
+
+ static File compile(String name, EBinary beam_data) throws IOException {
+
+ long crc = beam_data.crc();
+
+ File jarFile = new File(erjdir(), name + "-" + Long.toHexString(crc)
+ + ".jar");
+
+ if (!jarFile.exists()) {
+ JarClassRepo repo = new JarClassRepo(jarFile);
+
+ try {
+ compile(beam_data, repo);
+
+ repo.close();
+ repo = null;
+ } finally {
+ if (repo != null) {
+ repo.close();
+ jarFile.delete();
+ }
+ }
+ }
+
+ return jarFile;
+ }
+
+ static File erjdir() throws IOException {
+ File dir = new File(".erj");
+ if (!dir.exists()) {
+ if (!dir.mkdirs())
+ throw new IOException("cannot create " + dir);
+
+ } else if (!dir.canWrite()) {
+ throw new IOException("cannot write to " + dir);
+ }
+
+ return dir;
+ }
}
View
11 src/main/java/erjang/beam/CompilerVisitor.java
@@ -254,6 +254,7 @@ public void visitEnd() {
FieldVisitor fv = cv.visitField(ACC_STATIC, ent.getKey(), "L"
+ EFUN_NAME + f.no + ";", null, null);
+ EFun.ensure(f.no);
AnnotationVisitor av = fv.visitAnnotation(IMPORT_ANN_TYPE
.getDescriptor(), true);
av.visit("module", f.mod.getName());
@@ -446,9 +447,10 @@ public void visitEnd() {
FieldVisitor fv = cv.visitField(ACC_STATIC | ACC_FINAL, mname,
"L" + EFUN_NAME + arity + ";", null, null);
-
+ EFun.ensure(arity);
+
if (isExported(fun_name, arity)) {
- System.err.println("export " + module_name + ":" + fun_name
+ if (ERT.DEBUG) System.err.println("export " + module_name + ":" + fun_name
+ "/" + arity);
AnnotationVisitor an = fv.visitAnnotation(EXPORT_ANN_TYPE
.getDescriptor(), true);
@@ -462,7 +464,7 @@ public void visitEnd() {
funs.put(mname, full_inner_name);
funt.put(mname, EFUN_NAME + arity);
-
+ EFun.ensure(arity);
}
cv.visitInnerClass(full_inner_name, outer_name, inner_name,
@@ -474,6 +476,7 @@ public void visitEnd() {
ClassWeaver w = new ClassWeaver(data, new Compiler.ErjangDetector(self_type.getInternalName()));
for (ClassInfo ci : w.getClassInfos()) {
try {
+ //System.out.println("> storing "+ci.className);
classRepo.store(ci.className, ci.bytes);
} catch (IOException e) {
e.printStackTrace();
@@ -2289,6 +2292,7 @@ public void visitCall(ExtFunc fun, Arg[] args, boolean is_tail,
.getExternalFunction(fun);
String funTypeName = EFUN_NAME + args.length;
+ EFun.ensure(args.length);
mv.visitFieldInsn(GETSTATIC, self_type.getInternalName(),
field, "L" + funTypeName + ";");
mv.visitVarInsn(ALOAD, 0);
@@ -2430,6 +2434,7 @@ public int get_lambda(EAtom fun, int arity) {
ClassWriter cw = new ClassWriter(true);
String super_class_name = EFUN_NAME + (arity - freevars);
+ EFun.ensure(arity-freevars);
cw.visit(V1_6, ACC_FINAL | ACC_PUBLIC, full_inner_name, null,
super_class_name, null);
View
6 src/main/java/erjang/beam/JarClassRepo.java
@@ -51,10 +51,12 @@ public void close() throws IOException {
@Override
public void store(String internalName, byte[] data) throws IOException {
String out = internalName + ".class";
-
+
+ //System.out.println("# "+out);
+
jo.putNextEntry(new ZipEntry(out));
jo.write(data);
-
+ jo.closeEntry();
}
}
View
6 src/main/java/erjang/beam/analysis/BeamTypeAnalysis.java
@@ -300,13 +300,13 @@ private void function_visit_end() {
}
private void dump() {
-
+ if (ERT.DEBUG) {
System.err.println("DUMPING " + name + "/" + arity);
for (Map.Entry<Integer, LabeledBlock> ent : lbs.entrySet()) {
ent.getValue().dump();
}
-
+ }
}
@Override
@@ -1048,6 +1048,7 @@ public void analyze() {
}
private void dump() {
+ if (ERT.DEBUG == false) return;
next_insn: for (int i = 0; i < insns.size(); i++) {
System.err.println(name + "(" + block_label + "):" + i
+ " :: " + (map == null ? "?" : map[i]));
@@ -1504,6 +1505,7 @@ public void analyze0() {
System.out.println("merge " + current + "\n | "
+ lbv.initial + "\n FAILED");
+ throw e;
}
}
View
71 src/main/java/erjang/m/timer/Native.java
@@ -0,0 +1,71 @@
+/**
+ * This file is part of Erjang - A JVM-based Erlang VM
+ *
+ * Copyright (c) 2009 by Trifork
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+
+package erjang.m.timer;
+
+import java.util.concurrent.TimeUnit;
+
+import kilim.Pausable;
+import erjang.BIF;
+import erjang.EAtom;
+import erjang.EFun;
+import erjang.EModule;
+import erjang.ENative;
+import erjang.EObject;
+import erjang.EProc;
+import erjang.ERT;
+import erjang.ESeq;
+import erjang.ETuple;
+import erjang.FunID;
+
+/**
+ *
+ */
+public class Native extends ENative {
+
+ /* (non-Javadoc)
+ * @see erjang.ENative#getNativeClasses()
+ */
+ @Override
+ protected Class<?>[] getNativeClasses() {
+ return new Class[] { Native.class };
+ }
+
+ @BIF
+ public static final EObject tc(EProc proc, EObject mod, EObject fun, EObject args) throws Pausable
+ {
+ long before = System.nanoTime();
+
+ EAtom m = mod.testAtom();
+ EAtom f = fun.testAtom();
+ ESeq a = args.testSeq();
+
+ if (m==null||f==null||a==null) throw ERT.badarg(mod, fun);
+
+ EFun efun = EModule.resolve(new FunID(m,f,a.length()));
+
+ EObject result = efun.apply(proc, a);
+
+ long after = System.nanoTime();
+
+ long micros = TimeUnit.MICROSECONDS.convert(after-before, TimeUnit.NANOSECONDS);
+
+ return ETuple.make(ERT.box(micros), result);
+ }
+}
View
35 src/main/java/erjang/m/timer/timer.java
@@ -0,0 +1,35 @@
+/**
+ * This file is part of Erjang - A JVM-based Erlang VM
+ *
+ * Copyright (c) 2009 by Trifork
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+
+package erjang.m.timer;
+
+/**
+ *
+ */
+public class timer extends erjang.EModule {
+
+ /* (non-Javadoc)
+ * @see erjang.EModule#module_name()
+ */
+ @Override
+ public String module_name() {
+ return "timer";
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.