Search in sources :

Example 1 with BytecodeLinkedClass

use of de.mirkosertic.bytecoder.core.BytecodeLinkedClass in project Bytecoder by mirkosertic.

the class JSSSACompilerBackend method writeExceptionHandlerCode.

private void writeExceptionHandlerCode(BytecodeLinkerContext aLinkerContext, BytecodeLinkedClass aExceptionRethrower, PrintWriter aWriter, BytecodeProgram aProgram, String aInset, BytecodeInstruction aInstruction, String aExceptionVariableName) {
    BytecodeExceptionTableEntry[] theActiveHandlers = aProgram.getActiveExceptionHandlers(aInstruction.getOpcodeAddress(), aProgram.getExceptionHandlers());
    if (theActiveHandlers.length == 0) {
        // Missing catch block
        aWriter.println(aInset + JSWriterUtils.toClassName(aExceptionRethrower.getClassName()) + '.' + JSWriterUtils.toMethodName("registerExceptionOutcome", registerExceptionOutcomeSignature) + '(' + aExceptionVariableName + ");");
        aWriter.println(aInset + "return;");
    } else {
        for (BytecodeExceptionTableEntry theEntry : theActiveHandlers) {
            if (!theEntry.isFinally()) {
                BytecodeClassinfoConstant theConstant = theEntry.getCatchType();
                BytecodeLinkedClass theLinkedClass = aLinkerContext.isLinkedOrNull(theConstant.getConstant());
                if (theLinkedClass != null) {
                    aWriter.println(aInset + "if (" + aExceptionVariableName + ".clazz.instanceOfType(" + theLinkedClass.getUniqueId() + ")) {");
                    aWriter.println(aInset + "    currentLabel = " + theEntry.getHandlerPc().getAddress() + ';');
                    aWriter.println(aInset + "    continue controlflowloop;");
                    aWriter.println(aInset + '}');
                }
            }
        }
        aWriter.println(aInset + JSWriterUtils.toClassName(aExceptionRethrower.getClassName()) + '.' + JSWriterUtils.toMethodName("registerExceptionOutcome", registerExceptionOutcomeSignature) + '(' + aExceptionVariableName + ");");
        aWriter.println(aInset + "return;");
    }
}
Also used : BytecodeExceptionTableEntry(de.mirkosertic.bytecoder.core.BytecodeExceptionTableEntry) BytecodeClassinfoConstant(de.mirkosertic.bytecoder.core.BytecodeClassinfoConstant) BytecodeLinkedClass(de.mirkosertic.bytecoder.core.BytecodeLinkedClass)

Example 2 with BytecodeLinkedClass

use of de.mirkosertic.bytecoder.core.BytecodeLinkedClass in project Bytecoder by mirkosertic.

the class JSSSACompilerBackend method generateCodeFor.

