All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.luaj.vm2.luajc.JavaGen Maven / Gradle / Ivy

/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.luajc;

import org.luaj.vm2.Lua;
import org.luaj.vm2.Prototype;

/**
 * TODO: 
 *   propogate constants
 *   loader can find inner classes
 */
public class JavaGen {

	public String classname;
	public byte[] bytecode;
	public JavaGen[] inners;
	
	public JavaGen( Prototype p, String classname, String filename ) {
		this.classname = classname;
		
		// build this class
		JavaBuilder builder = new JavaBuilder(p, classname, filename);
		scanInstructions(p, classname, builder);
		this.bytecode = builder.completeClass();
		
		// build sub-prototypes
		int n = p.p.length;
		inners = new JavaGen[n];
		for ( int i=0; i C) then pc++			*/ 
				builder.loadLocal( pc, a );
				builder.toBoolean();
				builder.addBranch(pc, (c!=0? JavaBuilder.BRANCH_IFEQ: JavaBuilder.BRANCH_IFNE), pc+2);
				break;
				
			case Lua.OP_TESTSET: /*	A B C	if (R(B) <=> C) then R(A):= R(B) else pc++	*/
				builder.loadLocal( pc, b );
				builder.toBoolean();
				builder.addBranch(pc, (c!=0? JavaBuilder.BRANCH_IFEQ: JavaBuilder.BRANCH_IFNE), pc+2);
				builder.loadLocal( pc, b );
				builder.storeLocal( pc, a );
				break;
				
			case Lua.OP_CALL: /*	A B C	R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */

				// load function
				builder.loadLocal(pc, a);
				
				// load args
				int narg = b - 1;
				switch ( narg ) {
				case 0: case 1: case 2: case 3:
					for ( int i=1; i 3
					builder.newVarargs( pc, a+1, b-1 );
					narg = -1;
					break;
				case -1: // prev vararg result
					loadVarargResults( builder, pc, a+1, vresultbase );
					narg = -1;
					break;
				}
				
				// call or invoke
				boolean useinvoke = narg<0 || c<1 || c>2;
				if ( useinvoke )
					builder.invoke(narg);
				else
					builder.call(narg);
				
				// handle results
				switch ( c ) {
				case 1: 
					builder.pop(); 
					break;
				case 2:
					if ( useinvoke ) 
						builder.arg( 1 );
					builder.storeLocal(pc, a);
					break;
				default: // fixed result count - unpack args
					for ( int i=1; i 1
					builder.newVarargs( pc, a+1, b-1 );
					break;
				case 0: // prev vararg result
					loadVarargResults( builder, pc, a+1, vresultbase );
					break;
				}
				builder.newTailcallVarargs();
				builder.areturn();
				break;
				
			case Lua.OP_RETURN: /*	A B	return R(A), ... ,R(A+B-2)	(see note)	*/
				if ( c == 1 ) {
					builder.loadNone();
				} else {
					switch ( b ) {
					case 0: loadVarargResults( builder, pc, a, vresultbase ); break;
					case 1: builder.loadNone(); break;
					case 2: builder.loadLocal(pc, a); break;
					default: builder.newVarargs(pc, a, b-1); break;
					}
				}
				builder.areturn(); 
				break;
				
			case Lua.OP_FORPREP: /*	A sBx	R(A)-=R(A+2): pc+=sBx				*/
				builder.loadLocal(pc, a);
				builder.loadLocal(pc, a+2);
				builder.binaryop( Lua.OP_SUB );
				builder.storeLocal(pc, a);
				builder.addBranch(pc, JavaBuilder.BRANCH_GOTO, pc+1+sbx);
				break;
				
			case Lua.OP_FORLOOP: /*	A sBx	R(A)+=R(A+2): if R(A) =2 ) builder.dup();
				builder.arg( 1 );
				builder.dup();
				builder.storeLocal(pc, a+2);
				builder.storeLocal(pc, a+3);
				
				// a[a+2+i] = v[2+i], i=2..c
				for ( int i=2; i<=c; i++ ) {
					if ( i 0 ) {
						builder.setlistStack( pc, a+1, index0, nstack );
						index0 += nstack;
					}
					builder.setlistVarargs( index0, vresultbase );
				} else {
					builder.setlistStack( pc, a+1, index0, b );
					builder.pop();
				}
				break;
				
			case Lua.OP_CLOSE: /*	A 	close all variables in the stack up to (>=) R(A)*/
				break;
				
			case Lua.OP_CLOSURE: /*	A Bx	R(A):= closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
			{
				Prototype newp = p.p[bx];
				String protoname = closureName(classname, bx);
				int nup = newp.nups;
				builder.closureCreate( protoname );
				if ( nup > 0 )
					builder.dup();
				builder.storeLocal( pc, a );
				if ( nup > 0 ) {
					for ( int up=0; up




© 2015 - 2025 Weber Informatics LLC | Privacy Policy