changeset 572:f1601a4ce1aa

fix stack when calling meta-methods
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 12 Jul 2015 21:34:23 -0600
parents cd944b010f25
children 894f991baac5
files core/src/luan/LuanBit.java core/src/luan/LuanException.java core/src/luan/LuanJavaFunction.java core/src/luan/LuanState.java core/src/luan/LuanTable.java core/src/luan/impl/ConcatExpr.java core/src/luan/impl/LenExpr.java core/src/luan/impl/SetTableEntry.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/HtmlLuan.java core/src/luan/modules/IoLuan.java core/src/luan/modules/JavaLuan.java core/src/luan/modules/PackageLuan.java core/src/luan/modules/PickleCon.java core/src/luan/modules/StringLuan.java core/src/luan/modules/TableLuan.java http/src/luan/modules/http/Http.luan http/src/luan/modules/http/HttpServicer.java http/src/luan/modules/http/Http_test.luan logging/src/luan/modules/logging/LuanLogger.java lucene/src/luan/modules/lucene/LuceneIndex.java mail/src/luan/modules/mail/SmtpCon.java
diffstat 22 files changed, 126 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/LuanBit.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/LuanBit.java	Sun Jul 12 21:34:23 2015 -0600
@@ -125,4 +125,18 @@
 		throw exception("attempt to perform arithmetic on a "+type+" value");
 	}
 
+	public String toString(Object obj) throws LuanException {
+		if( obj instanceof LuanTable ) {
+			LuanTable tbl = (LuanTable)obj;
+			return tbl.toString(this);
+		}
+		if( obj == null )
+			return "nil";
+		if( obj instanceof Number )
+			return Luan.toString((Number)obj);
+		if( obj instanceof byte[] )
+			return "binary: " + Integer.toHexString(obj.hashCode());
+		return obj.toString();
+	}
+
 }