@Override
public JSCompileResult generateCodeFor(CompileOptions aOptions, BytecodeLinkerContext aLinkerContext, Class aEntryPointClass, String aEntryPointMethodName, BytecodeMethodSignature aEntryPointSignatue) {
    BytecodeLinkedClass theExceptionRethrower = aLinkerContext.resolveClass(BytecodeObjectTypeRef.fromRuntimeClass(ExceptionRethrower.class));
    theExceptionRethrower.resolveStaticMethod("registerExceptionOutcome", registerExceptionOutcomeSignature);
    theExceptionRethrower.resolveStaticMethod("getLastOutcomeOrNullAndReset", getLastExceptionOutcomeSignature);
    StringWriter theStrWriter = new StringWriter();
    PrintWriter theWriter = new PrintWriter(theStrWriter);
    theWriter.println("'use strict';");
    theWriter.println();
    theWriter.println("var bytecoderGlobalMemory = [];");
    theWriter.println();
    theWriter.println("var bytecoder = {");
    theWriter.println();
    theWriter.println("     logDebug : function(aValue) { ");
    theWriter.println("         console.log(aValue);");
    theWriter.println("     }, ");
    theWriter.println();
    theWriter.println("     logByteArrayAsString : function(aArray) { ");
    theWriter.println("         var theResult = '';");
    theWriter.println("         for (var i=0;i<aArray.data.length;i++) {");
    theWriter.println("             theResult += String.fromCharCode(aArray.data[i]);");
    theWriter.println("         }");
    theWriter.println("         console.log(theResult);");
    theWriter.println("     }, ");
    theWriter.println();
    theWriter.println("     newString : function(aByteArray) { ");
    BytecodeObjectTypeRef theStringTypeRef = BytecodeObjectTypeRef.fromRuntimeClass(String.class);
    BytecodeObjectTypeRef theArrayTypeRef = BytecodeObjectTypeRef.fromRuntimeClass(Array.class);
    BytecodeMethodSignature theStringConstructorSignature = new BytecodeMethodSignature(BytecodePrimitiveTypeRef.VOID, new BytecodeTypeRef[] { new BytecodeArrayTypeRef(BytecodePrimitiveTypeRef.BYTE, 1) });
    // Construct a String
    theWriter.println("          var theNewString = new " + JSWriterUtils.toClassName(theStringTypeRef) + ".Create();");
    theWriter.println("          var theBytes = new " + JSWriterUtils.toClassName(theArrayTypeRef) + ".Create();");
    theWriter.println("          theBytes.data = aByteArray;");
    theWriter.println("          " + JSWriterUtils.toClassName(theStringTypeRef) + '.' + JSWriterUtils.toMethodName("init", theStringConstructorSignature) + "(theNewString, theBytes);");
    theWriter.println("          return theNewString;");
    theWriter.println("     },");
    theWriter.println();
    theWriter.println("     newMultiArray : function(aDimensions, aDefault) {");
    theWriter.println("         var theLength = aDimensions[0];");
    theWriter.println("         var theArray = bytecoder.newArray(theLength, aDefault);");
    theWriter.println("         if (aDimensions.length > 1) {");
    theWriter.println("             var theNewDimensions = aDimensions.slice(0);");
    theWriter.println("             theNewDimensions.shift();");
    theWriter.println("             for (var i=0;i<theLength;i++) {");
    theWriter.println("                 theArray.data[i] = bytecoder.newMultiArray(theNewDimensions, aDefault);");
    theWriter.println("             }");
    theWriter.println("         }");
    theWriter.println("         return theArray;");
    theWriter.println("     },");
    theWriter.println();
    theWriter.println("     newArray : function(aLength, aDefault) {");
    BytecodeObjectTypeRef theArrayType = BytecodeObjectTypeRef.fromRuntimeClass(Array.class);
    theWriter.println("          var theInstance = new " + JSWriterUtils.toClassName(theArrayType) + ".Create();");
    theWriter.println("          theInstance.data = [];");
    theWriter.println("          theInstance.data.length = aLength;");
    theWriter.println("          for (var i=0;i<aLength;i++) {");
    theWriter.println("             theInstance.data[i] = aDefault;");
    theWriter.println("          }");
    theWriter.println("          return theInstance;");
    theWriter.println("     },");
    theWriter.println();
    theWriter.println("     dynamicType : function(aFunction) { ");
    theWriter.println("         return new Proxy({}, {");
    theWriter.println("             get: function(target, name) {");
    theWriter.println("                 return function(inst, _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9) {");
    theWriter.println("                    return aFunction(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);");
    theWriter.println("                 }");
    theWriter.println("             }");
    theWriter.println("         });");
    theWriter.println("     }, ");
    theWriter.println();
    theWriter.println("     resolveStaticCallSiteObject: function(aWhere, aKey, aProducerFunction) {");
    theWriter.println("         var resolvedCallsiteObject = aWhere.__staticCallSites[aKey];");
    theWriter.println("         if (resolvedCallsiteObject == null) {");
    theWriter.println("             resolvedCallsiteObject = aProducerFunction();");
    theWriter.println("             aWhere.__staticCallSites[aKey] = resolvedCallsiteObject;");
    theWriter.println("         }");
    theWriter.println("         return resolvedCallsiteObject;");
    theWriter.println("     },");
    theWriter.println();
    theWriter.println("     imports : [],");
    theWriter.println();
    theWriter.println("     stringpool : [],");
    theWriter.println();
    theWriter.println("};");
    theWriter.println();
    ConstantPool thePool = new ConstantPool();
    aLinkerContext.linkedClasses().forEach(theEntry -> {
        BytecodeLinkedClass theLinkedClass = theEntry.targetNode();
        // Here we collect everything that is required for class initialization
        // this includes the super class, all implementing interfaces and also static
        // dependencies of the class initialization code
        List<BytecodeObjectTypeRef> theInitDependencies = new ArrayList<>();
        BytecodeLinkedClass theSuperClass = theLinkedClass.getSuperClass();
        if (theSuperClass != null) {
            theInitDependencies.add(theSuperClass.getClassName());
        }
        for (BytecodeLinkedClass theInterface : theLinkedClass.getImplementingTypes()) {
            if (!theInitDependencies.contains(theInterface.getClassName())) {
                theInitDependencies.add(theInterface.getClassName());
            }
        }
        BytecodeResolvedMethods theMethods = theLinkedClass.resolvedMethods();
        String theJSClassName = JSWriterUtils.toClassName(theEntry.edgeType().objectTypeRef());
        theWriter.println("var " + theJSClassName + " = {");
        // First of all, we add static fields required by the framework
        theWriter.println("    __initialized : false,");
        theWriter.println("    __staticCallSites : [],");
        theWriter.print("    __typeId : ");
        theWriter.print(theLinkedClass.getUniqueId());
        theWriter.println(",");
        theWriter.print("    __implementedTypes : [");
        {
            boolean first = true;
            for (BytecodeLinkedClass theType : theLinkedClass.getImplementingTypes()) {
                if (!first) {
                    theWriter.print(",");
                }
                first = false;
                theWriter.print(theType.getUniqueId());
            }
        }
        theWriter.println("],");
        // then we add class specific static fields
        BytecodeResolvedFields theStaticFields = theLinkedClass.resolvedFields();
        theStaticFields.streamForStaticFields().forEach(aFieldEntry -> {
            BytecodeTypeRef theFieldType = aFieldEntry.getValue().getTypeRef();
            if (theFieldType.isPrimitive()) {
                BytecodePrimitiveTypeRef thePrimitive = (BytecodePrimitiveTypeRef) theFieldType;
                switch(thePrimitive) {
                    case BOOLEAN:
                        {
                            theWriter.print("    ");
                            theWriter.print(aFieldEntry.getValue().getName().stringValue());
                            theWriter.print(" : false, // declared in ");
                            theWriter.println(aFieldEntry.getProvidingClass().getClassName().name());
                            break;
                        }
                    default:
                        {
                            theWriter.print("    ");
                            theWriter.print(aFieldEntry.getValue().getName().stringValue());
                            theWriter.print(" : 0, // declared in ");
                            theWriter.println(aFieldEntry.getProvidingClass().getClassName().name());
                            break;
                        }
                }
            } else {
                theWriter.print("    ");
                theWriter.print(aFieldEntry.getValue().getName().stringValue());
                theWriter.print(" : null, // declared in ");
                theWriter.println(aFieldEntry.getProvidingClass().getClassName().name());
            }
        });
        theWriter.println();
        if (!theLinkedClass.getBytecodeClass().getAccessFlags().isAbstract()) {
            // The Constructor function initializes all object members with null
            // Only non abstract classes can be instantiated
            BytecodeResolvedFields theInstanceFields = theLinkedClass.resolvedFields();
            theWriter.println("    Create : function() {");
            theInstanceFields.streamForInstanceFields().forEach(aFieldEntry -> {
                BytecodeTypeRef theFieldType = aFieldEntry.getValue().getTypeRef();
                if (theFieldType.isPrimitive()) {
                    BytecodePrimitiveTypeRef thePrimitive = (BytecodePrimitiveTypeRef) theFieldType;
                    switch(thePrimitive) {
                        case BOOLEAN:
                            {
                                theWriter.print("        this.");
                                theWriter.print(aFieldEntry.getValue().getName().stringValue());
                                theWriter.print(" = false; // declared in ");
                                theWriter.println(aFieldEntry.getProvidingClass().getClassName().name());
                                break;
                            }
                        default:
                            {
                                theWriter.print("        this.");
                                theWriter.print(aFieldEntry.getValue().getName().stringValue());
                                theWriter.print(" = 0; // declared in ");
                                theWriter.println(aFieldEntry.getProvidingClass().getClassName().name());
                                break;
                            }
                    }
                } else {
                    theWriter.print("        this.");
                    theWriter.print(aFieldEntry.getValue().getName().stringValue());
                    theWriter.print(" = null; // declared in ");
                    theWriter.println(aFieldEntry.getProvidingClass().getClassName().name());
                }
            });
            theWriter.println("    },");
            theWriter.println();
        }
        if (!theLinkedClass.getBytecodeClass().getAccessFlags().isInterface()) {
            theWriter.println("    instanceOf : function(aType) {");
            theWriter.print("        return ");
            theWriter.print(theJSClassName);
            theWriter.println(".__implementedTypes.includes(aType.__typeId);");
            theWriter.println("    },");
            theWriter.println();
            theWriter.println("    ClassgetClass : function() {");
            theWriter.print("        return ");
            theWriter.print(theJSClassName);
            theWriter.println(";");
            theWriter.println("    },");
            theWriter.println();
            theWriter.println("    BOOLEANdesiredAssertionStatus : function() {");
            theWriter.println("        return false;");
            theWriter.println("    },");
            theWriter.println();
            theWriter.println("    A1jlObjectgetEnumConstants : function(aClazz) {");
            theWriter.println("        return aClazz.$VALUES;");
            theWriter.println("    },");
        }
        theMethods.stream().forEach(aEntry -> {
            BytecodeMethod theMethod = aEntry.getValue();
            BytecodeMethodSignature theCurrentMethodSignature = theMethod.getSignature();
            // If the method is provided by the runtime, we do not need to generate the implementation
            if (theMethod.getAttributes().getAnnotationByType(EmulatedByRuntime.class.getName()) != null) {
                return;
            }
            // Do not generate code for abstract methods
            if (theMethod.getAccessFlags().isAbstract()) {
                return;
            }
            if (!(aEntry.getProvidingClass() == theLinkedClass)) {
                // But include static methods, as they are inherited from the base classes
                if (aEntry.getValue().getAccessFlags().isStatic() && !aEntry.getValue().isClassInitializer()) {
                    StringBuilder theArguments = new StringBuilder();
                    ;
                    for (int i = 0; i < theCurrentMethodSignature.getArguments().length; i++) {
                        if (i > 0) {
                            theArguments.append(',');
                        }
                        theArguments.append('p');
                        theArguments.append(i);
                    }
                    // Static methods will just delegate to the implementation in the class
                    theWriter.println();
                    theWriter.println("    " + JSWriterUtils.toMethodName(theMethod.getName().stringValue(), theCurrentMethodSignature) + " : function(" + theArguments + ") {");
                    if (!theCurrentMethodSignature.getReturnType().isVoid()) {
                        theWriter.print("         return ");
                    } else {
                        theWriter.print("         ");
                    }
                    theWriter.print(JSWriterUtils.toClassName(aEntry.getProvidingClass().getClassName()));
                    theWriter.print(".");
                    theWriter.print(JSWriterUtils.toMethodName(theMethod.getName().stringValue(), theCurrentMethodSignature));
                    theWriter.print("(");
                    theWriter.print(theArguments);
                    theWriter.println(");");
                    theWriter.println("    },");
                }
                return;
            }
            aLinkerContext.getLogger().info("Compiling {}.{}", theLinkedClass.getClassName().name(), theMethod.getName().stringValue());
            ProgramGenerator theGenerator = programGeneratorFactory.createFor(aLinkerContext);
            Program theSSAProgram = theGenerator.generateFrom(aEntry.getProvidingClass().getBytecodeClass(), theMethod);
            // Run optimizer
            aOptions.getOptimizer().optimize(theSSAProgram.getControlFlowGraph(), aLinkerContext);
            StringBuilder theArguments = new StringBuilder();
            for (Program.Argument theArgument : theSSAProgram.getArguments()) {
                if (theArguments.length() > 0) {
                    theArguments.append(',');
                }
                theArguments.append(theArgument.getVariable().getName());
            }
            if (theMethod.getAccessFlags().isNative()) {
                if (theLinkedClass.getBytecodeClass().getAttributes().getAnnotationByType(EmulatedByRuntime.class.getName()) != null) {
                    return;
                }
                BytecodeImportedLink theLink = theLinkedClass.linkfor(theMethod);
                theWriter.println();
                theWriter.println("    " + JSWriterUtils.toMethodName(theMethod.getName().stringValue(), theCurrentMethodSignature) + " : function(" + theArguments + ") {");
                theWriter.print("         return bytecoder.imports.");
                theWriter.print(theLink.getModuleName());
                theWriter.print(".");
                theWriter.print(theLink.getLinkName());
                theWriter.print("(");
                theWriter.print(theArguments);
                theWriter.println(");");
                theWriter.println("    },");
                return;
            }
            theWriter.println();
            theWriter.println("    " + JSWriterUtils.toMethodName(theMethod.getName().stringValue(), theCurrentMethodSignature) + " : function(" + theArguments + ") {");
            if (Objects.equals(theMethod.getName().stringValue(), "<clinit>")) {
                for (BytecodeObjectTypeRef theRef : theSSAProgram.getStaticReferences()) {
                    if (!theInitDependencies.contains(theRef)) {
                        theInitDependencies.add(theRef);
                    }
                }
            }
            if (aOptions.isDebugOutput()) {
                theWriter.println("        /**");
                theWriter.println("        " + theSSAProgram.getControlFlowGraph().toDOT());
                theWriter.println("        */");
            }
            JSSSAWriter theVariablesWriter = new JSSSAWriter(aOptions, theSSAProgram, "        ", theWriter, aLinkerContext, thePool);
            for (Variable theVariable : theSSAProgram.globalVariables()) {
                if (!theVariable.isSynthetic()) {
                    theVariablesWriter.print("var ");
                    theVariablesWriter.print(theVariable.getName());
                    theVariablesWriter.print(" = null;");
                    theVariablesWriter.print(" // type is ");
                    theVariablesWriter.print(theVariable.resolveType().resolve().name());
                    theVariablesWriter.print(" # of inits = " + theVariable.incomingDataFlows().size());
                    theVariablesWriter.println();
                }
            }
            // Try to reloop it!
            try {
                Relooper theRelooper = new Relooper();
                Relooper.Block theReloopedBlock = theRelooper.reloop(theSSAProgram.getControlFlowGraph());
                theVariablesWriter.printRelooped(theReloopedBlock);
            } catch (Exception e) {
                System.out.println(theSSAProgram.getControlFlowGraph().toDOT());
                throw new IllegalStateException("Error relooping cfg for " + theLinkedClass.getClassName().name() + '.' + theMethod.getName().stringValue(), e);
            }
            theWriter.println("    },");
        });
        theWriter.println();
        theWriter.println("    classInitCheck : function() {");
        theWriter.println("        if (!" + theJSClassName + ".__initialized) {");
        theWriter.println("            " + theJSClassName + ".__initialized = true;");
        if (!theLinkedClass.getBytecodeClass().getAccessFlags().isAbstract()) {
            // Now we have to setup the prototype
            // Only in case this class can be instantiated of course
            theWriter.println("            var thePrototype = " + theJSClassName + ".Create.prototype;");
            theWriter.println("            thePrototype.instanceOf = " + theJSClassName + ".instanceOf;");
            theWriter.println("            thePrototype.ClassgetClass = " + theJSClassName + ".ClassgetClass;");
            List<BytecodeResolvedMethods.MethodEntry> theEntries = theMethods.stream().collect(Collectors.toList());
            Set<String> theVisitedMethods = new HashSet<>();
            for (int i = theEntries.size() - 1; i >= 0; i--) {
                BytecodeResolvedMethods.MethodEntry aEntry = theEntries.get(i);
                BytecodeMethod theMethod = aEntry.getValue();
                String theMethodName = JSWriterUtils.toMethodName(theMethod.getName().stringValue(), theMethod.getSignature());
                if (!theMethod.getAccessFlags().isStatic() && !theMethod.getAccessFlags().isAbstract() && !theMethod.isConstructor() && !theMethod.isClassInitializer()) {
                    if (theVisitedMethods.add(theMethodName)) {
                        theWriter.print("            thePrototype.");
                        theWriter.print(theMethodName);
                        theWriter.print(" = ");
                        theWriter.print(JSWriterUtils.toClassName(aEntry.getProvidingClass().getClassName()));
                        theWriter.print(".");
                        theWriter.print(theMethodName);
                        theWriter.println(";");
                    }
                }
            }
        }
        for (BytecodeObjectTypeRef theRef : theInitDependencies) {
            if (!Objects.equals(theRef, theEntry.edgeType().objectTypeRef())) {
                theWriter.print("            ");
                theWriter.print(JSWriterUtils.toClassName(theRef));
                theWriter.println(".classInitCheck();");
            }
        }
        if (theLinkedClass.hasClassInitializer()) {
            theWriter.println("            " + theJSClassName + ".VOIDclinit();");
        }
        theWriter.println("        }");
        theWriter.println("    },");
        theWriter.println();
        theWriter.println("};");
        theWriter.println();
    });
    theWriter.println();
    theWriter.println("bytecoder.bootstrap = function() {");
    List<StringValue> theValues = thePool.stringValues();
    for (int i = 0; i < theValues.size(); i++) {
        StringValue theValue = theValues.get(i);
        theWriter.print("    bytecoder.stringpool[");
        theWriter.print(i);
        theWriter.print("] = bytecoder.newString(");
        theWriter.print(JSWriterUtils.toArray(theValue.getStringValue().getBytes()));
        theWriter.println(");");
    }
    aLinkerContext.linkedClasses().forEach(aEntry -> {
        if (!aEntry.targetNode().getBytecodeClass().getAccessFlags().isInterface()) {
            theWriter.print("    ");
            theWriter.print(JSWriterUtils.toClassName(aEntry.edgeType().objectTypeRef()));
            theWriter.println(".classInitCheck();");
        }
    });
    theWriter.println("}");
    theWriter.flush();
    return new JSCompileResult(theStrWriter.toString());
}
Also used : Variable(de.mirkosertic.bytecoder.ssa.Variable) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) ArrayList(java.util.ArrayList) BytecodeMethod(de.mirkosertic.bytecoder.core.BytecodeMethod) ProgramGenerator(de.mirkosertic.bytecoder.ssa.ProgramGenerator) BytecodeResolvedMethods(de.mirkosertic.bytecoder.core.BytecodeResolvedMethods) StringWriter(java.io.StringWriter) BytecodeLinkedClass(de.mirkosertic.bytecoder.core.BytecodeLinkedClass) StringValue(de.mirkosertic.bytecoder.ssa.StringValue) BytecodeResolvedFields(de.mirkosertic.bytecoder.core.BytecodeResolvedFields) PrintWriter(java.io.PrintWriter) HashSet(java.util.HashSet) BytecodeProgram(de.mirkosertic.bytecoder.core.BytecodeProgram) Program(de.mirkosertic.bytecoder.ssa.Program) BytecodePrimitiveTypeRef(de.mirkosertic.bytecoder.core.BytecodePrimitiveTypeRef) BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeObjectTypeRef(de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef) Relooper(de.mirkosertic.bytecoder.relooper.Relooper) BytecodeArrayTypeRef(de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef) ConstantPool(de.mirkosertic.bytecoder.backend.ConstantPool) BytecodeImportedLink(de.mirkosertic.bytecoder.core.BytecodeImportedLink) ExceptionRethrower(de.mirkosertic.bytecoder.classlib.ExceptionRethrower)

