diff core/src/luan/modules/PackageLuan.java @ 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 d34be4588556
children 673eebd83b74
line wrap: on
line diff
--- 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;