Skip to content

Commit

Permalink
Move code-generation code out of EFun (and into new package erjang.co…
Browse files Browse the repository at this point in the history
…degen).
  • Loading branch information
esstrifork committed Jan 20, 2014
1 parent 0008f77 commit c3326bd
Show file tree
Hide file tree
Showing 9 changed files with 818 additions and 798 deletions.
714 changes: 28 additions & 686 deletions src/main/java/erjang/EFun.java

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/main/java/erjang/EModule.java
Expand Up @@ -22,6 +22,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import erjang.codegen.EFunCG;
import kilim.Pausable;


Expand Down Expand Up @@ -144,7 +145,7 @@ protected void process_native_annotations(Class<?> nat) throws Exception {

//System.out.println("N export " + f);

EModuleManager.add_export(this, f, EFun.make(method, mod));
EModuleManager.add_export(this, f, EFunCG.funForMethod(method, mod));
}

}
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/erjang/EModuleClassLoader.java
Expand Up @@ -25,6 +25,7 @@
import java.net.URLClassLoader;

import erjang.beam.RamClassRepo;
import erjang.codegen.EFunCG;

/**
* Each module has its own class loader.
Expand Down Expand Up @@ -66,10 +67,10 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
int num_start = EFUN_NAME.length();
int num_end = name.length() - "Exported".length();
int arity = Integer.parseInt(name.substring(num_start, num_end));
return EFun.get_exported_fun_class(arity);
return EFunCG.get_exported_fun_class(arity);
} else {
int arity = Integer.parseInt(name.substring(EFUN_NAME.length()));
return EFun.get_fun_class(arity);
return EFunCG.get_fun_class(arity);
}
}

Expand Down
141 changes: 71 additions & 70 deletions src/main/java/erjang/EModuleManager.java
Expand Up @@ -34,6 +34,7 @@
import java.util.logging.Logger;

import erjang.beam.Compiler;
import erjang.codegen.EFunCG;
import erjang.m.erlang.ErlBif;
import erjang.m.java.JavaObject;
import kilim.Pausable;
Expand Down Expand Up @@ -120,73 +121,73 @@ private EFun getFunErrorHandler() {
}

private EFun makeErrorHandler() {
return EFun.get_fun_with_handler(fun.module.getName(), fun.function.getName(), fun.arity,
new EFunHandler() {
@Override
public String toString() {
return "#EFunHandler<" + fun.toString() + ">";
}
public EObject invoke(EProc proc, EObject[] args)
throws Pausable {
/** Get reference to error_handler:undefined_function/3 */
EFun uf = proc.undefined_function.resolved_value;

/** this is just some debugging info to help understand downstream errors */
if (get_module_info(fun.module).is_loaded()) {
if (Boolean.getBoolean("erjang.declare_missing_imports") && fun.function != am_prep_stop && fun.function != am___info__)
log.log(Level.INFO, "MISSING "+fun);
} else {
log.log(Level.FINER, "resolving"+fun);
}

Class<?> c = null;
try {
c = Class.forName(fun.module.getName());
} catch (ClassNotFoundException e) {
}

if (c != null) {
if (fun.function == ERT.am_new) {
Constructor[] cons = c.getConstructors();
return JavaObject.choose_and_invoke_constructor(proc, args, cons);
} else {
Method[] methods = c.getMethods();
return JavaObject.choose_and_invoke_method(proc, null, fun.function, args, methods, true);
}
}
if (uf == null) {
if (!module_loaded(fun.module)) {
try {
EModuleLoader.find_and_load_module(fun.module.getName());
} catch (IOException e) {
// we don't report this separately; it ends up causing an undefined below...
}
}
if (resolved_value != null) {
return resolved_value.invoke(proc, args);
}
/** this is just some debugging info to help understand downstream errors */
log.log(Level.INFO, "failed to load "+fun+" ("+proc.undefined_function+" not found)");
throw new ErlangUndefined(fun.module,
fun.function, fun.arity);
} else {
ESeq arg_list = ESeq.fromArray(args);
ESeq ufa = ESeq.fromArray(new EObject[] {
fun.module, fun.function, arg_list });
return ErlBif.apply_last(proc, uf, ufa);
// return uf.apply(proc, ufa);
}
}
},
getModuleClassLoader());
return EFunCG.get_fun_with_handler(fun.module.getName(), fun.function.getName(), fun.arity,
new EFunHandler() {

@Override
public String toString() {
return "#EFunHandler<" + fun.toString() + ">";
}

public EObject invoke(EProc proc, EObject[] args)
throws Pausable {

/** Get reference to error_handler:undefined_function/3 */

EFun uf = proc.undefined_function.resolved_value;

/** this is just some debugging info to help understand downstream errors */
if (get_module_info(fun.module).is_loaded()) {
if (Boolean.getBoolean("erjang.declare_missing_imports") && fun.function != am_prep_stop && fun.function != am___info__)
log.log(Level.INFO, "MISSING " + fun);
} else {
log.log(Level.FINER, "resolving" + fun);
}

Class<?> c = null;
try {
c = Class.forName(fun.module.getName());
} catch (ClassNotFoundException e) {
}

if (c != null) {
if (fun.function == ERT.am_new) {
Constructor[] cons = c.getConstructors();
return JavaObject.choose_and_invoke_constructor(proc, args, cons);
} else {
Method[] methods = c.getMethods();
return JavaObject.choose_and_invoke_method(proc, null, fun.function, args, methods, true);
}
}

if (uf == null) {
if (!module_loaded(fun.module)) {
try {
EModuleLoader.find_and_load_module(fun.module.getName());
} catch (IOException e) {
// we don't report this separately; it ends up causing an undefined below...
}
}

if (resolved_value != null) {
return resolved_value.invoke(proc, args);
}

/** this is just some debugging info to help understand downstream errors */
log.log(Level.INFO, "failed to load " + fun + " (" + proc.undefined_function + " not found)");

throw new ErlangUndefined(fun.module,
fun.function, fun.arity);
} else {
ESeq arg_list = ESeq.fromArray(args);
ESeq ufa = ESeq.fromArray(new EObject[]{
fun.module, fun.function, arg_list});
return ErlBif.apply_last(proc, uf, ufa);
// return uf.apply(proc, ufa);
}
}
},
getModuleClassLoader());
}

