Skip to content

Commit

Permalink
feat(objectionary#329): convert DynamicInvocation back to opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
volodya-lombrozo committed Jul 10, 2024
1 parent fc1ffa1 commit e4c20f5
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 11 deletions.
28 changes: 21 additions & 7 deletions src/main/java/org/eolang/opeo/ast/DynamicInvocation.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
package org.eolang.opeo.ast;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eolang.jeo.representation.directives.DirectivesData;
import org.eolang.jeo.representation.xmir.HexString;
import org.eolang.jeo.representation.xmir.XmlNode;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.xembly.Directive;
import org.xembly.Directives;
Expand All @@ -44,7 +46,7 @@ public final class DynamicInvocation implements AstNode, Typed {
private final Handle factory;

private final Attributes attributes;
private final List<Xmir> arguments;
private final List<Object> arguments;

public DynamicInvocation(final XmlNode root) {
this(root, root.children().collect(Collectors.toList()));
Expand All @@ -61,9 +63,9 @@ public DynamicInvocation(final XmlNode root, final List<XmlNode> chldren) {

private static List<Object> xarguments(final List<XmlNode> children) {
List<Object> res = new ArrayList<>(3);
res.add(new HexString(children.get(2).text()).decode());
res.add(Type.getType(new HexString(children.get(2).text()).decode()));
res.add(new Handle(children.get(3)).toAsm());
res.add(new HexString(children.get(4).text()).decode());
res.add(Type.getType(new HexString(children.get(4).text()).decode()));
return res;
}

Expand Down Expand Up @@ -92,7 +94,7 @@ public DynamicInvocation(
.descriptor(descriptor)
.type("dynamic");
this.name = name;
this.arguments = this.toXmlArg(arguments);
this.arguments = arguments;
}

private List<Xmir> toXmlArg(final List<Object> arguments) {
Expand All @@ -113,15 +115,27 @@ public Iterable<Directive> toXmir() {
.attr("base", String.format(".%s", this.name))
.append(this.attributes.toXmir())
.append(this.factory.toXmir());
this.arguments.stream()
this.toXmlArg(this.arguments).stream()
.map(Xmir::toXmir)
.forEach(directives::append);
return directives.up();
}

@Override
public List<AstNode> opcodes() {
return Collections.emptyList();
return Arrays.asList(
new Opcode(
Opcodes.INVOKEDYNAMIC,
Stream.concat(
Stream.of(
this.name,
this.attributes.descriptor(),
this.factory.toAsm()
),
this.arguments.stream()
).toArray()
)
);
}

@Override
Expand Down
12 changes: 9 additions & 3 deletions src/main/java/org/eolang/opeo/ast/Handle.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import java.util.List;
import java.util.stream.Collectors;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eolang.jeo.representation.directives.DirectivesData;
import org.eolang.jeo.representation.xmir.HexString;
import org.eolang.jeo.representation.xmir.XmlNode;
import org.xembly.Directive;
import org.xembly.Directives;

@ToString
@EqualsAndHashCode
public final class Handle implements Xmir {

private final int tag;
Expand All @@ -32,15 +36,17 @@ public Handle(final XmlNode root, final List<XmlNode> children) {
}

private static String xowner(final XmlNode root) {
return root.attribute("base")
final String s1 = root.attribute("base")
.map(s -> s.substring(0, s.lastIndexOf('.')))
.orElseThrow(() -> new IllegalArgumentException("Owner is required"));
return s1.replace('.', '/');
}

private static String xname(final XmlNode root) {
return root.attribute("base")
.map(s -> s.substring(s.lastIndexOf('.')))
final String s1 = root.attribute("base")
.map(s -> s.substring(s.lastIndexOf('.') + 1))
.orElseThrow(() -> new IllegalArgumentException("Name is required"));
return s1;
}

private static int xtag(final List<XmlNode> children) {
Expand Down
4 changes: 3 additions & 1 deletion src/test/java/org/eolang/opeo/ast/DynamicInvocationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
*/
final class DynamicInvocationTest {

/**
* XMIR representation of the dynamic invocation.
*/
private final static String XMIR = String.join(
"",
"<o base='.run'>",
Expand Down Expand Up @@ -112,7 +115,6 @@ void createsDynamicInvocationFromXmir() {
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
false
),
"()Ljava/lang/Runnable;",
Type.getType("()V"),
new org.objectweb.asm.Handle(
6,
Expand Down

0 comments on commit e4c20f5

Please sign in to comment.