Search in sources :

Example 1 with ByRef

use of sharpen.core.framework.ByRef in project XobotOS by xamarin.

the class NativeGlueGenerator method generate.

public Method generate() {
    final Method method = new Method(_nativeFunction, _returnType, Visibility.PUBLIC, Flags.EXPORT);
    final List<Expression> args = new ArrayList<Expression>();
    final List<Statement> preStmnts = new ArrayList<Statement>();
    final List<Statement> postStmnts = new ArrayList<Statement>();
    final Kind kind = _method.getKind();
    final ByRef<Expression> instanceArg;
    if ((kind == Kind.INSTANCE) || (kind == Kind.PROXY))
        instanceArg = new ByRef<Expression>(null);
    else
        instanceArg = null;
    if (_implicitInstance != null) {
        Parameter param = new Parameter(new PointerType(_nativeClass), "_instance");
        method.addParameter(param);
        Expression arg = new VariableReference(param);
        if (instanceArg != null)
            instanceArg.value = arg;
        else
            args.add(new DereferenceExpression(arg));
    }
    for (int i = 0; i < _paramInfo.length; i++) {
        if (_paramInfo[i] == null)
            continue;
        VariableDeclaration vdecl = (VariableDeclaration) _decl.parameters().get(i);
        IVariableBinding vbinding = vdecl.resolveBinding();
        final String name = getNativeName(vbinding.getName());
        boolean hasInstanceArg = (instanceArg != null) && (instanceArg.value == null);
        final boolean isInstanceArg = hasInstanceArg && (i == 0);
        INativeMarshalContext context = new INativeMarshalContext() {

            @Override
            public void addPreStatement(Statement statement) {
                preStmnts.add(statement);
            }

            @Override
            public void addPostStatement(Statement statement) {
                postStmnts.add(statement);
            }

            @Override
            public NativeVariable createParameter(String suffix, AbstractTypeReference type) {
                String pname = suffix != null ? name + "_" + suffix : name;
                Parameter param = new Parameter(type, pname);
                method.addParameter(param);
                return new NativeVariable(param);
            }

            @Override
            public NativeVariable createVariable(String suffix, AbstractTypeReference type, Expression init) {
                String vname = suffix != null ? name + "_" + suffix : name;
                LocalVariable var = new LocalVariable(type, vname, init);
                preStmnts.add(var);
                return new NativeVariable(var);
            }

            @Override
            public void addArgument(Expression arg) {
                if (isInstanceArg)
                    instanceArg.value = arg;
                else
                    args.add(arg);
            }
        };
        _paramInfo[i].marshal.marshalNative(context, _paramInfo[i].mode, _paramInfo[i].flags);
    }
    if (_method.getKind() == Kind.DESTRUCTOR) {
        method.getBody().addStatement(new DestructorInvocation(args.get(0)));
        return method;
    }
    final AbstractInvocation invocation;
    if (_method.getKind() == Kind.INSTANCE) {
        Expression member = new InstanceMemberAccess(instanceArg.value, _nativeName);
        invocation = new MethodInvocation(member, args);
    } else if (_method.getKind() == Kind.PROXY) {
        Expression member = new StaticMemberAccess(_nativeClass, _nativeName);
        args.add(0, new DereferenceExpression(instanceArg.value));
        invocation = new MethodInvocation(member, args);
    } else if (_method.getKind() == Kind.STATIC) {
        Expression member = new StaticMemberAccess(_nativeClass, _nativeName);
        invocation = new MethodInvocation(member, args);
    } else if (_method.getKind() == Kind.CONSTRUCTOR) {
        AbstractTypeReference type = ((PointerType) _returnType).getElementType();
        invocation = new ConstructorInvocation(type, args);
    } else {
        return null;
    }
    for (Statement stm : preStmnts) {
        method.getBody().addStatement(stm);
    }
    final NativeVariable retval;
    if (_returnHelper != null) {
        NativeVariable cppRetval = NativeVariable.createLocal(method.getBody(), _returnHelper.getRealNativeType(), "_returnObj", invocation, NativeVariable.Flags.BYREF);
        retval = NativeVariable.createLocal(method.getBody(), _returnHelper.getNativePInvokeType(), "_retval", _returnHelper.marshalNativeRetval(cppRetval.getReference()), NativeVariable.Flags.BYREF);
        method.getBody().addStatement(new DestructorInvocation(cppRetval.getReference()));
    } else if (_returnInfo != null) {
        retval = NativeVariable.createLocal(method.getBody(), _returnType, "_retval", invocation);
    } else {
        method.getBody().addStatement(invocation);
        retval = null;
    }
    for (Statement stm : postStmnts) {
        method.getBody().addStatement(stm);
    }
    if (retval != null) {
        method.getBody().addStatement(new ReturnStatement(retval.getReference()));
    }
    return method;
}
Also used : ByRef(sharpen.core.framework.ByRef) ArrayList(java.util.ArrayList) Kind(sharpen.xobotos.api.interop.NativeMethod.Kind) VariableDeclaration(org.eclipse.jdt.core.dom.VariableDeclaration) IVariableBinding(org.eclipse.jdt.core.dom.IVariableBinding)

