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;
}
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;
}
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;
}
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;
}
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();
}
Aggregations