changeset 426:23a93c118042

fix LuanTable.get() to use metatables
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 01 May 2015 18:44:20 -0600
parents 0a2fb80907f9
children dae264ad6a7b
files core/src/luan/LuanPropertyMeta.java core/src/luan/LuanTable.java core/src/luan/impl/EqExpr.java core/src/luan/impl/IndexExpr.java core/src/luan/impl/SetTableEntry.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/BinaryLuan.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/PickleServer.java core/src/luan/modules/StringLuan.java core/src/luan/modules/TableLuan.java lucene/src/luan/modules/lucene/LuceneIndex.java lucene/src/luan/modules/lucene/LuceneWriter.java web/src/luan/modules/web/HttpServicer.java
diffstat 17 files changed, 80 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/LuanPropertyMeta.java
--- a/core/src/luan/LuanPropertyMeta.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/LuanPropertyMeta.java	Fri May 01 18:44:20 2015 -0600
@@ -10,19 +10,19 @@
 	private LuanPropertyMeta() {}
 
 	public LuanTable getters(LuanTable tbl) {
-		return (LuanTable)tbl.getMetatable().get("get");
+		return (LuanTable)tbl.getMetatable().rawGet("get");
 	}
 
 	public LuanTable setters(LuanTable tbl) {
-		return (LuanTable)tbl.getMetatable().get("set");
+		return (LuanTable)tbl.getMetatable().rawGet("set");
 	}
 
 	protected String type(LuanTable tbl) {
-		return (String)tbl.getMetatable().get("type");
+		return (String)tbl.getMetatable().rawGet("type");
 	}
 
 	@Override public Object __index(LuanState luan,LuanTable tbl,Object key) throws LuanException {
-		Object obj = getters(tbl).get(key);
+		Object obj = getters(tbl).rawGet(key);
 		if( obj == null )
 			return null;
 		if( !(obj instanceof LuanFunction) )
@@ -53,7 +53,7 @@
 	}
 
 	@Override public void __newindex(LuanState luan,LuanTable tbl,Object key,Object value) throws LuanException {
-		Object obj = setters(tbl).get(key);
+		Object obj = setters(tbl).rawGet(key);
 		if( obj == null )
 			throw luan.exception("can't set property '"+key+"'");
 		if( !(obj instanceof LuanFunction) )
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/LuanTable.java
--- a/core/src/luan/LuanTable.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/LuanTable.java	Fri May 01 18:44:20 2015 -0600
@@ -90,7 +90,29 @@
 		return list!=null ? list : Collections.emptyList();
 	}
 