Example 2 with ByRef

use of sharpen.core.framework.ByRef in project XobotOS by xamarin.

the class NativeMethodBuilder method createPInvokeWrapper.

public boolean createPInvokeWrapper(CSTypeDeclaration parent, final CSMethod method) {
    if (_resolveFailed)
        return false;
    final NamingStrategy ns = my(Configuration.class).getNamingStrategy();
    final CSTypeReferenceExpression pinvokeReturnType;
    final CSTypeReferenceExpression mappedReturnType;
    if (_returnInfo != null) {
        mappedReturnType = _returnInfo.getManagedType();
        pinvokeReturnType = _returnInfo.getPInvokeReturnType();
        method.returnType(mappedReturnType);
    } else {
        pinvokeReturnType = null;
        mappedReturnType = null;
    }
    CSTypeReferenceExpression[] mappedParamTypes = new CSTypeReferenceExpression[_paramInfo.length];
    for (int i = 0; i < _paramInfo.length; i++) {
        if (_paramInfo[i] == null)
            continue;
        mappedParamTypes[i] = _paramInfo[i].getManagedType();
        method.parameters().get(i).type(mappedParamTypes[i]);
    }
    final CSDllImport dllImport = _builder.getConfig().getDllImportAttribute();
    final List<CSExpression> args = new ArrayList<CSExpression>();
    final CSMethod pinvoke = new CSMethod(_nativeFunctionName);
    pinvoke.dllImport(dllImport);
    pinvoke.modifier(CSMethodModifier.Extern);
    pinvoke.visibility(CSVisibility.Private);
    if (_returnInfo != null) {
        pinvoke.returnType(pinvokeReturnType);
    } else {
        pinvoke.returnType(new CSTypeReference("void"));
    }
    if (_native.returnVoid())
        method.returnType(new CSTypeReference("void"));
    if (_native.getKind() == Kind.DESTRUCTOR) {
        final String name = method.parameters().get(0).name();
        CSExpression pref = new CSReferenceExpression(name);
        CSExpression mr = new CSMemberReferenceExpression(pref, "Dispose");
        method.body().addStatement(new CSMethodInvocationExpression(mr));
        return true;
    }
    if (_implicitInstance != null) {
        CSExpression fref = new CSReferenceExpression(_implicitInstance.getName());
        CSTypeReferenceExpression ftype = _nativeHandle.getManagedType();
        pinvoke.addParameter(new CSVariableDeclaration("_instance", ftype));
        args.add(fref);
    }
    final List<CSVariableDeclaration> decls = new ArrayList<CSVariableDeclaration>();
    final List<CSStatement> preStatements = new ArrayList<CSStatement>();
    final List<CSStatement> postStatements = new ArrayList<CSStatement>();
    final List<CSStatement> cleanupStatements = new ArrayList<CSStatement>();
    for (int i = 0, pos = 0; i < _paramInfo.length; i++) {
        if (_paramInfo[i] == null) {
            method.removeParameter(pos);
            continue;
        }
        final String name = ns.identifier(method.parameters().get(pos).name());
        CSExpression pref = new CSReferenceExpression(name);
        IManagedMarshalContext context = new IManagedMarshalContext() {

            @Override
            public void addDeclaration(CSVariableDeclaration decl, CSStatement cleanup) {
                decls.add(decl);
                if (cleanup != null)
                    cleanupStatements.add(cleanup);
            }

            @Override
            public void addPreStatement(CSStatement statement) {
                preStatements.add(statement);
            }

            @Override
            public void addPostStatement(CSStatement statement) {
                postStatements.add(statement);
            }

            @Override
            public ManagedVariable addParameter(String suffix, CSTypeReferenceExpression type, CSExpression arg, CSAttribute... attrs) {
                final String pname = suffix != null ? name + suffix : name;
                CSVariableDeclaration vdecl = pinvoke.addParameter(pname, type, attrs);
                args.add(arg);
                return new ManagedVariable(vdecl);
            }

            @Override
            public String getVariableName(String suffix) {
                return suffix != null ? name + "_" + suffix : name;
            }
        };
        _paramInfo[i].marshal.marshal(context, pref, _paramInfo[i].mode, _paramInfo[i].flags);
        pos++;
    }
    final CSExpression[] arglist = args.toArray(new CSExpression[0]);
    CSExpression mie = new CSMethodInvocationExpression(new CSReferenceExpression(pinvoke.name()), arglist);
    final CSExpression outExpr;
    final ByRef<ManagedVariable> retval = new ByRef<ManagedVariable>();
    if (_returnInfo != null) {
        IManagedReturnContext context = new IManagedReturnContext() {

            @Override
            public void addStatement(CSStatement statement) {
                postStatements.add(statement);
            }

            @Override
            public ManagedVariable createVariable(String name, CSTypeReferenceExpression type, CSExpression init) {
                final String vname = "_retval_" + name;
                ManagedVariable var = new ManagedVariable(vname, type);
                if (init != null)
                    var.getDeclaration().initializer(init);
                postStatements.add(var.getDeclarationStatement());
                return var;
            }

            @Override
            public ManagedVariable createRetval(CSExpression init) {
                retval.value = new ManagedVariable("_retval", mappedReturnType);
                retval.value.getDeclaration().initializer(init);
                postStatements.add(retval.value.getDeclarationStatement());
                return retval.value;
            }
        };
        outExpr = _returnInfo.marshal.marshalRetval(context, mie);
        if (retval.value != null) {
            if (outExpr != null)
                throw new IllegalStateException();
        } else if (outExpr == null) {
            throw new IllegalStateException();
        }
    } else {
        outExpr = null;
    }
    for (CSVariableDeclaration decl : decls) method.body().addStatement(new CSDeclarationStatement(-1, decl));
    final CSBlock block;
    if (cleanupStatements.size() > 0) {
        CSTryStatement tryBlock = new CSTryStatement(-1);
        CSBlock finallyBlock = new CSBlock();
        for (CSStatement stm : cleanupStatements) {
            finallyBlock.addStatement(stm);
        }
        tryBlock.finallyBlock(finallyBlock);
        method.body().addStatement(tryBlock);
        block = tryBlock.body();
    } else {
        block = method.body();
    }
    for (CSStatement stm : preStatements) block.addStatement(stm);
    if (_returnInfo != null) {
        if (postStatements.size() > 0) {
            if (retval.value == null) {
                retval.value = new ManagedVariable("_retval", mappedReturnType);
                retval.value.getDeclaration().initializer(outExpr);
                block.addStatement(retval.value.getDeclarationStatement());
            }
            for (CSStatement stmt : postStatements) block.addStatement(stmt);
            block.addStatement(new CSReturnStatement(-1, retval.value.getReference()));
        } else {
            block.addStatement(new CSReturnStatement(-1, outExpr));
        }
    } else {
        block.addStatement(mie);
        for (CSStatement stmt : postStatements) block.addStatement(stmt);
    }
    parent.addMember(pinvoke);
    return true;
}
Also used : Configuration(sharpen.core.Configuration) ByRef(sharpen.core.framework.ByRef) ArrayList(java.util.ArrayList) NamingStrategy(sharpen.core.NamingStrategy)

