diff --git a/core/src/main/java/org/teavm/backend/c/generate/CodeGenerationVisitor.java b/core/src/main/java/org/teavm/backend/c/generate/CodeGenerationVisitor.java index 5b762541b..72943125d 100644 --- a/core/src/main/java/org/teavm/backend/c/generate/CodeGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/c/generate/CodeGenerationVisitor.java @@ -714,14 +714,14 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor { ClassReader cls = context.getClassSource().get(field.getClassName()); writer.print("TEAVM_FIELD("); qualified.acceptVisitor(this); + writer.print(", "); if (cls != null && isNative(cls)) { InteropUtil.processInclude(cls.getAnnotations(), includes); - writer.print(", ").print(InteropUtil.getNativeName(cls)) - .print(", ").print(InteropUtil.getNativeName(cls, field.getFieldName())); + InteropUtil.printNativeReference(writer, cls); + writer.print(", ").print(InteropUtil.getNativeName(cls, field.getFieldName())); } else { includes.includeClass(field.getClassName()); - writer.print(", ").print(names.forClass(field.getClassName())) - .print(", ").print(names.forMemberField(field)); + writer.print(names.forClass(field.getClassName())).print(", ").print(names.forMemberField(field)); } writer.print(")"); } else { diff --git a/core/src/main/java/org/teavm/backend/c/generate/CodeGeneratorUtil.java b/core/src/main/java/org/teavm/backend/c/generate/CodeGeneratorUtil.java index 6e0bb3a7f..e4c58e8b8 100644 --- a/core/src/main/java/org/teavm/backend/c/generate/CodeGeneratorUtil.java +++ b/core/src/main/java/org/teavm/backend/c/generate/CodeGeneratorUtil.java @@ -15,6 +15,8 @@ */ package org.teavm.backend.c.generate; +import org.teavm.backend.c.util.InteropUtil; +import org.teavm.model.ClassReader; import org.teavm.model.ValueType; public final class CodeGeneratorUtil { @@ -99,4 +101,14 @@ public final class CodeGeneratorUtil { writer.print(String.valueOf(v)); } + public static void printClassReference(CodeWriter writer, IncludeManager includes, NameProvider names, + ClassReader cls, String className) { + if (cls != null && InteropUtil.isNative(cls)) { + InteropUtil.processInclude(cls.getAnnotations(), includes); + InteropUtil.printNativeReference(writer, cls); + } else { + includes.includeClass(className); + writer.print(names.forClass(className)); + } + } } diff --git a/core/src/main/java/org/teavm/backend/c/intrinsic/AddressIntrinsic.java b/core/src/main/java/org/teavm/backend/c/intrinsic/AddressIntrinsic.java index 34cd07b41..8e8557e5d 100644 --- a/core/src/main/java/org/teavm/backend/c/intrinsic/AddressIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/c/intrinsic/AddressIntrinsic.java @@ -16,8 +16,8 @@ package org.teavm.backend.c.intrinsic; import org.teavm.ast.InvocationExpr; +import org.teavm.backend.c.generate.CodeGeneratorUtil; import org.teavm.backend.c.util.ConstantUtil; -import org.teavm.backend.c.util.InteropUtil; import org.teavm.interop.Address; import org.teavm.model.ClassReader; import org.teavm.model.MethodReference; @@ -175,19 +175,17 @@ public class AddressIntrinsic implements Intrinsic { invocation.getArguments().get(1)); context.emit(invocation.getArguments().get(2)); - String structureName; - ClassReader cls = className != null ? context.classes().get(className) : null; - if (cls != null && InteropUtil.isNative(cls)) { - structureName = InteropUtil.getNativeName(cls); - InteropUtil.processInclude(cls.getAnnotations(), context.includes()); - } else if (className != null) { - structureName = context.names().forClass(className); - context.includes().includeClass(className); + context.writer().print(" * sizeof("); + + if (className != null) { + ClassReader cls = className != null ? context.classes().get(className) : null; + CodeGeneratorUtil.printClassReference(context.writer(), context.includes(), + context.names(), cls, className); } else { - structureName = "**"; + context.writer().print("**"); } - context.writer().print(" * sizeof(").print(structureName).print(")"); + context.writer().print(")"); context.writer().print(")"); } break; diff --git a/core/src/main/java/org/teavm/backend/c/intrinsic/StringsIntrinsic.java b/core/src/main/java/org/teavm/backend/c/intrinsic/StringsIntrinsic.java index ae2bae58f..1801722e7 100644 --- a/core/src/main/java/org/teavm/backend/c/intrinsic/StringsIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/c/intrinsic/StringsIntrinsic.java @@ -15,10 +15,8 @@ */ package org.teavm.backend.c.intrinsic; -import org.teavm.ast.ConstantExpr; import org.teavm.ast.Expr; import org.teavm.ast.InvocationExpr; -import org.teavm.backend.c.generate.StringPoolGenerator; import org.teavm.interop.Strings; import org.teavm.model.MethodReference; @@ -33,14 +31,9 @@ public class StringsIntrinsic implements Intrinsic { switch (invocation.getMethod().getName()) { case "toC": { Expr arg = invocation.getArguments().get(0); - String literal = extractStringConstant(arg); - if (literal != null) { - StringPoolGenerator.generateSimpleStringLiteral(context.writer(), literal); - } else { - context.writer().print("teavm_stringToC("); - context.emit(arg); - context.writer().print(")"); - } + context.writer().print("teavm_stringToC("); + context.emit(arg); + context.writer().print(")"); break; } case "fromC": @@ -50,13 +43,4 @@ public class StringsIntrinsic implements Intrinsic { break; } } - - private String extractStringConstant(Expr expr) { - if (!(expr instanceof ConstantExpr)) { - return null; - } - - Object value = ((ConstantExpr) expr).getValue(); - return value instanceof String ? (String) value : null; - } } diff --git a/core/src/main/java/org/teavm/backend/c/intrinsic/StructureIntrinsic.java b/core/src/main/java/org/teavm/backend/c/intrinsic/StructureIntrinsic.java index 9da7e8b27..85ab75d47 100644 --- a/core/src/main/java/org/teavm/backend/c/intrinsic/StructureIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/c/intrinsic/StructureIntrinsic.java @@ -16,8 +16,8 @@ package org.teavm.backend.c.intrinsic; import org.teavm.ast.InvocationExpr; +import org.teavm.backend.c.generate.CodeGeneratorUtil; import org.teavm.backend.c.util.ConstantUtil; -import org.teavm.backend.c.util.InteropUtil; import org.teavm.interop.Structure; import org.teavm.model.ClassReader; import org.teavm.model.MethodReference; @@ -64,7 +64,11 @@ public class StructureIntrinsic implements Intrinsic { case "sizeOf": { String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0)); if (className != null) { - context.writer().print("sizeof(").print(context.names().forClass(className)).print(")"); + context.writer().print("sizeof("); + ClassReader cls = context.classes().get(className); + CodeGeneratorUtil.printClassReference(context.writer(), context.includes(), context.names(), cls, + className); + context.writer().print(")"); } break; } @@ -72,15 +76,10 @@ public class StructureIntrinsic implements Intrinsic { String className = ConstantUtil.getClassLiteral(context, invocation, invocation.getArguments().get(0)); if (className != null) { ClassReader cls = context.classes().get(className); - String structureName; - if (InteropUtil.isNative(cls)) { - structureName = InteropUtil.getNativeName(cls); - InteropUtil.processInclude(cls.getAnnotations(), context.includes()); - } else { - structureName = context.names().forClass(className); - context.includes().includeClass(className); - } - context.writer().print("TEAVM_STRUCTURE_ADD(").print(structureName).print(", "); + context.writer().print("TEAVM_STRUCTURE_ADD("); + CodeGeneratorUtil.printClassReference(context.writer(), context.includes(), context.names(), cls, + className); + context.writer().print(", "); context.emit(invocation.getArguments().get(1)); context.writer().print(", "); context.emit(invocation.getArguments().get(2)); diff --git a/core/src/main/java/org/teavm/backend/c/util/InteropUtil.java b/core/src/main/java/org/teavm/backend/c/util/InteropUtil.java index 5f18bcdf3..8dbf1da5e 100644 --- a/core/src/main/java/org/teavm/backend/c/util/InteropUtil.java +++ b/core/src/main/java/org/teavm/backend/c/util/InteropUtil.java @@ -15,6 +15,7 @@ */ package org.teavm.backend.c.util; +import org.teavm.backend.c.generate.CodeWriter; import org.teavm.backend.c.generate.IncludeManager; import org.teavm.interop.c.Include; import org.teavm.interop.c.Name; @@ -33,8 +34,18 @@ public final class InteropUtil { return cls.getAnnotations().get(Native.class.getName()) != null; } + public static void printNativeReference(CodeWriter writer, ClassReader cls) { + AnnotationReader annot = cls.getAnnotations().get(Native.class.getName()); + if (annot != null) { + AnnotationValue fieldValue = annot.getValue("structKeyword"); + if (fieldValue != null && fieldValue.getBoolean()) { + writer.print("struct "); + } + } + writer.print(getNativeName(cls)); + } - public static String getNativeName(ClassReader cls) { + private static String getNativeName(ClassReader cls) { AnnotationReader nameAnnot = cls.getAnnotations().get(Name.class.getName()); if (nameAnnot != null) { return nameAnnot.getValue("value").getString(); diff --git a/interop/core/src/main/java/org/teavm/interop/c/Native.java b/interop/core/src/main/java/org/teavm/interop/c/Native.java index 5c92584f2..bd2e31355 100644 --- a/interop/core/src/main/java/org/teavm/interop/c/Native.java +++ b/interop/core/src/main/java/org/teavm/interop/c/Native.java @@ -23,4 +23,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Native { + boolean structKeyword() default false; }