Mercurial Hosting > luan
comparison src/luan/modules/ThreadLuan.java @ 1243:3ffc7c4a3b85
improve Thread.global_callable to allow passing of safe tables
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 05 Jul 2018 00:04:30 -0600 |
parents | d3a3ca116e42 |
children | 9fa8b8389578 |
comparison
equal
deleted
inserted
replaced
1242:ce3279ef1bd9 | 1243:3ffc7c4a3b85 |
---|---|
115 public static void sleep(long millis) throws InterruptedException { | 115 public static void sleep(long millis) throws InterruptedException { |
116 Thread.sleep(millis); | 116 Thread.sleep(millis); |
117 } | 117 } |
118 | 118 |
119 | 119 |
120 private static boolean isPrimitive(Object v) { | 120 private static class Unsafe { |
121 if( v instanceof Object[] ) { | 121 private final String reason; |
122 | |
123 Unsafe(String reason) { | |
124 this.reason = reason; | |
125 } | |
126 } | |
127 | |
128 private static Object makeSafe(Object v) { | |
129 if( v instanceof LuanTable ) { | |
130 LuanTable tbl = (LuanTable)v; | |
131 if( tbl.getMetatable() != null ) | |
132 return new Unsafe("table with metatable"); | |
133 LuanTable rtn = new LuanTable(); | |
134 for( Map.Entry entry : tbl.rawIterable() ) { | |
135 Object key = makeSafe( entry.getKey() ); | |
136 if( key instanceof Unsafe ) | |
137 return key; | |
138 Object value = makeSafe( entry.getValue() ); | |
139 if( value instanceof Unsafe ) | |
140 return value; | |
141 rtn.rawPut(key,value); | |
142 } | |
143 return rtn; | |
144 } else if( v instanceof Object[] ) { | |
122 Object[] a = (Object[])v; | 145 Object[] a = (Object[])v; |
123 for( Object obj : a ) { | 146 for( int i=0; i<a.length; i++ ) { |
124 if( !isPrimitive(obj) ) | 147 Object obj = makeSafe(a[i]); |
125 return false; | 148 if( obj instanceof Unsafe ) |
126 } | 149 return obj; |
127 return true; | 150 a[i] = obj; |
151 } | |
152 return a; | |
128 } else { | 153 } else { |
129 return v==null || v instanceof String || v instanceof Boolean || v instanceof Number; | 154 if( v==null || v instanceof String || v instanceof Boolean || v instanceof Number ) |
155 return v; | |
156 return new Unsafe("type "+Luan.type(v)); | |
130 } | 157 } |
131 } | 158 } |
132 | 159 |
133 public static final class Callable { | 160 public static final class Callable { |
134 private long expires; | 161 private long expires; |
139 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); | 166 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); |
140 this.fns = (LuanTable)cloner.get(fns); | 167 this.fns = (LuanTable)cloner.get(fns); |
141 } | 168 } |
142 | 169 |
143 public synchronized Object call(String fnName,Object... args) throws LuanException { | 170 public synchronized Object call(String fnName,Object... args) throws LuanException { |
144 if( !isPrimitive(args) ) | 171 Object obj = makeSafe(args); |
145 throw new LuanException("can't pass non-primitive type to global_callable "+Arrays.asList(args)); | 172 if( obj instanceof Unsafe ) |
173 throw new LuanException("can't pass "+((Unsafe)obj).reason+" to global_callable "+Arrays.asList(args)); | |
174 args = (Object[])obj; | |
146 Object f = fns.get(luan,fnName); | 175 Object f = fns.get(luan,fnName); |
147 if( f == null ) | 176 if( f == null ) |
148 throw new LuanException("function '"+fnName+"' not found in global_callable"); | 177 throw new LuanException("function '"+fnName+"' not found in global_callable"); |
149 if( !(f instanceof LuanFunction) ) | 178 if( !(f instanceof LuanFunction) ) |
150 throw new LuanException("value of '"+fnName+"' not a function in global_callable"); | 179 throw new LuanException("value of '"+fnName+"' not a function in global_callable"); |
151 LuanFunction fn = (LuanFunction)f; | 180 LuanFunction fn = (LuanFunction)f; |
152 Object rtn = fn.call(luan,args); | 181 Object rtn = fn.call(luan,args); |
153 if( !isPrimitive(rtn) ) | 182 rtn = makeSafe(rtn); |
154 throw new LuanException("can't return non-primitive type from global_callable"); | 183 if( rtn instanceof Unsafe ) |
184 throw new LuanException("can't return "+((Unsafe)rtn).reason+" from global_callable"); | |
155 return rtn; | 185 return rtn; |
156 } | 186 } |
157 } | 187 } |
158 | 188 |
159 private static Map<String,Callable> callableMap = new HashMap<String,Callable>(); | 189 private static Map<String,Callable> callableMap = new HashMap<String,Callable>(); |