Example 3 with ByRef

use of sharpen.core.framework.ByRef in project XobotOS by xamarin.

the class CompilationUnitTemplate method findTypeTemplate.

@Override
public TypeTemplate findTypeTemplate(final TypeDeclaration node) {
    if (!(node.getParent() instanceof CompilationUnit))
        return null;
    final CompilationUnit parent = (CompilationUnit) node.getParent();
    final ByRef<TypeTemplate> result = new ByRef<TypeTemplate>();
    TemplateVisitor visitor = new TemplateVisitor() {

        @Override
        public void accept(TypeTemplate type) {
            result.value = type;
        }
    };
    if (!visit(visitor, parent, node))
        return null;
    return result.value != null ? result.value : TypeTemplate.DEFAULT;
}
Also used : CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) TemplateVisitor(sharpen.xobotos.api.TemplateVisitor) ByRef(sharpen.core.framework.ByRef)

Example 4 with ByRef

use of sharpen.core.framework.ByRef in project XobotOS by xamarin.

the class CompilationUnitTemplate method findEnumTemplate.

@Override
public EnumTemplate findEnumTemplate(final EnumDeclaration node) {
    if (!(node.getParent() instanceof CompilationUnit))
        return null;
    final CompilationUnit parent = (CompilationUnit) node.getParent();
    final ByRef<EnumTemplate> result = new ByRef<EnumTemplate>();
    TemplateVisitor visitor = new TemplateVisitor() {

        @Override
        public void accept(EnumTemplate type) {
            result.value = type;
        }
    };
    if (!visit(visitor, parent, node))
        return null;
    return result.value != null ? result.value : EnumTemplate.DEFAULT;
}
Also used : CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) TemplateVisitor(sharpen.xobotos.api.TemplateVisitor) ByRef(sharpen.core.framework.ByRef)

