Skip to content

Commit 9219731

Browse files
committed
Added bridge methods to functional members
1 parent d84c9a8 commit 9219731

File tree

12 files changed

+139
-99
lines changed

12 files changed

+139
-99
lines changed

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private void createRangeClass(JavaSynthesizedRange range) {
106106
new FunctionParameter(range.baseType, "to")
107107
);
108108
JavaNativeMethod method = JavaNativeMethod.getConstructor(range.cls, getMethodDescriptor(ctorHeader), Opcodes.ACC_PUBLIC);
109-
JavaCompilingMethod compilingMethod = new JavaCompilingMethod(range.compiling.compiled, method, getMethodSignature(ctorHeader));
109+
JavaCompilingMethod compilingMethod = new JavaCompilingMethod(method, getMethodSignature(ctorHeader));
110110

111111
JavaWriter constructorWriter = new JavaWriter(logger, CodePosition.GENERATED, rangeWriter, compilingMethod, null);
112112
constructorWriter.loadObject(0);

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeRunUnit.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
import org.objectweb.asm.Type;
1111
import org.openzen.zencode.shared.CodePosition;
1212
import org.openzen.zencode.shared.logging.IZSLogger;
13-
import org.openzen.zenscript.codemodel.FunctionHeader;
1413
import org.openzen.zenscript.codemodel.FunctionParameter;
15-
import org.openzen.zenscript.codemodel.type.BasicTypeID;
1614
import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
1715
import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
1816
import org.openzen.zenscript.javashared.JavaClass;
@@ -157,7 +155,6 @@ private void writeScripts() {
157155
return;
158156

159157
JavaClassWriter scriptsClassWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
160-
JavaClass scriptsClass = JavaClass.fromInternalName("Scripts", JavaClass.Kind.CLASS);
161158
scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
162159

163160
StringBuilder headerBuilder = new StringBuilder();
@@ -168,7 +165,7 @@ private void writeScripts() {
168165
headerBuilder.append(")V");
169166

170167
JavaNativeMethod runMethod = JavaNativeMethod.getStatic(new JavaClass("script", "Scripts", JavaClass.Kind.CLASS), "run", headerBuilder.toString(), Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
171-
JavaCompilingMethod runMethodCompiling = new JavaCompilingMethod(scriptsClass, runMethod, headerBuilder.toString());
168+
JavaCompilingMethod runMethodCompiling = new JavaCompilingMethod(runMethod, headerBuilder.toString());
172169
final JavaWriter runWriter = new JavaWriter(logger, CodePosition.GENERATED, scriptsClassWriter, runMethodCompiling, null);
173170
runWriter.start();
174171
for (JavaScriptMethod method : scripts) {

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public JavaBytecodeModule compile(String packageName, SemanticModule module, Jav
119119
final JavaClassWriter visitor = scriptFile.classWriter;
120120
JavaClass scriptsClass = new JavaClass(context.getPackageName(script.pkg), className, JavaClass.Kind.CLASS);
121121
JavaNativeMethod method = JavaNativeMethod.getStatic(scriptsClass, methodName, scriptDescriptor, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
122-
JavaCompilingMethod compilingMethod = new JavaCompilingMethod(scriptsClass, method, scriptDescriptor);
122+
JavaCompilingMethod compilingMethod = new JavaCompilingMethod(method, scriptDescriptor);
123123
scriptFile.scriptMethods.add(new JavaScriptMethod(method, module.parameters, javaScriptParameters));
124124

125125
final JavaWriter writer = new JavaWriter(logger, CodePosition.UNKNOWN, visitor, compilingMethod, null);

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java

Lines changed: 26 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import org.objectweb.asm.Type;
77
import org.openzen.zencode.shared.CodePosition;
88
import org.openzen.zenscript.codemodel.CompareType;
9-
import org.openzen.zenscript.codemodel.FunctionParameter;
109
import org.openzen.zenscript.codemodel.OperatorType;
1110
import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
1211
import org.openzen.zenscript.codemodel.expression.captured.CapturedExpression;
@@ -24,6 +23,7 @@
2423
import org.openzen.zenscript.javabytecode.JavaMangler;
2524
import org.openzen.zenscript.javabytecode.compiler.JavaModificationExpressionVisitor.PushOption;
2625
import org.openzen.zenscript.javabytecode.compiler.capturing.*;
26+
import org.openzen.zenscript.javabytecode.compiler.definitions.JavaMemberVisitor;
2727
import org.openzen.zenscript.javashared.*;
2828
import org.openzen.zenscript.javashared.compiling.JavaCompilingMethod;
2929
import org.openzen.zenscript.javashared.expressions.JavaFunctionInterfaceCastExpression;
@@ -473,79 +473,41 @@ public Void visitFunction(FunctionExpression expression) {
473473
return null;
474474
}*/
475475

476-
final String signature;
477476
final String[] interfaces;
478-
final String descriptor;
479-
480-
{//Fill the info above
481-
if (expression.type instanceof JavaFunctionalInterfaceTypeID) {
482-
//Let's implement the functional Interface instead
483-
JavaFunctionalInterfaceTypeID type = (JavaFunctionalInterfaceTypeID) expression.type;
484-
final Method functionalInterfaceMethod = type.functionalInterfaceMethod;
485-
486-
//Should be the same, should it not?
487-
signature = context.getMethodSignature(expression.header, true);
488-
descriptor = context.getMethodDescriptor(expression.header);
489-
interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
490-
} else {
491-
//Normal way, no casting to functional interface
492-
signature = context.getMethodSignature(expression.header, true);
493-
descriptor = context.getMethodDescriptor(expression.header);
494-
interfaces = new String[]{context.getInternalName(new FunctionTypeID(expression.header))};
495-
}
477+
478+
if (expression.type instanceof JavaFunctionalInterfaceTypeID) {
479+
//Let's implement the functional Interface instead
480+
JavaFunctionalInterfaceTypeID type = (JavaFunctionalInterfaceTypeID) expression.type;
481+
final Method functionalInterfaceMethod = type.functionalInterfaceMethod;
482+
483+
//Should be the same, should it not?
484+
interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
485+
} else {
486+
//Normal way, no casting to functional interface
487+
interfaces = new String[]{context.getInternalName(new FunctionTypeID(expression.header))};
496488
}
497489

498490
final JavaNativeMethod methodInfo;
499491
final String className = this.javaMangler.mangleGeneratedLambdaName(interfaces[0]);
500492
{
501493
final JavaNativeMethod m = context.getFunctionalInterface(expression.type);
502-
methodInfo = new JavaNativeMethod(m.cls, m.kind, m.name, m.compile, m.descriptor, m.modifiers & ~JavaModifiers.ABSTRACT, m.genericResult, m.typeParameterArguments);
494+
methodInfo = m.withModifiers(m.modifiers & ~JavaModifiers.ABSTRACT);
503495
}
504496
final ClassWriter lambdaCW = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
505497
JavaClass lambdaClass = JavaClass.fromInternalName(className, JavaClass.Kind.CLASS);
506498
lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", interfaces);
507499
final JavaWriter functionWriter;
508500

509-
//Bridge method!!!
510-
if (!Objects.equals(methodInfo.descriptor, descriptor)) {
511-
final JavaNativeMethod bridgeMethodInfo = new JavaNativeMethod(methodInfo.cls, methodInfo.kind, methodInfo.name, methodInfo.compile, methodInfo.descriptor, methodInfo.modifiers | JavaModifiers.BRIDGE | JavaModifiers.SYNTHETIC, methodInfo.genericResult, methodInfo.typeParameterArguments);
512-
JavaCompilingMethod compilingBridgeMethod = new JavaCompilingMethod(javaWriter.method.class_, bridgeMethodInfo, signature);
513-
final JavaWriter bridgeWriter = new JavaWriter(context.logger, expression.position, lambdaCW, compilingBridgeMethod, null);
514-
bridgeWriter.start();
515-
516-
//This.name(parameters, casted)
517-
bridgeWriter.loadObject(0);
518-
519-
for (int i = 0; i < expression.header.parameters.length; i++) {
520-
final FunctionParameter functionParameter = expression.header.parameters[i];
521-
final Type type = context.getType(functionParameter.type);
522-
bridgeWriter.load(type, i + 1);
523-
if (!CompilerUtils.isPrimitive(functionParameter.type)) {
524-
bridgeWriter.checkCast(type);
525-
}
526-
}
527-
528-
bridgeWriter.invokeVirtual(new JavaNativeMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), JavaNativeMethod.Kind.INSTANCE, methodInfo.name, methodInfo.compile, descriptor, methodInfo.modifiers, methodInfo.genericResult));
529-
final TypeID returnType = expression.header.getReturnType();
530-
if (returnType != BasicTypeID.VOID) {
531-
final Type returnTypeASM = context.getType(returnType);
532-
if (!CompilerUtils.isPrimitive(returnType)) {
533-
bridgeWriter.checkCast(returnTypeASM);
534-
}
535-
bridgeWriter.returnType(returnTypeASM);
536-
}
537-
538-
bridgeWriter.ret();
539-
bridgeWriter.end();
540-
541-
JavaNativeMethod actualMethod = methodInfo.createBridge(context.getMethodDescriptor(expression.header));
542-
JavaCompilingMethod actualCompiling = new JavaCompilingMethod(lambdaClass, actualMethod, signature);
543-
//No @Override
544-
functionWriter = new JavaWriter(context.logger, expression.position, lambdaCW, actualCompiling, null);
545-
} else {
546-
JavaCompilingMethod actualCompiling = new JavaCompilingMethod(lambdaClass, methodInfo, signature);
547-
functionWriter = new JavaWriter(context.logger, expression.position, lambdaCW, actualCompiling, null);
548-
}
501+
JavaCompilingMethod actualCompiling = JavaMemberVisitor.compileBridgeableMethod(
502+
context,
503+
expression.position,
504+
lambdaCW,
505+
lambdaClass,
506+
methodInfo,
507+
expression.header,
508+
null
509+
);
510+
functionWriter = new JavaWriter(context.logger, expression.position, lambdaCW, actualCompiling, null);
549511
functionWriter.clazzVisitor.visitSource(expression.position.getFilename(), null);
550512
javaWriter.newObject(className);
551513
javaWriter.dup();
@@ -554,7 +516,7 @@ public Void visitFunction(FunctionExpression expression) {
554516
// To check: write a test where the ctor desc and signature would differ and make sure the program compiles/executes
555517
final String constructorDescriptorAndSignature = calcFunctionDescriptor(expression.closure);
556518
JavaNativeMethod constructor = JavaNativeMethod.getConstructor(lambdaClass, constructorDescriptorAndSignature, Opcodes.ACC_PUBLIC);
557-
JavaCompilingMethod constructorCompiling = new JavaCompilingMethod(lambdaClass, constructor, constructorDescriptorAndSignature);
519+
JavaCompilingMethod constructorCompiling = new JavaCompilingMethod(constructor, constructorDescriptorAndSignature);
558520
final JavaWriter constructorWriter = new JavaWriter(context.logger, expression.position, lambdaCW, constructorCompiling, null);
559521
constructorWriter.start();
560522
constructorWriter.loadObject(0);
@@ -1193,7 +1155,7 @@ private FunctionCastWrapperClass generateFunctionCastWrapperClass(CodePosition p
11931155
//Constructor
11941156
{
11951157
JavaNativeMethod constructor = JavaNativeMethod.getConstructor(classInfo, constructorDescriptor, Opcodes.ACC_PUBLIC);
1196-
JavaCompilingMethod compiling = new JavaCompilingMethod(classInfo, constructor, constructorSignature);
1158+
JavaCompilingMethod compiling = new JavaCompilingMethod(constructor, constructorSignature);
11971159
final JavaWriter constructorWriter = new JavaWriter(context.logger, position, lambdaCW, compiling, null);
11981160
constructorWriter.start();
11991161
constructorWriter.loadObject(0);
@@ -1209,7 +1171,7 @@ private FunctionCastWrapperClass generateFunctionCastWrapperClass(CodePosition p
12091171

12101172
//The actual method
12111173
{
1212-
JavaCompilingMethod compiling = new JavaCompilingMethod(classInfo, implementationMethod, methodSignature);
1174+
JavaCompilingMethod compiling = new JavaCompilingMethod(implementationMethod, methodSignature);
12131175
final JavaWriter functionWriter = new JavaWriter(context.logger, position, lambdaCW, compiling, null);
12141176
functionWriter.start();
12151177

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public byte[] visitEnum(EnumDefinition definition) {
148148
// TODO - expose an additional set of members including these generated ones
149149
if (definition.members.stream().noneMatch(it -> it instanceof ConstructorMember)) {
150150
final ConstructorMember autoConstructor = new ConstructorMember(CodePosition.BUILTIN, definition, Modifiers.NONE, new FunctionHeader(BasicTypeID.VOID));
151-
final JavaCompilingMethod compiling = new JavaCompilingMethod(class_.compiled, JavaNativeMethod.getConstructor(class_.compiled, "(Ljava/lang/String;I)V", 0), "(Ljava/lang/String;I)V");
151+
final JavaCompilingMethod compiling = new JavaCompilingMethod(JavaNativeMethod.getConstructor(class_.compiled, "(Ljava/lang/String;I)V", 0), "(Ljava/lang/String;I)V");
152152

153153
// This is used in the accept call below
154154
class_.addMethod(autoConstructor, compiling);
@@ -164,7 +164,7 @@ public byte[] visitEnum(EnumDefinition definition) {
164164
// Enums aren't generic, so the descriptor and signature will always be the same
165165
String valuesMethodDescriptorAndAlsoSignature = "()[L" + class_.getInternalName() + ";";
166166
JavaNativeMethod valuesMethod = JavaNativeMethod.getStatic(class_.compiled, "values", valuesMethodDescriptorAndAlsoSignature, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
167-
JavaCompilingMethod valuesMethodCompiling = new JavaCompilingMethod(class_.compiled, valuesMethod, valuesMethodDescriptorAndAlsoSignature);
167+
JavaCompilingMethod valuesMethodCompiling = new JavaCompilingMethod(valuesMethod, valuesMethodDescriptorAndAlsoSignature);
168168
JavaWriter valuesWriter = new JavaWriter(context.logger, CodePosition.BUILTIN, writer, valuesMethodCompiling, definition);
169169
valuesWriter.start();
170170
valuesWriter.getStaticField(class_.getInternalName(), "$VALUES", "[L" + class_.getInternalName() + ";");
@@ -182,7 +182,7 @@ public byte[] visitEnum(EnumDefinition definition) {
182182
// Enums aren't generic, so the descriptor and signature will always be the same
183183
String valueOfMethodDescriptorAndAlsoSignature = "(Ljava/lang/String;)L" + class_.getInternalName() + ";";
184184
JavaNativeMethod valueOfMethod = JavaNativeMethod.getStatic(class_.compiled, "valueOf", valueOfMethodDescriptorAndAlsoSignature, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
185-
final JavaCompilingMethod javaCompilingMethod = new JavaCompilingMethod(class_.compiled, valueOfMethod, valueOfMethodDescriptorAndAlsoSignature);
185+
final JavaCompilingMethod javaCompilingMethod = new JavaCompilingMethod(valueOfMethod, valueOfMethodDescriptorAndAlsoSignature);
186186
JavaWriter valueOfWriter = new JavaWriter(context.logger, CodePosition.BUILTIN, writer, javaCompilingMethod, definition);
187187
valueOfWriter.start();
188188
valueOfWriter.constant(class_.compiled);
@@ -326,7 +326,7 @@ public byte[] visitVariant(VariantDefinition variant) {
326326
optionInitSignatureBuilder.append(")V");
327327

328328
JavaNativeMethod constructorMethod = JavaNativeMethod.getConstructor(optionTag.variantOptionClass, optionInitDescBuilder.toString(), JavaModifiers.PUBLIC);
329-
final JavaCompilingMethod constructorMethodCompiling = new JavaCompilingMethod(class_.compiled, constructorMethod, signature);
329+
final JavaCompilingMethod constructorMethodCompiling = new JavaCompilingMethod(constructorMethod, signature);
330330
final JavaWriter initWriter = new JavaWriter(context.logger, option.position, optionWriter, constructorMethodCompiling, variant);
331331
initWriter.start();
332332
initWriter.loadObject(0);
@@ -345,7 +345,7 @@ public byte[] visitVariant(VariantDefinition variant) {
345345

346346
//Denominator for switch-cases
347347
JavaNativeMethod denominator = JavaNativeMethod.getVirtual(optionTag.variantOptionClass, "getDenominator", "()I", JavaModifiers.PUBLIC);
348-
final JavaCompilingMethod denominatorMethodCompiling = new JavaCompilingMethod(class_.compiled, denominator, signature);
348+
final JavaCompilingMethod denominatorMethodCompiling = new JavaCompilingMethod(denominator, signature);
349349
final JavaWriter getDenominator = new JavaWriter(context.logger, option.position, optionWriter, denominatorMethodCompiling, variant);
350350
getDenominator.start();
351351
getDenominator.constant(option.ordinal);
@@ -363,7 +363,7 @@ public byte[] visitVariant(VariantDefinition variant) {
363363
}
364364

365365
final JavaNativeMethod superInitMethod = JavaNativeMethod.getConstructor(class_.compiled, "()V", Opcodes.ACC_PUBLIC);
366-
final JavaCompilingMethod superInitMethodCompiling = new JavaCompilingMethod(class_.compiled, superInitMethod, "()V");
366+
final JavaCompilingMethod superInitMethodCompiling = new JavaCompilingMethod(superInitMethod, "()V");
367367
final JavaWriter superInitWriter = new JavaWriter(context.logger, variant.position, writer, superInitMethodCompiling, variant);
368368
superInitWriter.start();
369369
superInitWriter.loadObject(0);

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaExpansionMemberVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public JavaExpansionMemberVisitor(JavaBytecodeContext context, JavaCompilingClas
4444
javaModule = context.getJavaModule(definition.module);
4545

4646
JavaNativeMethod clinit = new JavaNativeMethod(context.getJavaClass(definition), JavaNativeMethod.Kind.STATICINIT, "<clinit>", true, "()V", Opcodes.ACC_STATIC, false);
47-
JavaCompilingMethod clinitCompiling = new JavaCompilingMethod(class_.compiled, clinit, "()V");
47+
JavaCompilingMethod clinitCompiling = new JavaCompilingMethod(clinit, "()V");
4848
final JavaWriter javaWriter = new JavaWriter(context.logger, definition.position, writer, clinitCompiling, definition);
4949
this.clinitStatementVisitor = new JavaStatementVisitor(context, javaModule, javaWriter, mangler);
5050
this.clinitStatementVisitor.start();

0 commit comments

Comments
 (0)