/**
Expand Down Expand Up @@ -384,7 +385,7 @@ public EFun resolve(EPID pid, EBinary md5, int index, final int old_uniq, final

if (maker == null || !md5.equals(module_md5)) {
LocalFunID fid = new LocalFunID(module, ERT.am_undefined, arity, old_index, index, old_uniq, md5);
return EFun.get_fun_with_handler(this.module.getName(), "badfun", 0, new EFunHandler() {
return EFunCG.get_fun_with_handler(this.module.getName(), "badfun", 0, new EFunHandler() {
@Override
public EObject invoke(EProc proc, EObject[] args) throws Pausable {
throw new ErlangError(am_badfun, args);
Expand All @@ -408,7 +409,7 @@ public EFun resolve(final EPID pid, final int old_uniq, final int old_index, fin

if (maker==null) {
LocalFunID fid = new LocalFunID(module, ERT.am_undef, 0, old_index, 0, old_uniq, empty_md5);
return EFun.get_fun_with_handler(module.getName(), "badfun", 0, new EFunHandler() {
return EFunCG.get_fun_with_handler(module.getName(), "badfun", 0, new EFunHandler() {
@Override
public EObject invoke(EProc proc, EObject[] args) throws Pausable {
throw new ErlangError(am_badfun, args);
Expand Down Expand Up @@ -438,7 +439,7 @@ public void bind_nif(FunID id, EFunHandler handler) throws Exception {
loader = resident.getModuleClassLoader();
}

EFun fun = EFun.get_fun_with_handler(
EFun fun = EFunCG.get_fun_with_handler(
id.module.getName(),
id.function.getName(),
id.arity,
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/erjang/ERT.java
Expand Up @@ -34,6 +34,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import erjang.codegen.EFunCG;
import kilim.Mailbox;
import kilim.Pausable;
import kilim.Task;
Expand Down Expand Up @@ -649,15 +650,15 @@ public static EFun resolve_fun(EObject mod, EObject fun, int arity) {

final EFun pfun = EModuleManager.resolve(new FunID(pmod, f, arity+1));

return EFun.get_fun_with_handler(pmod.getName(), f.getName(), arity, new EFunHandler() {
@Override
public EObject invoke(EProc proc, EObject[] args) throws Pausable {
EObject[] real_args = new EObject[args.length+1];
System.arraycopy(args, 0, real_args, 0, args.length);
real_args[args.length] = tup;
return pfun.invoke(proc, real_args);
}
}, ERT.class.getClassLoader());
return EFunCG.get_fun_with_handler(pmod.getName(), f.getName(), arity, new EFunHandler() {
@Override
public EObject invoke(EProc proc, EObject[] args) throws Pausable {
EObject[] real_args = new EObject[args.length + 1];
System.arraycopy(args, 0, real_args, 0, args.length);
real_args[args.length] = tup;
return pfun.invoke(proc, real_args);
}
}, ERT.class.getClassLoader());

}

Expand Down
15 changes: 8 additions & 7 deletions src/main/java/erjang/beam/CompilerVisitor.java
Expand Up @@ -37,6 +37,7 @@
import java.util.TreeSet;
import java.util.logging.Level;

import erjang.codegen.EFunCG;
import kilim.Pausable;
import kilim.analysis.ClassInfo;
import kilim.analysis.ClassWeaver;
Expand Down Expand Up @@ -325,7 +326,7 @@ public void visitEnd() {

FieldVisitor fv = cv.visitField(ACC_STATIC, ent.getKey(), "L"
+ EFUN_NAME + f.arity + ";", null, null);
EFun.ensure(f.arity);
EFunCG.ensure(f.arity);
AnnotationVisitor av = fv.visitAnnotation(
IMPORT_ANN_TYPE.getDescriptor(), true);
av.visit("module", f.mod.getName());
Expand Down Expand Up @@ -825,7 +826,7 @@ public void visitEnd() {
if (funInfo.mustHaveFun() || uses_on_load) {
FieldVisitor fv = cv.visitField(ACC_STATIC | (uses_on_load ? 0 : ACC_FINAL),
mname, "L" + fun_type + ";", null, null);
EFun.ensure(arity);
EFunCG.ensure(arity);

if (is_exported) {
if (ModuleAnalyzer.log.isLoggable(Level.FINE))
Expand All @@ -850,7 +851,7 @@ public void visitEnd() {

funs.put(mname, full_inner_name);
funt.put(mname, fun_type);
EFun.ensure(arity);
EFunCG.ensure(arity);
make_fun = true;
}
}
Expand Down Expand Up @@ -3349,7 +3350,7 @@ public void visitCall(ExtFun fun, Arg[] args, boolean is_tail,
field = EUtil.getJavaName(fun.fun, fun.arity);

String funTypeName = EFUN_NAME + args.length;
EFun.ensure(args.length);
EFunCG.ensure(args.length);
mv.visitFieldInsn(GETSTATIC,
self_type.getInternalName(), field, "L"
+ funTypeName + ";");
Expand Down Expand Up @@ -3629,13 +3630,13 @@ public static byte[] make_invoker(String module, String function,

if (is_guard) {
super_class_name = EFUN_NAME + residual_arity + "Guard";
EFun.ensure_guard(residual_arity);
EFunCG.ensure_guard(residual_arity);
} else if (exported) {
super_class_name = EFUN_NAME + residual_arity + "Exported";
EFun.ensure_exported(residual_arity);
EFunCG.ensure_exported(residual_arity);
} else {
super_class_name = EFUN_NAME + residual_arity;
EFun.ensure(residual_arity);
EFunCG.ensure(residual_arity);
}

cw.visit(V1_6, ACC_FINAL | ACC_PUBLIC, full_inner_name, null,
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/erjang/beam/interpreter/Interpreter.template
Expand Up @@ -24,6 +24,7 @@ import erjang.EModule;
import erjang.EModuleManager;
import erjang.EFun;
import erjang.EFunHandler;
import erjang.codegen.EFunCG;
import erjang.FunID;

import erjang.ERT;
Expand Down Expand Up @@ -172,7 +173,7 @@ public class Interpreter extends AbstractInterpreter {

if (bif != null && java.lang.reflect.Modifier.isStatic(bif.javaMethod.getModifiers())) {
//TODO: make this work for virtual methods as well
ext_funs[i] = EFun.make(bif.javaMethod, this.module_name());
ext_funs[i] = EFunCG.funForMethod(bif.javaMethod, this.module_name());
} else {
EModuleManager.add_import(imp, new VectorFunBinder(ext_funs, imp, i));
}
Expand All @@ -181,7 +182,7 @@ public class Interpreter extends AbstractInterpreter {
int j=0;
for (FunIDWithEntry fi : exports) {
log.finer("INT| Export #"+(j++)+": "+fi);
EFun fun = EFun.get_fun_with_handler(fi.module.toString(), fi.function.toString(), fi.arity, new Function(fi.start_pc), getModuleClassLoader());
EFun fun = EFunCG.get_fun_with_handler(fi.module.toString(), fi.function.toString(), fi.arity, new Function(fi.start_pc), getModuleClassLoader());
EModuleManager.add_export(this, fi, fun);
}

Expand Down Expand Up @@ -276,7 +277,7 @@ public class Interpreter extends AbstractInterpreter {
#INTERPRET<-REGS_AS_SEQ(arity) xregsSeq(reg,arity)#
#INTERPRET<-REGS_AS_ARRAY(arity) xregsArray(reg,arity)#
#INTERPRET<-LOCAL_CALL(keep,label) invoke_local(proc, reg, keep,label)#
#INTERPRET<-MAKE_CLOSURE(env,arity,label) (EFun.get_fun_with_handler("erlang", "make_fun2", arity, new Closure(env, label), getModuleClassLoader()))#
#INTERPRET<-MAKE_CLOSURE(env,arity,label) (EFunCG.get_fun_with_handler("erlang", "make_fun2", arity, new Closure(env, label), getModuleClassLoader()))#
#INTERPRET<-MAKE_EXH_LINK(new_exh_pc, is_try) (is_try ? new TryExceptionHandler(new_exh_pc, exh) : new CatchExceptionHandler(new_exh_pc, exh))#
#INTERPRET<-RESTORE_EXH(exh_elm) {exh = (ExceptionHandlerStackElement) exh_elm;}#

Expand Down

0 comments on commit c3326bd

Please sign in to comment.