Example 3 with BytecodeLinkedClass

use of de.mirkosertic.bytecoder.core.BytecodeLinkedClass in project Bytecoder by mirkosertic.

the class OpenCLCompileBackend method registerInputs.

private void registerInputs(BytecodeLinkerContext aContext, BytecodeLinkedClass aKernelClass, Value aValue, OpenCLInputOutputs aInputOutputs) {
    if (aValue instanceof GetFieldExpression) {
        GetFieldExpression theGetField = (GetFieldExpression) aValue;
        BytecodeLinkedClass theClass = aContext.resolveClass(BytecodeObjectTypeRef.fromUtf8Constant(theGetField.getField().getClassIndex().getClassConstant().getConstant()));
        if (theClass == aKernelClass) {
            BytecodeResolvedFields theInstanceFields = aKernelClass.resolvedFields();
            BytecodeResolvedFields.FieldEntry theField = theInstanceFields.fieldByName(theGetField.getField().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue());
            aInputOutputs.registerReadFrom(theField);
        }
    }
}
Also used : GetFieldExpression(de.mirkosertic.bytecoder.ssa.GetFieldExpression) BytecodeLinkedClass(de.mirkosertic.bytecoder.core.BytecodeLinkedClass) BytecodeResolvedFields(de.mirkosertic.bytecoder.core.BytecodeResolvedFields)

