Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebase dev onto refactor. #140

Merged
merged 18 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public ArrayTypeID(TypeID elementType, int dimension) {
type = ArrayTypeSymbol.get(dimension);
}

public TypeID removeOneDimension() {
return dimension > 1 ? new ArrayTypeID(elementType, dimension - 1) : elementType;
}

@Override
public Expression getDefaultValue() {
return new ArrayExpression(CodePosition.UNKNOWN, Expression.NONE, this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ public void register(String name, byte[] bytecode) {
}

private JavaMethod createLambdaInterface(JavaSynthesizedFunction function) {
String signature = "<" + new JavaTypeGenericVisitor(this).getGenericSignature(function.typeParameters) + ">Ljava/lang/Object;";
ClassWriter ifaceWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ifaceWriter.visitAnnotation("java/lang/FunctionalInterface", true).visitEnd();
ifaceWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, function.cls.internalName, null, "java/lang/Object", null);
ifaceWriter.visitAnnotation("Ljava/lang/FunctionalInterface;", true).visitEnd();
ifaceWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, function.cls.internalName, signature, "java/lang/Object", null);

ifaceWriter
.visitMethod(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.openzen.zenscript.javabytecode.compiler;

import org.objectweb.asm.Type;
import org.openzen.zenscript.codemodel.type.ArrayTypeID;
import org.openzen.zenscript.codemodel.type.GenericTypeID;
import org.openzen.zenscript.codemodel.type.TypeID;
import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
import org.openzen.zenscript.javashared.JavaClass;
import org.openzen.zenscript.javashared.JavaNativeMethod;

public class ArrayHelperType {

private final TypeID elementType;
private final JavaBytecodeContext context;

public ArrayHelperType(TypeID elementType, JavaBytecodeContext context) {
this.elementType = elementType;
this.context = context;
}


public ArrayHelperType getWithOneDimensionLess() {
ArrayTypeID arrayTypeID = ((ArrayTypeID) elementType);
return new ArrayHelperType(arrayTypeID.removeOneDimension(), context);
}

public void newArray(JavaWriter javaWriter) {
if(elementType instanceof GenericTypeID) {

elementType.accept(javaWriter, new JavaTypeExpressionVisitor(context));
javaWriter.swap();
final JavaClass arrayClass = JavaClass.fromInternalName("java/lang/reflect/Array", JavaClass.Kind.CLASS);
javaWriter.invokeStatic(JavaNativeMethod.getStatic(arrayClass, "newInstance", "(Ljava/lang/Class;I)Ljava/lang/Object;", 0));
javaWriter.checkCast("[Ljava/lang/Object;");
} else {
javaWriter.newArray(context.getType(elementType));
}
}

public Type getASMElementType() {
return context.getType(elementType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ static int[] getArraySizeLocationsFromConstructor(int dimension, Expression[] ar
* @param currentArrayType The current type of the array, reduced during the recursions of the functions
* @param defaultLocation The location of the default value. Needs to be of or assignable to elementType!
*/
void visitMultiDimArrayWithDefaultValue(JavaWriter javaWriter, int[] sizeLocations, int dim, Type currentArrayType, ArrayTypeID arrayType, int defaultLocation) {
visitMultiDimArray(javaWriter, sizeLocations, new int[dim], dim, currentArrayType, arrayType, (elementType, counterLocations) -> javaWriter.load(elementType, defaultLocation));
void visitMultiDimArrayWithDefaultValue(JavaWriter javaWriter, int[] sizeLocations, int dim, ArrayHelperType currentArrayType, ArrayTypeID arrayType, int defaultLocation) {
visitMultiDimArray(javaWriter, sizeLocations, new int[dim], dim, currentArrayType, arrayType, (elementType, counterLocations) -> javaWriter.load(elementType.getASMElementType(), defaultLocation));
}

/**
Expand All @@ -71,22 +71,22 @@ void visitMultiDimArrayWithDefaultValue(JavaWriter javaWriter, int[] sizeLocatio
* @param currentArrayType The current type of the array, reduced during the recursions of the functions
* @param innermostFunction The function that will decide what to add to the array, needs to increase the stack size by one and may not touch the other stacks!
*/
void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counterLocations, int dim, Type currentArrayType, ArrayTypeID arrayType, InnermostFunction innermostFunction) {
void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counterLocations, int dim, ArrayHelperType currentArrayType, ArrayTypeID arrayType, InnermostFunction innermostFunction) {
final Label begin = new Label();
final Label end = new Label();
javaWriter.label(begin);

final int currentArraySizeLocation = sizeLocations[sizeLocations.length - dim];

final Type elementType = Type.getType(currentArrayType.getDescriptor().substring(1));
final ArrayHelperType elementType = currentArrayType.getWithOneDimensionLess();
if (arrayType.elementType.isGeneric()) {
arrayType.elementType.accept(javaWriter, new JavaTypeExpressionVisitor(context));
javaWriter.loadInt(currentArraySizeLocation);
javaWriter.invokeStatic(ARRAY_NEWINSTANCE);
javaWriter.checkCast(context.getInternalName(arrayType));
} else {
javaWriter.loadInt(currentArraySizeLocation);
javaWriter.newArray(elementType);
elementType.newArray(javaWriter);
}
//javaWriter.dup();

Expand All @@ -113,7 +113,7 @@ void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counte
} else {
visitMultiDimArray(javaWriter, sizeLocations, counterLocations, dim - 1, elementType, arrayType, innermostFunction);
}
javaWriter.arrayStore(elementType);
javaWriter.arrayStore(elementType.getASMElementType());

//Return to the start
javaWriter.iinc(forLoopCounter);
Expand All @@ -133,7 +133,7 @@ void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counte

@FunctionalInterface
public interface InnermostFunction {
void apply(Type elementType, int[] counterLocations);
void apply(ArrayHelperType elementType, int[] counterLocations);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
import org.openzen.zenscript.codemodel.identifiers.MethodID;
import org.openzen.zenscript.codemodel.identifiers.ModuleSymbol;
import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
import org.openzen.zenscript.codemodel.expression.*;
import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
import org.openzen.zenscript.codemodel.statement.VarStatement;
Expand Down Expand Up @@ -257,6 +258,9 @@ public Void visitCall(CallExpression expression) {
JavaCompiledModule javaCompiledModule = context.getJavaModule(module);
JavaMethod method = javaCompiledModule.getMethodInfo(expression.method.method);
method.compileVirtual(methodCompiler, expression.type, expression.target, expression.arguments);
if (expression.method.getHeader().getReturnType().isGeneric())
javaWriter.checkCast(context.getType(expression.type));

return null;
}

Expand All @@ -280,7 +284,7 @@ public Void visitCallSuper(CallSuperExpression expression) {
return null;
}

private void handleReturnValue(TypeID original, TypeID actual) {
void handleReturnValue(TypeID original, TypeID actual) {
if (original.isGeneric()) {
handleGenericReturnValue(actual);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import org.openzen.zenscript.codemodel.statement.ForeachStatement;
import org.openzen.zenscript.codemodel.type.ArrayTypeID;
import org.openzen.zenscript.codemodel.type.BasicTypeID;
import org.openzen.zenscript.codemodel.type.OptionalTypeID;
import org.openzen.zenscript.codemodel.type.RangeTypeID;
import org.openzen.zenscript.codemodel.type.TypeID;
import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
import org.openzen.zenscript.javashared.JavaClass;
import org.openzen.zenscript.javashared.JavaNativeMethod;
Expand Down Expand Up @@ -176,8 +178,10 @@ public void visitAssocKeyValueIterator() {
}

private void downCast(int typeNumber, Type t) {
if (CompilerUtils.isPrimitive(statement.loopVariables[typeNumber].type)) {
statement.loopVariables[typeNumber].type.accept(statement.loopVariables[typeNumber].type, unboxingTypeVisitor);
TypeID type = statement.loopVariables[typeNumber].type;
if (CompilerUtils.isPrimitive(type)) {
javaWriter.checkCast(statementVisitor.context.getInternalName(new OptionalTypeID(type)));
type.accept(type, unboxingTypeVisitor);
} else {
javaWriter.checkCast(t);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.openzen.zenscript.codemodel.expression.*;
import org.openzen.zenscript.codemodel.statement.ReturnStatement;
import org.openzen.zenscript.codemodel.type.*;
import org.openzen.zenscript.codemodel.type.builtin.BuiltinMethodSymbol;
import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
import org.openzen.zenscript.javashared.*;

import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;

public class JavaMethodBytecodeCompiler implements JavaMethodCompiler<Void> {
Expand Down Expand Up @@ -266,7 +264,6 @@ public Void builtinConstructor(BuiltinMethodSymbol method, TypeID type, CallArgu
case ARRAY_CONSTRUCTOR_INITIAL_VALUE: {
ArrayTypeID arrayType = (ArrayTypeID) type;

final Type ASMType = context.getType(type);
final Type ASMElementType = context.getType(arrayType.elementType);

final Label begin = new Label();
Expand All @@ -286,7 +283,7 @@ public Void builtinConstructor(BuiltinMethodSymbol method, TypeID type, CallArgu


final int[] arraySizes = ArrayInitializerHelper.getArraySizeLocationsFromConstructor(arrayType.dimension, arguments, expressionVisitor);
new ArrayInitializerHelper(context).visitMultiDimArrayWithDefaultValue(javaWriter, arraySizes, arrayType.dimension, ASMType, arrayType, defaultValueLocation);
new ArrayInitializerHelper(context).visitMultiDimArrayWithDefaultValue(javaWriter, arraySizes, arrayType.dimension, new ArrayHelperType(arrayType, context), arrayType, defaultValueLocation);

javaWriter.label(end);
return null;
Expand All @@ -299,10 +296,9 @@ public Void builtinConstructor(BuiltinMethodSymbol method, TypeID type, CallArgu
final Label end = new Label();
javaWriter.label(begin);

final Type ASMElementType = context.getType(type);
final int dimension = ((ArrayTypeID) type).dimension;
final int[] arraySizes = ArrayInitializerHelper.getArraySizeLocationsFromConstructor(dimension, arguments, expressionVisitor);
new ArrayInitializerHelper(context).visitMultiDimArray(javaWriter, arraySizes, new int[dimension], dimension, ASMElementType, arrayType, (elementType, counterLocations) -> {
new ArrayInitializerHelper(context).visitMultiDimArray(javaWriter, arraySizes, new int[dimension], dimension, new ArrayHelperType(arrayType, context), arrayType, (elementType, counterLocations) -> {
arguments[dimension].accept(expressionVisitor);
for (int counterLocation : counterLocations) {
javaWriter.loadInt(counterLocation);
Expand Down Expand Up @@ -558,6 +554,13 @@ public Void builtinStaticMethod(BuiltinMethodSymbol method, TypeID returnType, C
}

switch (method) {
case FUNCTION_CALL: // ToDo: Was added from dev->refactor branch during rebase, is this still needed?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically what the ToDO said.
I'm not even sure if this is the proper place, it was part of one of these humongous switch-statements inside the JavaExpressionVisitors: b11c1ff

Maybe this can be removed, even?

FunctionTypeID expressionType = (FunctionTypeID) arguments[0].type;
JavaNativeMethod functionalInterface = context.getFunctionalInterface(expressionType);
javaWriter.invokeInterface(functionalInterface);
expressionVisitor.handleReturnValue(context.getFunction(expressionType).getHeader().getReturnType(), method.getHeader().instanceForCall(args).getReturnType());
break;

/* Casts */
case BOOL_TO_STRING:
if (arguments[0].type.isOptional()) {
Expand Down Expand Up @@ -1295,7 +1298,7 @@ public Void specialStaticMethod(JavaSpecialMethod method, CallArguments args) {
arguments[0].accept(expressionVisitor);
javaWriter.invokeVirtual(STRINGBUILDER_LENGTH);
break;
case LIST_TO_ARRAY: {
case COLLECTION_TO_ARRAY: {
Expression value = arguments[0];
value.accept(expressionVisitor);

Expand Down Expand Up @@ -1325,7 +1328,7 @@ public Void specialStaticMethod(JavaSpecialMethod method, CallArguments args) {
javaWriter.dup();

// Todo: Primitive method overloads if primitive Array!
final JavaNativeMethod sort = JavaNativeMethod.getNativeExpansion(JavaClass.ARRAYS, "sort", "([Ljava/lang/Object;)[Ljava/lang/Object;");
final JavaNativeMethod sort = JavaNativeMethod.getNativeExpansion(JavaClass.ARRAYS, "sort", "([Ljava/lang/Object;)V");
stanhebben marked this conversation as resolved.
Show resolved Hide resolved
javaWriter.invokeStatic(sort);
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.openzen.zenscript.javabytecode.BytecodeLoopLabels;
import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
import org.openzen.zenscript.javashared.JavaBuiltinModule;
import org.openzen.zenscript.javashared.JavaCompiledModule;

import java.util.Arrays;
Expand Down Expand Up @@ -221,6 +222,9 @@ public Boolean visitSwitch(SwitchStatement statement) {
statement.value.accept(expressionVisitor);
if (statement.value.type == BasicTypeID.STRING)
javaWriter.invokeVirtual(JavaMethodBytecodeCompiler.OBJECT_HASHCODE);
if (statement.value.type.isEnum()) {
stanhebben marked this conversation as resolved.
Show resolved Hide resolved
javaWriter.invokeVirtual(JavaBuiltinModule.ENUM_ORDINAL);
}
boolean out = false;

final boolean hasNoDefault = hasNoDefault(statement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ public byte[] visitExpansion(ExpansionDefinition definition) {
JavaCompilingClass class_ = module.getClass(definition);

JavaClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
writer.visitSource(definition.position.getFilename(), null);
final JavaClass expansionClassInfo = context.getJavaModule(definition.module).getExpansionClassInfo(definition);
final String internalName = expansionClassInfo.internalName;

Expand All @@ -256,14 +257,14 @@ public byte[] visitAlias(AliasDefinition definition) {
public byte[] visitVariant(VariantDefinition variant) {
JavaCompilingClass class_ = module.getClass(variant);
final JavaClassWriter writer = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);

writer.visitSource(variant.position.getFilename(), null);
final String variantName = variant.name;


final String ss = "<" + javaTypeGenericVisitor.getGenericSignature(variant.typeParameters) + ">Ljava/lang/Object;";
JavaClassWriter.registerSuperClass(variantName, "java/lang/Object");

writer.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, class_.getInternalName(), ss, "java/lang/Object", null);
writer.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, class_.getInternalName(), ss, "java/lang/Object", null);
writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "getDenominator", "()I", null, null).visitEnd();

final JavaMemberVisitor visitor = new JavaMemberVisitor(context, writer, class_, variant);
Expand All @@ -276,8 +277,7 @@ public byte[] visitVariant(VariantDefinition variant) {
final String optionClassName = variantName + "$" + option.name;
JavaClassWriter.registerSuperClass(optionClassName, variantName);

writer.visitInnerClass(optionTag.variantOptionClass.internalName, optionTag.variantClass.internalName, option.name, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL);

writer.visitInnerClass(optionTag.variantOptionClass.internalName, optionTag.variantClass.internalName, option.name, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL);
//Generic option signature
final String signature;
{
Expand All @@ -296,7 +296,7 @@ public byte[] visitVariant(VariantDefinition variant) {
for (final TypeID type : option.types)
if (type instanceof GenericTypeID) {
final GenericTypeID genericTypeID = (GenericTypeID) type;
if (genericParameter == genericTypeID.parameter) {
if (genericParameter.equals(genericTypeID.parameter)) {
builder.append("T").append(genericParameter.name).append(";");
t = false;
}
Expand All @@ -308,7 +308,7 @@ public byte[] visitVariant(VariantDefinition variant) {
signature = builder.append(">;").toString();
}

optionWriter.visit(Opcodes.V1_8, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, optionTag.variantOptionClass.internalName, signature, optionTag.variantClass.internalName, null);
optionWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, optionTag.variantOptionClass.internalName, signature, optionTag.variantClass.internalName, null);
final StringBuilder optionInitDescBuilder = new StringBuilder("(");
final StringBuilder optionInitSignatureBuilder = new StringBuilder("(");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.openzen.zencode.java;

import org.openzen.zencode.java.module.JavaNativeModule;
import org.openzen.zencode.java.module.JavaRuntimeClass;
import org.openzen.zencode.shared.CompileException;
import org.openzen.zenscript.codemodel.globals.IGlobal;

public interface JavaNativeModuleBuilder {
JavaNativeModuleBuilder addGlobals(Class<?> cls);

JavaNativeModuleBuilder addGlobal(String name, IGlobal global);

JavaNativeModuleBuilder addClass(Class<?> cls);

JavaNativeModule complete() throws CompileException;
}
Loading
Loading