-	public Object get(Object key) {
+	public Object get(LuanState luan,Object key) throws LuanException {
+		Object value = rawGet(key);
+		if( value != null )
+			return value;
+		Object h = getHandler("__index");
+		if( h==null )
+			return null;
+		if( h instanceof LuanFunction ) {
+			LuanFunction fn = (LuanFunction)h;
+			return Luan.first(luan.call(fn,"__index",new Object[]{this,key}));
+		}
+		if( h instanceof LuanMeta ) {
+			LuanMeta meta = (LuanMeta)h;
+			return meta.__index(luan,this,key);
+		}
+		if( h instanceof LuanTable ) {
+			LuanTable tbl = (LuanTable)h;
+			return tbl.get(luan,key);
+		}
+		throw luan.exception("invalid type "+Luan.type(h)+" for metamethod __index");
+	}
+
+	public Object rawGet(Object key) {
 		if( list != null ) {
 			Integer iT = Luan.asInteger(key);
 			if( iT != null ) {
@@ -260,7 +282,7 @@
 
 	public Object getHandler(String op) {
 		LuanTable t = getMetatable();
-		return t==null ? null : t.get(op);
+		return t==null ? null : t.rawGet(op);
 	}
 
 	public boolean hasJava() {
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/impl/EqExpr.java
--- a/core/src/luan/impl/EqExpr.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/impl/EqExpr.java	Fri May 01 18:44:20 2015 -0600
@@ -42,8 +42,8 @@
 		LuanTable mt2 = t2.getMetatable();
 		if( mt1==null || mt2==null )
 			return false;
-		Object f = mt1.get("__eq");
-		if( f == null || !f.equals(mt2.get("__eq")) )
+		Object f = mt1.rawGet("__eq");
+		if( f == null || !f.equals(mt2.rawGet("__eq")) )
 			return false;
 		LuanBit bit = luan.bit(se);
 		LuanFunction fn = bit.checkFunction(f);
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/impl/IndexExpr.java
--- a/core/src/luan/impl/IndexExpr.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/impl/IndexExpr.java	Fri May 01 18:44:20 2015 -0600
@@ -24,21 +24,7 @@
 	private Object index(LuanStateImpl luan,Object obj,Object key) throws LuanException {
 		if( obj instanceof LuanTable ) {
 			LuanTable tbl = (LuanTable)obj;
-			Object value = tbl.get(key);
-			if( value != null )
-				return value;
-			Object h = tbl.getHandler("__index");
-			if( h==null )
-				return null;
-			if( h instanceof LuanFunction ) {
-				LuanFunction fn = (LuanFunction)h;
-				return Luan.first(luan.bit(se).call(fn,"__index",new Object[]{tbl,key}));
-			}
-			if( h instanceof LuanMeta ) {
-				LuanMeta meta = (LuanMeta)h;
-				return meta.__index(luan,tbl,key);
-			}
-			return index(luan,h,key);
+			return tbl.get(luan,key);
 		}
 		if( obj instanceof String )
 			return StringLuan.__index(luan,(String)obj,key);
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/impl/SetTableEntry.java
--- a/core/src/luan/impl/SetTableEntry.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/impl/SetTableEntry.java	Fri May 01 18:44:20 2015 -0600
@@ -27,7 +27,7 @@
 		if( t instanceof LuanTable ) {
 			LuanTable table = (LuanTable)t;
 			Object h = table.getHandler("__newindex");
-			if( h==null || table.get(key)!=null ) {
+			if( h==null || table.rawGet(key)!=null ) {
 				try {
 					table.put(key,value);
 				} catch(IllegalArgumentException e) {
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/BasicLuan.java
--- a/core/src/luan/modules/BasicLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/BasicLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -106,7 +106,7 @@
 	}
 
 	public static Object raw_get(LuanTable table,Object index) {
-		return table.get(index);
+		return table.rawGet(index);
 	}
 
 	public static LuanTable raw_set(LuanTable table,Object index,Object value) {
@@ -218,21 +218,21 @@
 
 	public static Object try_(LuanState luan,LuanTable blocks) throws LuanException {
 		Utils.checkNotNull(luan,blocks);
-		Object obj = blocks.get(1);
+		Object obj = blocks.get(luan,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("catch");
+		obj = blocks.get(luan,"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("finally");
+		obj = blocks.get(luan,"finally");
 		if( obj != null ) {
 			if( !(obj instanceof LuanFunction) )
 				throw luan.exception("bad 'finally' value (function expected, got "+Luan.type(obj)+")");
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/BinaryLuan.java
--- a/core/src/luan/modules/BinaryLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/BinaryLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -12,7 +12,7 @@
 
 	public static Object __index(LuanState luan,final byte[] binary,Object key) throws LuanException {
 		LuanTable mod = (LuanTable)PackageLuan.require(luan,"luan:Binary");
-		Object obj = mod.get(key);
+		Object obj = mod.get(luan,key);
 		if( obj instanceof LuanFunction ) {
 			final LuanFunction fn = (LuanFunction)obj;
 			return new LuanFunction() {
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/HtmlLuan.java
--- a/core/src/luan/modules/HtmlLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/HtmlLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -99,7 +99,7 @@
 				String tagText = text.substring(i2+1,i);
 				try {
 					LuanTable tag = parseTag(tagText);
-					String tagName = (String)tag.get("name");
+					String tagName = (String)tag.rawGet("name");
 					if( containerTags.contains(tagName) ) {
 						i2 = i;
 						String endTagName = '/' + tagName;
@@ -200,7 +200,7 @@
 		while( i<len ) {
 			i2 = toEndName(text,i,len);
 			String attrName = unquote(text.substring(i,i2).toLowerCase());
-			if( attributes.get(attrName) != null )
+			if( attributes.rawGet(attrName) != null )
 				throw new BadTag("duplicate attribute: "+attrName);
 			i = i2;
 			while( i<len && Character.isWhitespace(text.charAt(i)) )  i++;
@@ -282,20 +282,20 @@
 				buf.append( o );
 			} else if( o instanceof LuanTable ) {
 				LuanTable t = (LuanTable)o;
-				String type = (String)t.get("type");
+				String type = (String)t.get(luan,"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("text") ).append( "-->" );
+					buf.append( "<!--" ).append( t.get(luan,"text") ).append( "-->" );
 				} else if( type.equals("cdata") ) {
-					buf.append( "<![CDATA[" ).append( t.get("text") ).append( "]]" );
+					buf.append( "<![CDATA[" ).append( t.get(luan,"text") ).append( "]]" );
 				} else if( type.equals("tag") ) {
-					buf.append( tagToString(t) );
+					buf.append( tagToString(luan,t) );
 				} else if( type.equals("container") ) {
-					LuanTable tag  = (LuanTable)t.get("tag");
-					buf.append( tagToString(tag) );
-					buf.append( t.get("text") );
-					buf.append( "</" ).append( tag.get("name") ).append( ">" );
+					LuanTable tag  = (LuanTable)t.get(luan,"tag");
+					buf.append( tagToString(luan,tag) );
+					buf.append( t.get(luan,"text") );
+					buf.append( "</" ).append( tag.get(luan,"name") ).append( ">" );
 				} else {
 					throw luan.exception( "invalid element type for 'Html.to_string'" );
 				}
@@ -305,11 +305,11 @@
 		return buf.toString();
 	}
 
-	private static String tagToString(LuanTable tbl) {
+	private static String tagToString(LuanState luan,LuanTable tbl) throws LuanException {
 		StringBuilder buf = new StringBuilder();
 		buf.append('<');
-		buf.append(tbl.get("name"));
-		LuanTable attributes = (LuanTable)tbl.get("attributes");
+		buf.append(tbl.get(luan,"name"));
+		LuanTable attributes = (LuanTable)tbl.get(luan,"attributes");
 		for( Map.Entry<Object,Object> attr : attributes ) {
 			buf.append( ' ' );
 			buf.append( attr.getKey() );
@@ -319,7 +319,7 @@
 				buf.append( quote((String)val) );
 			}
 		}
-		if( tbl.get("is_empty").equals(Boolean.TRUE) )
+		if( tbl.get(luan,"is_empty").equals(Boolean.TRUE) )
 			buf.append('/');
 		buf.append('>');
 		return buf.toString();
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/IoLuan.java
--- a/core/src/luan/modules/IoLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/IoLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -545,8 +545,8 @@
 	}
 
 	public static LuanTable stdin(LuanState luan) throws LuanException {
-		LuanTable io = (LuanTable)PackageLuan.loaded(luan).get("luan:Io");
-		return (LuanTable)io.get("stdin");
+		LuanTable io = (LuanTable)PackageLuan.require(luan,"luan:Io");
+		return (LuanTable)io.get(luan,"stdin");
 	}
 
 	public static LuanTable newSchemes() {
@@ -566,11 +566,11 @@
 		return schemes;
 	}
 
-	private static LuanTable schemes(LuanState luan) {
-		LuanTable t = (LuanTable)PackageLuan.loaded(luan).get("luan:Io");
+	private static LuanTable schemes(LuanState luan) throws LuanException {
+		LuanTable t = (LuanTable)PackageLuan.loaded(luan).rawGet("luan:Io");
 		if( t == null )
 			return newSchemes();
-		t = (LuanTable)t.get("schemes");
+		t = (LuanTable)t.get(luan,"schemes");
 		if( t == null )
 			return newSchemes();
 		return t;
@@ -583,7 +583,7 @@
 		String scheme = name.substring(0,i);
 		String location = name.substring(i+1);
 		LuanTable schemes = schemes(luan);
-		LuanFunction opener = (LuanFunction)schemes.get(scheme);
+		LuanFunction opener = (LuanFunction)schemes.get(luan,scheme);
 		if( opener == null )
 			throw luan.exception( "invalid scheme '"+scheme+"' in '"+name+"'" );
 		return (LuanTable)Luan.first(luan.call(opener,"<open \""+name+"\">",new Object[]{location}));
@@ -618,7 +618,7 @@
 			return new PickleClient(luan,in,out).table();
 		}
 
-		public void run_pickle_server(LuanState luan) throws IOException {
+		public void run_pickle_server(LuanState luan) throws IOException, LuanException {
 			InputStream in = new BufferedInputStream(inputStream());
 			OutputStream out = new BufferedOutputStream(outputStream());
 			new PickleServer(luan,in,out).run();
@@ -679,7 +679,7 @@
 	private static String SECURITY_KEY = "Io.Security";
 
 	private static void check(LuanState luan,String name) throws LuanException {
-		Security s = (Security)luan.registry().get(SECURITY_KEY);
+		Security s = (Security)luan.registry().rawGet(SECURITY_KEY);
 		if( s!=null )
 			s.check(luan,name);
 	}
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/JavaLuan.java
--- a/core/src/luan/modules/JavaLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/JavaLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -323,7 +323,7 @@
 						if( args==null )
 							args = new Object[0];
 						String name = method.getName();
-						Object fnObj = t.get(name);
+						Object fnObj = t.get(luan,name);
 						if( fnObj==null && base!=null )
 							return method.invoke(base,args);
 						LuanFunction fn = luan.checkFunction(fnObj);
@@ -465,7 +465,7 @@
 	private static String SECURITY_KEY = "Java.Security";
 
 	private static void check(LuanState luan,String name) throws LuanException {
-		Security s = (Security)luan.registry().get(SECURITY_KEY);
+		Security s = (Security)luan.registry().rawGet(SECURITY_KEY);
 		if( s!=null )
 			s.check(luan,name);
 	}
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/PackageLuan.java
--- a/core/src/luan/modules/PackageLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/PackageLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -24,7 +24,7 @@
 	}
 
 	public static LuanTable loaded(LuanState luan) {
-		LuanTable tbl = (LuanTable)luan.registry().get("Package.loaded");
+		LuanTable tbl = (LuanTable)luan.registry().rawGet("Package.loaded");
 		if( tbl == null ) {
 			tbl = new LuanTable();
 			luan.registry().put("Package.loaded",tbl);
@@ -41,7 +41,7 @@
 
 	public static Object load(LuanState luan,String modName) throws LuanException {
 		LuanTable loaded = loaded(luan);
-		Object mod = loaded.get(modName);
+		Object mod = loaded.rawGet(modName);
 		if( mod == null ) {
 			if( modName.startsWith("java:") ) {
 				mod = JavaLuan.load(luan,modName.substring(5));
@@ -65,11 +65,11 @@
 		LuanTable t = IoLuan.Uri(luan,uri);
 		if( t == null )
 			return null;
-		LuanFunction existsFn = (LuanFunction)t.get("exists");
+		LuanFunction existsFn = (LuanFunction)t.get(luan,"exists");
 		boolean exists = (Boolean)Luan.first(luan.call(existsFn));
 		if( !exists )
 			return null;
-		LuanFunction reader = (LuanFunction)t.get("read_text");
+		LuanFunction reader = (LuanFunction)t.get(luan,"read_text");
 		return (String)Luan.first(luan.call(reader));
 	}
 
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/PickleServer.java
--- a/core/src/luan/modules/PickleServer.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/PickleServer.java	Fri May 01 18:44:20 2015 -0600
@@ -66,11 +66,11 @@
 		}
 	}
 
-	public void run() {
-		LuanTable io = (LuanTable)PackageLuan.loaded(con.luan).get("luan:Io");
+	public void run() throws LuanException {
+		LuanTable io = (LuanTable)PackageLuan.require(con.luan,"luan:Io");
 		LuanTable env = con.env;
-		Object old_reverse_pickle = io.get("reverse_pickle");
-		Object old_unreverse_pickle = env.get("_unreverse_pickle");
+		Object old_reverse_pickle = io.rawGet("reverse_pickle");
+		Object old_unreverse_pickle = env.rawGet("_unreverse_pickle");
 		try {
 			try {
 				io.put("reverse_pickle", new LuanJavaFunction(
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/StringLuan.java
--- a/core/src/luan/modules/StringLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/StringLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -16,7 +16,7 @@
 
 	public static Object __index(LuanState luan,final String s,Object key) throws LuanException {
 		LuanTable mod = (LuanTable)PackageLuan.require(luan,"luan:String");
-		Object obj = mod.get(key);
+		Object obj = mod.get(luan,key);
 		if( obj instanceof LuanFunction ) {
 			final LuanFunction fn = (LuanFunction)obj;
 			return new LuanFunction() {
@@ -180,7 +180,7 @@
 			StringBuffer sb = new StringBuffer();
 			while( i<max && m.find() ) {
 				String match = m.groupCount()==0 ? m.group() : m.group(1);
-				Object val = t.get(match);
+				Object val = t.get(luan,match);
 				if( Luan.toBoolean(val) ) {
 					String replacement = Luan.asString(val);
 					if( replacement==null )
diff -r 0a2fb80907f9 -r 23a93c118042 core/src/luan/modules/TableLuan.java
--- a/core/src/luan/modules/TableLuan.java	Fri May 01 17:18:23 2015 -0600
+++ b/core/src/luan/modules/TableLuan.java	Fri May 01 18:44:20 2015 -0600
@@ -21,7 +21,7 @@
 		int last = j==null ? list.length() : j;
 		StringBuilder buf = new StringBuilder();
 		for( int k=first; k<=last; k++ ) {
-			Object val = list.get(k);
+			Object val = list.rawGet(k);
 			if( val==null )
 				break;
 			if( sep!=null && k > first )
@@ -102,7 +102,7 @@
 		int to = iTo!=null ? iTo : tbl.length();
 		List<Object> list = new ArrayList<Object>();
 		for( int i=from; i<=to; i++ ) {
-			list.add( tbl.get(i) );
+			list.add( tbl.rawGet(i) );
 		}
 		return list.toArray();
 	}
diff -r 0a2fb80907f9 -r 23a93c118042 lucene/src/luan/modules/lucene/LuceneIndex.java
--- a/lucene/src/luan/modules/lucene/LuceneIndex.java	Fri May 01 17:18:23 2015 -0600
+++ b/lucene/src/luan/modules/lucene/LuceneIndex.java	Fri May 01 18:44:20 2015 -0600
@@ -119,7 +119,7 @@
 			break;  // do nothing
 		case 1:
 			LuanTable doc = searcher.doc(luan,td.scoreDocs[0].doc);
-			idLim = (Long)doc.get(FLD_NEXT_ID);
+			idLim = (Long)doc.rawGet(FLD_NEXT_ID);
 			id = idLim;
 			break;
 		default:
diff -r 0a2fb80907f9 -r 23a93c118042 lucene/src/luan/modules/lucene/LuceneWriter.java
--- a/lucene/src/luan/modules/lucene/LuceneWriter.java	Fri May 01 17:18:23 2015 -0600
+++ b/lucene/src/luan/modules/lucene/LuceneWriter.java	Fri May 01 18:44:20 2015 -0600
@@ -58,9 +58,9 @@
 	}
 
 	public void save_document(LuanState luan,LuanTable doc) throws LuanException, IOException {
-		if( doc.get("type")==null )
+		if( doc.get(luan,"type")==null )
 			throw luan.exception("missing 'type' field");
-		String id = (String)doc.get("id");
+		String id = (String)doc.get(luan,"id");
 		if( id == null ) {
 			id = nextId(luan);
 			doc.put("id",id);
diff -r 0a2fb80907f9 -r 23a93c118042 web/src/luan/modules/web/HttpServicer.java
--- a/web/src/luan/modules/web/HttpServicer.java	Fri May 01 17:18:23 2015 -0600
+++ b/web/src/luan/modules/web/HttpServicer.java	Fri May 01 18:44:20 2015 -0600
@@ -51,7 +51,7 @@
 			if( !(mod instanceof LuanTable) )
 				throw luan.exception( "module '"+modName+"' must return a table" );
 			LuanTable tbl = (LuanTable)mod;
-			if( Luan.toBoolean( tbl.get("per_session") ) ) {
+			if( Luan.toBoolean( tbl.get(luan,"per_session") ) ) {
 				HttpSession session = request.getSession();
 				LuanState sessionLuan  = (LuanState)session.getValue("luan");
 				if( sessionLuan!=null ) {
@@ -71,9 +71,7 @@
 			}
 		}
 
-		LuanTable module = (LuanTable)PackageLuan.loaded(luan).get("luan:web/Http");
-		if( module == null )
-			throw luan.exception( "module 'web/Http' not defined" );
+		LuanTable module = (LuanTable)PackageLuan.require(luan,"luan:web/Http");
 		HttpServicer lib = new HttpServicer(request,response);
 		try {
 			module.put( "request", lib.requestTable() );
@@ -99,7 +97,7 @@
 	private static LuanFunction getService(LuanState luan,LuanTable tbl)
 		throws LuanException
 	{
-		Object service = tbl.get("service");
+		Object service = tbl.get(luan,"service");
 		if( service == null )
 			throw luan.exception( "function 'service' is not defined" );
 		if( !(service instanceof LuanFunction) )