Example 4 with BytecodeLinkedClass

use of de.mirkosertic.bytecoder.core.BytecodeLinkedClass in project Bytecoder by mirkosertic.

the class OpenCLCompileBackend method generateCodeFor.

@Override
public OpenCLCompileResult generateCodeFor(CompileOptions aOptions, BytecodeLinkerContext aLinkerContext, Class aEntryPointClass, String aEntryPointMethodName, BytecodeMethodSignature aEntryPointSignatue) {
    BytecodeLinkerContext theLinkerContext = new BytecodeLinkerContext(loader, aOptions.getLogger());
    BytecodeLinkedClass theKernelClass = theLinkerContext.resolveClass(BytecodeObjectTypeRef.fromRuntimeClass(aEntryPointClass));
    theKernelClass.resolveVirtualMethod(aEntryPointMethodName, aEntryPointSignatue);
    BytecodeResolvedMethods theMethodMap = theKernelClass.resolvedMethods();
    StringWriter theStrWriter = new StringWriter();
    OpenCLInputOutputs theInputOutputs;
    // First of all, we link the kernel method
    BytecodeMethod theKernelMethod = theKernelClass.getBytecodeClass().methodByNameAndSignatureOrNull("processWorkItem", new BytecodeMethodSignature(BytecodePrimitiveTypeRef.VOID, new BytecodeTypeRef[0]));
    ProgramGenerator theGenerator = programGeneratorFactory.createFor(aLinkerContext);
    Program theSSAProgram = theGenerator.generateFrom(theKernelClass.getBytecodeClass(), theKernelMethod);
    // Run optimizer
    aOptions.getOptimizer().optimize(theSSAProgram.getControlFlowGraph(), aLinkerContext);
    // Every member of the kernel class becomes a kernel function argument
    try {
        theInputOutputs = inputOutputsFor(theLinkerContext, theKernelClass, theSSAProgram);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    // And then we ca pass it to the code generator to generate the kernel code
    OpenCLWriter theSSAWriter = new OpenCLWriter(theKernelClass, aOptions, theSSAProgram, "", new PrintWriter(theStrWriter), aLinkerContext, theInputOutputs);
    // We use the relooper here
    Relooper theRelooper = new Relooper();
    theMethodMap.stream().forEach(aMethodMapEntry -> {
        BytecodeMethod theMethod = aMethodMapEntry.getValue();
        if (theMethod.isConstructor()) {
            return;
        }
        if (theMethod != theKernelMethod) {
            Program theSSAProgram1 = theGenerator.generateFrom(aMethodMapEntry.getProvidingClass().getBytecodeClass(), theMethod);
            // Run optimizer
            aOptions.getOptimizer().optimize(theSSAProgram1.getControlFlowGraph(), aLinkerContext);
            // Try to reloop it!
            try {
                Relooper.Block theReloopedBlock = theRelooper.reloop(theSSAProgram1.getControlFlowGraph());
                theSSAWriter.printReloopedInline(theMethod, theSSAProgram1, theReloopedBlock);
            } catch (Exception e) {
                throw new IllegalStateException("Error relooping cfg", e);
            }
        }
    });
    // Finally, we write the kernel method
    try {
        Relooper.Block theReloopedBlock = theRelooper.reloop(theSSAProgram.getControlFlowGraph());
        theSSAWriter.printReloopedKernel(theSSAProgram, theReloopedBlock);
    } catch (Exception e) {
        throw new IllegalStateException("Error relooping cfg", e);
    }
    return new OpenCLCompileResult(theInputOutputs, theStrWriter.toString());
}
Also used : Program(de.mirkosertic.bytecoder.ssa.Program) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) BytecodeMethod(de.mirkosertic.bytecoder.core.BytecodeMethod) NaiveProgramGenerator(de.mirkosertic.bytecoder.ssa.NaiveProgramGenerator) ProgramGenerator(de.mirkosertic.bytecoder.ssa.ProgramGenerator) BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeResolvedMethods(de.mirkosertic.bytecoder.core.BytecodeResolvedMethods) StringWriter(java.io.StringWriter) Relooper(de.mirkosertic.bytecoder.relooper.Relooper) BytecodeLinkerContext(de.mirkosertic.bytecoder.core.BytecodeLinkerContext) BytecodeLinkedClass(de.mirkosertic.bytecoder.core.BytecodeLinkedClass) PrintWriter(java.io.PrintWriter)

