提交 4ac71488 authored 作者: Thomas Mueller's avatar Thomas Mueller

Java to C++ converter

上级 637b845a
...@@ -101,7 +101,8 @@ public class ClassObj { ...@@ -101,7 +101,8 @@ public class ClassObj {
list = new ArrayList<MethodObj>(); list = new ArrayList<MethodObj>();
methods.put(method.name, list); methods.put(method.name, list);
} else { } else {
method.name = method.name + "_" + (list.size() + 1); // for overloaded methods
// method.name = method.name + "_" + (list.size() + 1);
} }
list.add(method); list.add(method);
} }
...@@ -248,6 +249,11 @@ class MethodObj { ...@@ -248,6 +249,11 @@ class MethodObj {
* Whether this is a constructor. * Whether this is a constructor.
*/ */
boolean isConstructor; boolean isConstructor;
public String toString() {
return name;
}
} }
/** /**
...@@ -305,6 +311,10 @@ class FieldObj { ...@@ -305,6 +311,10 @@ class FieldObj {
*/ */
ClassObj declaredClass; ClassObj declaredClass;
public String toString() {
return name;
}
} }
/** /**
...@@ -338,12 +348,12 @@ class Type { ...@@ -338,12 +348,12 @@ class Type {
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append(JavaParser.toC(classObj.toString())); for (int i = 0; i < arrayLevel; i++) {
if (!classObj.isPrimitive) { buff.append("ptr<array< ");
buff.append("*");
} }
buff.append(classObj.toString());
for (int i = 0; i < arrayLevel; i++) { for (int i = 0; i < arrayLevel; i++) {
buff.append("*"); buff.append(" > >");
} }
return buff.toString(); return buff.toString();
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.java; package org.h2.java;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
/** /**
* An expression. * An expression.
...@@ -14,6 +15,7 @@ import java.util.ArrayList; ...@@ -14,6 +15,7 @@ import java.util.ArrayList;
public interface Expr { public interface Expr {
// toString // toString
Type getType(); Type getType();
Expr cast(Type type);
} }
/** /**
...@@ -52,7 +54,6 @@ class CallExpr implements Expr { ...@@ -52,7 +54,6 @@ class CallExpr implements Expr {
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
String methodName;
initMethod(); initMethod();
if (method.isIgnore) { if (method.isIgnore) {
if (args.size() == 0) { if (args.size() == 0) {
...@@ -64,23 +65,23 @@ class CallExpr implements Expr { ...@@ -64,23 +65,23 @@ class CallExpr implements Expr {
"Cannot ignore method with multiple arguments: " + method); "Cannot ignore method with multiple arguments: " + method);
} }
} else { } else {
if (method.isVirtual) { if (expr == null) {
methodName = "virtual_" + method.name + "[CLASS_ID("+expr.toString()+")]"; // static method
buff.append(JavaParser.toC(classObj.toString() + "." + method.name));
} else { } else {
methodName = JavaParser.toC(classObj.toString() + "." + method.name); buff.append(expr.toString()).append("->");
buff.append(method.name);
} }
buff.append(methodName).append("("); buff.append("(");
int i = 0; int i = 0;
if (expr != null) { Iterator<FieldObj> paramIt = method.parameters.values().iterator();
buff.append(expr.toString());
i++;
}
for (Expr a : args) { for (Expr a : args) {
if (i > 0) { if (i > 0) {
buff.append(", "); buff.append(", ");
} }
FieldObj f = paramIt.next();
i++; i++;
buff.append(a); buff.append(a.cast(f.type));
} }
buff.append(")"); buff.append(")");
} }
...@@ -92,6 +93,10 @@ class CallExpr implements Expr { ...@@ -92,6 +93,10 @@ class CallExpr implements Expr {
return method.returnType; return method.returnType;
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -104,19 +109,17 @@ class AssignExpr implements Expr { ...@@ -104,19 +109,17 @@ class AssignExpr implements Expr {
Expr right; Expr right;
public String toString() { public String toString() {
if (left.getType().isSimplePrimitive()) { return left + " " + op + " " + right.cast(left.getType());
return left + " " + op + " " + right;
}
if (right.toString().equals("null")) {
return "release(" + left + ")";
}
return left + " = set(" + left + ", " + right + ")";
} }
public Type getType() { public Type getType() {
return left.getType(); return left.getType();
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -135,6 +138,14 @@ class ConditionalExpr implements Expr { ...@@ -135,6 +138,14 @@ class ConditionalExpr implements Expr {
return ifTrue.getType(); return ifTrue.getType();
} }
public Expr cast(Type type) {
ConditionalExpr e2 = new ConditionalExpr();
e2.condition = condition;
e2.ifTrue = ifTrue.cast(type);
e2.ifFalse = ifFalse.cast(type);
return e2;
}
} }
/** /**
...@@ -153,6 +164,9 @@ class LiteralExpr implements Expr { ...@@ -153,6 +164,9 @@ class LiteralExpr implements Expr {
} }
public String toString() { public String toString() {
if ("null".equals(literal)) {
return JavaParser.toCType(type) + "()";
}
return literal; return literal;
} }
...@@ -164,6 +178,14 @@ class LiteralExpr implements Expr { ...@@ -164,6 +178,14 @@ class LiteralExpr implements Expr {
return type; return type;
} }
public Expr cast(Type type) {
if ("null".equals(literal)) {
// TODO should be immutable
this.type = type;
}
return this;
}
} }
/** /**
...@@ -193,13 +215,11 @@ class OpExpr implements Expr { ...@@ -193,13 +215,11 @@ class OpExpr implements Expr {
if (left.getType().isObject() || right.getType().isObject()) { if (left.getType().isObject() || right.getType().isObject()) {
// TODO convert primitive to to String, call toString // TODO convert primitive to to String, call toString
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append("java_lang_StringBuilder_toString("); buff.append("ptr<java_lang_StringBuilder>(new java_lang_StringBuilder(");
buff.append("java_lang_StringBuilder_append(");
buff.append("java_lang_StringBuilder_init_obj(");
buff.append(convertToString(left)); buff.append(convertToString(left));
buff.append("), "); buff.append("))->append(");
buff.append(convertToString(right)); buff.append(convertToString(right));
buff.append("))"); buff.append(")->toString()");
return buff.toString(); return buff.toString();
} }
} }
...@@ -209,7 +229,7 @@ class OpExpr implements Expr { ...@@ -209,7 +229,7 @@ class OpExpr implements Expr {
private String convertToString(Expr e) { private String convertToString(Expr e) {
Type t = e.getType(); Type t = e.getType();
if (t.arrayLevel > 0) { if (t.arrayLevel > 0) {
return e.toString() + ".toString()"; return e.toString() + "->toString()";
} }
if (t.classObj.isPrimitive) { if (t.classObj.isPrimitive) {
ClassObj wrapper = context.getWrapper(t.classObj); ClassObj wrapper = context.getWrapper(t.classObj);
...@@ -217,7 +237,12 @@ class OpExpr implements Expr { ...@@ -217,7 +237,12 @@ class OpExpr implements Expr {
} else if (e.getType().toString().equals("java_lang_String*")) { } else if (e.getType().toString().equals("java_lang_String*")) {
return e.toString(); return e.toString();
} }
return e.toString() + ".toString()"; return e.toString() + "->toString()";
}
private static boolean isComparison(String op) {
return op.equals("==") || op.equals(">") || op.equals("<") ||
op.equals(">=") || op.equals("<=") || op.equals("!=");
} }
public Type getType() { public Type getType() {
...@@ -227,6 +252,11 @@ class OpExpr implements Expr { ...@@ -227,6 +252,11 @@ class OpExpr implements Expr {
if (right == null) { if (right == null) {
return left.getType(); return left.getType();
} }
if (isComparison(op)) {
Type t = new Type();
t.classObj = JavaParser.getBuiltInClass("boolean");
return t;
}
if (op.equals("+")) { if (op.equals("+")) {
if (left.getType().isObject() || right.getType().isObject()) { if (left.getType().isObject() || right.getType().isObject()) {
Type t = new Type(); Type t = new Type();
...@@ -242,6 +272,10 @@ class OpExpr implements Expr { ...@@ -242,6 +272,10 @@ class OpExpr implements Expr {
return lt; return lt;
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -261,23 +295,14 @@ class NewExpr implements Expr { ...@@ -261,23 +295,14 @@ class NewExpr implements Expr {
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
if (arrayInitExpr.size() > 0) { if (arrayInitExpr.size() > 0) {
if (classObj.isPrimitive) { buff.append("ptr<array<" + classObj + "> >(new array<" + classObj + ">(1 ");
buff.append("NEW_ARRAY(sizeof(" + classObj + ")"); for (Expr e : arrayInitExpr) {
buff.append(", 1 "); buff.append("* ").append(e);
for (Expr e : arrayInitExpr) {
buff.append("* ").append(e);
}
buff.append(")");
} else {
buff.append("NEW_OBJ_ARRAY(1 ");
for (Expr e : arrayInitExpr) {
buff.append("* ").append(e);
}
buff.append(")");
} }
buff.append("))");
} else { } else {
MethodObj m = classObj.getMethod("init_obj", args); buff.append("new " + JavaParser.toC(classObj.toString()));
buff.append(JavaParser.toC(classObj.toString() + "." + m.name)).append("("); buff.append("(");
int i = 0; int i = 0;
for (Expr a : args) { for (Expr a : args) {
if (i++ > 0) { if (i++ > 0) {
...@@ -297,6 +322,10 @@ class NewExpr implements Expr { ...@@ -297,6 +322,10 @@ class NewExpr implements Expr {
return t; return t;
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -386,6 +415,11 @@ class StringExpr implements Expr { ...@@ -386,6 +415,11 @@ class StringExpr implements Expr {
} }
return buff.toString(); return buff.toString();
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -405,23 +439,19 @@ class VariableExpr implements Expr { ...@@ -405,23 +439,19 @@ class VariableExpr implements Expr {
public String toString() { public String toString() {
init(); init();
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
if ("length".equals(name) && base.getType().arrayLevel > 0) { if (base != null) {
buff.append("LENGTH("); buff.append(base.toString()).append("->");
buff.append(base.toString()); }
buff.append(")"); if (field != null) {
} else { if (field.isStatic) {
if (base != null) { buff.append(JavaParser.toC(field.declaredClass + "." + field.name));
buff.append(base.toString()).append("->"); } else if (field.name != null) {
} buff.append(field.name);
if (field != null) { } else if ("length".equals(name) && base.getType().arrayLevel > 0) {
if (field.isStatic) { buff.append("length()");
buff.append(JavaParser.toC(field.declaredClass + "." + field.name));
} else {
buff.append(field.name);
}
} else {
buff.append(JavaParser.toC(name));
} }
} else {
buff.append(JavaParser.toC(name));
} }
return buff.toString(); return buff.toString();
} }
...@@ -450,6 +480,10 @@ class VariableExpr implements Expr { ...@@ -450,6 +480,10 @@ class VariableExpr implements Expr {
return field.type; return field.type;
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -473,6 +507,10 @@ class ArrayExpr implements Expr { ...@@ -473,6 +507,10 @@ class ArrayExpr implements Expr {
return expr.getType(); return expr.getType();
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -500,6 +538,10 @@ class ArrayInitExpr implements Expr { ...@@ -500,6 +538,10 @@ class ArrayInitExpr implements Expr {
return buff.toString(); return buff.toString();
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -518,6 +560,10 @@ class CastExpr implements Expr { ...@@ -518,6 +560,10 @@ class CastExpr implements Expr {
return "(" + type + ") " + expr; return "(" + type + ") " + expr;
} }
public Expr cast(Type type) {
return this;
}
} }
/** /**
...@@ -536,7 +582,11 @@ class ArrayAccessExpr implements Expr { ...@@ -536,7 +582,11 @@ class ArrayAccessExpr implements Expr {
} }
public String toString() { public String toString() {
return base + "[" + index + "]"; return base + "->at(" + index + ")";
}
public Expr cast(Type type) {
return this;
} }
} }
...@@ -22,6 +22,8 @@ import org.h2.util.New; ...@@ -22,6 +22,8 @@ import org.h2.util.New;
*/ */
public class JavaParser { public class JavaParser {
private static final HashMap<String, ClassObj> BUILT_IN_CLASSES = New.hashMap();
private static final int TOKEN_LITERAL_CHAR = 0; private static final int TOKEN_LITERAL_CHAR = 0;
private static final int TOKEN_LITERAL_STRING = 1; private static final int TOKEN_LITERAL_STRING = 1;
private static final int TOKEN_LITERAL_NUMBER = 2; private static final int TOKEN_LITERAL_NUMBER = 2;
...@@ -33,7 +35,6 @@ public class JavaParser { ...@@ -33,7 +35,6 @@ public class JavaParser {
private static final HashMap<String, String> JAVA_IMPORT_MAP = New.hashMap(); private static final HashMap<String, String> JAVA_IMPORT_MAP = New.hashMap();
private final ArrayList<ClassObj> allClasses = New.arrayList(); private final ArrayList<ClassObj> allClasses = New.arrayList();
private final HashMap<String, ClassObj> builtInTypes = New.hashMap();
private String source; private String source;
...@@ -122,7 +123,7 @@ public class JavaParser { ...@@ -122,7 +123,7 @@ public class JavaParser {
c.className = type; c.className = type;
c.isPrimitive = primitive; c.isPrimitive = primitive;
c.primitiveType = primitiveType; c.primitiveType = primitiveType;
builtInTypes.put(type, c); BUILT_IN_CLASSES.put(type, c);
addClass(c); addClass(c);
} }
...@@ -197,7 +198,7 @@ public class JavaParser { ...@@ -197,7 +198,7 @@ public class JavaParser {
isInterface = true; isInterface = true;
} }
String name = readIdentifier(); String name = readIdentifier();
classObj = builtInTypes.get(packageName + "." + name); classObj = BUILT_IN_CLASSES.get(packageName + "." + name);
if (classObj == null) { if (classObj == null) {
classObj = new ClassObj(); classObj = new ClassObj();
classObj.id = nextClassId++; classObj.id = nextClassId++;
...@@ -228,7 +229,7 @@ public class JavaParser { ...@@ -228,7 +229,7 @@ public class JavaParser {
} }
private boolean isTypeOrIdentifier() { private boolean isTypeOrIdentifier() {
if (builtInTypes.containsKey(current.token)) { if (BUILT_IN_CLASSES.containsKey(current.token)) {
return true; return true;
} }
return current.type == TOKEN_IDENTIFIER; return current.type == TOKEN_IDENTIFIER;
...@@ -242,8 +243,12 @@ public class JavaParser { ...@@ -242,8 +243,12 @@ public class JavaParser {
return c; return c;
} }
static ClassObj getBuiltInClass(String type) {
return BUILT_IN_CLASSES.get(type);
}
private ClassObj getClassIf(String type) { private ClassObj getClassIf(String type) {
ClassObj c = builtInTypes.get(type); ClassObj c = BUILT_IN_CLASSES.get(type);
if (c != null) { if (c != null) {
return c; return c;
} }
...@@ -260,7 +265,7 @@ public class JavaParser { ...@@ -260,7 +265,7 @@ public class JavaParser {
} }
c = classes.get(mappedType); c = classes.get(mappedType);
if (c == null) { if (c == null) {
c = builtInTypes.get(mappedType); c = BUILT_IN_CLASSES.get(mappedType);
if (c == null) { if (c == null) {
throw new RuntimeException("Unknown class: " + mappedType); throw new RuntimeException("Unknown class: " + mappedType);
} }
...@@ -313,7 +318,7 @@ public class JavaParser { ...@@ -313,7 +318,7 @@ public class JavaParser {
if (readIf("{")) { if (readIf("{")) {
method = new MethodObj(); method = new MethodObj();
method.isIgnore = isIgnore; method.isIgnore = isIgnore;
method.name = isStatic ? "cl_init_obj" : "init_obj"; method.name = isStatic ? "cl_init_obj" : "";
method.isStatic = isStatic; method.isStatic = isStatic;
localVars.clear(); localVars.clear();
if (!isStatic) { if (!isStatic) {
...@@ -340,7 +345,7 @@ public class JavaParser { ...@@ -340,7 +345,7 @@ public class JavaParser {
if (type.classObj != classObj) { if (type.classObj != classObj) {
throw getSyntaxException("Constructor of wrong type: " + type); throw getSyntaxException("Constructor of wrong type: " + type);
} }
method.name = "init_obj"; method.name = "";
method.isConstructor = true; method.isConstructor = true;
parseFormalParameters(method); parseFormalParameters(method);
if (!readIf(";")) { if (!readIf(";")) {
...@@ -350,6 +355,9 @@ public class JavaParser { ...@@ -350,6 +355,9 @@ public class JavaParser {
addMethod(method); addMethod(method);
} else { } else {
String name = readIdentifier(); String name = readIdentifier();
if (name.endsWith("Method")) {
name = name.substring(0, name.length() - "Method".length());
}
method.name = name; method.name = name;
if (readIf("(")) { if (readIf("(")) {
parseFormalParameters(method); parseFormalParameters(method);
...@@ -423,7 +431,7 @@ public class JavaParser { ...@@ -423,7 +431,7 @@ public class JavaParser {
private void initThisPointer() { private void initThisPointer() {
thisPointer = new FieldObj(); thisPointer = new FieldObj();
thisPointer.isLocal = true; thisPointer.isLocal = true;
thisPointer.name = "thiz"; thisPointer.name = "this";
thisPointer.type = new Type(); thisPointer.type = new Type();
thisPointer.type.classObj = classObj; thisPointer.type.classObj = classObj;
} }
...@@ -465,7 +473,7 @@ public class JavaParser { ...@@ -465,7 +473,7 @@ public class JavaParser {
private String readTypeOrIdentifier() { private String readTypeOrIdentifier() {
if (current.type == TOKEN_RESERVED) { if (current.type == TOKEN_RESERVED) {
if (builtInTypes.containsKey(current.token)) { if (BUILT_IN_CLASSES.containsKey(current.token)) {
return read(); return read();
} }
} }
...@@ -888,7 +896,7 @@ public class JavaParser { ...@@ -888,7 +896,7 @@ public class JavaParser {
VariableExpr expr = new VariableExpr(this); VariableExpr expr = new VariableExpr(this);
expr.field = thisPointer; expr.field = thisPointer;
if (thisPointer == null) { if (thisPointer == null) {
throw getSyntaxException("this usage in static context"); throw getSyntaxException("'this' used in a static context");
} }
return expr; return expr;
} }
...@@ -958,7 +966,7 @@ public class JavaParser { ...@@ -958,7 +966,7 @@ public class JavaParser {
ve.field = thisPointer; ve.field = thisPointer;
expr.base = ve; expr.base = ve;
if (thisPointer == null) { if (thisPointer == null) {
throw getSyntaxException("this usage in static context"); throw getSyntaxException("'this' used in a static context");
} }
} }
expr.name = name; expr.name = name;
...@@ -1374,7 +1382,7 @@ public class JavaParser { ...@@ -1374,7 +1382,7 @@ public class JavaParser {
} }
/** /**
* Write the C header. * Write the C++ header.
* *
* @param out the output writer * @param out the output writer
*/ */
...@@ -1383,8 +1391,9 @@ public class JavaParser { ...@@ -1383,8 +1391,9 @@ public class JavaParser {
out.println(s); out.println(s);
} }
out.println(); out.println();
// two classes, similar to the pimpl idiom
for (ClassObj c : classes.values()) { for (ClassObj c : classes.values()) {
out.println("struct " + toC(c.className) + ";"); out.println("class " + toC(c.className) + ";");
} }
for (ClassObj c : classes.values()) { for (ClassObj c : classes.values()) {
for (FieldObj f : c.staticFields.values()) { for (FieldObj f : c.staticFields.values()) {
...@@ -1393,123 +1402,95 @@ public class JavaParser { ...@@ -1393,123 +1402,95 @@ public class JavaParser {
if (f.isFinal) { if (f.isFinal) {
buff.append("const "); buff.append("const ");
} }
buff.append(toC(f.type.classObj.toString())); buff.append(toCType(f.type));
if (!f.type.classObj.isPrimitive) {
buff.append("*");
}
buff.append(" ").append(toC(c.className + "." + f.name)); buff.append(" ").append(toC(c.className + "." + f.name));
for (int i = 0; i < f.type.arrayLevel; i++) {
buff.append("[]");
}
buff.append(";"); buff.append(";");
out.println(buff.toString()); out.println(buff.toString());
} }
out.println("typedef struct " + toC(c.className) + " {"); for (ArrayList<MethodObj> list : c.methods.values()) {
for (MethodObj m : list) {
if (m.isIgnore) {
continue;
}
if (m.isStatic) {
out.print(toCType(m.returnType));
out.print(" " + toC(c.className + "_" + m.name) + "(");
int i = 0;
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(toCType(p.type) + " " + p.name);
i++;
}
out.println(");");
}
}
}
out.print("class " + toC(c.className) + " : public ");
if (c.superClassName == null) {
if (c.className.equals("java.lang.Object")) {
out.print("RefBase");
} else {
out.print("java_lang_Object");
}
} else {
out.print(toC(c.superClassName));
}
out.println(" {");
out.println("public:");
for (FieldObj f : c.instanceFields.values()) { for (FieldObj f : c.instanceFields.values()) {
out.print(" "); out.print(" ");
if (!f.type.classObj.isPrimitive) { out.print(toCType(f.type) + " " + f.name);
out.print("struct ");
}
out.print(toC(f.type.toString()) + " " + f.name);
if (f.value != null) { if (f.value != null) {
out.print(" = " + f.value); out.print(" = " + f.value);
} }
out.println(";"); out.println(";");
} }
if (c.instanceFields.size() == 0) { out.println("public:");
out.println(" int dummy;");
}
out.println("} " + toC(c.className) + ";");
}
ArrayList<String> constantNames = New.arrayList(stringConstantToStringMap.keySet());
Collections.sort(constantNames);
for (String c : constantNames) {
String s = stringConstantToStringMap.get(c);
out.println("const java_lang_String* " + c + " = STRING(\"" + s + "\");");
}
for (ClassObj c : classes.values()) {
out.println("/* " + c.className + " */");
for (ArrayList<MethodObj> list : c.methods.values()) { for (ArrayList<MethodObj> list : c.methods.values()) {
for (MethodObj m : list) { for (MethodObj m : list) {
if (m.isIgnore) { if (m.isIgnore) {
continue; continue;
} }
out.print(m.returnType + " " + toC(c.className) + "_" + m.name + "("); if (m.isStatic) {
int i = 0; continue;
if (!m.isStatic && !m.isConstructor) {
out.print(toC(c.className) + "* this");
i++;
} }
if (m.isConstructor) {
out.print(" " + toC(c.className) + "(");
} else {
out.print(" " + toCType(m.returnType) + " " + m.name + "(");
}
int i = 0;
for (FieldObj p : m.parameters.values()) { for (FieldObj p : m.parameters.values()) {
if (i > 0) { if (i > 0) {
out.print(", "); out.print(", ");
} }
out.print(p.type + " " + p.name); out.print(toCType(p.type));
out.print(" " + p.name);
i++; i++;
} }
out.println(");"); out.println(");");
} }
} }
out.println(); out.println("};");
} }
out.println(); ArrayList<String> constantNames = New.arrayList(stringConstantToStringMap.keySet());
out.println("/* method pointers */"); Collections.sort(constantNames);
for (MethodObj m : allMethodsMap.values()) { for (String c : constantNames) {
out.print("extern " + m.returnType + " (*virtual_" + m.name + "[])("); String s = stringConstantToStringMap.get(c);
int i = 0; out.println("ptr<java_lang_String> " + c + " = STRING(L\"" + s + "\");");
if (!m.isConstructor) {
out.print("void*");
i++;
}
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(p.type);
i++;
}
out.println(");");
out.println();
} }
} }
/** /**
* Write the C source code. * Write the C++ source code.
* *
* @param out the output writer * @param out the output writer
*/ */
void writeSource(PrintWriter out) { void writeSource(PrintWriter out) {
out.println("/* method pointers */");
for (MethodObj m : allMethodsMap.values()) {
if (m.isIgnore) {
continue;
}
out.print(m.returnType + " (*virtual_" + m.name + "[])(");
int i = 0;
if (!m.isConstructor) {
out.print("void*");
i++;
}
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(p.type);
i++;
}
out.println(") = {");
for (ClassObj c : allClasses) {
if (c != null && c.methods.containsKey(m.name)) {
out.println(toC(c.className) + "_" + m.name + ", ");
} else {
out.print("0, ");
}
}
out.println("};");
}
out.println();
for (ClassObj c : classes.values()) { for (ClassObj c : classes.values()) {
out.println("/* " + c.className + ".c */"); out.println("/* " + c.className + ".cpp */");
for (Statement s : c.nativeCode) { for (Statement s : c.nativeCode) {
out.println(s); out.println(s);
} }
...@@ -1518,14 +1499,8 @@ public class JavaParser { ...@@ -1518,14 +1499,8 @@ public class JavaParser {
if (f.isFinal) { if (f.isFinal) {
buff.append("const "); buff.append("const ");
} }
buff.append(toC(f.type.classObj.toString())); buff.append(toCType(f.type));
if (!f.type.classObj.isPrimitive) {
buff.append("*");
}
buff.append(" ").append(toC(c.className + "." + f.name)); buff.append(" ").append(toC(c.className + "." + f.name));
for (int i = 0; i < f.type.arrayLevel; i++) {
buff.append("[]");
}
if (f.value != null) { if (f.value != null) {
buff.append(" = " + f.value); buff.append(" = " + f.value);
} }
...@@ -1537,29 +1512,28 @@ public class JavaParser { ...@@ -1537,29 +1512,28 @@ public class JavaParser {
if (m.isIgnore) { if (m.isIgnore) {
continue; continue;
} }
out.print(m.returnType + " " + toC(c.className) + "_" + m.name + "("); if (m.isStatic) {
int i = 0; out.print(toCType(m.returnType) + " " + toC(c.className + "_" + m.name) + "(");
if (!m.isStatic && !m.isConstructor) { } else if (m.isConstructor) {
out.print(toC(c.className) + "* this"); out.print(toC(c.className) + "::" + toC(c.className) + "(");
i++; } else {
out.print(toCType(m.returnType) + " " + toC(c.className) + "::" + m.name + "(");
} }
int i = 0;
for (FieldObj p : m.parameters.values()) { for (FieldObj p : m.parameters.values()) {
if (i > 0) { if (i > 0) {
out.print(", "); out.print(", ");
} }
out.print(p.type + " " + p.name); out.print(toCType(p.type) + " " + p.name);
i++; i++;
} }
out.println(") {"); out.println(") {");
if (m.isConstructor) { if (m.isConstructor) {
out.println(indent(toC(c.className) + "* this = NEW_OBJ(" + c.id + ", " + toC(c.className) +");")); // TODO
} }
if (m.block != null) { if (m.block != null) {
out.print(m.block.toString()); out.print(m.block.toString());
} }
if (m.isConstructor) {
out.println(indent("return this;"));
}
out.println("}"); out.println("}");
out.println(); out.println();
} }
...@@ -1595,7 +1569,7 @@ public class JavaParser { ...@@ -1595,7 +1569,7 @@ public class JavaParser {
} }
/** /**
* Get the C representation of this identifier. * Get the C++ representation of this identifier.
* *
* @param identifier the identifier * @param identifier the identifier
* @return the C representation * @return the C representation
...@@ -1604,6 +1578,22 @@ public class JavaParser { ...@@ -1604,6 +1578,22 @@ public class JavaParser {
return identifier.replace('.', '_'); return identifier.replace('.', '_');
} }
static String toCType(Type type) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < type.arrayLevel; i++) {
buff.append("ptr<array< ");
}
if (type.classObj.isPrimitive) {
buff.append(toC(type.classObj.toString()));
} else {
buff.append("ptr<").append(toC(type.classObj.toString())).append('>');
}
for (int i = 0; i < type.arrayLevel; i++) {
buff.append(" > >");
}
return buff.toString();
}
ClassObj getClassObj() { ClassObj getClassObj() {
return classObj; return classObj;
} }
...@@ -1615,7 +1605,7 @@ public class JavaParser { ...@@ -1615,7 +1605,7 @@ public class JavaParser {
* @return the class * @return the class
*/ */
ClassObj getClassObj(String className) { ClassObj getClassObj(String className) {
ClassObj c = builtInTypes.get(className); ClassObj c = BUILT_IN_CLASSES.get(className);
if (c == null) { if (c == null) {
c = classes.get(className); c = classes.get(className);
} }
......
...@@ -38,7 +38,13 @@ class ReturnStatement extends StatementBase { ...@@ -38,7 +38,13 @@ class ReturnStatement extends StatementBase {
Expr expr; Expr expr;
public String toString() { public String toString() {
return "return " + (expr == null ? "" : expr) + ";"; if (expr == null) {
return "return;";
}
if (expr.getType().isSimplePrimitive()) {
return "return " + expr + ";";
}
return "return " + JavaParser.toCType(expr.getType()) + "(" + expr + ");";
} }
} }
...@@ -187,9 +193,9 @@ class ForStatement extends StatementBase { ...@@ -187,9 +193,9 @@ class ForStatement extends StatementBase {
Type it = iterable.getType(); Type it = iterable.getType();
if (it != null && it.arrayLevel > 0) { if (it != null && it.arrayLevel > 0) {
String idx = "i_" + iterableVariable; String idx = "i_" + iterableVariable;
buff.append("int " + idx + " = 0; " + idx + " < LENGTH(" + iterable + "); " + idx + "++"); buff.append("int " + idx + " = 0; " + idx + " < " + iterable + "->length(); " + idx + "++");
buff.append(") {\n"); buff.append(") {\n");
buff.append(JavaParser.indent(iterableType + " " + iterableVariable + " = " + iterable + "["+ idx +"];\n")); buff.append(JavaParser.indent(iterableType + " " + iterableVariable + " = " + iterable + "->at("+ idx +");\n"));
buff.append(block.toString()).append("}"); buff.append(block.toString()).append("}");
} else { } else {
// TODO iterate over a collection // TODO iterate over a collection
...@@ -247,7 +253,7 @@ class VarDecStatement extends StatementBase { ...@@ -247,7 +253,7 @@ class VarDecStatement extends StatementBase {
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append(type).append(' '); buff.append(JavaParser.toCType(type)).append(' ');
StringBuilder assign = new StringBuilder(); StringBuilder assign = new StringBuilder();
for (int i = 0; i < variables.size(); i++) { for (int i = 0; i < variables.size(); i++) {
if (i > 0) { if (i > 0) {
...@@ -260,7 +266,7 @@ class VarDecStatement extends StatementBase { ...@@ -260,7 +266,7 @@ class VarDecStatement extends StatementBase {
if (value.getType().isSimplePrimitive()) { if (value.getType().isSimplePrimitive()) {
buff.append(" = ").append(value); buff.append(" = ").append(value);
} else { } else {
assign.append(varName).append(" = reference(").append(value).append(");\n"); assign.append(varName).append(" = ").append(value).append(";\n");
} }
} }
} }
......
...@@ -26,7 +26,7 @@ public class Test extends TestBase { ...@@ -26,7 +26,7 @@ public class Test extends TestBase {
} }
public void test() throws IOException { public void test() throws IOException {
// gcc --std=c99 -o test test.cpp // g++ -o test test.cpp
// chmod +x test // chmod +x test
// ./test // ./test
...@@ -76,7 +76,7 @@ public class Test extends TestBase { ...@@ -76,7 +76,7 @@ public class Test extends TestBase {
parser.writeHeader(w); parser.writeHeader(w);
parser.writeSource(w); parser.writeSource(w);
w.flush(); w.flush();
w = new PrintWriter(new FileWriter("bin/test.c")); w = new PrintWriter(new FileWriter("bin/test.cpp"));
parser.writeHeader(w); parser.writeHeader(w);
parser.writeSource(w); parser.writeSource(w);
w.close(); w.close();
......
...@@ -14,7 +14,7 @@ public class TestApp { ...@@ -14,7 +14,7 @@ public class TestApp {
/* c: /* c:
int main(int argc, char** argv) { int main(int argc, char** argv) {
org_h2_java_TestApp_main(null); org_h2_java_TestApp_main(ptr<array<ptr<java_lang_String> > >());
} }
*/ */
...@@ -26,9 +26,7 @@ int main(int argc, char** argv) { ...@@ -26,9 +26,7 @@ int main(int argc, char** argv) {
*/ */
public static void main(String... args) { public static void main(String... args) {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
String s = "Hello " + i; System.out.println("Hello " + i);
System.out.println(s);
s = null;
} }
} }
......
...@@ -17,8 +17,8 @@ public class PrintStream { ...@@ -17,8 +17,8 @@ public class PrintStream {
* @param s the string * @param s the string
*/ */
public void println(String s) { public void println(String s) {
// c: int x = LENGTH(s->chars); // c: int x = s->chars->length();
// c: printf("%.*S\n", x, s->chars); // c: printf("%.*S\n", x, s->chars->getData());
} }
} }
...@@ -22,9 +22,9 @@ public class Integer { ...@@ -22,9 +22,9 @@ public class Integer {
* @return the String * @return the String
*/ */
public static String toString(int x) { public static String toString(int x) {
// c: char ch[20]; // c: wchar_t ch[20];
// c: snprintf(ch, 20, "%d", x); // c: swprintf(ch, 20, L"%d", x);
// c: return string(ch); // c: return STRING(ch);
// c: return; // c: return;
if (x == MIN_VALUE) { if (x == MIN_VALUE) {
return String.wrap("-2147483648"); return String.wrap("-2147483648");
......
...@@ -11,14 +11,16 @@ package org.h2.java.lang; ...@@ -11,14 +11,16 @@ package org.h2.java.lang;
*/ */
public class Object { public class Object {
private static final int[] K = { 1 };
public int hashCode() { public int hashCode() {
return K[0]; return 0;
} }
public boolean equals(Object other) { public boolean equals(Object other) {
return this == other; return other == this;
}
public java.lang.String toString() {
return "?";
} }
} }
...@@ -30,126 +30,116 @@ import org.h2.java.Ignore; ...@@ -30,126 +30,116 @@ import org.h2.java.Ignore;
#define false 0 #define false 0
#define null 0 #define null 0
#define LENGTH(a) (*(((jint*)(a))-3)) #define STRING(s) ptr<java_lang_String>(new java_lang_String(ptr< array<jchar> >(new array<jchar>(s, (jint) wcslen(s)))));
#define CLASS_ID(a) (*(((jint*)(a))-2))
#define NEW_ARRAY(size, length) new_array(0, size, length) class RefBase {
#define NEW_OBJ_ARRAY(length) new_array(0, sizeof(void*), length) protected:
#define NEW_OBJ(typeId, typeName) new_object(typeId, sizeof(struct typeName)) jint refCount;
#define SET(variable, p) set_object(variable, p) public:
#define STRING(s) ((java_lang_String*) string(s)) RefBase() {
refCount = 1;
void* new_array(jint object, jint size, jint length); }
void* new_object(jint type, jint size); void reference() {
void* reference(void* o); refCount++;
void release(void* o); }
void* set(void* o, void* n); void release() {
void* string(char* s); if (--refCount == 0) {
delete this;
*/
/*
* Object layout:
* m-2: data type
* m-1: number of references
* m: object data
*
* Array layout:
* m-3: length (number of elements)
* m-2: 0 (array marker)
* m-1: number of references
* m: first element
*/
/**
* A java.lang.String implementation.
*/
public class String {
/* c:
void* new_array_with_count(jint object, jint size, jint length, jint refCount) {
jint count = sizeof(jint) * 3 + size * length;
jint* m = (jint*) calloc(1, count);
*m = length;
*(m + 2) = refCount;
return m + 3;
}
void* new_array(jint object, jint size, jint length) {
return new_array_with_count(object, size, length, 1);
}
void* new_static_array(jint object, jint size, jint length) {
return new_array_with_count(object, size, length, 0);
}
void* new_object_with_count(jint type, jint size, jint refCount) {
jint count = sizeof(jint) * 2 + size;
jint* m = (jint*) calloc(1, count);
*m = type;
*(m + 1) = refCount;
return m + 2;
}
void* new_object(jint type, jint size) {
return new_object_with_count(type, size, 1);
}
void* new_static_object(jint type, jint size) {
return new_object_with_count(type, size, 0);
}
void* reference(void* o) {
if (o != 0) {
jint* m = (jint*) o;
if (*(m - 1) > 0) {
(*(m - 1))++;
} }
} }
return o; };
} template <class T> class ptr {
T* pointer;
void release(void* o) { public:
if (o == 0) { explicit ptr(T* p=0) : pointer(p) {
return; if (p != 0) {
((RefBase*)p)->reference();
}
} }
jint* m = (jint*) o; ptr(const ptr<T>& p) : pointer(p.pointer) {
if (*(m - 1) <= 1) { if (p.pointer != 0) {
if (*(m - 1) == 0) { ((RefBase*)p.pointer)->reference();
return;
} }
if (*(m - 2) == 0) { }
free(m - 3); ~ptr() {
} else { if (pointer != 0) {
free(m - 2); ((RefBase*)pointer)->release();
} }
} else {
(*(m - 1))--;
} }
} ptr<T>& operator= (const ptr<T>& p) {
if (this != &p && pointer != p.pointer) {
void* set(void* o, void* n) { if (pointer != 0) {
release(o); ((RefBase*)pointer)->release();
return reference(n); }
} pointer = p.pointer;
if (pointer != 0) {
void* string(char* s) { ((RefBase*)pointer)->reference();
jint len = strlen(s); }
jchar* chars = NEW_ARRAY(sizeof(jchar), len); }
for (int i = 0; i < len; i++) { return *this;
chars[i] = s[i];
} }
return java_lang_String_init_obj(chars); T& operator*() {
} return *pointer;
}
T* operator->() {
return pointer;
}
jboolean operator==(const ptr<T>& p) {
return pointer == p->pointer;
}
jboolean operator==(const RefBase* t) {
return pointer == t;
}
};
template <class T> class array : RefBase {
jint len;
T* data;
public:
array(const T* d, jint len) {
this->len = len;
data = new T[len];
memcpy(data, d, sizeof(T) * len);
}
array(jint len) {
this->len = len;
data = new T[len];
}
~array() {
delete[] data;
}
T* getData() {
return data;
}
jint length() {
return len;
}
T& operator[](jint index) {
if (index < 0 || index >= len) {
throw "index set";
}
return data[index];
}
T& at(jint index) {
if (index < 0 || index >= len) {
throw "index set";
}
return data[index];
}
};
*/ */
/**
* A java.lang.String implementation.
*/
public class String {
/** /**
* The character array. * The character array.
*/ */
char[] chars; char[] chars;
private int hashCode; private int hash;
public String(char[] chars) { public String(char[] chars) {
this.chars = new char[chars.length]; this.chars = new char[chars.length];
...@@ -162,7 +152,7 @@ void* string(char* s) { ...@@ -162,7 +152,7 @@ void* string(char* s) {
} }
public int hashCode() { public int hashCode() {
if (hashCode == 0) { if (hash == 0) {
if (chars.length == 0) { if (chars.length == 0) {
return 0; return 0;
} }
...@@ -170,10 +160,10 @@ void* string(char* s) { ...@@ -170,10 +160,10 @@ void* string(char* s) {
for (char c : chars) { for (char c : chars) {
h = h * 31 + c; h = h * 31 + c;
} }
hashCode = h; hash = h;
return h; return h;
} }
return hashCode; return hash;
} }
/** /**
...@@ -185,6 +175,10 @@ void* string(char* s) { ...@@ -185,6 +175,10 @@ void* string(char* s) {
return chars.length; return chars.length;
} }
public String toStringMethod() {
return this;
}
@Ignore @Ignore
public java.lang.String asString() { public java.lang.String asString() {
return new java.lang.String(chars); return new java.lang.String(chars);
......
...@@ -30,8 +30,8 @@ public class System { ...@@ -30,8 +30,8 @@ public class System {
*/ */
public static void arraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) { public static void arraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) {
/* c: /* c:
memmove(((jchar*)dest) + destPos, memmove(((jchar*)dest->getData()) + destPos,
((jchar*)src) + srcPos, sizeof(jchar) * length); ((jchar*)src->getData()) + srcPos, sizeof(jchar) * length);
*/ */
// c: return; // c: return;
java.lang.System.arraycopy(src, srcPos, dest, destPos, length); java.lang.System.arraycopy(src, srcPos, dest, destPos, length);
...@@ -49,8 +49,8 @@ public class System { ...@@ -49,8 +49,8 @@ public class System {
*/ */
public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) { public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
/* c: /* c:
memmove(((jbyte*)dest) + destPos, memmove(((jbyte*)dest->getData()) + destPos,
((jbyte*)src) + srcPos, sizeof(jbyte) * length); ((jbyte*)src->getData()) + srcPos, sizeof(jbyte) * length);
*/ */
// c: return; // c: return;
java.lang.System.arraycopy(src, srcPos, dest, destPos, length); java.lang.System.arraycopy(src, srcPos, dest, destPos, length);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论