--- a/core/src/luan/LuanException.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/LuanException.java	Sun Jul 12 21:34:23 2015 -0600
@@ -12,10 +12,10 @@
 	}
 
 	LuanException(LuanBit bit,Object msg) throws LuanException {
-		this( bit.luan.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
+		this( bit.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
 		table.rawPut( "java", this );
 		table.rawPut( "message", msg );
-		table.rawPut( "message_string", bit.luan.toString(msg) );
+		table.rawPut( "message_string", bit.toString(msg) );
 		for( StackTraceElement ste : bit.stackTrace() ) {
 			LuanTable tbl = new LuanTable();
 			tbl.rawPut( "source", ste.call.source.name );
--- a/core/src/luan/LuanJavaFunction.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/LuanJavaFunction.java	Sun Jul 12 21:34:23 2015 -0600
@@ -383,7 +383,7 @@
 		public Object convert(LuanState luan,Object obj) throws LuanException {
 			if( obj instanceof LuanTable ) {
 				LuanTable t = (LuanTable)obj;
-				return t.asMap(luan);
+				return t.asMap(luan.JAVA);
 			}
 			return obj;
 		}
@@ -410,8 +410,8 @@
 		public Object convert(LuanState luan,Object obj) throws LuanException {
 			if( obj instanceof LuanTable ) {
 				LuanTable t = (LuanTable)obj;
-				if( t.isSet(luan) )
-					return t.asSet(luan);
+				if( t.isSet(luan.JAVA) )
+					return t.asSet(luan.JAVA);
 			}
 			return obj;
 		}
@@ -426,8 +426,8 @@
 				LuanTable t = (LuanTable)obj;
 				if( t.isList() )
 					return t.asList();
-				if( t.isSet(luan) )
-					return t.asSet(luan);
+				if( t.isSet(luan.JAVA) )
+					return t.asSet(luan.JAVA);
 			}
 			return obj;
 		}
--- a/core/src/luan/LuanState.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/LuanState.java	Sun Jul 12 21:34:23 2015 -0600
@@ -63,27 +63,13 @@
 		return call(fn);
 	}
 
-	public String toString(Object obj) throws LuanException {
-		if( obj instanceof LuanTable ) {
-			LuanTable tbl = (LuanTable)obj;
-			return tbl.toString(this);
-		}
-		if( obj == null )
-			return "nil";
-		if( obj instanceof Number )
-			return Luan.toString((Number)obj);
-		if( obj instanceof byte[] )
-			return "binary: " + Integer.toHexString(obj.hashCode());
-		return obj.toString();
-	}
-
 	public final LuanBit bit(LuanElement el) {
 		return new LuanBit(this,el);
 	}
 
 	// convenience methods
 
-	final LuanBit JAVA = bit(null);
+	public final LuanBit JAVA = bit(null);
 
 	public LuanException exception(Object msg) throws LuanException {
 		return JAVA.exception(msg);
--- a/core/src/luan/LuanTable.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/LuanTable.java	Sun Jul 12 21:34:23 2015 -0600
@@ -92,23 +92,23 @@
 		return list!=null ? list : Collections.emptyList();
 	}
 
-	public String toString(LuanState luan) throws LuanException {
+	public String toString(LuanBit bit) throws LuanException {
 		Object h = getHandler("__to_string");
 		if( h == null )
 			return rawToString();
 		if( h instanceof LuanMeta ) {
 			LuanMeta meta = (LuanMeta)h;
-			return meta.__to_string(luan,this);
+			return meta.__to_string(bit.luan,this);
 		}
-		LuanFunction fn = luan.checkFunction(h);
-		return luan.checkString( Luan.first( luan.call(fn,"__to_string",new Object[]{this}) ) );
+		LuanFunction fn = bit.checkFunction(h);
+		return bit.checkString( Luan.first( bit.call(fn,"__to_string",new Object[]{this}) ) );
 	}
 
 	public String rawToString() {
 		return "table: " + Integer.toHexString(hashCode());
 	}
 
-	public Object get(LuanState luan,Object key) throws LuanException {
+	public Object get(LuanBit bit,Object key) throws LuanException {
 		Object value = rawGet(key);
 		if( value != null )
 			return value;
@@ -117,22 +117,21 @@
 			return null;
 		if( h instanceof LuanFunction ) {
 			LuanFunction fn = (LuanFunction)h;
-			return Luan.first(luan.call(fn,"__index",new Object[]{this,key}));
+			return Luan.first(bit.call(fn,"__index",new Object[]{this,key}));
 		}
 		if( h instanceof LuanMeta ) {
 			LuanMeta meta = (LuanMeta)h;
-			return meta.__index(luan,this,key);
+			return meta.__index(bit.luan,this,key);
 		}
-		return index(luan.JAVA,h,key);
+		return index(bit,h,key);
 	}
 
 	public static Object index(LuanBit bit,Object obj,Object key) throws LuanException {
-		LuanState luan = bit.luan;
 		if( obj instanceof LuanTable ) {
 			LuanTable tbl = (LuanTable)obj;
-			return tbl.get(luan,key);
+			return tbl.get(bit,key);
 		}
-		if( obj != null && luan.hasJava() )
+		if( obj != null && bit.luan.hasJava() )
 			return JavaLuan.__index(bit,obj,key,false);
 		else if( bit.el==null )
 			throw bit.exception( "attempt to index a " + Luan.type(obj) + " value" );
@@ -158,7 +157,7 @@
 		return map.get(key);
 	}
 
-	public void put(LuanState luan,Object key,Object value) throws LuanException {
+	public void put(LuanBit bit,Object key,Object value) throws LuanException {
 		Object h = getHandler("__new_index");
 		if( h==null || rawGet(key)!=null ) {
 			rawPut(key,value);
@@ -166,20 +165,20 @@
 		}
 		if( h instanceof LuanFunction ) {
 			LuanFunction fn = (LuanFunction)h;
-			luan.call(fn,"__new_index",new Object[]{this,key,value});
+			bit.call(fn,"__new_index",new Object[]{this,key,value});
 			return;
 		}
 		if( h instanceof LuanMeta ) {
 			LuanMeta meta = (LuanMeta)h;
-			meta.__new_index(luan,this,key,value);
+			meta.__new_index(bit.luan,this,key,value);
 			return;
 		}
 		if( h instanceof LuanTable ) {
 			LuanTable tbl = (LuanTable)h;
-			tbl.put(luan,key,value);
+			tbl.put(bit,key,value);
 			return;
 		}
-		throw luan.exception("invalid type "+Luan.type(h)+" for metamethod __new_index");
+		throw bit.exception("invalid type "+Luan.type(h)+" for metamethod __new_index");
 	}
 
 	public void rawPut(Object key,Object val) {
@@ -263,11 +262,11 @@
 		Collections.sort(list(),cmp);
 	}
 
-	public int length(LuanState luan) throws LuanException {
+	public int length(LuanBit bit) throws LuanException {
 		Object h = getHandler("__len");
 		if( h != null ) {
-			LuanFunction fn = luan.checkFunction(h);
-			return (Integer)Luan.first(luan.call(fn,"__len",new Object[]{this}));
+			LuanFunction fn = bit.checkFunction(h);
+			return (Integer)Luan.first(bit.call(fn,"__len",new Object[]{this}));
 		}
 		return rawLength();
 	}
@@ -276,8 +275,8 @@
 		return list==null ? 0 : list.size();
 	}
 
-	public Iterable<Map.Entry<Object,Object>> iterable(LuanState luan) throws LuanException {
-		final Iterator<Map.Entry<Object,Object>> iter = iterator(luan);
+	public Iterable<Map.Entry<Object,Object>> iterable(LuanBit bit) throws LuanException {
+		final Iterator<Map.Entry<Object,Object>> iter = iterator(bit);
 		return new Iterable<Map.Entry<Object,Object>>() {
 			public Iterator<Map.Entry<Object,Object>> iterator() {
 				return iter;
@@ -294,16 +293,16 @@
 		};
 	}
 
-	public Iterator<Map.Entry<Object,Object>> iterator(final LuanState luan) throws LuanException {
+	public Iterator<Map.Entry<Object,Object>> iterator(final LuanBit bit) throws LuanException {
 		if( getHandler("__pairs") == null )
 			return rawIterator();
-		final LuanFunction fn = pairs(luan);
+		final LuanFunction fn = pairs(bit);
 		return new Iterator<Map.Entry<Object,Object>>() {
 			private Map.Entry<Object,Object> next = getNext();
 
 			private Map.Entry<Object,Object> getNext() {
 				try {
-					Object obj = luan.call(fn);
+					Object obj = bit.call(fn,null,LuanFunction.NOTHING);
 					if( obj==null )
 						return null;
 					Object[] a = (Object[])obj;
@@ -331,20 +330,20 @@
 		};
 	}
 
-	public LuanFunction pairs(final LuanState luan) throws LuanException {
+	public LuanFunction pairs(LuanBit bit) throws LuanException {
 		Object h = getHandler("__pairs");
 		if( h != null ) {
 			if( h instanceof LuanFunction ) {
-				Object obj = Luan.first(luan.call((LuanFunction)h,"__pairs",new Object[]{this}));
+				Object obj = Luan.first(bit.call((LuanFunction)h,"__pairs",new Object[]{this}));
 				if( !(obj instanceof LuanFunction) )
-					throw luan.exception( "metamethod __pairs should return function but returned " + Luan.type(obj) );
+					throw bit.exception( "metamethod __pairs should return function but returned " + Luan.type(obj) );
 				return (LuanFunction)obj;
 			}
 			if( h instanceof LuanMeta ) {
 				LuanMeta meta = (LuanMeta)h;
-				return meta.__pairs(luan,this);
+				return meta.__pairs(bit.luan,this);
 			}
-			throw luan.exception( "invalid type of metamethod __pairs: " + Luan.type(h) );
+			throw bit.exception( "invalid type of metamethod __pairs: " + Luan.type(h) );
 		}
 		return rawPairs();
 	}
@@ -437,25 +436,25 @@
 		return new LinkedHashMap<Object,Object>();
 	}
 
-	public boolean isSet(LuanState luan) throws LuanException {
-		for( Map.Entry<Object,Object> entry : iterable(luan) ) {
+	public boolean isSet(LuanBit bit) throws LuanException {
+		for( Map.Entry<Object,Object> entry : iterable(bit) ) {
 			if( !entry.getValue().equals(Boolean.TRUE) )
 				return false;
 		}
 		return true;
 	}
 
-	public Set<Object> asSet(LuanState luan) throws LuanException {
+	public Set<Object> asSet(LuanBit bit) throws LuanException {
 		Set<Object> set = new HashSet<Object>();
-		for( Map.Entry<Object,Object> entry : iterable(luan) ) {
+		for( Map.Entry<Object,Object> entry : iterable(bit) ) {
 			set.add(entry.getKey());
 		}
 		return set;
 	}
 
-	public Map<Object,Object> asMap(LuanState luan) throws LuanException {
+	public Map<Object,Object> asMap(LuanBit bit) throws LuanException {
 		Map<Object,Object> map = newMap();
-		for( Map.Entry<Object,Object> entry : iterable(luan) ) {
+		for( Map.Entry<Object,Object> entry : iterable(bit) ) {
 			map.put(entry.getKey(),entry.getValue());
 		}
 		return map;
--- a/core/src/luan/impl/ConcatExpr.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/impl/ConcatExpr.java	Sun Jul 12 21:34:23 2015 -0600
@@ -20,8 +20,8 @@
 		LuanFunction fn = bit.getBinHandler("__concat",o1,o2);
 		if( fn != null )
 			return Luan.first(bit.call(fn,"__concat",new Object[]{o1,o2}));
-		String s1 = luan.toString(o1);
-		String s2 = luan.toString(o2);
+		String s1 = luan.bit(op1.el()).toString(o1);
+		String s2 = luan.bit(op2.el()).toString(o2);
 		return s1 + s2;
 	}
 }
--- a/core/src/luan/impl/LenExpr.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/impl/LenExpr.java	Sun Jul 12 21:34:23 2015 -0600
@@ -28,6 +28,6 @@
 		if( !(o instanceof LuanTable) )
 			throw bit.exception( "attempt to get length of a " + Luan.type(o) + " value" );
 		LuanTable t = (LuanTable)o;
-		return t.length(luan);
+		return t.length(bit);
 	}
 }
--- a/core/src/luan/impl/SetTableEntry.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/impl/SetTableEntry.java	Sun Jul 12 21:34:23 2015 -0600
@@ -25,12 +25,12 @@
 	}
 
 	private void newIndex(LuanStateImpl luan,Object t,Object key,Object value) throws LuanException {
+		LuanBit bit = luan.bit(el());
 		if( t instanceof LuanTable ) {
 			LuanTable tbl = (LuanTable)t;
-			tbl.put(luan,key,value);
+			tbl.put(bit,key,value);
 			return;
 		}
-		LuanBit bit = luan.bit(el());
 		if( t != null && luan.hasJava() )
 			JavaLuan.__new_index(bit,t,key,value);
 		else
--- a/core/src/luan/modules/BasicLuan.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/BasicLuan.java	Sun Jul 12 21:34:23 2015 -0600
@@ -45,7 +45,7 @@
 
 	public static LuanFunction pairs(final LuanState luan,final LuanTable t) throws LuanException {
 		Utils.checkNotNull(luan,t);
-		return t.pairs(luan);
+		return t.pairs(luan.JAVA);
 	}
 
 	public static LuanFunction ipairs(LuanState luan,final LuanTable t) throws LuanException {
@@ -105,7 +105,7 @@
 	}
 
 	public static String to_string(LuanState luan,Object v) throws LuanException {
-		return luan.toString(v);
+		return luan.JAVA.toString(v);
 	}
 
 	public static LuanTable new_error(LuanState luan,Object msg) throws LuanException {
@@ -183,21 +183,21 @@
 
 	public static Object try_(LuanState luan,LuanTable blocks) throws LuanException {
 		Utils.checkNotNull(luan,blocks);
-		Object obj = blocks.get(luan,1);
+		Object obj = blocks.get(luan.JAVA,1);
 		if( obj == null )
 			throw luan.exception("missing 'try' value");
 		if( !(obj instanceof LuanFunction) )
 			throw luan.exception("bad 'try' value (function expected, got "+Luan.type(obj)+")");
 		LuanFunction tryFn = (LuanFunction)obj;
 		LuanFunction catchFn = null;
-		obj = blocks.get(luan,"catch");
+		obj = blocks.get(luan.JAVA,"catch");
 		if( obj != null ) {
 			if( !(obj instanceof LuanFunction) )
 				throw luan.exception("bad 'catch' value (function expected, got "+Luan.type(obj)+")");
 			catchFn = (LuanFunction)obj;
 		}
 		LuanFunction finallyFn = null;
-		obj = blocks.get(luan,"finally");
+		obj = blocks.get(luan.JAVA,"finally");
 		if( obj != null ) {
 			if( !(obj instanceof LuanFunction) )
 				throw luan.exception("bad 'finally' value (function expected, got "+Luan.type(obj)+")");
--- a/core/src/luan/modules/HtmlLuan.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/HtmlLuan.java	Sun Jul 12 21:34:23 2015 -0600
@@ -282,20 +282,20 @@
 				buf.append( o );
 			} else if( o instanceof LuanTable ) {
 				LuanTable t = (LuanTable)o;
-				String type = (String)t.get(luan,"type");
+				String type = (String)t.get(luan.JAVA,"type");
 				if( type==null )
 					throw luan.exception( "no type in element of table for 'Html.to_string'" );
 				if( type.equals("comment") ) {
-					buf.append( "<!--" ).append( t.get(luan,"text") ).append( "-->" );
+					buf.append( "<!--" ).append( t.get(luan.JAVA,"text") ).append( "-->" );
 				} else if( type.equals("cdata") ) {
-					buf.append( "<![CDATA[" ).append( t.get(luan,"text") ).append( "]]" );
+					buf.append( "<![CDATA[" ).append( t.get(luan.JAVA,"text") ).append( "]]" );
 				} else if( type.equals("tag") ) {
 					buf.append( tagToString(luan,t) );
 				} else if( type.equals("container") ) {
-					LuanTable tag  = (LuanTable)t.get(luan,"tag");
+					LuanTable tag  = (LuanTable)t.get(luan.JAVA,"tag");
 					buf.append( tagToString(luan,tag) );
-					buf.append( t.get(luan,"text") );
-					buf.append( "</" ).append( tag.get(luan,"name") ).append( ">" );
+					buf.append( t.get(luan.JAVA,"text") );
+					buf.append( "</" ).append( tag.get(luan.JAVA,"name") ).append( ">" );
 				} else {
 					throw luan.exception( "invalid element type for 'Html.to_string'" );
 				}
@@ -308,9 +308,9 @@
 	private static String tagToString(LuanState luan,LuanTable tbl) throws LuanException {
 		StringBuilder buf = new StringBuilder();
 		buf.append('<');
-		buf.append(tbl.get(luan,"name"));
-		LuanTable attributes = (LuanTable)tbl.get(luan,"attributes");
-		for( Map.Entry<Object,Object> attr : attributes.iterable(luan) ) {
+		buf.append(tbl.get(luan.JAVA,"name"));
+		LuanTable attributes = (LuanTable)tbl.get(luan.JAVA,"attributes");
+		for( Map.Entry<Object,Object> attr : attributes.iterable(luan.JAVA) ) {
 			buf.append( ' ' );
 			buf.append( attr.getKey() );
 			Object val = attr.getValue();
@@ -319,7 +319,7 @@
 				buf.append( quote((String)val) );
 			}
 		}
-		if( tbl.get(luan,"is_empty").equals(Boolean.TRUE) )
+		if( tbl.get(luan.JAVA,"is_empty").equals(Boolean.TRUE) )
 			buf.append('/');
 		buf.append('>');
 		return buf.toString();
--- a/core/src/luan/modules/IoLuan.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/IoLuan.java	Sun Jul 12 21:34:23 2015 -0600
@@ -58,7 +58,7 @@
 
 			public void write(LuanState luan,Object... args) throws LuanException {
 				for( Object obj : args ) {
-					out.print( luan.toString(obj) );
+					out.print( luan.JAVA.toString(obj) );
 				}
 			}
 
@@ -74,7 +74,7 @@
 
 			public void write(LuanState luan,Object... args) throws LuanException, IOException {
 				for( Object obj : args ) {
-					out.write( luan.toString(obj) );
+					out.write( luan.JAVA.toString(obj) );
 				}
 			}
 
@@ -339,7 +339,7 @@
 	
 				public void write(LuanState luan,Object... args) throws LuanException, IOException {
 					for( Object obj : args ) {
-						out.write( luan.toString(obj) );
+						out.write( luan.JAVA.toString(obj) );
 					}
 				}
 	
@@ -552,7 +552,7 @@
 
 	public static LuanTable stdin(LuanState luan) throws LuanException {
 		LuanTable io = (LuanTable)PackageLuan.require(luan,"luan:Io");
-		return (LuanTable)io.get(luan,"stdin");
+		return (LuanTable)io.get(luan.JAVA,"stdin");
 	}
 
 	public static LuanTable newSchemes() {
@@ -576,7 +576,7 @@
 		LuanTable t = (LuanTable)PackageLuan.loaded(luan).rawGet("luan:Io");
 		if( t == null )
 			return newSchemes();
-		t = (LuanTable)t.get(luan,"schemes");
+		t = (LuanTable)t.get(luan.JAVA,"schemes");
 		if( t == null )
 			return newSchemes();
 		return t;
@@ -589,7 +589,7 @@
 		String scheme = name.substring(0,i);
 		String location = name.substring(i+1);
 		LuanTable schemes = schemes(luan);
-		LuanFunction opener = (LuanFunction)schemes.get(luan,scheme);
+		LuanFunction opener = (LuanFunction)schemes.get(luan.JAVA,scheme);
 		if( opener == null )
 			throw luan.exception( "invalid scheme '"+scheme+"' in '"+name+"'" );
 		return (LuanTable)Luan.first(luan.call(opener,"<open \""+name+"\">",new Object[]{location,addExtension}));
--- a/core/src/luan/modules/JavaLuan.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/JavaLuan.java	Sun Jul 12 21:34:23 2015 -0600
@@ -331,7 +331,7 @@
 						if( args==null )
 							args = new Object[0];
 						String name = method.getName();
-						Object fnObj = t.get(luan,name);
+						Object fnObj = t.get(luan.JAVA,name);
 						if( fnObj == null )
 							throw new NullPointerException("luan_proxy couldn't find method '"+name+"'");
 						LuanFunction fn = luan.checkFunction(fnObj);
--- a/core/src/luan/modules/PackageLuan.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/PackageLuan.java	Sun Jul 12 21:34:23 2015 -0600
@@ -69,11 +69,11 @@
 		LuanTable t = IoLuan.uri(luan,uri,addExtension);
 		if( t == null )
 			return null;
-		LuanFunction existsFn = (LuanFunction)t.get(luan,"exists");
+		LuanFunction existsFn = (LuanFunction)t.get(luan.JAVA,"exists");
 		boolean exists = (Boolean)Luan.first(luan.call(existsFn));
 		if( !exists )
 			return null;
-		LuanFunction reader = (LuanFunction)t.get(luan,"read_text");
+		LuanFunction reader = (LuanFunction)t.get(luan.JAVA,"read_text");
 		return (String)Luan.first(luan.call(reader));
 	}
 
--- a/core/src/luan/modules/PickleCon.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/PickleCon.java	Sun Jul 12 21:34:23 2015 -0600
@@ -96,7 +96,7 @@
 		}
 		StringBuilder sb = new StringBuilder();
 		sb.append( "{" );
-		for( Map.Entry<Object,Object> entry : tbl.iterable(luan) ) {
+		for( Map.Entry<Object,Object> entry : tbl.iterable(luan.JAVA) ) {
 			sb.append( "[" );
 			sb.append( pickle(entry.getKey(),set) );
 			sb.append( "]=" );
@@ -116,7 +116,7 @@
 			}
 		}
 		for( Object obj : args ) {
-			sb.append( luan.toString(obj) );
+			sb.append( luan.JAVA.toString(obj) );
 		}
 		writeString( sb.toString() );
 //System.out.println("aaaaaaaaaaaaaaaaaaaaaaaa");
--- a/core/src/luan/modules/StringLuan.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/StringLuan.java	Sun Jul 12 21:34:23 2015 -0600
@@ -168,9 +168,9 @@
 			StringBuffer sb = new StringBuffer();
 			while( i<max && m.find() ) {
 				String match = m.groupCount()==0 ? m.group() : m.group(1);
-				Object val = t.get(luan,match);
+				Object val = t.get(luan.JAVA,match);
 				if( val != null ) {
-					String replacement = luan.toString(val);
+					String replacement = luan.JAVA.toString(val);
 					m.appendReplacement(sb,replacement);
 				}
 				i++;
@@ -195,7 +195,7 @@
 				}
 				Object val = Luan.first( luan.call(fn,"repl-arg",args) );
 				if( val != null ) {
-					String replacement = luan.toString(val);
+					String replacement = luan.JAVA.toString(val);
 					m.appendReplacement(sb,replacement);
 				}
 				i++;
@@ -214,7 +214,7 @@
 	public static String concat(LuanState luan,Object... args) throws LuanException {
 		StringBuilder sb = new StringBuilder();
 		for( Object arg : args ) {
-			sb.append( luan.toString(arg) );
+			sb.append( luan.JAVA.toString(arg) );
 		}
 		return sb.toString();
 	}
--- a/core/src/luan/modules/TableLuan.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/core/src/luan/modules/TableLuan.java	Sun Jul 12 21:34:23 2015 -0600
@@ -18,15 +18,15 @@
 
 	public static String concat(LuanState luan,LuanTable list,String sep,Integer i,Integer j) throws LuanException {
 		int first = i==null ? 1 : i;
-		int last = j==null ? list.length(luan) : j;
+		int last = j==null ? list.length(luan.JAVA) : j;
 		StringBuilder buf = new StringBuilder();
 		for( int k=first; k<=last; k++ ) {
-			Object val = list.get(luan,k);
+			Object val = list.get(luan.JAVA,k);
 			if( val==null )
 				break;
 			if( sep!=null && k > first )
 				buf.append(sep);
-			String s = luan.toString(val);
+			String s = luan.JAVA.toString(val);
 			buf.append(s);
 		}
 		return buf.toString();
@@ -92,10 +92,10 @@
 
 	@LuanMethod public static Object[] unpack(LuanState luan,LuanTable tbl,Integer iFrom,Integer iTo) throws LuanException {
 		int from = iFrom!=null ? iFrom : 1;
-		int to = iTo!=null ? iTo : tbl.length(luan);
+		int to = iTo!=null ? iTo : tbl.length(luan.JAVA);
 		List<Object> list = new ArrayList<Object>();
 		for( int i=from; i<=to; i++ ) {
-			list.add( tbl.get(luan,i) );
+			list.add( tbl.get(luan.JAVA,i) );
 		}
 		return list.toArray();
 	}
--- a/http/src/luan/modules/http/Http.luan	Wed Jul 08 23:10:52 2015 -0600
+++ b/http/src/luan/modules/http/Http.luan	Sun Jul 12 21:34:23 2015 -0600
@@ -1,12 +1,12 @@
 java()
 local Luan = require "luan:Luan"
-local ipairs = Luan.ipairs
-local pairs = Luan.pairs
 local error = Luan.error
-local set_metatable = Luan.set_metatable
+local ipairs = Luan.ipairs or error()
+local pairs = Luan.pairs or error()
+local set_metatable = Luan.set_metatable or error()
 local Io = require "luan:Io"
 local Html = require "luan:Html"
-local url_encode = Html.url_encode
+local url_encode = Html.url_encode or error()
 local HttpServicer = require "java:luan.modules.http.HttpServicer"
 local IoLuan = require "java:luan.modules.IoLuan"
 
@@ -31,6 +31,13 @@
 	end
 end
 
+local function sent_error()
+	error "headers are not accessible after you start writing content"
+end
+
+M.sent_error_metatable = { __index=sent_error, __new_index=sent_error }
+
+
 
 local function new_common(this)
 	this = this or {}
@@ -104,6 +111,7 @@
 
 		function this.set()
 			HttpServicer.setResponse(this,this.java)
+			set_metatable(this.headers,M.sent_error_metatable)
 		end
 
 		function this.text_writer()
--- a/http/src/luan/modules/http/HttpServicer.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/http/src/luan/modules/http/HttpServicer.java	Sun Jul 12 21:34:23 2015 -0600
@@ -155,7 +155,6 @@
 		module.rawPut("response",responseTbl);
 
 		luan.call(fn,"<http>");
-//		setResponse(module,response);
 		return true;
 	}
 
@@ -180,9 +179,6 @@
 				throw new IllegalArgumentException("value must be string or integer for headers table");
 			}
 		}
-		// no more headers
-		responseTbl.rawPut("headers",null);
-		responseTbl.rawPut("header",null);
 	}
 
 
--- a/http/src/luan/modules/http/Http_test.luan	Wed Jul 08 23:10:52 2015 -0600
+++ b/http/src/luan/modules/http/Http_test.luan	Sun Jul 12 21:34:23 2015 -0600
@@ -1,8 +1,12 @@
+local Luan = require "luan:Luan"
+local error = Luan.error
+local set_metatable = Luan.set_metatable or error()
 local Io = require "luan:Io"
 local String = require "luan:String"
-local matches = String.matches
+local matches = String.matches or error()
 local Http = require "luan:http/Http"
 
+
 local M = {}
 
 M.welcome_file = "index.html"
@@ -27,7 +31,7 @@
 	Http.response = Http.new_response{
 
 		text_writer = function()
-			Http.response.headers = nil
+			set_metatable(Http.response.headers,M.sent_error_metatable)
 			M.result = Io.uri "string:"
 			M.text_writer = M.result.text_writer()
 			return M.text_writer
--- a/logging/src/luan/modules/logging/LuanLogger.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/logging/src/luan/modules/logging/LuanLogger.java	Sun Jul 12 21:34:23 2015 -0600
@@ -16,19 +16,19 @@
 	}
 
 	public void error(LuanState luan,Object obj) throws LuanException {
-		logger.error( luan.toString(obj) );
+		logger.error( luan.JAVA.toString(obj) );
 	}
 
 	public void warn(LuanState luan,Object obj) throws LuanException {
-		logger.warn( luan.toString(obj) );
+		logger.warn( luan.JAVA.toString(obj) );
 	}
 
 	public void info(LuanState luan,Object obj) throws LuanException {
-		logger.info( luan.toString(obj) );
+		logger.info( luan.JAVA.toString(obj) );
 	}
 
 	public void debug(LuanState luan,Object obj) throws LuanException {
-		logger.debug( luan.toString(obj) );
+		logger.debug( luan.JAVA.toString(obj) );
 	}
 
 }
--- a/lucene/src/luan/modules/lucene/LuceneIndex.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/lucene/src/luan/modules/lucene/LuceneIndex.java	Sun Jul 12 21:34:23 2015 -0600
@@ -134,16 +134,16 @@
 	}
 
 	public void save(LuanState luan,LuanTable doc) throws LuanException, IOException {
-		if( doc.get(luan,"type")==null )
+		if( doc.get(luan.JAVA,"type")==null )
 			throw luan.exception("missing 'type' field");
-		Long id = (Long)doc.get(luan,"id");
+		Long id = (Long)doc.get(luan.JAVA,"id");
 
 		boolean commit = !writeLock.isHeldByCurrentThread();
 		writeLock.lock();
 		try {
 			if( id == null ) {
 				id = nextId(luan);
-				doc.put(luan,"id",id);
+				doc.put(luan.JAVA,"id",id);
 				writer.addDocument(toLucene(luan,doc));
 			} else {
 				writer.updateDocument( term("id",id), toLucene(luan,doc) );
@@ -403,7 +403,7 @@
 	private Document toLucene(LuanState luan,LuanTable table) throws LuanException {
 		Set<String> indexed = mfp.fields.keySet();
 		Document doc = new Document();
-		for( Map.Entry<Object,Object> entry : table.iterable(luan) ) {
+		for( Map.Entry<Object,Object> entry : table.iterable(luan.JAVA) ) {
 			Object key = entry.getKey();
 			if( !(key instanceof String) )
 				throw luan.exception("key must be string");
--- a/mail/src/luan/modules/mail/SmtpCon.java	Wed Jul 08 23:10:52 2015 -0600
+++ b/mail/src/luan/modules/mail/SmtpCon.java	Sun Jul 12 21:34:23 2015 -0600
@@ -25,7 +25,7 @@
 	private final Session session;
 
 	public SmtpCon(LuanState luan,LuanTable paramsTbl) throws LuanException {
-		Map<Object,Object> params = new HashMap<Object,Object>(paramsTbl.asMap(luan));
+		Map<Object,Object> params = new HashMap<Object,Object>(paramsTbl.asMap(luan.JAVA));
 		Properties props = new Properties(System.getProperties());
 
 		String host = getString(luan,params,"host");
@@ -81,7 +81,7 @@
 
 	public void send(LuanState luan,LuanTable mailTbl) throws LuanException {
 		try {
-			Map<Object,Object> mailParams = new HashMap<Object,Object>(mailTbl.asMap(luan));
+			Map<Object,Object> mailParams = new HashMap<Object,Object>(mailTbl.asMap(luan.JAVA));
 			MimeMessage msg = new MimeMessage(session);
 
 			String from = getString(luan,mailParams,"from");
@@ -109,7 +109,7 @@
 					bodyPart.setText((String)body);
 				} else if( body instanceof LuanTable ) {
 					LuanTable bodyTbl = (LuanTable)body;
-					Map<Object,Object> map = new HashMap<Object,Object>(bodyTbl.asMap(luan));
+					Map<Object,Object> map = new HashMap<Object,Object>(bodyTbl.asMap(luan.JAVA));
 					MimeMultipart mp = new MimeMultipart("alternative");
 					String text = (String)map.remove("text");
 					if( text != null ) {
@@ -142,7 +142,7 @@
 				for( Object attachment : attachmentsTbl.asList() ) {
 					if( !(attachment instanceof LuanTable) )
 						throw luan.exception( "each attachment must be a table" );
-					Map<Object,Object> attachmentMap = new HashMap<Object,Object>(((LuanTable)attachment).asMap(luan));
+					Map<Object,Object> attachmentMap = new HashMap<Object,Object>(((LuanTable)attachment).asMap(luan.JAVA));
 					Object obj;
 
 					obj = attachmentMap.remove("filename");