+ * @author wenshao[szujobs@hotmail.com]
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.METHOD, ElementType.FIELD })
+@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface JSONField {
+ /**
+ * config encode/decode ordinal
+ * @since 1.1.42
+ * @return
+ */
+ int ordinal() default 0;
String name() default "";
@@ -41,4 +47,36 @@
SerializerFeature[] serialzeFeatures() default {};
Feature[] parseFeatures() default {};
+
+ String label() default "";
+
+ /**
+ * @since 1.2.12
+ */
+ boolean jsonDirect() default false;
+
+ /**
+ * Serializer class to use for serializing associated value.
+ *
+ * @since 1.2.16
+ */
+ Class> serializeUsing() default Void.class;
+
+ /**
+ * Deserializer class to use for deserializing associated value.
+ *
+ * @since 1.2.16
+ */
+ Class> deserializeUsing() default Void.class;
+
+ /**
+ * @since 1.2.21
+ * @return the alternative names of the field when it is deserialized
+ */
+ String[] alternateNames() default {};
+
+ /**
+ * @since 1.2.31
+ */
+ boolean unwrapped() default false;
}
diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONPOJOBuilder.java b/src/main/java/com/alibaba/fastjson/annotation/JSONPOJOBuilder.java
new file mode 100644
index 0000000000..648065dbc0
--- /dev/null
+++ b/src/main/java/com/alibaba/fastjson/annotation/JSONPOJOBuilder.java
@@ -0,0 +1,42 @@
+package com.alibaba.fastjson.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * @since 1.2.8
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE })
+public @interface JSONPOJOBuilder {
+ /**
+ * Property to use for re-defining which zero-argument method
+ * is considered the actual "build-method": method called after
+ * all data has been bound, and the actual instance needs to
+ * be instantiated.
+ *
+ * Default value is "build".
+ */
+ public String buildMethod() default "build";
+
+ /**
+ * Property used for (re)defining name prefix to use for
+ * auto-detecting "with-methods": methods that are similar to
+ * "set-methods" (in that they take an argument), but that
+ * may also return the new builder instance to use
+ * (which may be 'this', or a new modified builder instance).
+ * Note that in addition to this prefix, it is also possible
+ * to use {@link com.alibaba.fastjson.annotation.JSONField}
+ * annotation to indicate "with-methods".
+ *
+ * Default value is "with", so that method named "withValue()"
+ * would be used for binding JSON property "value" (using type
+ * indicated by the argument; or one defined with annotations.
+ */
+ public String withPrefix() default "with";
+
+}
diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONType.java b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java
new file mode 100755
index 0000000000..1be2bd6955
--- /dev/null
+++ b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java
@@ -0,0 +1,64 @@
+package com.alibaba.fastjson.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.alibaba.fastjson.parser.Feature;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+
+/**
+ * @author wenshao[szujobs@hotmail.com]
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE })
+public @interface JSONType {
+
+ boolean asm() default true;
+
+ String[] orders() default {};
+
+ /**
+ * @since 1.2.6
+ */
+ String[] includes() default {};
+
+ String[] ignores() default {};
+
+ SerializerFeature[] serialzeFeatures() default {};
+ Feature[] parseFeatures() default {};
+
+ boolean alphabetic() default true;
+
+ Class> mappingTo() default Void.class;
+
+ Class> builder() default Void.class;
+
+ /**
+ * @since 1.2.11
+ */
+ String typeName() default "";
+
+ /**
+ * @since 1.2.32
+ */
+ String typeKey() default "";
+
+ /**
+ * @since 1.2.11
+ */
+ Class>[] seeAlso() default{};
+
+ /**
+ * @since 1.2.14
+ */
+ Class> serializer() default Void.class;
+
+ /**
+ * @since 1.2.14
+ */
+ Class> deserializer() default Void.class;
+
+ boolean serializeEnumAsJavaBean() default false;
+}
diff --git a/src/main/java/com/alibaba/fastjson/asm/ByteVector.java b/src/main/java/com/alibaba/fastjson/asm/ByteVector.java
old mode 100644
new mode 100755
diff --git a/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java b/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java
old mode 100644
new mode 100755
index 08edae65fc..f7e9a3e6d1
--- a/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java
+++ b/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java
@@ -30,202 +30,10 @@
package com.alibaba.fastjson.asm;
/**
- * A {@link ClassVisitor} that generates classes in bytecode form. More precisely this visitor generates a byte array
- * conforming to the Java class file format. It can be used alone, to generate a Java class "from scratch", or with one
- * or more and adapter class visitor to generate a modified class from one or more existing Java classes.
*
* @author Eric Bruneton
*/
public class ClassWriter {
-
- /**
- * Flag to automatically compute the maximum stack size and the maximum number of local variables of methods. If
- * this flag is set, then the arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the
- * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod} method will be ignored, and computed
- * automatically from the signature and the bytecode of each method.
- *
- * @see #ClassWriter(int)
- */
- public static final int COMPUTE_MAXS = 1;
-
- /**
- * Flag to automatically compute the stack map frames of methods from scratch. If this flag is set, then the calls
- * to the {@link MethodVisitor#visitFrame} method are ignored, and the stack map frames are recomputed from the
- * methods bytecode. The arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
- * recomputed from the bytecode. In other words, computeFrames implies computeMaxs.
- *
- * @see #ClassWriter(int)
- */
- public static final int COMPUTE_FRAMES = 2;
-
- /**
- * Pseudo access flag to distinguish between the synthetic attribute and the synthetic access flag.
- */
- static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
-
- /**
- * The type of instructions without any argument.
- */
- static final int NOARG_INSN = 0;
-
- /**
- * The type of instructions with an signed byte argument.
- */
- static final int SBYTE_INSN = 1;
-
- /**
- * The type of instructions with an signed short argument.
- */
- static final int SHORT_INSN = 2;
-
- /**
- * The type of instructions with a local variable index argument.
- */
- static final int VAR_INSN = 3;
-
- /**
- * The type of instructions with an implicit local variable index argument.
- */
- static final int IMPLVAR_INSN = 4;
-
- /**
- * The type of instructions with a type descriptor argument.
- */
- static final int TYPE_INSN = 5;
-
- /**
- * The type of field and method invocations instructions.
- */
- static final int FIELDORMETH_INSN = 6;
-
- /**
- * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction.
- */
- static final int ITFDYNMETH_INSN = 7;
-
- /**
- * The type of instructions with a 2 bytes bytecode offset label.
- */
- static final int LABEL_INSN = 8;
-
- /**
- * The type of instructions with a 4 bytes bytecode offset label.
- */
- static final int LABELW_INSN = 9;
-
- /**
- * The type of the LDC instruction.
- */
- static final int LDC_INSN = 10;
-
- /**
- * The type of the LDC_W and LDC2_W instructions.
- */
- static final int LDCW_INSN = 11;
-
- /**
- * The type of the IINC instruction.
- */
- static final int IINC_INSN = 12;
-
- /**
- * The type of the TABLESWITCH instruction.
- */
- static final int TABL_INSN = 13;
-
- /**
- * The type of the LOOKUPSWITCH instruction.
- */
- static final int LOOK_INSN = 14;
-
- /**
- * The type of the MULTIANEWARRAY instruction.
- */
- static final int MANA_INSN = 15;
-
- /**
- * The type of the WIDE instruction.
- */
- static final int WIDE_INSN = 16;
-
- /**
- * The instruction types of all JVM opcodes.
- */
- static final byte[] TYPE;
-
- /**
- * The type of CONSTANT_Class constant pool items.
- */
- static final int CLASS = 7;
-
- /**
- * The type of CONSTANT_Fieldref constant pool items.
- */
- static final int FIELD = 9;
-
- /**
- * The type of CONSTANT_Methodref constant pool items.
- */
- static final int METH = 10;
-
- /**
- * The type of CONSTANT_InterfaceMethodref constant pool items.
- */
- static final int IMETH = 11;
-
- /**
- * The type of CONSTANT_String constant pool items.
- */
- static final int STR = 8;
-
- /**
- * The type of CONSTANT_Integer constant pool items.
- */
- static final int INT = 3;
-
- /**
- * The type of CONSTANT_Float constant pool items.
- */
- static final int FLOAT = 4;
-
- /**
- * The type of CONSTANT_Long constant pool items.
- */
- static final int LONG = 5;
-
- /**
- * The type of CONSTANT_Double constant pool items.
- */
- static final int DOUBLE = 6;
-
- /**
- * The type of CONSTANT_NameAndType constant pool items.
- */
- static final int NAME_TYPE = 12;
-
- /**
- * The type of CONSTANT_Utf8 constant pool items.
- */
- static final int UTF8 = 1;
-
- /**
- * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, instead of the constant pool, in order
- * to avoid clashes with normal constant pool items in the ClassWriter constant pool's hash table.
- */
- static final int TYPE_NORMAL = 13;
-
- /**
- * Uninitialized type Item stored in the ClassWriter {@link ClassWriter#typeTable}, instead of the constant pool, in
- * order to avoid clashes with normal constant pool items in the ClassWriter constant pool's hash table.
- */
- static final int TYPE_UNINIT = 14;
-
- /**
- * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, instead of the constant pool, in order
- * to avoid clashes with normal constant pool items in the ClassWriter constant pool's hash table.
- */
- static final int TYPE_MERGED = 15;
-
/**
* Minor and major version numbers of the class to be generated.
*/
@@ -331,91 +139,6 @@ public class ClassWriter {
*/
MethodWriter lastMethod;
- // ------------------------------------------------------------------------
- // Static initializer
- // ------------------------------------------------------------------------
-
- /**
- * Computes the instruction types of JVM opcodes.
- */
- static {
- int i;
- byte[] b = new byte[220];
- String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA" + "AAAAGGGGGGGHHFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII";
- for (i = 0; i < b.length; ++i) {
- b[i] = (byte) (s.charAt(i) - 'A');
- }
- TYPE = b;
-
- // code to generate the above string
- //
- // // SBYTE_INSN instructions
- // b[Constants.NEWARRAY] = SBYTE_INSN;
- // b[Constants.BIPUSH] = SBYTE_INSN;
- //
- // // SHORT_INSN instructions
- // b[Constants.SIPUSH] = SHORT_INSN;
- //
- // // (IMPL)VAR_INSN instructions
- // b[Constants.RET] = VAR_INSN;
- // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
- // b[i] = VAR_INSN;
- // }
- // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
- // b[i] = VAR_INSN;
- // }
- // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3
- // b[i] = IMPLVAR_INSN;
- // }
- // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3
- // b[i] = IMPLVAR_INSN;
- // }
- //
- // // TYPE_INSN instructions
- // b[Constants.NEW] = TYPE_INSN;
- // b[Constants.ANEWARRAY] = TYPE_INSN;
- // b[Constants.CHECKCAST] = TYPE_INSN;
- // b[Constants.INSTANCEOF] = TYPE_INSN;
- //
- // // (Set)FIELDORMETH_INSN instructions
- // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
- // b[i] = FIELDORMETH_INSN;
- // }
- // b[Constants.INVOKEINTERFACE] = ITFDYNMETH_INSN;
- // b[Constants.INVOKEDYNAMIC] = ITFDYNMETH_INSN;
- //
- // // LABEL(W)_INSN instructions
- // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
- // b[i] = LABEL_INSN;
- // }
- // b[Constants.IFNULL] = LABEL_INSN;
- // b[Constants.IFNONNULL] = LABEL_INSN;
- // b[200] = LABELW_INSN; // GOTO_W
- // b[201] = LABELW_INSN; // JSR_W
- // // temporary opcodes used internally by ASM - see Label and
- // MethodWriter
- // for (i = 202; i < 220; ++i) {
- // b[i] = LABEL_INSN;
- // }
- //
- // // LDC(_W) instructions
- // b[Constants.LDC] = LDC_INSN;
- // b[19] = LDCW_INSN; // LDC_W
- // b[20] = LDCW_INSN; // LDC2_W
- //
- // // special instructions
- // b[Constants.IINC] = IINC_INSN;
- // b[Constants.TABLESWITCH] = TABL_INSN;
- // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
- // b[Constants.MULTIANEWARRAY] = MANA_INSN;
- // b[196] = WIDE_INSN; // WIDE
- //
- // for (i = 0; i < b.length; ++i) {
- // System.err.print((char)('A' + b[i]));
- // }
- // System.err.println();
- }
-
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
@@ -424,12 +147,6 @@ public ClassWriter(){
this(0);
}
- /**
- * Constructs a new {@link ClassWriter} object.
- *
- * @param flags option flags that can be used to modify the default behavior of this class. See
- * {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
- */
private ClassWriter(final int flags){
index = 1;
pool = new ByteVector();
@@ -447,29 +164,18 @@ private ClassWriter(final int flags){
public void visit(final int version, final int access, final String name, final String superName, final String[] interfaces) {
this.version = version;
this.access = access;
- this.name = newClass(name);
+ this.name = newClassItem(name).index;
thisName = name;
- this.superName = superName == null ? 0 : newClass(superName);
+ this.superName = superName == null ? 0 : newClassItem(superName).index;
if (interfaces != null && interfaces.length > 0) {
interfaceCount = interfaces.length;
this.interfaces = new int[interfaceCount];
for (int i = 0; i < interfaceCount; ++i) {
- this.interfaces[i] = newClass(interfaces[i]);
+ this.interfaces[i] = newClassItem(interfaces[i]).index;
}
}
}
- public FieldVisitor visitField(final int access, final String name, final String desc) {
- return new FieldWriter(this, access, name, desc);
- }
-
- public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
- return new MethodWriter(this, access, name, desc, signature, exceptions);
- }
-
- public void visitEnd() {
- }
-
// ------------------------------------------------------------------------
// Other public methods
// ------------------------------------------------------------------------
@@ -503,7 +209,7 @@ public byte[] toByteArray() {
ByteVector out = new ByteVector(size);
out.putInt(0xCAFEBABE).putInt(version);
out.putShort(index).putByteArray(pool.data, 0, pool.length);
- int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+ int mask = 393216; // Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
out.putShort(access & ~mask).putShort(name).putShort(superName);
out.putShort(interfaceCount);
for (int i = 0; i < interfaceCount; ++i) {
@@ -538,42 +244,49 @@ public byte[] toByteArray() {
* @return a new or already existing constant item with the given value.
*/
Item newConstItem(final Object cst) {
- if (cst instanceof String) {
+ if (cst instanceof Integer) {
+ int val = ((Integer) cst).intValue();
+ // return newInteger(val);
+ key.set(val);
+ Item result = get(key);
+ if (result == null) {
+ pool.putByte(3 /* INT */ ).putInt(val);
+ result = new Item(index++, key);
+ put(result);
+ }
+ return result;
+ } else if (cst instanceof String) {
return newString((String) cst);
} else if (cst instanceof Type) {
Type t = (Type) cst;
- return newClassItem(t.getSort() == Type.OBJECT ? t.getInternalName() : t.getDescriptor());
+ return newClassItem(t.sort == 10 /*Type.OBJECT*/ ? t.getInternalName() : t.getDescriptor());
} else {
throw new IllegalArgumentException("value " + cst);
}
}
public int newUTF8(final String value) {
- key.set(UTF8, value, null, null);
+ key.set(1 /* UTF8 */, value, null, null);
Item result = get(key);
if (result == null) {
- pool.putByte(UTF8).putUTF8(value);
+ pool.putByte(1 /* UTF8 */).putUTF8(value);
result = new Item(index++, key);
put(result);
}
return result.index;
}
- Item newClassItem(final String value) {
- key2.set(CLASS, value, null, null);
+ public Item newClassItem(final String value) {
+ key2.set(7 /* CLASS */, value, null, null);
Item result = get(key2);
if (result == null) {
- pool.put12(CLASS, newUTF8(value));
+ pool.put12(7 /* CLASS */, newUTF8(value));
result = new Item(index++, key2);
put(result);
}
return result;
}
- public int newClass(final String value) {
- return newClassItem(value).index;
- }
-
/**
* Adds a field reference to the constant pool of the class being build. Does nothing if the constant pool already
* contains a similar item.
@@ -584,10 +297,12 @@ public int newClass(final String value) {
* @return a new or already existing field reference item.
*/
Item newFieldItem(final String owner, final String name, final String desc) {
- key3.set(FIELD, owner, name, desc);
+ key3.set(9 /* FIELD */, owner, name, desc);
Item result = get(key3);
if (result == null) {
- put122(FIELD, newClass(owner), newNameType(name, desc));
+ // put122(9 /* FIELD */, newClassItem(owner).index, newNameTypeItem(name, desc).index);
+ int s1 = newClassItem(owner).index, s2 = newNameTypeItem(name, desc).index;
+ pool.put12(9 /* FIELD */, s1).putShort(s2);
result = new Item(index++, key3);
put(result);
}
@@ -605,11 +320,13 @@ Item newFieldItem(final String owner, final String name, final String desc) {
* @return a new or already existing method reference item.
*/
Item newMethodItem(final String owner, final String name, final String desc, final boolean itf) {
- int type = itf ? IMETH : METH;
+ int type = itf ? 11 /* IMETH */ : 10 /* METH */;
key3.set(type, owner, name, desc);
Item result = get(key3);
if (result == null) {
- put122(type, newClass(owner), newNameType(name, desc));
+ // put122(type, newClassItem(owner).index, newNameTypeItem(name, desc).index);
+ int s1 = newClassItem(owner).index, s2 = newNameTypeItem(name, desc).index;
+ pool.put12(type, s1).putShort(s2);
result = new Item(index++, key3);
put(result);
}
@@ -624,20 +341,16 @@ Item newMethodItem(final String owner, final String name, final String desc, fin
* @return a new or already existing string item.
*/
private Item newString(final String value) {
- key2.set(STR, value, null, null);
+ key2.set(8 /* STR */, value, null, null);
Item result = get(key2);
if (result == null) {
- pool.put12(STR, newUTF8(value));
+ pool.put12(8 /*STR*/, newUTF8(value));
result = new Item(index++, key2);
put(result);
}
return result;
}
- public int newNameType(final String name, final String desc) {
- return newNameTypeItem(name, desc).index;
- }
-
/**
* Adds a name and type to the constant pool of the class being build. Does nothing if the constant pool already
* contains a similar item.
@@ -646,11 +359,13 @@ public int newNameType(final String name, final String desc) {
* @param desc a type descriptor.
* @return a new or already existing name and type item.
*/
- Item newNameTypeItem(final String name, final String desc) {
- key2.set(NAME_TYPE, name, desc, null);
+ public Item newNameTypeItem(final String name, final String desc) {
+ key2.set(12 /* NAME_TYPE */, name, desc, null);
Item result = get(key2);
if (result == null) {
- put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
+ //put122(12 /* NAME_TYPE */, newUTF8(name), newUTF8(desc));
+ int s1 = newUTF8(name), s2 = newUTF8(desc);
+ pool.put12(12 /* NAME_TYPE */, s1).putShort(s2);
result = new Item(index++, key2);
put(result);
}
@@ -700,14 +415,8 @@ private void put(final Item i) {
items[index] = i;
}
- /**
- * Puts one byte and two shorts into the constant pool.
- *
- * @param b a byte.
- * @param s1 a short.
- * @param s2 another short.
- */
- private void put122(final int b, final int s1, final int s2) {
- pool.put12(b, s1).putShort(s2);
- }
+
+// private void put122(final int b, final int s1, final int s2) {
+// pool.put12(b, s1).putShort(s2);
+// }
}
diff --git a/src/main/java/com/alibaba/fastjson/asm/FieldVisitor.java b/src/main/java/com/alibaba/fastjson/asm/FieldVisitor.java
deleted file mode 100644
index e14ff77c17..0000000000
--- a/src/main/java/com/alibaba/fastjson/asm/FieldVisitor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.alibaba.fastjson.asm;
-
-/**
- * A visitor to visit a Java field. The methods of this interface must be called in the following order: (
- * visitAnnotation | visitAttribute )* visitEnd.
- *
- * @author Eric Bruneton
- */
-public interface FieldVisitor {
-
- /**
- * Visits the end of the field. This method, which is the last one to be called, is used to inform the visitor that
- * all the annotations and attributes of the field have been visited.
- */
- void visitEnd();
-}
diff --git a/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java b/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java
old mode 100644
new mode 100755
index 2a75dbf683..4a93009e4a
--- a/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java
+++ b/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java
@@ -30,15 +30,12 @@
package com.alibaba.fastjson.asm;
/**
- * An {@link FieldVisitor} that generates Java fields in bytecode form.
+ * An FieldWriter that generates Java fields in bytecode form.
*
* @author Eric Bruneton
*/
-final class FieldWriter implements FieldVisitor {
+public final class FieldWriter {
- /**
- * Next field writer (see {@link ClassWriter#firstField firstField}).
- */
FieldWriter next;
/**
@@ -60,17 +57,7 @@ final class FieldWriter implements FieldVisitor {
// Constructor
// ------------------------------------------------------------------------
- /**
- * Constructs a new {@link FieldWriter}.
- *
- * @param cw the class writer to which this field must be added.
- * @param access the field's access flags (see {@link Opcodes}).
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link Type}).
- * @param signature the field's signature. May be null.
- * @param value the field's constant value. May be null.
- */
- FieldWriter(final ClassWriter cw, final int access, final String name, final String desc){
+ public FieldWriter(final ClassWriter cw, final int access, final String name, final String desc){
if (cw.firstField == null) {
cw.firstField = this;
} else {
@@ -108,7 +95,7 @@ int getSize() {
* @param out where the content of this field must be put.
*/
void put(final ByteVector out) {
- int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+ final int mask = 393216; // Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0;
out.putShort(attributeCount);
diff --git a/src/main/java/com/alibaba/fastjson/asm/Item.java b/src/main/java/com/alibaba/fastjson/asm/Item.java
old mode 100644
new mode 100755
index 1b1a559892..d941c41b47
--- a/src/main/java/com/alibaba/fastjson/asm/Item.java
+++ b/src/main/java/com/alibaba/fastjson/asm/Item.java
@@ -41,16 +41,6 @@ final class Item {
*/
int index;
- /**
- * Type of this constant pool item. A single class is used to represent all constant pool item types, in order to
- * minimize the bytecode size of this package. The value of this field is one of {@link ClassWriter#INT},
- * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
- * {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
- * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}. Special Item types are used for Items that are stored in the
- * ClassWriter {@link ClassWriter#typeTable}, instead of the constant pool, in order to avoid clashes with normal
- * constant pool items in the ClassWriter constant pool's hash table. These special item types are
- * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and {@link ClassWriter#TYPE_MERGED}.
- */
int type;
/**
@@ -125,13 +115,13 @@ void set(final int type, final String strVal1, final String strVal2, final Strin
this.strVal2 = strVal2;
this.strVal3 = strVal3;
switch (type) {
- case ClassWriter.UTF8:
- case ClassWriter.STR:
- case ClassWriter.CLASS:
- case ClassWriter.TYPE_NORMAL:
+ case 1 /* ClassWriter.UTF8 */:
+ case 8 /* ClassWriter.STR */:
+ case 7 /* ClassWriter.CLASS */:
+ case 13 /* ClassWriter.TYPE_NORMAL */:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return;
- case ClassWriter.NAME_TYPE:
+ case 12 /* ClassWriter.NAME_TYPE */:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode());
return;
// ClassWriter.FIELD:
@@ -141,6 +131,17 @@ void set(final int type, final String strVal1, final String strVal2, final Strin
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode());
}
}
+
+ /**
+ * Sets this item to an integer item.
+ *
+ * @param intVal the value of this item.
+ */
+ void set(final int intVal) {
+ this.type = 3 /* ClassWriter.INT */;
+ this.intVal = intVal;
+ this.hashCode = 0x7FFFFFFF & (type + intVal);
+ }
/**
* Indicates if the given item is equal to this one. This method assumes that the two items have the same
@@ -151,21 +152,19 @@ void set(final int type, final String strVal1, final String strVal2, final Strin
*/
boolean isEqualTo(final Item i) {
switch (type) {
- case ClassWriter.UTF8:
- case ClassWriter.STR:
- case ClassWriter.CLASS:
- case ClassWriter.TYPE_NORMAL:
+ case 1 /* ClassWriter.UTF8 */:
+ case 8 /* ClassWriter.STR */:
+ case 7 /* ClassWriter.CLASS */ :
+ case 13 /* ClassWriter.TYPE_NORMAL */ :
return i.strVal1.equals(strVal1);
- case ClassWriter.TYPE_MERGED:
- case ClassWriter.LONG:
- case ClassWriter.DOUBLE:
+ case 15 /* ClassWriter.TYPE_MERGED */ :
+ case 5 /* ClassWriter.LONG */ :
+ case 6 /* ClassWriter.DOUBLE */:
return i.longVal == longVal;
- case ClassWriter.INT:
- case ClassWriter.FLOAT:
+ case 3 /* ClassWriter.INT */ :
+ case 4 /* ClassWriter.FLOAT */:
return i.intVal == intVal;
- case ClassWriter.TYPE_UNINIT:
- return i.intVal == intVal && i.strVal1.equals(strVal1);
- case ClassWriter.NAME_TYPE:
+ case 12 /* ClassWriter.NAME_TYPE */:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
// case ClassWriter.FIELD:
// case ClassWriter.METH:
diff --git a/src/main/java/com/alibaba/fastjson/asm/Label.java b/src/main/java/com/alibaba/fastjson/asm/Label.java
old mode 100644
new mode 100755
index 5adbd03e1c..f37786b623
--- a/src/main/java/com/alibaba/fastjson/asm/Label.java
+++ b/src/main/java/com/alibaba/fastjson/asm/Label.java
@@ -38,26 +38,8 @@
* @author Eric Bruneton
*/
public class Label {
-
- /**
- * Indicates if the position of this label is known.
- */
- static final int RESOLVED = 2;
-
- /**
- * Field used to associate user information to a label. Warning: this field is used by the ASM tree package. In
- * order to use it with the ASM tree package you must override the
- * {@link com.alibaba.fastjson.asm.tree.MethodNode#getLabelNode} method.
- */
- public Object info;
-
int status;
- /**
- * The line number corresponding to this label, if known.
- */
- int line;
-
/**
* The position of this label in the code, if known.
*/
@@ -74,7 +56,7 @@ public class Label {
* reference, while the second is the position of the first byte of the forward reference itself. In fact the sign
* of the first integer indicates if this reference uses 2 or 4 bytes, and its absolute value gives the position of
* the bytecode instruction. This array is also used as a bitset to store the subroutines to which a basic block
- * belongs. This information is needed in {@linked MethodWriter#visitMaxs}, after all forward references have been
+ * belongs. This information is needed in MethodWriter#visitMaxs, after all forward references have been
* resolved. Hence the same array can be used for both purposes without problems.
*/
private int[] srcAndRefPositions;
@@ -90,7 +72,7 @@ public class Label {
* stack map frames are similar and use two steps. The first step, during the visit of each instruction, builds
* information about the state of the local variables and the operand stack at the end of each basic block, called
* the "output frame", relatively to the frame state at the beginning of the basic block, which is called the
- * "input frame", and which is unknown during this step. The second step, in {@link MethodWriter#visitMaxs},
+ * "input frame", and which is unknown during this step. The second step, in link MethodWriter#visitMaxs,
* is a fix point algorithm that computes information about the input frame of each basic block, from the input
* state of the first basic block (known from the method signature), and by the using the previously computed
* relative output frames. The algorithm used to compute the maximum stack size only computes the relative output
@@ -117,7 +99,7 @@ public class Label {
/**
* The successor of this label, in the order they are visited. This linked list does not include labels used for
- * debug info only. If {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it does not contain
+ * debug info only. If ClassWriter#COMPUTE_FRAMES option is used then, in addition, it does not contain
* successive labels that denote the same bytecode position (in this case only the first label appears in this
* list).
*/
@@ -159,7 +141,7 @@ public Label(){
* @throws IllegalArgumentException if this label has not been created by the given code writer.
*/
void put(final MethodWriter owner, final ByteVector out, final int source) {
- if ((status & RESOLVED) == 0) {
+ if ((status & 2 /* RESOLVED */ ) == 0) {
addReference(source, out.length);
out.putShort(-1);
} else {
@@ -204,45 +186,18 @@ private void addReference(final int sourcePosition, final int referencePosition)
* @throws IllegalArgumentException if this label has already been resolved, or if it has not been created by the
* given code writer.
*/
- boolean resolve(final MethodWriter owner, final int position, final byte[] data) {
- boolean needUpdate = false;
- this.status |= RESOLVED;
+ void resolve(final MethodWriter owner, final int position, final byte[] data) {
+ this.status |= 2 /* RESOLVED */ ;
this.position = position;
int i = 0;
while (i < referenceCount) {
int source = srcAndRefPositions[i++];
int reference = srcAndRefPositions[i++];
- int offset;
- if (source >= 0) {
- offset = position - source;
- if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) {
- /*
- * changes the opcode of the jump instruction, in order to be able to find it later (see
- * resizeInstructions in MethodWriter). These temporary opcodes are similar to jump instruction
- * opcodes, except that the 2 bytes offset is unsigned (and can therefore represent values from 0 to
- * 65535, which is sufficient since the size of a method is limited to 65535 bytes).
- */
- int opcode = data[reference - 1] & 0xFF;
- if (opcode <= Opcodes.JSR) {
- // changes IFEQ ... JSR to opcodes 202 to 217
- data[reference - 1] = (byte) (opcode + 49);
- } else {
- // changes IFNULL and IFNONNULL to opcodes 218 and 219
- data[reference - 1] = (byte) (opcode + 20);
- }
- needUpdate = true;
- }
- data[reference++] = (byte) (offset >>> 8);
- data[reference] = (byte) offset;
- } else {
- offset = position + source + 1;
- data[reference++] = (byte) (offset >>> 24);
- data[reference++] = (byte) (offset >>> 16);
- data[reference++] = (byte) (offset >>> 8);
- data[reference] = (byte) offset;
- }
+ int offset = position - source;
+ data[reference++] = (byte) (offset >>> 8);
+ data[reference] = (byte) offset;
+
}
- return needUpdate;
}
}
diff --git a/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java b/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java
old mode 100644
new mode 100755
index 1c916ddd16..e32a216de6
--- a/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java
+++ b/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java
@@ -30,15 +30,6 @@
package com.alibaba.fastjson.asm;
/**
- * A visitor to visit a Java method. The methods of this interface must be called in the following order: [
- * visitAnnotationDefault ] ( visitAnnotation | visitParameterAnnotation |
- * visitAttribute )* [ visitCode ( visitFrame | visitXInsn |
- * visitLabel | visitTryCatchBlock | visitLocalVariable | visitLineNumber)*
- * visitMaxs ] visitEnd. In addition, the visitXInsn and visitLabel
- * methods must be called in the sequential order of the bytecode instructions of the visited code,
- * visitTryCatchBlock must be called before the labels passed as arguments have been visited, and the
- * visitLocalVariable and visitLineNumber methods must be called after the labels passed as
- * arguments have been visited.
*
* @author Eric Bruneton
*/
@@ -66,17 +57,6 @@ public interface MethodVisitor {
*/
void visitInsn(int opcode);
- /**
- * Visits an instruction with a single int operand.
- *
- * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH or NEWARRAY.
- * @param operand the operand of the instruction to be visited.
- * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE.
- * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE.
- * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
- * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
- * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
- */
void visitIntInsn(int opcode, int operand);
/**
@@ -112,16 +92,6 @@ public interface MethodVisitor {
*/
void visitFieldInsn(int opcode, String owner, String name, String desc);
- /**
- * Visits a method instruction. A method instruction is an instruction that invokes a method.
- *
- * @param opcode the opcode of the type instruction to be visited. This opcode is either INVOKEVIRTUAL,
- * INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE or INVOKEDYNAMIC.
- * @param owner the internal name of the method's owner class (see {@link Type#getInternalName() getInternalName})
- * or {@link com.alibaba.fastjson.asm.Opcodes#INVOKEDYNAMIC_OWNER}.
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
- */
void visitMethodInsn(int opcode, String owner, String name, String desc);
/**
diff --git a/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java b/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java
old mode 100644
new mode 100755
index 4ec9776ce0..1cd633d2e0
--- a/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java
+++ b/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java
@@ -30,62 +30,10 @@
package com.alibaba.fastjson.asm;
/**
- * A {@link MethodVisitor} that generates methods in bytecode form. Each visit method of this class appends the bytecode
- * corresponding to the visited instruction to a byte vector, in the order these methods are called.
- *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-class MethodWriter implements MethodVisitor {
-
- /**
- * Pseudo access flag used to denote constructors.
- */
- static final int ACC_CONSTRUCTOR = 262144;
-
- /**
- * Frame has exactly the same locals as the previous stack map frame and number of stack items is zero.
- */
- static final int SAME_FRAME = 0; // to 63 (0-3f)
-
- /**
- * Frame has exactly the same locals as the previous stack map frame and number of stack items is 1
- */
- static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; // to 127 (40-7f)
-
- /**
- * Reserved for future use
- */
- static final int RESERVED = 128;
-
- /**
- * Frame has exactly the same locals as the previous stack map frame and number of stack items is 1. Offset is
- * bigger then 63;
- */
- static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; // f7
-
- /**
- * Frame where current locals are the same as the locals in the previous frame, except that the k last locals are
- * absent. The value of k is given by the formula 251-frame_type.
- */
- static final int CHOP_FRAME = 248; // to 250 (f8-fA)
-
- /**
- * Frame has exactly the same locals as the previous stack map frame and number of stack items is zero. Offset is
- * bigger then 63;
- */
- static final int SAME_FRAME_EXTENDED = 251; // fb
-
- /**
- * Frame where current locals are the same as the locals in the previous frame, except that k additional locals are
- * defined. The value of k is given by the formula frame_type-251.
- */
- static final int APPEND_FRAME = 252; // to 254 // fc-fe
-
- /**
- * Full frame
- */
- static final int FULL_FRAME = 255; // ff
+public class MethodWriter implements MethodVisitor {
/**
* Next method writer (see {@link ClassWriter#firstMethod firstMethod}).
@@ -112,12 +60,6 @@ class MethodWriter implements MethodVisitor {
*/
private final int desc;
- /**
- * If not zero, indicates that the code of this method must be copied from the ClassReader associated to this writer
- * in cw.cr
. More precisely, this field gives the number of bytes to copied from cw.cr.b
.
- */
- int classReaderLength;
-
/**
* Number of exceptions that can be thrown by this method.
*/
@@ -144,11 +86,6 @@ class MethodWriter implements MethodVisitor {
*/
private int maxLocals;
- /**
- * Indicates if some jump instructions are too small and need to be resized.
- */
- private boolean resize;
-
// ------------------------------------------------------------------------
/*
@@ -162,20 +99,7 @@ class MethodWriter implements MethodVisitor {
// Constructor
// ------------------------------------------------------------------------
- /**
- * Constructs a new {@link MethodWriter}.
- *
- * @param cw the class writer in which the method must be added.
- * @param access the method's access flags (see {@link Opcodes}).
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type}).
- * @param signature the method's signature. May be null.
- * @param exceptions the internal names of the method's exceptions. May be null.
- * @param computeMaxs true if the maximum stack size and number of local variables must be automatically
- * computed.
- * @param computeFrames true if the stack map tables must be recomputed from scratch.
- */
- MethodWriter(final ClassWriter cw, final int access, final String name, final String desc, final String signature, final String[] exceptions){
+ public MethodWriter(final ClassWriter cw, final int access, final String name, final String desc, final String signature, final String[] exceptions){
if (cw.firstMethod == null) {
cw.firstMethod = this;
} else {
@@ -191,7 +115,7 @@ class MethodWriter implements MethodVisitor {
exceptionCount = exceptions.length;
this.exceptions = new int[exceptionCount];
for (int i = 0; i < exceptionCount; ++i) {
- this.exceptions[i] = cw.newClass(exceptions[i]);
+ this.exceptions[i] = cw.newClassItem(exceptions[i]).index;
}
}
}
@@ -271,7 +195,7 @@ public void visitMethodInsn(final int opcode, final String owner, final String n
public void visitJumpInsn(final int opcode, final Label label) {
// Label currentBlock = this.currentBlock;
// adds the instruction to the bytecode of the method
- if ((label.status & Label.RESOLVED) != 0 && label.position - code.length < Short.MIN_VALUE) {
+ if ((label.status & 2 /* Label.RESOLVED */ ) != 0 && label.position - code.length < Short.MIN_VALUE) {
throw new UnsupportedOperationException();
} else {
/*
@@ -286,7 +210,7 @@ public void visitJumpInsn(final int opcode, final Label label) {
public void visitLabel(final Label label) {
// resolves previous forward references to label, if any
- resize |= label.resolve(this, code.length, code.data);
+ label.resolve(this, code.length, code.data);
}
public void visitLdcInsn(final Object cst) {
@@ -294,22 +218,22 @@ public void visitLdcInsn(final Object cst) {
// Label currentBlock = this.currentBlock;
// adds the instruction to the bytecode of the method
int index = i.index;
- if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
+ if (i.type == 5 /* ClassWriter.LONG */ || i.type == 6 /* ClassWriter.DOUBLE */) {
code.put12(20 /* LDC2_W */, index);
} else if (index >= 256) {
code.put12(19 /* LDC_W */, index);
} else {
- code.put11(Opcodes.LDC, index);
+ code.put11(18 /*Opcodes.LDC*/, index);
}
}
public void visitIincInsn(final int var, final int increment) {
// adds the instruction to the bytecode of the method
- if ((var > 255) || (increment > 127) || (increment < -128)) {
- code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var).putShort(increment);
- } else {
- code.putByte(Opcodes.IINC).put11(var, increment);
- }
+// if ((var > 255) || (increment > 127) || (increment < -128)) {
+// code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var).putShort(increment);
+// } else {
+ code.putByte(132 /* Opcodes.IINC*/ ).put11(var, increment);
+// }
}
public void visitMaxs(final int maxStack, final int maxLocals) {
@@ -338,10 +262,6 @@ public void visitEnd() {
* @return the size of the bytecode of this method.
*/
final int getSize() {
- if (resize) {
- // replaces the temporary jump opcodes introduced by Label.resolve.
- throw new UnsupportedOperationException();
- }
int size = 8;
if (code.length > 0) {
cw.newUTF8("Code");
@@ -360,7 +280,7 @@ final int getSize() {
* @param out the byte vector into which the bytecode of this method must be copied.
*/
final void put(final ByteVector out) {
- int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+ final int mask = 393216; //Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0;
if (code.length > 0) {
diff --git a/src/main/java/com/alibaba/fastjson/asm/Opcodes.java b/src/main/java/com/alibaba/fastjson/asm/Opcodes.java
old mode 100644
new mode 100755
index cc9e9b6ac5..3440da9804
--- a/src/main/java/com/alibaba/fastjson/asm/Opcodes.java
+++ b/src/main/java/com/alibaba/fastjson/asm/Opcodes.java
@@ -39,6 +39,7 @@
* @author Eugene Kuleshov
*/
public interface Opcodes {
+ int T_INT = 10;
// versions
@@ -53,59 +54,20 @@ public interface Opcodes {
// access flags
int ACC_PUBLIC = 0x0001; // class, field, method
- int ACC_PRIVATE = 0x0002; // class, field, method
int ACC_SUPER = 0x0020; // class
- int ACC_SYNTHETIC = 0x1000; // class, field, method
-
- // ASM specific pseudo access flags
-
- int ACC_DEPRECATED = 0x20000; // class, field, method
-
- // types for NEWARRAY
-
- int T_BOOLEAN = 4;
- int T_CHAR = 5;
- int T_FLOAT = 6;
- int T_DOUBLE = 7;
- int T_BYTE = 8;
- int T_SHORT = 9;
- int T_INT = 10;
- int T_LONG = 11;
-
- // Integer TOP = new Integer(0);
- // Integer INTEGER = new Integer(1);
- // Integer FLOAT = new Integer(2);
- // Integer DOUBLE = new Integer(3);
- // Integer LONG = new Integer(4);
- // Integer NULL = new Integer(5);
- // Integer UNINITIALIZED_THIS = new Integer(6);
-
- /**
- * Represents a owner of an invokedynamic call.
- */
- String INVOKEDYNAMIC_OWNER = "java/lang/dyn/Dynamic";
// opcodes // visit method (- = idem)
- int NOP = 0; // visitInsn
int ACONST_NULL = 1; // -
- int ICONST_M1 = 2; // -
int ICONST_0 = 3; // -
int ICONST_1 = 4; // -
- int ICONST_2 = 5; // -
- int ICONST_3 = 6; // -
- int ICONST_4 = 7; // -
- int ICONST_5 = 8; // -
int LCONST_0 = 9; // -
int LCONST_1 = 10; // -
int FCONST_0 = 11; // -
- int FCONST_1 = 12; // -
- int FCONST_2 = 13; // -
int DCONST_0 = 14; // -
- int DCONST_1 = 15; // -
int BIPUSH = 16; // visitIntInsn
-// int SIPUSH = 17; // -
- int LDC = 18; // visitLdcInsn
+ // int SIPUSH = 17; // -
+// int LDC = 18; // visitLdcInsn
// int LDC_W = 19; // -
// int LDC2_W = 20; // -
int ILOAD = 21; // visitVarInsn
@@ -113,160 +75,48 @@ public interface Opcodes {
int FLOAD = 23; // -
int DLOAD = 24; // -
int ALOAD = 25; // -
- // int ILOAD_0 = 26; // -
- // int ILOAD_1 = 27; // -
- // int ILOAD_2 = 28; // -
- // int ILOAD_3 = 29; // -
- // int LLOAD_0 = 30; // -
- // int LLOAD_1 = 31; // -
- // int LLOAD_2 = 32; // -
- // int LLOAD_3 = 33; // -
- // int FLOAD_0 = 34; // -
- // int FLOAD_1 = 35; // -
- // int FLOAD_2 = 36; // -
- // int FLOAD_3 = 37; // -
- // int DLOAD_0 = 38; // -
- // int DLOAD_1 = 39; // -
- // int DLOAD_2 = 40; // -
- // int DLOAD_3 = 41; // -
- // int ALOAD_0 = 42; // -
- // int ALOAD_1 = 43; // -
- // int ALOAD_2 = 44; // -
- // int ALOAD_3 = 45; // -
- int IALOAD = 46; // visitInsn
- int LALOAD = 47; // -
- int FALOAD = 48; // -
- int DALOAD = 49; // -
- int AALOAD = 50; // -
- int BALOAD = 51; // -
- int CALOAD = 52; // -
- int SALOAD = 53; // -
+
int ISTORE = 54; // visitVarInsn
int LSTORE = 55; // -
int FSTORE = 56; // -
int DSTORE = 57; // -
int ASTORE = 58; // -
- // int ISTORE_0 = 59; // -
- // int ISTORE_1 = 60; // -
- // int ISTORE_2 = 61; // -
- // int ISTORE_3 = 62; // -
- // int LSTORE_0 = 63; // -
- // int LSTORE_1 = 64; // -
- // int LSTORE_2 = 65; // -
- // int LSTORE_3 = 66; // -
- // int FSTORE_0 = 67; // -
- // int FSTORE_1 = 68; // -
- // int FSTORE_2 = 69; // -
- // int FSTORE_3 = 70; // -
- // int DSTORE_0 = 71; // -
- // int DSTORE_1 = 72; // -
- // int DSTORE_2 = 73; // -
- // int DSTORE_3 = 74; // -
- // int ASTORE_0 = 75; // -
- // int ASTORE_1 = 76; // -
- // int ASTORE_2 = 77; // -
- // int ASTORE_3 = 78; // -
- // int IASTORE = 79; // visitInsn
- // int LASTORE = 80; // -
- // int FASTORE = 81; // -
- // int DASTORE = 82; // -
- // int AASTORE = 83; // -
- // int BASTORE = 84; // -
- // int CASTORE = 85; // -
- // int SASTORE = 86; // -
+ int IASTORE = 79; // visitInsn
+
int POP = 87; // -
- int POP2 = 88; // -
+// int POP2 = 88; // -
int DUP = 89; // -
-// int DUP_X1 = 90; // -
-// int DUP_X2 = 91; // -
-// int DUP2 = 92; // -
-// int DUP2_X1 = 93; // -
-// int DUP2_X2 = 94; // -
-// int SWAP = 95; // -
+
int IADD = 96; // -
- int LADD = 97; // -
-// int FADD = 98; // -
-// int DADD = 99; // -
- int ISUB = 100; // -
-// int LSUB = 101; // -
-// int FSUB = 102; // -
-// int DSUB = 103; // -
-// int IMUL = 104; // -
-// int LMUL = 105; // -
-// int FMUL = 106; // -
-// int DMUL = 107; // -
-// int IDIV = 108; // -
-// int LDIV = 109; // -
-// int FDIV = 110; // -
-// int DDIV = 111; // -
-// int IREM = 112; // -
-// int LREM = 113; // -
-// int FREM = 114; // -
-// int DREM = 115; // -
-// int INEG = 116; // -
-// int LNEG = 117; // -
-// int FNEG = 118; // -
-// int DNEG = 119; // -
-// int ISHL = 120; // -
-// int LSHL = 121; // -
-// int ISHR = 122; // -
-// int LSHR = 123; // -
-// int IUSHR = 124; // -
-// int LUSHR = 125; // -
-// int IAND = 126; // -
-// int LAND = 127; // -
-// int IOR = 128; // -
-// int LOR = 129; // -
-// int IXOR = 130; // -
-// int LXOR = 131; // -
- int IINC = 132; // visitIincInsn
-// int I2L = 133; // visitInsn
-// int I2F = 134; // -
-// int I2D = 135; // -
-// int L2I = 136; // -
-// int L2F = 137; // -
-// int L2D = 138; // -
-// int F2I = 139; // -
-// int F2L = 140; // -
-// int F2D = 141; // -
-// int D2I = 142; // -
-// int D2L = 143; // -
-// int D2F = 144; // -
- int I2B = 145; // -
- int I2C = 146; // -
- int I2S = 147; // -
+
+// int ISUB = 100; // -
+
+ int IAND = 126; // -
+ // int LAND = 127; // -
+ int IOR = 128; // -
+ // int LOR = 129; // -
+ // int IXOR = 130; // -
+ // int LXOR = 131; // -
+ // int IINC = 132; // visitIincInsn
+
int LCMP = 148; // -
int FCMPL = 149; // -
- int FCMPG = 150; // -
int DCMPL = 151; // -
- int DCMPG = 152; // -
int IFEQ = 153; // visitJumpInsn
int IFNE = 154; // -
- int IFLT = 155; // -
- int IFGE = 156; // -
- int IFGT = 157; // -
int IFLE = 158; // -
int IF_ICMPEQ = 159; // -
int IF_ICMPNE = 160; // -
int IF_ICMPLT = 161; // -
int IF_ICMPGE = 162; // -
int IF_ICMPGT = 163; // -
- int IF_ICMPLE = 164; // -
int IF_ACMPEQ = 165; // -
int IF_ACMPNE = 166; // -
int GOTO = 167; // -
- int JSR = 168; // -
int RET = 169; // visitVarInsn
-// int TABLESWITCH = 170; // visiTableSwitchInsn
-// int LOOKUPSWITCH = 171; // visitLookupSwitch
- int IRETURN = 172; // visitInsn
-// int LRETURN = 173; // -
-// int FRETURN = 174; // -
-// int DRETURN = 175; // -
int ARETURN = 176; // -
int RETURN = 177; // -
int GETSTATIC = 178; // visitFieldInsn
- int PUTSTATIC = 179; // -
int GETFIELD = 180; // -
int PUTFIELD = 181; // -
int INVOKEVIRTUAL = 182; // visitMethodInsn
@@ -275,16 +125,13 @@ public interface Opcodes {
int INVOKEINTERFACE = 185; // -
// int INVOKEDYNAMIC = 186; // -
int NEW = 187; // visitTypeInsn
-// int NEWARRAY = 188; // visitIntInsn
-// int ANEWARRAY = 189; // visitTypeInsn
-// int ARRAYLENGTH = 190; // visitInsn
-// int ATHROW = 191; // -
+ int NEWARRAY = 188; // visitIntInsn
+ // int ANEWARRAY = 189; // visitTypeInsn
+ // int ARRAYLENGTH = 190; // visitInsn
+ // int ATHROW = 191; // -
int CHECKCAST = 192; // visitTypeInsn
- int INSTANCEOF = 193; // -
-// int MONITORENTER = 194; // visitInsn
-// int MONITOREXIT = 195; // -
- // int WIDE = 196; // NOT VISITED
-// int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
+ int INSTANCEOF = 193;
+
int IFNULL = 198; // visitJumpInsn
int IFNONNULL = 199; // -
// int GOTO_W = 200; // -
diff --git a/src/main/java/com/alibaba/fastjson/asm/Type.java b/src/main/java/com/alibaba/fastjson/asm/Type.java
old mode 100644
new mode 100755
index cfc0751724..769c1f7672
--- a/src/main/java/com/alibaba/fastjson/asm/Type.java
+++ b/src/main/java/com/alibaba/fastjson/asm/Type.java
@@ -36,106 +36,50 @@
* @author Chris Nokleberg
*/
public class Type {
-
- /**
- * The sort of the void type. See {@link #getSort getSort}.
- */
- public static final int VOID = 0;
-
- /**
- * The sort of the boolean type. See {@link #getSort getSort}.
- */
- public static final int BOOLEAN = 1;
-
- /**
- * The sort of the char type. See {@link #getSort getSort}.
- */
- public static final int CHAR = 2;
-
- /**
- * The sort of the byte type. See {@link #getSort getSort}.
- */
- public static final int BYTE = 3;
-
- /**
- * The sort of the short type. See {@link #getSort getSort}.
- */
- public static final int SHORT = 4;
-
- /**
- * The sort of the int type. See {@link #getSort getSort}.
- */
- public static final int INT = 5;
-
- /**
- * The sort of the float type. See {@link #getSort getSort}.
- */
- public static final int FLOAT = 6;
-
- /**
- * The sort of the long type. See {@link #getSort getSort}.
- */
- public static final int LONG = 7;
-
- /**
- * The sort of the double type. See {@link #getSort getSort}.
- */
- public static final int DOUBLE = 8;
-
- /**
- * The sort of array reference types. See {@link #getSort getSort}.
- */
- public static final int ARRAY = 9;
-
- /**
- * The sort of object reference type. See {@link #getSort getSort}.
- */
- public static final int OBJECT = 10;
-
/**
* The void type.
*/
- public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1);
+ public static final Type VOID_TYPE = new Type(0, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1);
/**
* The boolean type.
*/
- public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1);
+ public static final Type BOOLEAN_TYPE = new Type(1, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1);
/**
* The char type.
*/
- public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1);
+ public static final Type CHAR_TYPE = new Type(2, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1);
/**
* The byte type.
*/
- public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1);
+ public static final Type BYTE_TYPE = new Type(3, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1);
/**
* The short type.
*/
- public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1);
+ public static final Type SHORT_TYPE = new Type(4, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1);
/**
* The int type.
*/
- public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1);
+ public static final Type INT_TYPE = new Type(5, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1);
/**
* The float type.
*/
- public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1);
+ public static final Type FLOAT_TYPE = new Type(6, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1);
/**
* The long type.
*/
- public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1);
+ public static final Type LONG_TYPE = new Type(7, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1);
/**
* The double type.
*/
- public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) | (3 << 16) | (3 << 8) | 2, 1);
+ public static final Type DOUBLE_TYPE = new Type(8, null, ('D' << 24) | (3 << 16) | (3 << 8) | 2, 1);
// ------------------------------------------------------------------------
// Fields
@@ -144,7 +88,7 @@ public class Type {
/**
* The sort of this Java type.
*/
- private final int sort;
+ protected final int sort;
/**
* A buffer containing the internal name of this Java type. This field is only used for reference types.
@@ -167,14 +111,6 @@ public class Type {
// Constructors
// ------------------------------------------------------------------------
- /**
- * Constructs a reference type.
- *
- * @param sort the sort of the reference type to be constructed.
- * @param buf a buffer containing the descriptor of the previous type.
- * @param off the offset of this descriptor in the previous buffer.
- * @param len the length of this descriptor.
- */
private Type(final int sort, final char[] buf, final int off, final int len){
this.sort = sort;
this.buf = buf;
@@ -192,14 +128,6 @@ public static Type getType(final String typeDescriptor) {
return getType(typeDescriptor.toCharArray(), 0);
}
- /**
- * Computes the size of the arguments and of the return value of a method.
- *
- * @param desc the descriptor of a method.
- * @return the size of the arguments of the method (plus one for the implicit this argument), argSize, and the size
- * of its return value, retSize, packed into a single int i = (argSize << 2) | retSize (argSize is
- * therefore equal to i >> 2, and retSize to i & 0x03).
- */
public static int getArgumentsAndReturnSizes(final String desc) {
int n = 1;
int c = 1;
@@ -212,13 +140,13 @@ public static int getArgumentsAndReturnSizes(final String desc) {
while (desc.charAt(c++) != ';') {
}
n += 1;
- } else if (car == '[') {
- while ((car = desc.charAt(c)) == '[') {
- ++c;
- }
- if (car == 'D' || car == 'J') {
- n -= 1;
- }
+// } else if (car == '[') {
+// while ((car = desc.charAt(c)) == '[') {
+// ++c;
+// }
+// if (car == 'D' || car == 'J') {
+// n -= 1;
+// }
} else if (car == 'D' || car == 'J') {
n += 2;
} else {
@@ -266,39 +194,17 @@ private static Type getType(final char[] buf, final int off) {
++len;
}
}
- return new Type(ARRAY, buf, off, len + 1);
+ return new Type(9 /*ARRAY*/, buf, off, len + 1);
// case 'L':
default:
len = 1;
while (buf[off + len] != ';') {
++len;
}
- return new Type(OBJECT, buf, off + 1, len - 1);
+ return new Type(10/*OBJECT*/, buf, off + 1, len - 1);
}
}
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
-
- /**
- * Returns the sort of this Java type.
- *
- * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT
- * SHORT}, {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY}
- * or {@link #OBJECT OBJECT}.
- */
- public int getSort() {
- return sort;
- }
-
- /**
- * Returns the internal name of the class corresponding to this object or array type. The internal name of a class
- * is its fully qualified name (as returned by Class.getName(), where '.' are replaced by '/'. This method should
- * only be used for an object or array type.
- *
- * @return the internal name of the class corresponding to this object type.
- */
public String getInternalName() {
return new String(buf, off, len);
}
@@ -312,20 +218,7 @@ public String getInternalName() {
*
* @return the descriptor corresponding to this Java type.
*/
- public String getDescriptor() {
- StringBuffer buf = new StringBuffer();
-
- if (this.buf == null) {
- // descriptor is in byte 3 of 'off' for primitive types (buf == null)
- buf.append((char) ((off & 0xFF000000) >>> 24));
- } else if (sort == ARRAY) {
- buf.append(this.buf, off, len);
- } else { // sort == OBJECT
- buf.append('L');
- buf.append(this.buf, off, len);
- buf.append(';');
- }
-
- return buf.toString();
+ String getDescriptor() {
+ return new String(this.buf, off, len);
}
}
diff --git a/src/main/java/com/alibaba/fastjson/asm/package.html b/src/main/java/com/alibaba/fastjson/asm/package.html
deleted file mode 100644
index fd6caf73f6..0000000000
--- a/src/main/java/com/alibaba/fastjson/asm/package.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
- Provides a small and fast bytecode manipulation framework.
-
-
- The ASM framework is
- organized around the {@link org.objectweb.asm.ClassVisitor
- ClassVisitor}, {@link org.objectweb.asm.FieldVisitor FieldVisitor} and
- {@link org.objectweb.asm.MethodVisitor MethodVisitor} interfaces,
- which allow one to visit the fields and methods of a class, including
- the bytecode instructions of each method.
-
In addition to these main interfaces, ASM provides a {@link
- org.objectweb.asm.ClassReader ClassReader} class, that can parse an
- existing class and make a given visitor visit it. ASM also provides a
- {@link org.objectweb.asm.ClassWriter ClassWriter} class, which is a
- visitor that generates Java class files.
-
- In order to generate a class from scratch, only the {@link
- org.objectweb.asm.ClassWriter ClassWriter} class is necessary. Indeed,
- in order to generate a class, one must just call its visitXXX
- methods with the appropriate arguments to generate the desired fields
- and methods. See the "helloworld" example in the ASM distribution for
- more details about class generation.
-
In order to modify existing classes, one must use a {@link
- org.objectweb.asm.ClassReader ClassReader} class to analyze the
- original class, a class modifier, and a {@link
- org.objectweb.asm.ClassWriter ClassWriter} to construct the modified
- class. The class modifier is just a {@link
- org.objectweb.asm.ClassVisitor ClassVisitor} that delegates most of
- the work to another {@link org.objectweb.asm.ClassVisitor
- ClassVisitor}, but that sometimes changes some parameter values, or
- call additional methods, in order to implement the desired
- modification process. In order to make it easier to implement such
- class modifiers, ASM provides the {@link
- org.objectweb.asm.ClassAdapter ClassAdapter} and {@link
- org.objectweb.asm.MethodAdapter MethodAdapter} classes, which
- implement the {@link org.objectweb.asm.ClassVisitor ClassVisitor} and
- {@link org.objectweb.asm.MethodVisitor MethodVisitor} interfaces by
- delegating all work to other visitors. See the "adapt" example in the
- ASM distribution for more details about class modification.
-
- The size of the core ASM library,
- asm.jar
- , is only 42KB, which is much smaller than the size of the BCEL library (504KB), and
- than the size of the SERP
- library (150KB). ASM is also much faster than these tools. Indeed the
- overhead of a load time class transformation process is of the order
- of 60% with ASM, 700% or more with BCEL, and 1100% or more with SERP
- (see the
- test/perf
- directory in the ASM distribution)! @since ASM 1.3
-
-
diff --git a/src/main/java/com/alibaba/fastjson/parser/AbstractJSONParser.java b/src/main/java/com/alibaba/fastjson/parser/AbstractJSONParser.java
deleted file mode 100644
index e6e084653a..0000000000
--- a/src/main/java/com/alibaba/fastjson/parser/AbstractJSONParser.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package com.alibaba.fastjson.parser;
-
-import static com.alibaba.fastjson.parser.JSONToken.EOF;
-import static com.alibaba.fastjson.parser.JSONToken.FALSE;
-import static com.alibaba.fastjson.parser.JSONToken.LBRACE;
-import static com.alibaba.fastjson.parser.JSONToken.LBRACKET;
-import static com.alibaba.fastjson.parser.JSONToken.LITERAL_FLOAT;
-import static com.alibaba.fastjson.parser.JSONToken.LITERAL_INT;
-import static com.alibaba.fastjson.parser.JSONToken.LITERAL_STRING;
-import static com.alibaba.fastjson.parser.JSONToken.NEW;
-import static com.alibaba.fastjson.parser.JSONToken.NULL;
-import static com.alibaba.fastjson.parser.JSONToken.RBRACKET;
-import static com.alibaba.fastjson.parser.JSONToken.TRUE;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.Map;
-
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONException;
-import com.alibaba.fastjson.JSONObject;
-
-public abstract class AbstractJSONParser {
-
- @SuppressWarnings("rawtypes")
- public abstract void parseObject(final Map object);
-
- public JSONObject parseObject() {
- JSONObject object = new JSONObject();
- parseObject(object);
- return object;
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public final void parseArray(final Collection array) {
- final JSONLexer lexer = getLexer();
-
- if (lexer.token() != JSONToken.LBRACKET) {
- throw new JSONException("syntax error, expect [, actual "
- + JSONToken.name(lexer.token()));
- }
-
- lexer.nextToken(JSONToken.LITERAL_STRING);
-
- for (;;) {
- if (isEnabled(Feature.AllowArbitraryCommas)) {
- while (lexer.token() == JSONToken.COMMA) {
- lexer.nextToken();
- continue;
- }
- }
-
- Object value;
- switch (lexer.token()) {
- case LITERAL_INT:
- value = lexer.integerValue();
- lexer.nextToken(JSONToken.COMMA);
- break;
- case LITERAL_FLOAT:
- if (lexer.isEnabled(Feature.UseBigDecimal)) {
- value = lexer.decimalValue();
- } else {
- value = lexer.doubleValue();
- }
- lexer.nextToken(JSONToken.COMMA);
- break;
- case LITERAL_STRING:
- String stringLiteral = lexer.stringVal();
- lexer.nextToken(JSONToken.COMMA);
-
- if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) {
- JSONScanner iso8601Lexer = new JSONScanner(stringLiteral);
- if (iso8601Lexer.scanISO8601DateIfMatch()) {
- value = iso8601Lexer.getCalendar().getTime();
- } else {
- value = stringLiteral;
- }
- } else {
- value = stringLiteral;
- }
-
- break;
- case TRUE:
- value = Boolean.TRUE;
- lexer.nextToken(JSONToken.COMMA);
- break;
- case FALSE:
- value = Boolean.FALSE;
- lexer.nextToken(JSONToken.COMMA);
- break;
- case LBRACE:
- JSONObject object = new JSONObject();
- parseObject(object);
- value = object;
- break;
- case LBRACKET:
- Collection items = new JSONArray();
- parseArray(items);
- value = items;
- break;
- case NULL:
- value = null;
- lexer.nextToken(JSONToken.LITERAL_STRING);
- break;
- case RBRACKET:
- lexer.nextToken(JSONToken.COMMA);
- return;
- default:
- value = parse();
- break;
- }
-
- array.add(value);
-
- if (lexer.token() == JSONToken.COMMA) {
- lexer.nextToken(JSONToken.LITERAL_STRING);
- continue;
- }
- }
- }
-
- public Object parse() {
- final JSONLexer lexer = getLexer();
- switch (lexer.token()) {
- case LBRACKET:
- JSONArray array = new JSONArray();
- parseArray(array);
- return array;
- case LBRACE:
- JSONObject object = new JSONObject();
- parseObject(object);
- return object;
- case LITERAL_INT:
- Number intValue = lexer.integerValue();
- lexer.nextToken();
- return intValue;
- case LITERAL_FLOAT:
-
- Object value;
- if (isEnabled(Feature.UseBigDecimal)) {
- value = lexer.decimalValue();
- } else {
- value = lexer.doubleValue();
- }
- lexer.nextToken();
- return value;
- case LITERAL_STRING:
- String stringLiteral = lexer.stringVal();
- lexer.nextToken(JSONToken.COMMA);
-
- if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) {
- JSONScanner iso8601Lexer = new JSONScanner(stringLiteral);
- if (iso8601Lexer.scanISO8601DateIfMatch()) {
- return iso8601Lexer.getCalendar().getTime();
- }
- }
-
- return stringLiteral;
- case NULL:
- lexer.nextToken();
- return null;
- case TRUE:
- lexer.nextToken();
- return Boolean.TRUE;
- case FALSE:
- lexer.nextToken();
- return Boolean.FALSE;
- case NEW:
- lexer.nextToken(JSONToken.IDENTIFIER);
-
- if (lexer.token() != JSONToken.IDENTIFIER) {
- throw new JSONException("syntax error");
- }
- lexer.nextToken(JSONToken.LPAREN);
-
- accept(JSONToken.LPAREN);
- long time = ((Number) lexer.integerValue()).longValue();
- accept(JSONToken.LITERAL_INT);
-
- accept(JSONToken.RPAREN);
-
- return new Date(time);
- case EOF:
- if (lexer.isBlankInput()) {
- return null;
- }
- default:
- throw new JSONException("TODO " + JSONToken.name(lexer.token())
- + " " + lexer.stringVal());
- }
- }
-
- public void config(Feature feature, boolean state) {
- getLexer().config(feature, state);
- }
-
- public boolean isEnabled(Feature feature) {
- return getLexer().isEnabled(feature);
- }
-
- public abstract JSONLexer getLexer();
-
- public final void accept(final int token) {
- final JSONLexer lexer = getLexer();
- if (lexer.token() == token) {
- lexer.nextToken();
- } else {
- throw new JSONException("syntax error, expect "
- + JSONToken.name(token) + ", actual "
- + JSONToken.name(lexer.token()));
- }
- }
-
- public void close() {
- final JSONLexer lexer = getLexer();
-
- if (isEnabled(Feature.AutoCloseSource)) {
- if (!lexer.isEOF()) {
- throw new JSONException("not close json text, token : "
- + JSONToken.name(lexer.token()));
- }
- }
- }
-}
diff --git a/src/main/java/com/alibaba/fastjson/parser/CharTypes.java b/src/main/java/com/alibaba/fastjson/parser/CharTypes.java
deleted file mode 100644
index c3ab3df2b2..0000000000
--- a/src/main/java/com/alibaba/fastjson/parser/CharTypes.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 1999-2101 Alibaba Group.
- *
- * 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.alibaba.fastjson.parser;
-
-/**
- * @author wenshao
- */
-public final class CharTypes {
-
- public final static boolean[] firstIdentifierFlags = new boolean[256];
- static {
- for (char c = 0; c < firstIdentifierFlags.length; ++c) {
- if (c >= 'A' && c <= 'Z') {
- firstIdentifierFlags[c] = true;
- } else if (c >= 'a' && c <= 'z') {
- firstIdentifierFlags[c] = true;
- } else if (c == '_') {
- firstIdentifierFlags[c] = true;
- }
- }
- }
-
- public final static boolean[] identifierFlags = new boolean[256];
-
- static {
- for (char c = 0; c < identifierFlags.length; ++c) {
- if (c >= 'A' && c <= 'Z') {
- identifierFlags[c] = true;
- } else if (c >= 'a' && c <= 'z') {
- identifierFlags[c] = true;
- } else if (c == '_') {
- identifierFlags[c] = true;
- } else if (c >= '0' && c <= '9') {
- identifierFlags[c] = true;
- }
- }
- }
-
- public final static boolean[] specicalFlags_doubleQuotes = new boolean[((int) '\\' + 1)];
- public final static boolean[] specicalFlags_singleQuotes = new boolean[((int) '\\' + 1)];
-
- public static boolean isSpecial_doubleQuotes(char ch) {
- return ch < specicalFlags_doubleQuotes.length && specicalFlags_doubleQuotes[ch];
- }
-
- public final static char[] replaceChars = new char[((int) '\\' + 1)];
- static {
- specicalFlags_doubleQuotes['\b'] = true;
- specicalFlags_doubleQuotes['\n'] = true;
- specicalFlags_doubleQuotes['\f'] = true;
- specicalFlags_doubleQuotes['\r'] = true;
- specicalFlags_doubleQuotes['\"'] = true;
- specicalFlags_doubleQuotes['\\'] = true;
-
- specicalFlags_singleQuotes['\b'] = true;
- specicalFlags_singleQuotes['\n'] = true;
- specicalFlags_singleQuotes['\f'] = true;
- specicalFlags_singleQuotes['\r'] = true;
- specicalFlags_singleQuotes['\''] = true;
- specicalFlags_singleQuotes['\\'] = true;
-
- replaceChars['\b'] = 'b';
- replaceChars['\n'] = 'n';
- replaceChars['\f'] = 'f';
- replaceChars['\r'] = 'r';
- replaceChars['\"'] = '"';
- replaceChars['\''] = '\'';
- replaceChars['\\'] = '\\';
- replaceChars['\t'] = 't';
- }
-
-}
diff --git a/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java b/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java
index 35dc417784..cbfcac7508 100644
--- a/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java
+++ b/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java
@@ -1,372 +1,42 @@
-/*
- * Copyright 1999-2101 Alibaba Group.
- *
- * 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.alibaba.fastjson.parser;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import com.alibaba.fastjson.JSONException;
-import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer;
-import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer;
-import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
-import com.alibaba.fastjson.parser.deserializer.StringDeserializer;
-import com.alibaba.fastjson.util.TypeUtils;
-
-/**
- * @author wenshao
- */
-@SuppressWarnings("rawtypes")
-public class DefaultExtJSONParser extends DefaultJSONParser {
-
- private DefaultObjectDeserializer derializer = new DefaultObjectDeserializer();
-
- private final static Set> primitiveClasses = new HashSet>();
- static {
- primitiveClasses.add(boolean.class);
- primitiveClasses.add(byte.class);
- primitiveClasses.add(short.class);
- primitiveClasses.add(int.class);
- primitiveClasses.add(long.class);
- primitiveClasses.add(float.class);
- primitiveClasses.add(double.class);
-
- primitiveClasses.add(Boolean.class);
- primitiveClasses.add(Byte.class);
- primitiveClasses.add(Short.class);
- primitiveClasses.add(Integer.class);
- primitiveClasses.add(Long.class);
- primitiveClasses.add(Float.class);
- primitiveClasses.add(Double.class);
-
- primitiveClasses.add(BigInteger.class);
- primitiveClasses.add(BigDecimal.class);
- primitiveClasses.add(String.class);
- }
-
- public DefaultExtJSONParser(String input){
- this(input, ParserConfig.getGlobalInstance());
- }
-
- public DefaultExtJSONParser(String input, ParserConfig mapping){
- super(input, mapping);
- }
-
- public DefaultExtJSONParser(String input, ParserConfig mapping, int features){
- super(input, mapping, features);
- }
-
- public DefaultExtJSONParser(char[] input, int length, ParserConfig mapping, int features){
- super(input, length, mapping, features);
- }
-
- public ParserConfig getConfig() {
- return config;
- }
-
- public void setConfig(ParserConfig config) {
- this.config = config;
- }
-
- // compatible
- @SuppressWarnings("unchecked")
- public T parseObject(Class clazz) {
- return (T) parseObject((Type) clazz);
- }
-
- @SuppressWarnings("unchecked")
- public T parseObject(Type type) {
- if (lexer.token() == JSONToken.NULL) {
- lexer.nextToken();
- return null;
- }
-
- ObjectDeserializer derializer = config.getDeserializer(type);
-
- try {
- return (T) derializer.deserialze(this, type);
- } catch (JSONException e) {
- throw e;
- } catch (Throwable e) {
- throw new JSONException(e.getMessage(), e);
- }
- }
-
- public List parseArray(Class clazz) {
- List array = new ArrayList();
- parseArray(clazz, array);
- return array;
- }
-
- public void parseArray(Class> clazz, Collection array) {
- parseArray((Type) clazz, array);
- }
-
- @SuppressWarnings({ "unchecked" })
- public void parseArray(Type type, Collection array) {
- if (lexer.token() != JSONToken.LBRACKET) {
- throw new JSONException("exepct '[', but " + JSONToken.name(lexer.token()));
- }
-
- ObjectDeserializer deserializer = null;
- if (int.class == type) {
- deserializer = IntegerDeserializer.instance;
- lexer.nextToken(JSONToken.LITERAL_INT);
- } else if (String.class == type) {
- deserializer = StringDeserializer.instance;
- lexer.nextToken(JSONToken.LITERAL_STRING);
- } else {
- deserializer = config.getDeserializer(type);
- lexer.nextToken(deserializer.getFastMatchToken());
- }
-
- for (;;) {
- if (isEnabled(Feature.AllowArbitraryCommas)) {
- while (lexer.token() == JSONToken.COMMA) {
- lexer.nextToken();
- continue;
- }
- }
-
- if (lexer.token() == JSONToken.RBRACKET) {
- break;
- }
-
- if (int.class == type) {
- Object val = IntegerDeserializer.deserialze(this);
- array.add(val);
- } else if (String.class == type) {
- String value;
- if (lexer.token() == JSONToken.LITERAL_STRING) {
- value = lexer.stringVal();
- lexer.nextToken(JSONToken.COMMA);
- } else {
- Object obj = this.parse();
- if (obj == null) {
- value = null;
- } else {
- value = obj.toString();
- }
- }
-
- array.add(value);
- } else {
- Object val = deserializer.deserialze(this, type);
- array.add(val);
- }
-
- if (lexer.token() == JSONToken.COMMA) {
- lexer.nextToken(deserializer.getFastMatchToken());
- continue;
- }
- }
-
- lexer.nextToken(JSONToken.COMMA);
- }
-
- public Object[] parseArray(Type[] types) {
-
- if (lexer.token() != JSONToken.LBRACKET) {
- throw new JSONException("syntax error");
- }
-
- Object[] list = new Object[types.length];
- if (types.length == 0) {
- lexer.nextToken(JSONToken.RBRACKET);
-
- if (lexer.token() != JSONToken.RBRACKET) {
- throw new JSONException("syntax error");
- }
-
- lexer.nextToken(JSONToken.COMMA);
- return new Object[0];
- }
-
- lexer.nextToken(JSONToken.LITERAL_INT);
-
- for (int i = 0; i < types.length; ++i) {
- Object value;
-
- if (lexer.token() == JSONToken.NULL) {
- value = null;
- lexer.nextToken(JSONToken.COMMA);
- } else {
- Type type = types[i];
- if (type == int.class || type == Integer.class) {
- if (lexer.token() == JSONToken.LITERAL_INT) {
- value = Integer.valueOf(lexer.intValue());
- lexer.nextToken(JSONToken.COMMA);
- } else {
- value = this.parse();
- value = TypeUtils.cast(value, type, config);
- }
- } else if (type == String.class) {
- if (lexer.token() == JSONToken.LITERAL_STRING) {
- value = lexer.stringVal();
- lexer.nextToken(JSONToken.COMMA);
- } else {
- value = this.parse();
- value = TypeUtils.cast(value, type, config);
- }
- } else {
- boolean isArray = false;
- Class> componentType = null;
- if (i == types.length - 1) {
- if (type instanceof Class) {
- Class> clazz = (Class>) type;
- isArray = clazz.isArray();
- componentType = clazz.getComponentType();
- }
- }
-
- // support varArgs
- if (isArray && lexer.token() != JSONToken.LBRACKET) {
- List