package s3.services.simplejit.bootimage;

import ovm.core.domain.LinkageException;
import ovm.services.bytecode.analysis.State;
import s3.core.domain.S3ByteCode;
import s3.core.domain.S3Domain;
import s3.core.domain.S3Method;
import s3.services.bootimage.NativeCallGenerator;
import s3.services.simplejit.bytecode.SimpleJITAbstractInterpreter;
import s3.services.simplejit.bytecode.SimpleJITEphemeralTypeMap;
import s3.services.simplejit.bytecode.SimpleJITJSRProblemSolver;

public class SimpleJITBootImageJSRProblemSolver {

    private static S3ByteCode 
	splitLocalsOnByteCode(S3ByteCode bc,
			      State state,
			      S3Domain targetDomain) {
	SimpleJITJSRProblemSolver solver =
	    new SimpleJITJSRProblemSolver
	    (bc,
	     state,
	     new SimpleJITEphemeralTypeMap(targetDomain));
	solver.run();
	S3ByteCode rewritten = solver.getRewrittenByteCode();
	if (bc != rewritten)
	    if (bc.getMaxLocals() != rewritten.getMaxLocals())
		System.err.println("LOCAL_SPLIT_DONE");
	    else
		System.err.println("LOCAL_SPLIT_DONE BUT NO EFFECT");
	return rewritten;
    }

    public static S3ByteCode.Builder
	splitLocalsOnByteCodeBuilder(S3Method method,
				     S3ByteCode.Builder builder,
				     S3Domain executiveDomain,
				     S3Domain targetDomain,
				     NativeCallGenerator ncg) {
 	method.addCode(builder.build());
	SimpleJITBootImageCompilerVMInterface compilerVMInterface =
	    new SimpleJITBootImageCompilerVMInterface
	    (executiveDomain,
	     targetDomain,
	     null,
	     null);
	SimpleJITAbstractInterpreter.Driver ai_driver =
	    new SimpleJITAbstractInterpreter.Driver();
	SimpleJITAbstractInterpreter.StateAndBlockMap stateNBlocks = 
	    ai_driver.run(method, compilerVMInterface);
	S3ByteCode code = (S3ByteCode)method.getCode(S3ByteCode.KIND);

	if (stateNBlocks == null)
	    return new S3ByteCode.Builder(code); // return original
	try {
	    S3ByteCode splitBC = splitLocalsOnByteCode(code,
						       stateNBlocks.state,
						       targetDomain);
	    return new S3ByteCode.Builder(splitBC);
	} catch (LinkageException.Runtime e) {
	    System.err.println(e.toString());
	}
	return new S3ByteCode.Builder(code); // return original
    }
}

