提交 e2e4e117 编写于 作者: K ksrini

8037221: [asm] refresh internal ASM version

Reviewed-by: psandoz, coffeys
上级 a65d3682
...@@ -259,41 +259,68 @@ public class ByteVector { ...@@ -259,41 +259,68 @@ public class ByteVector {
if (c >= '\001' && c <= '\177') { if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c; data[len++] = (byte) c;
} else { } else {
int byteLength = i; length = len;
for (int j = i; j < charLength; ++j) { return encodeUTF8(s, i, 65535);
c = s.charAt(j); }
if (c >= '\001' && c <= '\177') { }
byteLength++; length = len;
} else if (c > '\u07FF') { return this;
byteLength += 3; }
} else {
byteLength += 2; /**
} * Puts an UTF8 string into this byte vector. The byte vector is
} * automatically enlarged if necessary. The string length is encoded in two
if (byteLength > 65535) { * bytes before the encoded characters, if there is space for that (i.e. if
throw new IllegalArgumentException(); * this.length - i - 2 >= 0).
} *
data[length] = (byte) (byteLength >>> 8); * @param s
data[length + 1] = (byte) byteLength; * the String to encode.
if (length + 2 + byteLength > data.length) { * @param i
length = len; * the index of the first character to encode. The previous
enlarge(2 + byteLength); * characters are supposed to have already been encoded, using
data = this.data; * only one byte per character.
} * @param maxByteLength
for (int j = i; j < charLength; ++j) { * the maximum byte length of the encoded string, including the
c = s.charAt(j); * already encoded characters.
if (c >= '\001' && c <= '\177') { * @return this byte vector.
data[len++] = (byte) c; */
} else if (c > '\u07FF') { ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
data[len++] = (byte) (0xE0 | c >> 12 & 0xF); int charLength = s.length();
data[len++] = (byte) (0x80 | c >> 6 & 0x3F); int byteLength = i;
data[len++] = (byte) (0x80 | c & 0x3F); char c;
} else { for (int j = i; j < charLength; ++j) {
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F); c = s.charAt(j);
data[len++] = (byte) (0x80 | c & 0x3F); if (c >= '\001' && c <= '\177') {
} byteLength++;
} } else if (c > '\u07FF') {
break; byteLength += 3;
} else {
byteLength += 2;
}
}
if (byteLength > maxByteLength) {
throw new IllegalArgumentException();
}
int start = length - i - 2;
if (start >= 0) {
data[start] = (byte) (byteLength >>> 8);
data[start + 1] = (byte) byteLength;
}
if (length + byteLength - i > data.length) {
enlarge(byteLength - i);
}
int len = length;
for (int j = i; j < charLength; ++j) {
c = s.charAt(j);
if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c;
} else if (c > '\u07FF') {
data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
data[len++] = (byte) (0x80 | c & 0x3F);
} else {
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
data[len++] = (byte) (0x80 | c & 0x3F);
} }
} }
length = len; length = len;
......
...@@ -716,7 +716,8 @@ public class ClassWriter extends ClassVisitor { ...@@ -716,7 +716,8 @@ public class ClassWriter extends ClassVisitor {
sourceFile = newUTF8(file); sourceFile = newUTF8(file);
} }
if (debug != null) { if (debug != null) {
sourceDebug = new ByteVector().putUTF8(debug); sourceDebug = new ByteVector().encodeUTF8(debug, 0,
Integer.MAX_VALUE);
} }
} }
...@@ -857,7 +858,7 @@ public class ClassWriter extends ClassVisitor { ...@@ -857,7 +858,7 @@ public class ClassWriter extends ClassVisitor {
} }
if (sourceDebug != null) { if (sourceDebug != null) {
++attributeCount; ++attributeCount;
size += sourceDebug.length + 4; size += sourceDebug.length + 6;
newUTF8("SourceDebugExtension"); newUTF8("SourceDebugExtension");
} }
if (enclosingMethodOwner != 0) { if (enclosingMethodOwner != 0) {
...@@ -946,9 +947,9 @@ public class ClassWriter extends ClassVisitor { ...@@ -946,9 +947,9 @@ public class ClassWriter extends ClassVisitor {
out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
} }
if (sourceDebug != null) { if (sourceDebug != null) {
int len = sourceDebug.length - 2; int len = sourceDebug.length;
out.putShort(newUTF8("SourceDebugExtension")).putInt(len); out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
out.putByteArray(sourceDebug.data, 2, len); out.putByteArray(sourceDebug.data, 0, len);
} }
if (enclosingMethodOwner != 0) { if (enclosingMethodOwner != 0) {
out.putShort(newUTF8("EnclosingMethod")).putInt(4); out.putShort(newUTF8("EnclosingMethod")).putInt(4);
......
...@@ -99,8 +99,8 @@ final class Frame { ...@@ -99,8 +99,8 @@ final class Frame {
* stack types. VALUE depends on KIND. For LOCAL types, it is an index in * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
* the input local variable types. For STACK types, it is a position * the input local variable types. For STACK types, it is a position
* relatively to the top of input frame stack. For BASE types, it is either * relatively to the top of input frame stack. For BASE types, it is either
* one of the constants defined in FrameVisitor, or for OBJECT and * one of the constants defined below, or for OBJECT and UNINITIALIZED
* UNINITIALIZED types, a tag and an index in the type table. * types, a tag and an index in the type table.
* *
* Output frames can contain types of any kind and with a positive or * Output frames can contain types of any kind and with a positive or
* negative dimension (and even unassigned types, represented by 0 - which * negative dimension (and even unassigned types, represented by 0 - which
...@@ -537,7 +537,7 @@ final class Frame { ...@@ -537,7 +537,7 @@ final class Frame {
/** /**
* The types that are initialized in the basic block. A constructor * The types that are initialized in the basic block. A constructor
* invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
* <i>every occurrence</i> of this type in the local variables and in the * <i>every occurence</i> of this type in the local variables and in the
* operand stack. This cannot be done during the first phase of the * operand stack. This cannot be done during the first phase of the
* algorithm since, during this phase, the local variables and the operand * algorithm since, during this phase, the local variables and the operand
* stack are not completely computed. It is therefore necessary to store the * stack are not completely computed. It is therefore necessary to store the
...@@ -1446,6 +1446,7 @@ final class Frame { ...@@ -1446,6 +1446,7 @@ final class Frame {
// if t is the NULL type, merge(u,t)=u, so there is no change // if t is the NULL type, merge(u,t)=u, so there is no change
return false; return false;
} else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) { } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) {
// if t and u have the same dimension and same base kind
if ((u & BASE_KIND) == OBJECT) { if ((u & BASE_KIND) == OBJECT) {
// if t is also a reference type, and if u and t have the // if t is also a reference type, and if u and t have the
// same dimension merge(u,t) = dim(t) | common parent of the // same dimension merge(u,t) = dim(t) | common parent of the
...@@ -1458,9 +1459,13 @@ final class Frame { ...@@ -1458,9 +1459,13 @@ final class Frame {
v = OBJECT | cw.addType("java/lang/Object"); v = OBJECT | cw.addType("java/lang/Object");
} }
} else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) {
// if t is any other reference or array type, // if t is any other reference or array type, the merged type
// merge(u,t)=java/lang/Object // is Object, or min(dim(u), dim(t)) | java/lang/Object is u
v = OBJECT | cw.addType("java/lang/Object"); // and t have different array dimensions
int tdim = t & DIM;
int udim = u & DIM;
v = (udim != tdim ? Math.min(tdim, udim) : 0) | OBJECT
| cw.addType("java/lang/Object");
} else { } else {
// if t is any other type, merge(u,t)=TOP // if t is any other type, merge(u,t)=TOP
v = TOP; v = TOP;
......
...@@ -240,6 +240,7 @@ public class AnalyzerAdapter extends MethodVisitor { ...@@ -240,6 +240,7 @@ public class AnalyzerAdapter extends MethodVisitor {
locals.add(types[i].getInternalName()); locals.add(types[i].getInternalName());
} }
} }
maxLocals = locals.size();
} }
@Override @Override
...@@ -519,12 +520,12 @@ public class AnalyzerAdapter extends MethodVisitor { ...@@ -519,12 +520,12 @@ public class AnalyzerAdapter extends MethodVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
private Object get(final int local) { private Object get(final int local) {
maxLocals = Math.max(maxLocals, local); maxLocals = Math.max(maxLocals, local + 1);
return local < locals.size() ? locals.get(local) : Opcodes.TOP; return local < locals.size() ? locals.get(local) : Opcodes.TOP;
} }
private void set(final int local, final Object type) { private void set(final int local, final Object type) {
maxLocals = Math.max(maxLocals, local); maxLocals = Math.max(maxLocals, local + 1);
while (local >= locals.size()) { while (local >= locals.size()) {
locals.add(Opcodes.TOP); locals.add(Opcodes.TOP);
} }
......
...@@ -556,6 +556,8 @@ public class InsnList { ...@@ -556,6 +556,8 @@ public class InsnList {
AbstractInsnNode prev; AbstractInsnNode prev;
AbstractInsnNode remove;
InsnListIterator(int index) { InsnListIterator(int index) {
if (index == size()) { if (index == size()) {
next = null; next = null;
...@@ -577,12 +579,22 @@ public class InsnList { ...@@ -577,12 +579,22 @@ public class InsnList {
AbstractInsnNode result = next; AbstractInsnNode result = next;
prev = result; prev = result;
next = result.next; next = result.next;
remove = result;
return result; return result;
} }
public void remove() { public void remove() {
InsnList.this.remove(prev); if (remove != null) {
prev = prev.prev; if (remove == next) {
next = next.next;
} else {
prev = prev.prev;
}
InsnList.this.remove(remove);
remove = null;
} else {
throw new IllegalStateException();
}
} }
public boolean hasPrevious() { public boolean hasPrevious() {
...@@ -593,6 +605,7 @@ public class InsnList { ...@@ -593,6 +605,7 @@ public class InsnList {
AbstractInsnNode result = prev; AbstractInsnNode result = prev;
next = result; next = result;
prev = result.prev; prev = result.prev;
remove = result;
return result; return result;
} }
...@@ -619,6 +632,7 @@ public class InsnList { ...@@ -619,6 +632,7 @@ public class InsnList {
public void add(Object o) { public void add(Object o) {
InsnList.this.insertBefore(next, (AbstractInsnNode) o); InsnList.this.insertBefore(next, (AbstractInsnNode) o);
prev = (AbstractInsnNode) o; prev = (AbstractInsnNode) o;
remove = null;
} }
public void set(Object o) { public void set(Object o) {
......
...@@ -404,7 +404,7 @@ public class Analyzer<V extends Value> implements Opcodes { ...@@ -404,7 +404,7 @@ public class Analyzer<V extends Value> implements Opcodes {
* instruction of the method. The size of the returned array is * instruction of the method. The size of the returned array is
* equal to the number of instructions (and labels) of the method. A * equal to the number of instructions (and labels) of the method. A
* given frame is <tt>null</tt> if the corresponding instruction * given frame is <tt>null</tt> if the corresponding instruction
* cannot be reached, or if an error occurred during the analysis of * cannot be reached, or if an error occured during the analysis of
* the method. * the method.
*/ */
public Frame<V>[] getFrames() { public Frame<V>[] getFrames() {
......
...@@ -111,7 +111,7 @@ public abstract class Interpreter<V extends Value> { ...@@ -111,7 +111,7 @@ public abstract class Interpreter<V extends Value> {
* the bytecode instruction to be interpreted. * the bytecode instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException * @throws AnalyzerException
* if an error occurred during the interpretation. * if an error occured during the interpretation.
*/ */
public abstract V newOperation(AbstractInsnNode insn) public abstract V newOperation(AbstractInsnNode insn)
throws AnalyzerException; throws AnalyzerException;
...@@ -130,7 +130,7 @@ public abstract class Interpreter<V extends Value> { ...@@ -130,7 +130,7 @@ public abstract class Interpreter<V extends Value> {
* @return the result of the interpretation of the given instruction. The * @return the result of the interpretation of the given instruction. The
* returned value must be <tt>equal</tt> to the given value. * returned value must be <tt>equal</tt> to the given value.
* @throws AnalyzerException * @throws AnalyzerException
* if an error occurred during the interpretation. * if an error occured during the interpretation.
*/ */
public abstract V copyOperation(AbstractInsnNode insn, V value) public abstract V copyOperation(AbstractInsnNode insn, V value)
throws AnalyzerException; throws AnalyzerException;
...@@ -151,7 +151,7 @@ public abstract class Interpreter<V extends Value> { ...@@ -151,7 +151,7 @@ public abstract class Interpreter<V extends Value> {
* the argument of the instruction to be interpreted. * the argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException * @throws AnalyzerException
* if an error occurred during the interpretation. * if an error occured during the interpretation.
*/ */
public abstract V unaryOperation(AbstractInsnNode insn, V value) public abstract V unaryOperation(AbstractInsnNode insn, V value)
throws AnalyzerException; throws AnalyzerException;
...@@ -175,7 +175,7 @@ public abstract class Interpreter<V extends Value> { ...@@ -175,7 +175,7 @@ public abstract class Interpreter<V extends Value> {
* the second argument of the instruction to be interpreted. * the second argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException * @throws AnalyzerException
* if an error occurred during the interpretation. * if an error occured during the interpretation.
*/ */
public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2) public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
throws AnalyzerException; throws AnalyzerException;
...@@ -196,7 +196,7 @@ public abstract class Interpreter<V extends Value> { ...@@ -196,7 +196,7 @@ public abstract class Interpreter<V extends Value> {
* the third argument of the instruction to be interpreted. * the third argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException * @throws AnalyzerException
* if an error occurred during the interpretation. * if an error occured during the interpretation.
*/ */
public abstract V ternaryOperation(AbstractInsnNode insn, V value1, public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
V value2, V value3) throws AnalyzerException; V value2, V value3) throws AnalyzerException;
...@@ -214,7 +214,7 @@ public abstract class Interpreter<V extends Value> { ...@@ -214,7 +214,7 @@ public abstract class Interpreter<V extends Value> {
* the arguments of the instruction to be interpreted. * the arguments of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException * @throws AnalyzerException
* if an error occurred during the interpretation. * if an error occured during the interpretation.
*/ */
public abstract V naryOperation(AbstractInsnNode insn, public abstract V naryOperation(AbstractInsnNode insn,
List<? extends V> values) throws AnalyzerException; List<? extends V> values) throws AnalyzerException;
...@@ -232,7 +232,7 @@ public abstract class Interpreter<V extends Value> { ...@@ -232,7 +232,7 @@ public abstract class Interpreter<V extends Value> {
* @param expected * @param expected
* the expected return type of the analyzed method. * the expected return type of the analyzed method.
* @throws AnalyzerException * @throws AnalyzerException
* if an error occurred during the interpretation. * if an error occured during the interpretation.
*/ */
public abstract void returnOperation(AbstractInsnNode insn, V value, public abstract void returnOperation(AbstractInsnNode insn, V value,
V expected) throws AnalyzerException; V expected) throws AnalyzerException;
......
...@@ -99,7 +99,7 @@ public class CheckAnnotationAdapter extends AnnotationVisitor { ...@@ -99,7 +99,7 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
} }
if (value instanceof Type) { if (value instanceof Type) {
int sort = ((Type) value).getSort(); int sort = ((Type) value).getSort();
if (sort != Type.OBJECT && sort != Type.ARRAY) { if (sort == Type.METHOD) {
throw new IllegalArgumentException("Invalid annotation value"); throw new IllegalArgumentException("Invalid annotation value");
} }
} }
......
...@@ -166,6 +166,11 @@ public class Textifier extends Printer { ...@@ -166,6 +166,11 @@ public class Textifier extends Printer {
*/ */
protected Map<Label, String> labelNames; protected Map<Label, String> labelNames;
/**
* Class access flags
*/
private int access;
private int valueNumber = 0; private int valueNumber = 0;
/** /**
...@@ -245,6 +250,7 @@ public class Textifier extends Printer { ...@@ -245,6 +250,7 @@ public class Textifier extends Printer {
public void visit(final int version, final int access, final String name, public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String signature, final String superName,
final String[] interfaces) { final String[] interfaces) {
this.access = access;
int major = version & 0xFFFF; int major = version & 0xFFFF;
int minor = version >>> 16; int minor = version >>> 16;
buf.setLength(0); buf.setLength(0);
...@@ -447,6 +453,11 @@ public class Textifier extends Printer { ...@@ -447,6 +453,11 @@ public class Textifier extends Printer {
if ((access & Opcodes.ACC_BRIDGE) != 0) { if ((access & Opcodes.ACC_BRIDGE) != 0) {
buf.append("bridge "); buf.append("bridge ");
} }
if ((this.access & Opcodes.ACC_INTERFACE) != 0
&& (access & Opcodes.ACC_ABSTRACT) == 0
&& (access & Opcodes.ACC_STATIC) == 0) {
buf.append("default ");
}
buf.append(name); buf.append(name);
appendDescriptor(METHOD_DESCRIPTOR, desc); appendDescriptor(METHOD_DESCRIPTOR, desc);
...@@ -856,7 +867,6 @@ public class Textifier extends Printer { ...@@ -856,7 +867,6 @@ public class Textifier extends Printer {
appendDescriptor(INTERNAL_NAME, owner); appendDescriptor(INTERNAL_NAME, owner);
buf.append('.').append(name).append(' '); buf.append('.').append(name).append(' ');
appendDescriptor(METHOD_DESCRIPTOR, desc); appendDescriptor(METHOD_DESCRIPTOR, desc);
buf.append(' ').append(itf ? "itf" : "");
buf.append('\n'); buf.append('\n');
text.add(buf.toString()); text.add(buf.toString());
} }
...@@ -869,26 +879,35 @@ public class Textifier extends Printer { ...@@ -869,26 +879,35 @@ public class Textifier extends Printer {
buf.append(name); buf.append(name);
appendDescriptor(METHOD_DESCRIPTOR, desc); appendDescriptor(METHOD_DESCRIPTOR, desc);
buf.append(" ["); buf.append(" [");
buf.append('\n');
buf.append(tab3);
appendHandle(bsm); appendHandle(bsm);
buf.append('\n');
buf.append(tab3).append("// arguments:"); buf.append(tab3).append("// arguments:");
if (bsmArgs.length == 0) { if (bsmArgs.length == 0) {
buf.append(" none"); buf.append(" none");
} else { } else {
buf.append('\n').append(tab3); buf.append('\n');
for (int i = 0; i < bsmArgs.length; i++) { for (int i = 0; i < bsmArgs.length; i++) {
buf.append(tab3);
Object cst = bsmArgs[i]; Object cst = bsmArgs[i];
if (cst instanceof String) { if (cst instanceof String) {
Printer.appendString(buf, (String) cst); Printer.appendString(buf, (String) cst);
} else if (cst instanceof Type) { } else if (cst instanceof Type) {
buf.append(((Type) cst).getDescriptor()).append(".class"); Type type = (Type) cst;
if(type.getSort() == Type.METHOD){
appendDescriptor(METHOD_DESCRIPTOR, type.getDescriptor());
} else {
buf.append(type.getDescriptor()).append(".class");
}
} else if (cst instanceof Handle) { } else if (cst instanceof Handle) {
appendHandle((Handle) cst); appendHandle((Handle) cst);
} else { } else {
buf.append(cst); buf.append(cst);
} }
buf.append(", "); buf.append(", \n");
} }
buf.setLength(buf.length() - 2); buf.setLength(buf.length() - 3);
} }
buf.append('\n'); buf.append('\n');
buf.append(tab2).append("]\n"); buf.append(tab2).append("]\n");
...@@ -1234,10 +1253,10 @@ public class Textifier extends Printer { ...@@ -1234,10 +1253,10 @@ public class Textifier extends Printer {
* a handle, non null. * a handle, non null.
*/ */
protected void appendHandle(final Handle h) { protected void appendHandle(final Handle h) {
buf.append('\n').append(tab3);
int tag = h.getTag(); int tag = h.getTag();
buf.append("// handle kind 0x").append(Integer.toHexString(tag)) buf.append("// handle kind 0x").append(Integer.toHexString(tag))
.append(" : "); .append(" : ");
boolean isMethodHandle = false;
switch (tag) { switch (tag) {
case Opcodes.H_GETFIELD: case Opcodes.H_GETFIELD:
buf.append("GETFIELD"); buf.append("GETFIELD");
...@@ -1253,18 +1272,23 @@ public class Textifier extends Printer { ...@@ -1253,18 +1272,23 @@ public class Textifier extends Printer {
break; break;
case Opcodes.H_INVOKEINTERFACE: case Opcodes.H_INVOKEINTERFACE:
buf.append("INVOKEINTERFACE"); buf.append("INVOKEINTERFACE");
isMethodHandle = true;
break; break;
case Opcodes.H_INVOKESPECIAL: case Opcodes.H_INVOKESPECIAL:
buf.append("INVOKESPECIAL"); buf.append("INVOKESPECIAL");
isMethodHandle = true;
break; break;
case Opcodes.H_INVOKESTATIC: case Opcodes.H_INVOKESTATIC:
buf.append("INVOKESTATIC"); buf.append("INVOKESTATIC");
isMethodHandle = true;
break; break;
case Opcodes.H_INVOKEVIRTUAL: case Opcodes.H_INVOKEVIRTUAL:
buf.append("INVOKEVIRTUAL"); buf.append("INVOKEVIRTUAL");
isMethodHandle = true;
break; break;
case Opcodes.H_NEWINVOKESPECIAL: case Opcodes.H_NEWINVOKESPECIAL:
buf.append("NEWINVOKESPECIAL"); buf.append("NEWINVOKESPECIAL");
isMethodHandle = true;
break; break;
} }
buf.append('\n'); buf.append('\n');
...@@ -1272,9 +1296,13 @@ public class Textifier extends Printer { ...@@ -1272,9 +1296,13 @@ public class Textifier extends Printer {
appendDescriptor(INTERNAL_NAME, h.getOwner()); appendDescriptor(INTERNAL_NAME, h.getOwner());
buf.append('.'); buf.append('.');
buf.append(h.getName()); buf.append(h.getName());
buf.append('('); if(!isMethodHandle){
buf.append('(');
}
appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc()); appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc());
buf.append(')').append('\n'); if(!isMethodHandle){
buf.append(')');
}
} }
/** /**
......
Path: . Path: .
Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/ASM_5_0_BETA Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-03-12
URL: svn://svn.forge.objectweb.org/svnroot/asm/trunk/asm URL: file:///svnroot/asm/trunk/asm
Repository Root: svn://svn.forge.objectweb.org/svnroot/asm Repository Root: file:///svnroot/asm
Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9 Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
Revision: 1700 Revision: 1721
Node Kind: directory Node Kind: directory
Schedule: normal Schedule: normal
Last Changed Author: ebruneton Last Changed Author: ebruneton
Last Changed Rev: 1700 Last Changed Rev: 1721
Last Changed Date: 2013-10-29 20:22:52 +0100 (Tue, 29 Oct 2013) Last Changed Date: 2014-03-02 17:25:35 +0100 (Sun, 02 Mar 2014)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册