]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/CreateMVectorProto.java
(refs #7562) Better handling of exceptions in procedural modules
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / java / CreateMVectorProto.java
1 package org.simantics.scl.compiler.elaboration.java;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
5 import org.simantics.scl.compiler.constants.FunctionValue;
6 import org.simantics.scl.compiler.internal.codegen.references.Val;
7 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
8 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
9 import org.simantics.scl.compiler.types.TVar;
10 import org.simantics.scl.compiler.types.Type;
11 import org.simantics.scl.compiler.types.Types;
12 import org.simantics.scl.compiler.types.exceptions.MatchException;
13 import org.simantics.scl.compiler.types.kinds.Kinds;
14
15 public class CreateMVectorProto extends FunctionValue {
16     private static final TVar A = Types.var(Kinds.STAR);
17     public static final CreateMVectorProto INSTANCE = new CreateMVectorProto();    
18
19     private CreateMVectorProto() {
20         super(new TVar[] {A}, Types.PROC, Types.mvector(A), Types.vector(A), Types.INTEGER);
21     }
22
23     @Override
24     public Type applyExact(MethodBuilder mb, Val[] parameters) {
25         Val prototypeVar = parameters[0];
26         Val lengthVar = parameters[1];
27
28         try {
29             Type elementType = Types.canonical(
30                     Types.matchApply(Types.VECTOR, prototypeVar.getType()));
31             if(elementType instanceof TVar) {
32                 prototypeVar.push(mb);
33                 mb.invokeVirtual("java/lang/Object", "getClass", Constants.CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
34                 mb.invokeVirtual("java/lang/Class", "getComponentType", Constants.CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
35                 lengthVar.push(mb);
36                 mb.invokeStatic("java/lang/reflect/Array", "newInstance", TypeDesc.OBJECT, 
37                         new TypeDesc[] {Constants.CLASS, TypeDesc.INT});
38
39                 return Types.mvector(A);
40             }
41             else {
42                 TypeDesc desc = mb.getJavaTypeTranslator().toTypeDesc(elementType);
43                 TypeDesc arrayDesc = desc.toArrayType();      
44
45                 lengthVar.push(mb);
46                 mb.newObject(arrayDesc, 1);                                
47
48                 return Types.mvector(elementType);
49             }
50         } catch(MatchException e) {
51             throw new InternalCompilerError(e);
52         }
53     }   
54
55 }