Example 5 with BytecodeLinkedClass

use of de.mirkosertic.bytecoder.core.BytecodeLinkedClass in project Bytecoder by mirkosertic.

the class OpenCLWriter method toStructName.

private String toStructName(BytecodeObjectTypeRef aObjectType) {
    BytecodeLinkedClass theLinkedClass = linkerContext.resolveClass(aObjectType);
    BytecodeClass theBytecodeClass = theLinkedClass.getBytecodeClass();
    BytecodeAnnotation theAnnotation = theBytecodeClass.getAttributes().getAnnotationByType(OpenCLType.class.getName());
    if (theAnnotation == null) {
        throw new IllegalArgumentException("No @OpenCLType found for " + aObjectType.name());
    }
    return theAnnotation.getElementValueByName("name").stringValue();
}
Also used : BytecodeAnnotation(de.mirkosertic.bytecoder.core.BytecodeAnnotation) OpenCLType(de.mirkosertic.bytecoder.api.opencl.OpenCLType) BytecodeLinkedClass(de.mirkosertic.bytecoder.core.BytecodeLinkedClass) BytecodeClass(de.mirkosertic.bytecoder.core.BytecodeClass)

Aggregations

BytecodeLinkedClass (de.mirkosertic.bytecoder.core.BytecodeLinkedClass)17 BytecodeMethodSignature (de.mirkosertic.bytecoder.core.BytecodeMethodSignature)7 BytecodeMethod (de.mirkosertic.bytecoder.core.BytecodeMethod)6 BytecodeResolvedFields (de.mirkosertic.bytecoder.core.BytecodeResolvedFields)6 BytecodeObjectTypeRef (de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef)5 BytecodeTypeRef (de.mirkosertic.bytecoder.core.BytecodeTypeRef)5 BytecodeResolvedMethods (de.mirkosertic.bytecoder.core.BytecodeResolvedMethods)4 DoubleValue (de.mirkosertic.bytecoder.ssa.DoubleValue)4 FloatValue (de.mirkosertic.bytecoder.ssa.FloatValue)4 IntegerValue (de.mirkosertic.bytecoder.ssa.IntegerValue)4 LongValue (de.mirkosertic.bytecoder.ssa.LongValue)4 StringValue (de.mirkosertic.bytecoder.ssa.StringValue)4 Value (de.mirkosertic.bytecoder.ssa.Value)4 BytecodeAnnotation (de.mirkosertic.bytecoder.core.BytecodeAnnotation)3 BytecodeArrayTypeRef (de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef)3 Relooper (de.mirkosertic.bytecoder.relooper.Relooper)3 Program (de.mirkosertic.bytecoder.ssa.Program)3 ProgramGenerator (de.mirkosertic.bytecoder.ssa.ProgramGenerator)3 Variable (de.mirkosertic.bytecoder.ssa.Variable)3 PrintWriter (java.io.PrintWriter)3