jasm, jdis updates to support nested static arguments of bootstrap methods.

This commit is contained in:
lkuskov 2018-05-18 12:45:49 -07:00
parent 1039e6c886
commit 05ed6dee93
3 changed files with 88 additions and 32 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -43,6 +43,11 @@ public class ParserCP extends ParseBase {
* Visitor object
*/
private ParserCPVisitor pConstVstr;
/**
* counter of left braces
*/
private int lbrace = 0;
/**
* main constructor
@ -70,6 +75,7 @@ public class ParserCP extends ParseBase {
private IOException IOProb;
private Scanner.SyntaxError SyProb;
public ParserCPVisitor() {
IOProb = null;
SyProb = null;
@ -494,14 +500,31 @@ d2l: {
ConstantPool.ConstCell MHCell = parser.pool.FindCell(parseConstValue(ConstType.CONSTANT_METHODHANDLE));
scanner.expect(Token.COLON);
ConstantPool.ConstCell NapeCell = parser.pool.FindCell(parseConstValue(ConstType.CONSTANT_NAMEANDTYPE));
if(scanner.token == Token.LBRACE) {
ParserCP.this.lbrace++;
scanner.scan();
}
ArrayList<ConstantPool.ConstCell> bsm_args = new ArrayList<>(256);
while (scanner.token != Token.SEMICOLON) {
while(true) {
if( ParserCP.this.lbrace > 0 ) {
if(scanner.token == Token.RBRACE ) {
ParserCP.this.lbrace--;
scanner.scan();
break;
} else if(scanner.token == Token.SEMICOLON) {
scanner.expect(Token.RBRACE);
}
} else if(scanner.token == Token.SEMICOLON) {
break;
}
if (scanner.token == Token.COMMA) {
scanner.scan();
}
bsm_args.add(parseConstRef(null));
}
if( ParserCP.this.lbrace == 0 ) {
scanner.check(Token.SEMICOLON);
}
BootstrapMethodData bsmData = new BootstrapMethodData(MHCell, bsm_args);
parser.cd.addBootstrapMethod(bsmData);
obj = new ConstantPool.ConstValue_CondyPair(bsmData, NapeCell);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -169,9 +169,17 @@ prefix:
}
/**
* Expect a token, return its value, scan the next token or throw an exception.
* Expects a token, scans the next token or throws an exception.
*/
protected final void expect(Token t) throws SyntaxError, IOException {
check(t);
scan();
}
/**
* Checks a token, throws an exception if not the same
*/
protected final void check(Token t) throws SyntaxError, IOException {
if (token != t) {
if ((t != Token.IDENT) || !checkTokenIdent()) {
env.traceln("expect:" + t + " instead of " + token);
@ -192,7 +200,6 @@ prefix:
}
}
}
scan();
}
private void putCh(int ch) {

View File

@ -28,7 +28,10 @@ import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
*
@ -41,7 +44,30 @@ public class ConstantPool {
private static final Hashtable<Byte, TAG> taghash = new Hashtable<>();
private static final Hashtable<Byte, SUBTAG> subtaghash = new Hashtable<>();
private Throwable foundProblem;
class Indent {
private int length, offset, step;
void inc() { length+=step; }
void dec() { length-=step; }
Indent(int offset, int step) {
this.length = 0;
this.step = step;
this.offset = offset;
}
int size() { return offset + length; }
/**
* Creates indent string based on current indent size.
*/
private String get() {
return Collections.nCopies(size(), "\t").stream().collect(Collectors.joining());
}
}
private final Indent indent = new Indent(2, 1);
/**
* TAG
@ -374,7 +400,7 @@ public class ConstantPool {
CP_Float(TAG tagval, float fltvl) {
super(tagval);
this.value = new Float(fltvl);
this.value = fltvl;
}
@Override
@ -412,7 +438,7 @@ public class ConstantPool {
CP_Double(TAG tagval, double fltvl) {
super(tagval);
this.value = new Double(fltvl);
this.value = fltvl;
}
@Override
@ -504,7 +530,6 @@ public class ConstantPool {
class CPX2 extends Constant {
int value1, value2;
CPX2(TAG tagval, int cpx1, int cpx2) {
super(tagval);
this.value1 = cpx1;
@ -539,36 +564,37 @@ public class ConstantPool {
} catch (IndexOutOfBoundsException ioob) {
return "<Invalid bootstrap method index:" + bsm_attr_idx + ">";
}
int bsm_ref = bsmData.bsm_index;
StringBuilder bsm_args_str = new StringBuilder();
String offsetParm,offsetBrace;
int bsm_ref = bsmData.bsm_index;
int bsm_args_len = bsmData.bsm_args_indexes.size();
for (int i = 0; i < bsm_args_len; i++) {
int bsm_arg_idx = bsmData.bsm_args_indexes.get(i);
Constant cnt = pool.get(bsm_arg_idx);
if(cnt.equals(this)) {
String s = "circular reference to " + cnt.tag.tagname() + " #" + bsm_arg_idx;
bsm_args_str.append(" <")
.append(s)
.append(">");
cnt.setIssue(new IOException(s));
} else {
bsm_args_str.append(" ")
.append(ConstantStrValue(bsm_arg_idx));
if (i + 1 < bsm_args_len) {
bsm_args_str.append(",");
if (bsm_args_len > 0) {
bsm_args_str.append(" {\n");
offsetBrace = indent.get();
indent.inc();
offsetParm = indent.get();
for (int i = 0; i < bsm_args_len; i++) {
int bsm_arg_idx = bsmData.bsm_args_indexes.get(i);
Constant cnt = pool.get(bsm_arg_idx);
if (cnt.equals(this)) {
String s = "circular reference to " + cnt.tag.tagname() + " #" + bsm_arg_idx;
bsm_args_str.append(offsetParm).append(" <").append(s).append(">");
cnt.setIssue(new IOException(s));
} else {
bsm_args_str.append(offsetParm).append(ConstantStrValue(bsm_arg_idx));
if (i + 1 < bsm_args_len) {
bsm_args_str.append(",");
}
}
bsm_args_str.append('\n');
}
indent.dec();
bsm_args_str.append(offsetBrace).append("}");
}
str = StringValue(bsm_ref) +
":" +
StringValue(nape_idx) +
bsm_args_str.toString();
str = StringValue(bsm_ref) + ":" + StringValue(nape_idx) + bsm_args_str.toString();
default:
break;
}
return str;
}