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

Java to C++ converter

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