Package soot

Examples of soot.SootField


                    .hasNext();) {
                TypedIORelation relation = (TypedIORelation) relations.next();

                for (int i = 0; i < relation.getWidth(); i++, channel++) {
                    if (channel == argChannel) {
                        SootField arrayField = modelClass
                                .getFieldByName(InlinePortTransformer
                                        .getBufferFieldName(relation, i, type));

                        return arrayField;
                    }
View Full Code Here


    /** Generate code for a reference to a static field.
     *  @param v The static field reference.
     */
    public void caseStaticFieldRef(StaticFieldRef v) {
        SootField field = v.getField();
        SootClass className = field.getDeclaringClass();
        _push(CNames.classStructureNameOf(className) + ".classvars."
                + CNames.fieldNameOf(field));
        _context.addIncludeFile("\"" + CNames.includeFileNameOf(className)
                + "\"");
    }
View Full Code Here

                // Otherwise there is nothing to be done.
            } else if (rightOp instanceof FieldRef) {
                // System.out.println("fieldRef stmt = " + stmt);
                FieldRef fieldRef = (FieldRef) rightOp;
                SootField field = fieldRef.getField();
                TypeTag tag = (TypeTag) field.getTag("_CGType");
                Object newType;

                if (tag == null) {
                    //  System.out.println("No Tag... Existing type = " + in.get(rightOp));
                    //                     System.out.println("No Tag... field type = " + field.getType());
                    if (in.get(rightOp) == null) {
                        RefType fieldType = PtolemyUtilities
                                .getBaseTokenType(field.getType());
                        newType = PtolemyUtilities
                                .getTokenTypeForSootType(fieldType);
                    } else {
                        // Then flow the type.
                        newType = in.get(field);
View Full Code Here

            for (Iterator entities = model.deepEntityList().iterator(); entities
                    .hasNext();) {
                Entity entity = (Entity) entities.next();
                String fieldName = ModelTransformer.getFieldNameForEntity(
                        entity, model);
                SootField field = modelClass.getFieldByName(fieldName);
                String className = ModelTransformer.getInstanceClassName(
                        entity, options);
                SootClass theClass = Scene.v().loadClassAndSupport(className);
                SootMethod preinitializeMethod = SootUtilities
                        .searchForMethodByName(theClass, "preinitialize");
                Local actorLocal = Jimple.v().newLocal("actor",
                        RefType.v(theClass));
                body.getLocals().add(actorLocal);

                // Get the field.
                units.insertBefore(Jimple.v().newAssignStmt(
                        actorLocal,
                        Jimple.v().newInstanceFieldRef(thisLocal,
                                field.makeRef())), insertPoint);
                units.insertBefore(Jimple.v().newInvokeStmt(
                        Jimple.v().newVirtualInvokeExpr(actorLocal,
                                preinitializeMethod.makeRef())), insertPoint);
            }

            //           units.add(Jimple.v().newReturnVoidStmt());
        }

        {
            // populate the initialize method
            SootMethod classMethod = modelClass.getMethodByName("initialize");
            JimpleBody body = (JimpleBody) classMethod.getActiveBody();
            Stmt insertPoint = body.getFirstNonIdentityStmt();

            Chain units = body.getUnits();
            Local thisLocal = body.getThisLocal();

            Local actorLocal = Jimple.v().newLocal("actor", actorType);
            body.getLocals().add(actorLocal);

            for (Iterator entities = model.deepEntityList().iterator(); entities
                    .hasNext();) {
                Entity entity = (Entity) entities.next();
                String fieldName = ModelTransformer.getFieldNameForEntity(
                        entity, model);
                SootField field = modelClass.getFieldByName(fieldName);
                String className = ModelTransformer.getInstanceClassName(
                        entity, options);
                SootClass theClass = Scene.v().loadClassAndSupport(className);
                SootMethod initializeMethod = SootUtilities
                        .searchForMethodByName(theClass, "initialize");

                // Set the field.
                units.insertBefore(Jimple.v().newAssignStmt(
                        actorLocal,
                        Jimple.v().newInstanceFieldRef(thisLocal,
                                field.makeRef())), insertPoint);
                units.insertBefore(Jimple.v().newInvokeStmt(
                        Jimple.v().newVirtualInvokeExpr(actorLocal,
                                initializeMethod.makeRef())), insertPoint);
            }

            //           units.add(Jimple.v().newReturnVoidStmt());
        }

        {
            // populate the prefire method
            SootMethod classMethod = modelClass.getMethodByName("prefire");
            JimpleBody body = (JimpleBody) classMethod.getActiveBody();
            Chain units = body.getUnits();
            Stmt insertPoint = (Stmt) units.getLast();

            Local thisLocal = body.getThisLocal();

            Local prefireReturnsLocal = Jimple.v().newLocal("preReturns",
                    BooleanType.v());
            body.getLocals().add(prefireReturnsLocal);

            // Prefire the controller.
            Local actorLocal = Jimple.v().newLocal("actor", actorType);
            body.getLocals().add(actorLocal);

            String fieldName = ModelTransformer.getFieldNameForEntity(
                    controller, model);
            SootField field = modelClass.getFieldByName(fieldName);
            String className = ModelTransformer.getInstanceClassName(
                    controller, options);
            SootClass theClass = Scene.v().loadClassAndSupport(className);
            SootMethod actorPrefireMethod = SootUtilities
                    .searchForMethodByName(theClass, "prefire");

            units.insertBefore(
                    Jimple.v().newAssignStmt(
                            actorLocal,
                            Jimple.v().newInstanceFieldRef(thisLocal,
                                    field.makeRef())), insertPoint);
            units.insertBefore(Jimple.v().newAssignStmt(
                    prefireReturnsLocal,
                    Jimple.v().newVirtualInvokeExpr(actorLocal,
                            actorPrefireMethod.makeRef())), insertPoint);

            units.insertBefore(Jimple.v().newReturnStmt(prefireReturnsLocal),
                    insertPoint);

            LocalSplitter.v().transform(body, phaseName + ".lns");
            LocalNameStandardizer.v().transform(body, phaseName + ".lns");
            TypeResolver.resolve(body, Scene.v());
        }

        {
            // populate the fire method
            SootMethod classMethod = modelClass.getMethodByName("fire");
            JimpleBody body = (JimpleBody) classMethod.getActiveBody();
            Stmt insertPoint = body.getFirstNonIdentityStmt();

            Chain units = body.getUnits();
            Local thisLocal = body.getThisLocal();

            Local indexLocal = Jimple.v().newLocal("index", IntType.v());
            body.getLocals().add(indexLocal);

            Local tokenLocal = Jimple.v().newLocal("token",
                    PtolemyUtilities.tokenType);
            body.getLocals().add(tokenLocal);

            // Transfer Inputs from input ports.
            for (Iterator ports = model.inputPortList().iterator(); ports
                    .hasNext();) {
                IOPort port = (IOPort) ports.next();
                int rate = 1;

                String fieldName = ModelTransformer.getFieldNameForPort(port,
                        model);
                SootField field = modelClass.getFieldByName(fieldName);

                // Get a reference to the port.
                Local portLocal = Jimple.v().newLocal("port",
                        PtolemyUtilities.ioportType);
                body.getLocals().add(portLocal);

                Local tempPortLocal = Jimple.v().newLocal("tempPort",
                        PtolemyUtilities.ioportType);
                body.getLocals().add(tempPortLocal);
                units.insertBefore(Jimple.v().newAssignStmt(
                        tempPortLocal,
                        Jimple.v().newInstanceFieldRef(thisLocal,
                                field.makeRef())), insertPoint);
                units.insertBefore(Jimple.v().newAssignStmt(
                        portLocal,
                        Jimple.v().newCastExpr(tempPortLocal,
                                PtolemyUtilities.ioportType)), insertPoint);

                for (int i = 0; i < port.getWidth(); i++) {
                    // The list of initializer instructions.
                    List initializerList = new LinkedList();
                    initializerList.add(Jimple.v().newAssignStmt(indexLocal,
                            IntConstant.v(0)));

                    // The list of body instructions.
                    List bodyList = new LinkedList();

                    // Read
                    bodyList.add(Jimple.v().newAssignStmt(
                            tokenLocal,
                            Jimple.v().newVirtualInvokeExpr(portLocal,
                                    PtolemyUtilities.getMethod.makeRef(),
                                    IntConstant.v(i))));

                    // Write
                    bodyList.add(Jimple.v().newInvokeStmt(
                            Jimple.v()
                                    .newVirtualInvokeExpr(
                                            portLocal,
                                            PtolemyUtilities.sendInsideMethod
                                                    .makeRef(),
                                            IntConstant.v(i), tokenLocal)));

                    // Increment the index.
                    bodyList.add(Jimple.v()
                            .newAssignStmt(
                                    indexLocal,
                                    Jimple.v().newAddExpr(indexLocal,
                                            IntConstant.v(1))));

                    Expr conditionalExpr = Jimple.v().newLtExpr(indexLocal,
                            IntConstant.v(rate));

                    SootUtilities.createForLoopBefore(body, insertPoint,
                            initializerList, bodyList, conditionalExpr);
                }
            }

            {
                // Fire the controller.
                Local actorLocal = Jimple.v().newLocal("actor", actorType);
                body.getLocals().add(actorLocal);

                String fieldName = ModelTransformer.getFieldNameForEntity(
                        controller, model);
                SootField field = modelClass.getFieldByName(fieldName);
                String className = ModelTransformer.getInstanceClassName(
                        controller, options);
                SootClass theClass = Scene.v().loadClassAndSupport(className);
                SootMethod actorFireMethod = SootUtilities
                        .searchForMethodByName(theClass, "fire");

                units.insertBefore(Jimple.v().newAssignStmt(
                        actorLocal,
                        Jimple.v().newInstanceFieldRef(thisLocal,
                                field.makeRef())), insertPoint);
                units.insertBefore(Jimple.v().newInvokeStmt(
                        Jimple.v().newVirtualInvokeExpr(actorLocal,
                                actorFireMethod.makeRef())), insertPoint);
            }

            // Transfer outputs from output ports
            for (Iterator ports = model.outputPortList().iterator(); ports
                    .hasNext();) {
                IOPort port = (IOPort) ports.next();
                int rate = DFUtilities.getTokenProductionRate(port);

                String fieldName = ModelTransformer.getFieldNameForPort(port,
                        model);
                SootField field = modelClass.getFieldByName(fieldName);

                // Get a reference to the port.
                Local portLocal = Jimple.v().newLocal("port",
                        PtolemyUtilities.ioportType);
                body.getLocals().add(portLocal);

                Local tempPortLocal = Jimple.v().newLocal("tempPort",
                        PtolemyUtilities.ioportType);
                body.getLocals().add(tempPortLocal);
                units.insertBefore(Jimple.v().newAssignStmt(
                        tempPortLocal,
                        Jimple.v().newInstanceFieldRef(thisLocal,
                                field.makeRef())), insertPoint);
                units.insertBefore(Jimple.v().newAssignStmt(
                        portLocal,
                        Jimple.v().newCastExpr(tempPortLocal,
                                PtolemyUtilities.ioportType)), insertPoint);

                for (int i = 0; i < port.getWidth(); i++) {
                    // The list of initializer instructions.
                    List initializerList = new LinkedList();
                    initializerList.add(Jimple.v().newAssignStmt(indexLocal,
                            IntConstant.v(0)));

                    // The list of body instructions.
                    List bodyList = new LinkedList();

                    // Read
                    bodyList.add(Jimple.v().newAssignStmt(
                            tokenLocal,
                            Jimple.v().newVirtualInvokeExpr(portLocal,
                                    PtolemyUtilities.getInsideMethod.makeRef(),
                                    IntConstant.v(i))));

                    // Write
                    bodyList.add(Jimple.v().newInvokeStmt(
                            Jimple.v().newVirtualInvokeExpr(portLocal,
                                    PtolemyUtilities.sendMethod.makeRef(),
                                    IntConstant.v(i), tokenLocal)));

                    // Increment the index.
                    bodyList.add(Jimple.v()
                            .newAssignStmt(
                                    indexLocal,
                                    Jimple.v().newAddExpr(indexLocal,
                                            IntConstant.v(1))));

                    Expr conditionalExpr = Jimple.v().newLtExpr(indexLocal,
                            IntConstant.v(rate));

                    SootUtilities.createForLoopBefore(body, insertPoint,
                            initializerList, bodyList, conditionalExpr);
                }
            }

            // Return.
            //            units.add(Jimple.v().newReturnVoidStmt());
            LocalSplitter.v().transform(body, phaseName + ".lns");
            LocalNameStandardizer.v().transform(body, phaseName + ".lns");
            TypeResolver.resolve(body, Scene.v());
        }

        {
            // populate the postfire method
            SootMethod classMethod = modelClass.getMethodByName("postfire");
            JimpleBody body = (JimpleBody) classMethod.getActiveBody();
            Stmt insertPoint = body.getFirstNonIdentityStmt();

            Chain units = body.getUnits();
            Local thisLocal = body.getThisLocal();

            Local postfireReturnsLocal = Jimple.v().newLocal("postfireReturns",
                    BooleanType.v());
            body.getLocals().add(postfireReturnsLocal);

            // Postfire the controller.
            Local actorLocal = Jimple.v().newLocal("actor", actorType);
            body.getLocals().add(actorLocal);

            String fieldName = ModelTransformer.getFieldNameForEntity(
                    controller, model);
            SootField field = modelClass.getFieldByName(fieldName);
            String className = ModelTransformer.getInstanceClassName(
                    controller, options);
            SootClass theClass = Scene.v().loadClassAndSupport(className);
            SootMethod actorPostfireMethod = SootUtilities
                    .searchForMethodByName(theClass, "postfire");

            units.insertBefore(
                    Jimple.v().newAssignStmt(
                            actorLocal,
                            Jimple.v().newInstanceFieldRef(thisLocal,
                                    field.makeRef())), insertPoint);
            units.insertBefore(Jimple.v().newAssignStmt(
                    postfireReturnsLocal,
                    Jimple.v().newVirtualInvokeExpr(actorLocal,
                            actorPostfireMethod.makeRef())), insertPoint);

            units.insertBefore(Jimple.v().newReturnStmt(postfireReturnsLocal),
                    insertPoint);
            LocalSplitter.v().transform(body, phaseName + ".lns");
            LocalNameStandardizer.v().transform(body, phaseName + ".lns");
            TypeResolver.resolve(body, Scene.v());
        }

        {
            // populate the wrapup method
            SootMethod classMethod = modelClass.getMethodByName("wrapup");
            JimpleBody body = (JimpleBody) classMethod.getActiveBody();
            Stmt insertPoint = body.getFirstNonIdentityStmt();

            Chain units = body.getUnits();
            Local thisLocal = body.getThisLocal();

            Local actorLocal = Jimple.v().newLocal("actor", actorType);
            body.getLocals().add(actorLocal);

            for (Iterator entities = model.deepEntityList().iterator(); entities
                    .hasNext();) {
                Entity entity = (Entity) entities.next();
                String fieldName = ModelTransformer.getFieldNameForEntity(
                        entity, model);
                SootField field = modelClass.getFieldByName(fieldName);
                String className = ModelTransformer.getInstanceClassName(
                        entity, options);
                SootClass theClass = Scene.v().loadClassAndSupport(className);
                SootMethod wrapupMethod = SootUtilities.searchForMethodByName(
                        theClass, "wrapup");

                // Set the field.
                units.insertBefore(Jimple.v().newAssignStmt(
                        actorLocal,
                        Jimple.v().newInstanceFieldRef(thisLocal,
                                field.makeRef())), insertPoint);
                units.insertBefore(Jimple.v().newInvokeStmt(
                        Jimple.v().newVirtualInvokeExpr(actorLocal,
                                wrapupMethod.makeRef())), insertPoint);
            }
View Full Code Here

                        localUses);
            } else if (value instanceof CastExpr) {
                return getTypeValue(method, (Local) ((CastExpr) value).getOp(),
                        stmt, localDefs, localUses);
            } else if (value instanceof FieldRef) {
                SootField field = ((FieldRef) value).getField();

                if (field.equals(unknownTypeField)) {
                    return ptolemy.data.type.BaseType.UNKNOWN;
                } else if (field.equals(booleanTypeField)) {
                    return ptolemy.data.type.BaseType.BOOLEAN;
                } else if (field.equals(booleanMatrixTypeField)) {
                    return ptolemy.data.type.BaseType.BOOLEAN_MATRIX;
                } else if (field.equals(byteTypeField)) {
                    return ptolemy.data.type.BaseType.UNSIGNED_BYTE;
                } else if (field.equals(complexTypeField)) {
                    return ptolemy.data.type.BaseType.COMPLEX;
                } else if (field.equals(complexMatrixTypeField)) {
                    return ptolemy.data.type.BaseType.COMPLEX_MATRIX;
                } else if (field.equals(doubleTypeField)) {
                    return ptolemy.data.type.BaseType.DOUBLE;
                } else if (field.equals(doubleMatrixTypeField)) {
                    return ptolemy.data.type.BaseType.DOUBLE_MATRIX;
                } else if (field.equals(fixTypeField)) {
                    return ptolemy.data.type.BaseType.FIX;
                } else if (field.equals(fixMatrixTypeField)) {
                    return ptolemy.data.type.BaseType.FIX_MATRIX;
                } else if (field.equals(floatTypeField)) {
                    return ptolemy.data.type.BaseType.FLOAT;
                } else if (field.equals(intTypeField)) {
                    return ptolemy.data.type.BaseType.INT;
                } else if (field.equals(intMatrixTypeField)) {
                    return ptolemy.data.type.BaseType.INT_MATRIX;
                } else if (field.equals(longTypeField)) {
                    return ptolemy.data.type.BaseType.LONG;
                } else if (field.equals(longMatrixTypeField)) {
                    return ptolemy.data.type.BaseType.LONG_MATRIX;
                } else if (field.equals(objectTypeField)) {
                    return ptolemy.data.type.BaseType.OBJECT;
                } else if (field.equals(shortTypeField)) {
                    return ptolemy.data.type.BaseType.SHORT;
                } else if (field.equals(stringTypeField)) {
                    return ptolemy.data.type.BaseType.STRING;
                } else {
                    throw new RuntimeException("Unknown type field: " + field);
                }
            } else if (value instanceof InstanceInvokeExpr) {
View Full Code Here

            if (identifierReference instanceof Local) {
                return (Local) identifierReference;
            }

            if (identifierReference instanceof SootField) {
                SootField portField = (SootField) identifierReference;

                Local portLocal = Jimple
                        .v()
                        .newLocal(
                                "portToken",
                                PtolemyUtilities
                                        .getSootTypeForTokenType(getType(name)));
                _body.getLocals().add(portLocal);

                Local tokenLocal = Jimple.v().newLocal("portToken",
                        PtolemyUtilities.tokenType);
                _body.getLocals().add(tokenLocal);

                _units.insertBefore(Jimple.v().newAssignStmt(
                        tokenLocal,
                        Jimple.v().newInstanceFieldRef(thisLocal,
                                portField.makeRef())), _insertPoint);
                _units
                        .insertBefore(
                                Jimple
                                        .v()
                                        .newAssignStmt(
View Full Code Here

    public static void changeTypesOfFields(SootClass theClass,
            SootClass oldClass, SootClass newClass) {
        Iterator fields = theClass.getFields().snapshotIterator();

        while (fields.hasNext()) {
            SootField oldField = (SootField) fields.next();
            Type type = oldField.getType();

            //  System.out.println("field with type " + type);
            if (type instanceof RefType) {
                SootClass refClass = ((RefType) type).getSootClass();

                if (refClass == oldClass) {
                    oldField.setType(RefType.v(newClass));

                    // we have to do this seemingly useless
                    // thing, since the scene caches a pointer
                    // to the field based on it's parameter types.
                    theClass.removeField(oldField);
                    theClass.addField(oldField);
                } else if (refClass.getName().startsWith(oldClass.getName())) {
                    SootClass changeClass = _getInnerClassCopy(oldClass,
                            refClass, newClass);
                    oldField.setType(RefType.v(changeClass));

                    // we have to do this seemingly useless
                    // thing, since the scene caches a pointer
                    // to the field based on it's parameter types.
                    theClass.removeField(oldField);
View Full Code Here

                    Jimple.v().newCastExpr(local, type)), insertPoint);
            insertPoint = (Unit) body.getUnits().getSuccOf(insertPoint);
        }

        // Create the new field if necessary
        SootField field;

        if (theClass.declaresFieldByName(name)) {
            field = theClass.getFieldByName(name);
        } else {
            field = new SootField(name, type, Modifier.PUBLIC);
            theClass.addField(field);
        }

        // Set the field.
        units.insertAfter(Jimple.v().newAssignStmt(
                Jimple.v().newInstanceFieldRef(thisLocal, field.makeRef()),
                castLocal), insertPoint);
        return field;
    }
View Full Code Here

                // Ignore anything that isn't an assignment to a field.
                if (assignStmt.getRightOp() instanceof FieldRef) {
                    FieldRef ref = (FieldRef) assignStmt.getRightOp();
                    SootFieldRef fieldRef = ref.getFieldRef();
                    SootField field = ref.getField();

                    Type type = field.getType();

                    if (!PtolemyUtilities.isTokenType(type)) {
                        continue;
                    }
                    // Things that aren't token types are ignored.
                    // Things that are already the same type are ignored.
                    Type newType = typeAnalysis.getSpecializedSootType(field);
                    if ((newType != null) && !newType.equals(type)) {

                        ref.setFieldRef(Scene.v().makeFieldRef(
                                fieldRef.declaringClass(), fieldRef.name(),
                                newType, fieldRef.isStatic()));
                    }
                    continue;
                }
                if (!(assignStmt.getLeftOp() instanceof FieldRef)) {
                    continue;
                }

                if (!PtolemyUtilities.isTokenType(assignStmt.getLeftOp()
                        .getType())) {
                    continue;
                }

                if (debug) {
                    System.out.println("checking assignment " + assignStmt);
                }

                // FIXME: We need to figure out a way to insert casts where appropriate.
                // See RampFiringLimitSDF
                //                 ptolemy.data.type.Type leftType, rightType;
                //                 leftType = _getReplacementTokenType(
                //                         assignStmt.getLeftOp(), typeAnalysis);
                //                 rightType = _getReplacementTokenType(
                //                         assignStmt.getRightOp(), typeAnalysis);
                //                 if (leftType != null && rightType != null && !leftType.equals(rightType)) {
                //                     if (debug) System.out.println("inserting conversion: leftType = " +
                //                             leftType + ", rightType = " + rightType);
                //                     // insert a call to convert(), and a cast.
                //                     FieldRef ref = (FieldRef)assignStmt.getLeftOp();
                //                     SootField field = ref.getField();
                //                     Type newType =
                //                         typeAnalysis.getSpecializedSootType(field);
                //                     Local tempLocal =
                //                         Jimple.v().newLocal("fieldUpdateLocal", newType);
                //                     body.getLocals().add(tempLocal);
                //                     Local tokenLocal =
                //                         Jimple.v().newLocal("tokenLocal", PtolemyUtilities.tokenType);
                //                     body.getLocals().add(tokenLocal);
                //                     Local typeLocal =
                //                         PtolemyUtilities.buildConstantTypeLocal(body, unit, leftType);
                //                     body.getUnits().insertBefore(
                //                             Jimple.v().newAssignStmt(tokenLocal,
                //                                     Jimple.v().newVirtualInvokeExpr(
                //                                             typeLocal,
                //                                             PtolemyUtilities.typeConvertMethod,
                //                                             assignStmt.getRightOp())),
                //                             unit);
                //                     body.getUnits().insertBefore(
                //                             Jimple.v().newAssignStmt(tempLocal,
                //                                     Jimple.v().newCastExpr(
                //                                             tokenLocal,
                //                                             newType)),
                //                             unit);
                //                     assignStmt.setRightOp(tempLocal);
                //                 } else {
                FieldRef ref = (FieldRef) assignStmt.getLeftOp();
                SootFieldRef fieldRef = ref.getFieldRef();
                SootField field = ref.getField();

                Type type = field.getType();

                // Things that aren't token types are ignored.
                // Things that are already the same type are ignored.
                Type newType = typeAnalysis.getSpecializedSootType(field);
View Full Code Here

        // Loop through the class and make all the non-static fields static.
        // Make all reference to this into static references.
        for (Iterator fields = staticClass.getFields().iterator(); fields
                .hasNext();) {
            SootField field = (SootField) fields.next();

            // make the fieldd static.
            field.setModifiers(field.getModifiers() | Modifier.STATIC);
        }

        System.out.println("inlining = " + constructorMethod);
        System.out.println("inlineCall = " + insertStmt);
        System.out.println("container = " + clinitMethod);
View Full Code Here

TOP

Related Classes of soot.SootField

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.