changeset 327:0be73ac9103d

handle circular package loading git-svn-id: https://luan-java.googlecode.com/svn/trunk@328 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Thu, 19 Mar 2015 05:36:05 +0000
parents db37d6aee4db
children 71e4f4ce74a3
files core/src/luan/impl/LuanCompiler.java core/src/luan/modules/PackageLuan.java
diffstat 2 files changed, 39 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/impl/LuanCompiler.java	Thu Mar 19 00:01:57 2015 +0000
+++ b/core/src/luan/impl/LuanCompiler.java	Thu Mar 19 05:36:05 2015 +0000
@@ -16,8 +16,7 @@
 	private LuanCompiler() {}  // never
 
 	public static LuanFunction compile(LuanState luan,LuanSource src,LuanTable env,boolean allowExpr) throws LuanException {
-		boolean passedEnv = env != null;
-		if( !passedEnv )
+		if( env==null )
 			env = Luan.newTable();
 		UpValue.Getter envGetter = new UpValue.ValueGetter(env);
 		LuanParser parser = new LuanParser(src,envGetter);
@@ -25,17 +24,7 @@
 		parser.addVar( "require", PackageLuan.requireFn );
 		FnDef fnDef = parse(luan,parser,allowExpr);
 		final LuanStateImpl luanImpl = (LuanStateImpl)luan;
-		final Closure c = new Closure(luanImpl,fnDef);
-		if( passedEnv )
-			return c;
-		return new LuanFunction() {
-			@Override public Object call(LuanState luan,Object[] args) throws LuanException {
-				Object rtn = c.call(luan,args);
-				if( rtn instanceof Object[] && ((Object[])rtn).length==0 )
-					rtn = c.upValues()[0].get();
-				return rtn;
-			}
-		};
+		return new Closure(luanImpl,fnDef);
 	}
 
 	private static FnDef parse(LuanState luan,LuanParser parser,boolean allowExpr) throws LuanException {
--- a/core/src/luan/modules/PackageLuan.java	Thu Mar 19 00:01:57 2015 +0000
+++ b/core/src/luan/modules/PackageLuan.java	Thu Mar 19 05:36:05 2015 +0000
@@ -3,7 +3,8 @@
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
 import luan.Luan;
 import luan.LuanState;
 import luan.LuanTable;
@@ -46,25 +47,46 @@
 		if( mod == null ) {
 			if( modName.startsWith("java:") ) {
 				mod = JavaLuan.load(luan,modName.substring(5));
-				if( mod == null )
-					return null;
+				if( mod != null )
+					loaded.put(modName,mod);
 			} else {
 				String src = read(luan,modName+".luan");
 				if( src == null )
 					return null;
-				LuanFunction loader = BasicLuan.load(luan,src,modName,null,false);
-				mod = Luan.first(
-					luan.call(loader,"<require \""+modName+"\">",new Object[]{modName})
-				);
-			}
-			if( mod != null ) {
-				loaded.put(modName,mod);
-			} else {
-				mod = loaded.get(modName);
-				if( mod==null ) {
-					mod = true;
+				LuanTable env = Luan.newTable();
+				LuanFunction loader = BasicLuan.load(luan,src,modName,env,false);
+				loaded.put(modName,env);
+				@SuppressWarnings("unchecked")
+				Set<String> loading = (Set<String>)luan.registry().get("Package.loading");
+				boolean top = loading==null;
+				if(top) {
+					loading = new HashSet<String>();
+					luan.registry().put("Package.loading",loading);
+				}
+				loading.add(modName);
+				boolean ok = false;
+				try {
+					mod = Luan.first(
+						luan.call(loader,"<require \""+modName+"\">",new Object[]{modName})
+					);
+					ok = true;
+				} finally {
+					if( !ok ) {
+						if(top) {
+							for( String mn : loading ) {
+								loaded.put(mn,null);
+							}
+						} else {
+							loaded.put(modName,null);
+						}
+					}
+					if(top)
+						luan.registry().put("Package.loading",null);
+				}
+				if( mod != null )
 					loaded.put(modName,mod);
-				}
+				else
+					mod = env;
 			}
 		}
 		return mod;