package org.simantics.scl.compiler.elaboration.java; import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.constants.FunctionValue; import org.simantics.scl.compiler.internal.codegen.references.Val; import org.simantics.scl.compiler.internal.codegen.utils.Constants; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; public class CreateMVector extends FunctionValue { private static final TVar A = Types.var(Kinds.STAR); public static final CreateMVector INSTANCE = new CreateMVector(); private CreateMVector() { super(new TVar[] {A}, Types.PROC, Types.mvector(A), Types.pred(Types.VEC_COMP, A), Types.INTEGER); } @Override public Type applyExact(MethodBuilder mb, Val[] parameters) { Val constraintVar = parameters[0]; Val lengthVar = parameters[1]; Type pred_ = Types.canonical(constraintVar.getType()); if(!(pred_ instanceof TPred)) throw new InternalCompilerError(); TPred pred = (TPred)pred_; Type elementType = pred.parameters[0]; if(elementType instanceof TVar) { constraintVar.push(mb); lengthVar.push(mb); mb.invokeStatic("java/lang/reflect/Array", "newInstance", TypeDesc.OBJECT, new TypeDesc[] {Constants.CLASS, TypeDesc.INT}); return Types.mvector(A); } else { TypeDesc desc = mb.getJavaTypeTranslator().toTypeDesc(elementType); TypeDesc arrayDesc = desc.toArrayType(); lengthVar.push(mb); mb.newObject(arrayDesc, 1); return Types.mvector(elementType); } } }