无论 eval 还是 直接 compile 都生成了jvm字节码类. compile 会在磁盘上生成文件. eval
直接load 不会生成类.
public static Object eval(Object form, boolean freshLoader) {
boolean createdLoader = false;
if(true)//!LOADER.isBound())
{
Var.pushThreadBindings(RT.map(LOADER, RT.makeClassLoader()));
createdLoader = true;
}
try
{
IPersistentMap meta = RT.meta(form);
Object line = (meta != null ? meta.valAt(RT.LINE_KEY, LINE.deref()) : LINE.deref());
Object column = (meta != null ? meta.valAt(RT.COLUMN_KEY, COLUMN.deref()) : COLUMN.deref());
IPersistentMap bindings = RT.mapUniqueKeys(LINE, line, COLUMN, column);
if(meta != null) {
Object eval_file = meta.valAt(RT.EVAL_FILE_KEY);
if(eval_file != null) {
bindings = bindings.assoc(SOURCE_PATH, eval_file);
try {
bindings = bindings.assoc(SOURCE, new File((String)eval_file).getName());
} catch (Throwable t) {
}
}
}
Var.pushThreadBindings(bindings);
try
{
form = macroexpand(form);
if(form instanceof ISeq && Util.equals(RT.first(form), DO))
{
ISeq s = RT.next(form);
for(; RT.next(s) != null; s = RT.next(s))
eval(RT.first(s), false);
return eval(RT.first(s), false);
}
else if((form instanceof IType) ||
(form instanceof IPersistentCollection
&& !(RT.first(form) instanceof Symbol
&& ((Symbol) RT.first(form)).name.startsWith("def"))))
{
ObjExpr fexpr = (ObjExpr) analyze(C.EXPRESSION, RT.list(FN, PersistentVector.EMPTY, form),
"eval" + RT.nextID());
IFn fn = (IFn) fexpr.eval();
return fn.invoke();
}
else
{
Expr expr = analyze(C.EVAL, form);
return expr.eval(); //需要返回
}
}
finally
{
Var.popThreadBindings();
}
}
finally
{
if(createdLoader)
Var.popThreadBindings();
}
}
static void compile1(GeneratorAdapter gen, ObjExpr objx, Object form) {
Object line = lineDeref();
Object column = columnDeref();
if(RT.meta(form) != null && RT.meta(form).containsKey(RT.LINE_KEY))
line = RT.meta(form).valAt(RT.LINE_KEY);
if(RT.meta(form) != null && RT.meta(form).containsKey(RT.COLUMN_KEY))
column = RT.meta(form).valAt(RT.COLUMN_KEY);
Var.pushThreadBindings(
RT.map(LINE, line, COLUMN, column
,LOADER, RT.makeClassLoader()
));
try
{
form = macroexpand(form);
if(form instanceof ISeq && Util.equals(RT.first(form), DO))
{
for(ISeq s = RT.next(form); s != null; s = RT.next(s))
{
compile1(gen, objx, RT.first(s));
}
}
else
{
Expr expr = analyze(C.EVAL, form);
objx.keywords = (IPersistentMap) KEYWORDS.deref();
objx.vars = (IPersistentMap) VARS.deref();
objx.constants = (PersistentVector) CONSTANTS.deref();
expr.emit(C.EXPRESSION, objx, gen);
expr.eval(); // 不需要返回 ,但 eval 和compile 都会 eval .
//这就是clojure文件中写了调用函数都会执行的原因
}
}
finally
{
Var.popThreadBindings();
}
}
网友评论