Example 5 with ByRef

use of sharpen.core.framework.ByRef in project XobotOS by xamarin.

the class XobotBuilder method run.

protected boolean run(final IProgressMonitor monitor) {
    Sharpen.Log(Level.INFO, "Starting build");
    try {
        checkFileList();
    } catch (Exception e) {
        Sharpen.Log(e, "Cannot compute file list");
        return false;
    }
    int countModified = 0;
    for (final Entry<ICompilationUnit, Boolean> entry : _sources.entrySet()) {
        if (!entry.getValue())
            continue;
        ++countModified;
        _mustParse.put(entry.getKey(), true);
    }
    if (countModified < 1) {
        Sharpen.Log(Level.INFO, "Nothing to do.");
        return true;
    }
    List<ICompilationUnit> parsingList = new ArrayList<ICompilationUnit>();
    for (final Entry<ICompilationUnit, Boolean> entry : _mustParse.entrySet()) {
        if (!entry.getValue())
            continue;
        parsingList.add(entry.getKey());
    }
    final int totalWork = parsingList.size() * PARSING_PRICE + countModified * (GENERATING_PRICE + OUTPUT_PRICE);
    Sharpen.Log(Level.INFO, "Converting %d files (must parse %d).", countModified, parsingList.size());
    monitor.beginTask("Converting", totalWork);
    final List<CompilationUnitPair> pairs = stage1_parse(parsingList, monitor);
    if (monitor.isCanceled() || (pairs == null) || (pairs.size() == 0))
        return false;
    if (!stage1b_checkForErrors(pairs)) {
        Sharpen.Log(Level.SEVERE, "Found errors while parsing compilation units; aborting!");
        return false;
    }
    AST ast = pairs.get(0).ast.getAST();
    final BindingManager bindings = new BindingManager(ast, _configFile.getNativeConfig());
    final ByRef<Map<ICompilationUnit, CompilationUnitBuilder>> builders = new ByRef<Map<ICompilationUnit, CompilationUnitBuilder>>();
    Environments.runWith(Environments.newClosedEnvironment(_api, bindings, _config), new Runnable() {

        @Override
        public void run() {
            builders.value = stage2_preprocess(bindings, pairs);
        }
    });
    if (monitor.isCanceled())
        return false;
    if (builders.value == null) {
        Sharpen.Log(Level.SEVERE, "Found errors while pre-processing; aborting!");
        return false;
    }
    final List<CompilationUnitPair> modifiedPairs = new ArrayList<CompilationUnitPair>();
    final List<CompilationUnitBuilder> modified = new ArrayList<CompilationUnitBuilder>();
    for (final CompilationUnitBuilder builder : builders.value.values()) {
        if (_sources.get(builder.getPair().source)) {
            modifiedPairs.add(builder.getPair());
            modified.add(builder);
        }
    }
    final ASTResolver resolver = new DefaultASTResolver(modifiedPairs);
    final ByRef<Boolean> ok = new ByRef<Boolean>();
    Environments.runWith(Environments.newClosedEnvironment(_api, bindings, _config, _configFile, resolver), new Runnable() {

        @Override
        public void run() {
            ok.value = stage3_generate(monitor, modified);
        }
    });
    if (monitor.isCanceled() || !ok.value)
        return false;
    Environments.runWith(Environments.newClosedEnvironment(_api, bindings, _config, _configFile, resolver), new Runnable() {

        @Override
        public void run() {
            // ok.value =
            // stage4_post_processs(monitor,
            // modified);
            ok.value = bindings.postProcess();
        }
    });
    if (monitor.isCanceled() || !ok.value)
        return false;
    Environments.runWith(Environments.newClosedEnvironment(_api, bindings, _config, _configFile, resolver), new Runnable() {

        @Override
        public void run() {
            ok.value = stage4_save_output(monitor, modified);
        }
    });
    if (monitor.isCanceled() || !ok.value)
        return false;
    return stage5_generate_csproj();
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) AST(org.eclipse.jdt.core.dom.AST) CompilationUnitPair(sharpen.core.framework.CompilationUnitPair) ByRef(sharpen.core.framework.ByRef) DefaultASTResolver(sharpen.core.framework.DefaultASTResolver) CoreException(org.eclipse.core.runtime.CoreException) BindingManager(sharpen.xobotos.api.bindings.BindingManager) CompilationUnitBuilder(sharpen.xobotos.generator.CompilationUnitBuilder) ASTResolver(sharpen.core.framework.ASTResolver) DefaultASTResolver(sharpen.core.framework.DefaultASTResolver)

