Skip to content

Commit

Permalink
🦄 refactor: Add JavaByteCodeMethodVariableAccess
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed Oct 27, 2024
1 parent 798d4af commit 0efeee3
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 102 deletions.
6 changes: 5 additions & 1 deletion scripts/ts/test.add.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { type int } from "./type.aliases";
import { type int, type long } from "./type.aliases";

class Test {
public add_II_I(a: int, b: int): int {
return a + b;
}
// public add_IL_L(a: int, b: long): long {
// return a + b;
// }
}

console.log(new Test().add_II_I(1, 2));
// console.log(new Test().add_IL_L(1, 2));
1 change: 1 addition & 0 deletions scripts/ts/type.aliases.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export type int = number;
export type long = number;
Original file line number Diff line number Diff line change
Expand Up @@ -16,51 +16,42 @@

package com.caoccao.javet.buddy.ts2java.ast;

import com.caoccao.javet.buddy.ts2java.compiler.JavaByteCodeOpLoad;
import com.caoccao.javet.buddy.ts2java.compiler.JavaByteCodeMethodVariableAccess;
import com.caoccao.javet.buddy.ts2java.compiler.JavaFunctionContext;
import com.caoccao.javet.buddy.ts2java.exceptions.Ts2JavaAstException;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstBinExpr;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstIdent;
import com.caoccao.javet.swc4j.ast.interfaces.ISwc4jAstExpr;
import com.caoccao.javet.utils.SimpleFreeMarkerFormat;
import com.caoccao.javet.utils.SimpleMap;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.implementation.bytecode.Addition;

