<commit_before>package lua.addon.luajava;


/** LuaJava-like bindings to Java scripting. 
 * 
 * TODO: coerce types on way in and out, pick method base on arg count ant types.
 */
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lua.GlobalState;
import lua.VM;
import lua.value.LFunction;
import lua.value.LTable;
import lua.value.LUserData;
import lua.value.LValue;

public final class LuaJava extends LFunction {

	public static void install() {
		LTable luajava = new LTable();
		for ( int i=0; i<NAMES.length; i++ )
			luajava.put( NAMES[i], new LuaJava(i) );
		GlobalState.getGlobalsTable().put( "luajava", luajava );
	}

	private static final int NEWINSTANCE  = 0;
	private static final int BINDCLASS    = 1;
	private static final int NEW          = 2;
	private static final int CREATEPROXY  = 3;
	private static final int LOADLIB      = 4;
	
	private static final String[] NAMES = { 
		"newInstance", 
		"bindClass", 
		"new", 
		"createProxy", 
		"loadLib" };
	
	private int id;
	private LuaJava( int id ) {			
		this.id = id;
	}

	public String toString() {
		return "luajava."+NAMES[id];
	}
	
	// perform a lua call
	public boolean luaStackCall(VM vm) {
		String className;
		switch ( id ) {
		case BINDCLASS:
			className = vm.getArgAsString(0);
			try {
				Class clazz = Class.forName(className);
				vm.setResult( new LInstance( clazz, clazz ) );
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			break;
		case NEWINSTANCE:
			className = vm.getArgAsString(0);
			try {
				// get constructor
				Class clazz = Class.forName(className);
				ParamsList params = new ParamsList( vm );
				Constructor con = resolveConstructor( clazz, params );

				// coerce args 
				Object[] args = CoerceLuaToJava.coerceArgs( params.values, con.getParameterTypes() );
				Object o = con.newInstance( args );
				
				// set the result
				vm.setResult( new LInstance( o, clazz ) );
				
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			break;
		default:
			luaUnsupportedOperation();
		}
		return false;
	}

	public static class ParamsList {
		public final LValue[] values;
		public final Class[] classes;
		public int hash;
		ParamsList( VM vm ) {
			int n = vm.getArgCount()-1;
			values = new LValue[n];
			classes = new Class[n];
			for ( int i=0; i<n; i++ ) {
				values[i] = vm.getArg(i+1);
				classes[i] = values[i].getClass();
				hash += classes[i].hashCode();
			}
		}
		public int hashCode() {
			return hash;
		}
		public boolean equals( Object o ) {
			return ( o instanceof ParamsList )? 
				Arrays.equals( classes, ((ParamsList) o).classes ):
				false;
		}
	}
	
	public static class LInstance extends LUserData {
		private Class clazz;
		public LInstance(Object o, Class clazz) {
			super(o);
			this.clazz = clazz;
		}
		public void luaGetTable(VM vm, LValue table, LValue key) {
			final String s = key.luaAsString();
			try {
				Field f = clazz.getField(s);
				Object o = f.get(m_instance);
				LValue v = CoerceJavaToLua.coerce( o );
				vm.setResult( v );
			} catch (NoSuchFieldException nsfe) {
				vm.setResult( new LMethod(m_instance,clazz,s) );
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		public void luaSetTable(VM vm, LValue table, LValue key, LValue val) {
			Class c = m_instance.getClass();
			String s = key.luaAsString();
			try {
				Field f = c.getField(s);
				Object v = CoerceLuaToJava.coerceArg(val, f.getType());
				f.set(m_instance,v);
				vm.setResult();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		
	}

	private static final class LMethod extends LFunction {
		private final Object instance;
		private final Class clazz;
		private final String s;
		private LMethod(Object instance, Class clazz, String s) {
			this.instance = instance;
			this.clazz = clazz;
			this.s = s;
		}
		public String toString() {
			return clazz.getName()+"."+s+"()";
		}
		public boolean luaStackCall(VM vm) {
			try {
				// find the method 
				ParamsList params = new ParamsList( vm );
				Method meth = resolveMethod( clazz, s, params );

				// coerce the arguments
				Object[] args = CoerceLuaToJava.coerceArgs( params.values, meth.getParameterTypes() );
				Object result = meth.invoke( instance, args );<commit_msg>Fix gettable result handling in LInstances<commit_after>package lua.addon.luajava;


/** LuaJava-like bindings to Java scripting. 
 * 
 * TODO: coerce types on way in and out, pick method base on arg count ant types.
 */
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lua.GlobalState;
import lua.VM;
import lua.value.LFunction;
import lua.value.LTable;
import lua.value.LUserData;
import lua.value.LValue;

public final class LuaJava extends LFunction {

	public static void install() {
		LTable luajava = new LTable();
		for ( int i=0; i<NAMES.length; i++ )
			luajava.put( NAMES[i], new LuaJava(i) );
		GlobalState.getGlobalsTable().put( "luajava", luajava );
	}

	private static final int NEWINSTANCE  = 0;
	private static final int BINDCLASS    = 1;
	private static final int NEW          = 2;
	private static final int CREATEPROXY  = 3;
	private static final int LOADLIB      = 4;
	
	private static final String[] NAMES = { 
		"newInstance", 
		"bindClass", 
		"new", 
		"createProxy", 
		"loadLib" };
	
	private int id;
	private LuaJava( int id ) {			
		this.id = id;
	}

	public String toString() {
		return "luajava."+NAMES[id];
	}
	
	// perform a lua call
	public boolean luaStackCall(VM vm) {
		String className;
		switch ( id ) {
		case BINDCLASS:
			className = vm.getArgAsString(0);
			try {
				Class clazz = Class.forName(className);
				vm.setResult( new LInstance( clazz, clazz ) );
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			break;
		case NEWINSTANCE:
			className = vm.getArgAsString(0);
			try {
				// get constructor
				Class clazz = Class.forName(className);
				ParamsList params = new ParamsList( vm );
				Constructor con = resolveConstructor( clazz, params );

				// coerce args 
				Object[] args = CoerceLuaToJava.coerceArgs( params.values, con.getParameterTypes() );
				Object o = con.newInstance( args );
				
				// set the result
				vm.setResult( new LInstance( o, clazz ) );
				
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			break;
		default:
			luaUnsupportedOperation();
		}
		return false;
	}

	public static class ParamsList {
		public final LValue[] values;
		public final Class[] classes;
		public int hash;
		ParamsList( VM vm ) {
			int n = vm.getArgCount()-1;
			values = new LValue[n];
			classes = new Class[n];
			for ( int i=0; i<n; i++ ) {
				values[i] = vm.getArg(i+1);
				classes[i] = values[i].getClass();
				hash += classes[i].hashCode();
			}
		}
		public int hashCode() {
			return hash;
		}
		public boolean equals( Object o ) {
			return ( o instanceof ParamsList )? 
				Arrays.equals( classes, ((ParamsList) o).classes ):
				false;
		}
	}
	
	public static class LInstance extends LUserData {
		private Class clazz;
		public LInstance(Object o, Class clazz) {
			super(o);
			this.clazz = clazz;
		}
		public void luaGetTable(VM vm, LValue table, LValue key) {
			final String s = key.luaAsString();
			try {
				Field f = clazz.getField(s);
				Object o = f.get(m_instance);
				LValue v = CoerceJavaToLua.coerce( o );
				vm.push( v );
			} catch (NoSuchFieldException nsfe) {
				vm.setResult( new LMethod(m_instance,clazz,s) );
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		public void luaSetTable(VM vm, LValue table, LValue key, LValue val) {
			Class c = m_instance.getClass();
			String s = key.luaAsString();
			try {
				Field f = c.getField(s);
				Object v = CoerceLuaToJava.coerceArg(val, f.getType());
				f.set(m_instance,v);
				vm.setResult();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		@Override
		public boolean luaStackCall(VM vm) {
			// TODO Auto-generated method stub
			return super.luaStackCall(vm);
		}
		
	}

	private static final class LMethod extends LFunction {
		private final Object instance;
		private final Class clazz;
		private final String s;
		private LMethod(Object instance, Class clazz, String s) {
			this.instance = instance;
			this.clazz = clazz;
			this.s = s;
		}
		public String toString() {
			return clazz.getName()+"."+s+"()";
		}
		public boolean luaStackCall(VM vm) {
			try {
				// find the method 
				ParamsList params = new ParamsList( vm );
				Method meth = resolveMethod( clazz, s, params );

				// coerce the arguments
				Object[] args = CoerceLuaToJava.coerceArgs( params.values, meth.getParameterTypes() );
				Object result = meth.invoke( instance, args );
{'fraction_non_alphanumeric': 0.11730790553276417, 'fraction_numerical': 0.002439294822042355, 'mean_word_length': 3.1490340386384545, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6098234', 'n_tokens_mistral': 3563, 'n_tokens_neox': 3000, 'n_words': 866}