Aggregations

ByRef (sharpen.core.framework.ByRef)9 TemplateVisitor (sharpen.xobotos.api.TemplateVisitor)3 NamespaceTemplate (sharpen.xobotos.api.templates.NamespaceTemplate)3 ArrayList (java.util.ArrayList)2 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)2 BindingManager (sharpen.xobotos.api.bindings.BindingManager)2 CompilationUnitTemplate (sharpen.xobotos.api.templates.CompilationUnitTemplate)2 CoreException (org.eclipse.core.runtime.CoreException)1 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)1 AST (org.eclipse.jdt.core.dom.AST)1 IVariableBinding (org.eclipse.jdt.core.dom.IVariableBinding)1 VariableDeclaration (org.eclipse.jdt.core.dom.VariableDeclaration)1 Configuration (sharpen.core.Configuration)1 NamingStrategy (sharpen.core.NamingStrategy)1 CSTypeDeclaration (sharpen.core.csharp.ast.CSTypeDeclaration)1 ASTResolver (sharpen.core.framework.ASTResolver)1 CompilationUnitPair (sharpen.core.framework.CompilationUnitPair)1 DefaultASTResolver (sharpen.core.framework.DefaultASTResolver)1 IBindingProvider (sharpen.xobotos.api.bindings.IBindingProvider)1 Kind (sharpen.xobotos.api.interop.NativeMethod.Kind)1