public final class Ts2JavaAstBinExpr implements ITs2JavaAstStackManipulation<Swc4jAstBinExpr> {
@Override
public void manipulate(JavaFunctionContext functionContext, Swc4jAstBinExpr ast) {
StackManipulation stackManipulation = new StackManipulation.Simple((
MethodVisitor methodVisitor,
Implementation.Context implementationContext) -> {
int stackSize = 0;
for (ISwc4jAstExpr expr : new ISwc4jAstExpr[]{ast.getLeft(), ast.getRight()}) {
switch (expr.getType()) {
case Ident:
String name = expr.as(Swc4jAstIdent.class).getSym();
stackSize += JavaByteCodeOpLoad.visit(functionContext, name, methodVisitor);
break;
default:
throw new Ts2JavaAstException(
expr,
SimpleFreeMarkerFormat.format("BinExpr expr type ${exprType} is not supported",
SimpleMap.of("exprType", expr.getType().name())));
}
}
switch (ast.getOp()) {
case Add:
methodVisitor.visitInsn(Opcodes.IADD);
ISwc4jAstExpr[] expressions = new ISwc4jAstExpr[]{ast.getLeft(), ast.getRight()};
for (ISwc4jAstExpr expression : expressions) {
switch (expression.getType()) {
case Ident:
String name = expression.as(Swc4jAstIdent.class).getSym();
JavaByteCodeMethodVariableAccess.load(functionContext, name);
break;
default:
throw new Ts2JavaAstException(
ast,
SimpleFreeMarkerFormat.format("BinExpr op ${op} is not supported",
SimpleMap.of("op", ast.getOp().name())));
expression,
SimpleFreeMarkerFormat.format("BinExpr expr type ${exprType} is not supported",
SimpleMap.of("exprType", expression.getType().name())));
}
return new StackManipulation.Size(stackSize, 0);
});
functionContext.getStackManipulations().add(stackManipulation);
}
switch (ast.getOp()) {
case Add:
functionContext.getStackManipulations().add(Addition.INTEGER);
break;
default:
throw new Ts2JavaAstException(
ast,
SimpleFreeMarkerFormat.format("BinExpr op ${op} is not supported",
SimpleMap.of("op", ast.getOp().name())));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
import java.util.stream.IntStream;

public final class Ts2JavaAstClassFunction implements ITs2JavaAstTranspile<Swc4jAstFunction> {
private final boolean _static;
private final Swc4jAstAccessibility accessibility;
private final String name;

public Ts2JavaAstClassFunction(String name, Swc4jAstAccessibility accessibility) {
public Ts2JavaAstClassFunction(String name, boolean _static, Swc4jAstAccessibility accessibility) {
this._static = _static;
this.name = Objects.requireNonNull(name);
this.accessibility = Objects.requireNonNull(accessibility);
}
Expand All @@ -49,6 +51,10 @@ public String getName() {
return name;
}

public boolean isStatic() {
return _static;
}

@Override
public DynamicType.Builder<?> transpile(
DynamicType.Builder<?> builder,
Expand All @@ -59,7 +65,7 @@ public DynamicType.Builder<?> transpile(
.orElse((Class) Object.class);
final List<JavaStackFrame> stackFrames = new ArrayList<>();
final List<JavaStackObject> stackObjects = IntStream.range(0, ast.getParams().size())
.mapToObj(i -> Ts2JavaAstParam.getStackObject(i, ast.getParams().get(i)))
.mapToObj(i -> Ts2JavaAstParam.getStackObject(i + (_static ? 0 : 1), ast.getParams().get(i)))
.collect(Collectors.toList());
final JavaStackFrame initialStackFrame = new JavaStackFrame(0, stackObjects);
stackFrames.add(initialStackFrame);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public DynamicType.Builder<?> transpile(
}
String name = ast.getKey().as(Swc4jAstIdentName.class).getSym();
Swc4jAstAccessibility accessibility = ast.getAccessibility().orElse(Swc4jAstAccessibility.Public);
builder = new Ts2JavaAstClassFunction(name, accessibility).transpile(builder, ast.getFunction());
builder = new Ts2JavaAstClassFunction(name, ast.isStatic(), accessibility).transpile(builder, ast.getFunction());
return builder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2024. caoccao.com Sam Cao
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.caoccao.javet.buddy.ts2java.compiler;

import com.caoccao.javet.buddy.ts2java.exceptions.Ts2JavaException;
import com.caoccao.javet.utils.SimpleFreeMarkerFormat;
import com.caoccao.javet.utils.SimpleMap;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess;

public final class JavaByteCodeMethodVariableAccess {
private JavaByteCodeMethodVariableAccess() {
}

private static JavaStackObject getStackObject(JavaFunctionContext functionContext, String name) {
final int size = functionContext.getStackFrames().size();
JavaStackObject stackObject;
int stackFrameIndex;
for (stackFrameIndex = size - 1; stackFrameIndex >= 0; stackFrameIndex--) {
JavaStackFrame stackFrame = functionContext.getStackFrames().get(stackFrameIndex);
stackObject = stackFrame.getObjectMap().get(name);
if (stackObject != null) {
return stackObject;
}
}
throw new Ts2JavaException(
SimpleFreeMarkerFormat.format("The variable ${name} is not defined",
SimpleMap.of("name", name)));
}

public static void load(JavaFunctionContext functionContext, String name) {
JavaStackObject stackObject = getStackObject(functionContext, name);
MethodVariableAccess methodVariableAccess =
MethodVariableAccess.of(TypeDescription.ForLoadedType.of(stackObject.getType()));
functionContext.getStackManipulations().add(methodVariableAccess.loadFrom(stackObject.getIndex()));
}

public static void store(JavaFunctionContext functionContext, String name) {
JavaStackObject stackObject = getStackObject(functionContext, name);
MethodVariableAccess methodVariableAccess =
MethodVariableAccess.of(TypeDescription.ForLoadedType.of(stackObject.getType()));
functionContext.getStackManipulations().add(methodVariableAccess.storeAt(stackObject.getIndex()));
}
}

This file was deleted.

13 changes: 13 additions & 0 deletions src/test/java/com/caoccao/javet/buddy/ts2java/TestAdd.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,17 @@ public void testAdd_II_I() throws Exception {
Object object = clazz.getConstructor().newInstance();
assertEquals(3, method.invoke(object, 1, 2));
}

// @Test
// public void testAdd_IL_L() throws Exception {
// assertEquals(3, add(1, 2));
// Method method = clazz.getMethod("add_IL_L", int.class, long.class);
// assertNotNull(method);
// assertEquals(long.class, method.getReturnType());
// assertEquals(2, method.getParameterCount());
// assertEquals(int.class, method.getParameters()[0].getType());
// assertEquals(long.class, method.getParameters()[1].getType());
// Object object = clazz.getConstructor().newInstance();
// assertEquals(3L, method.invoke(object, 1, 2L));
// }
}

0 comments on commit 0efeee3

Please sign in to comment.