diff --git a/classlib/src/main/java/org/teavm/classlib/impl/reflection/Flags.java b/classlib/src/main/java/org/teavm/classlib/impl/reflection/Flags.java index 1d61d8c99..0dfcda70f 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/reflection/Flags.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/reflection/Flags.java @@ -20,21 +20,20 @@ public final class Flags { } public static final int ABSTRACT = 1; - public static final int ANNOTATION = 2; - public static final int BRIDGE = 4; - public static final int DEPRECATED = 8; - public static final int ENUM = 16; - public static final int FINAL = 32; - public static final int INTERFACE = 64; - public static final int NATIVE = 128; - public static final int STATIC = 256; - public static final int STRICT = 512; - public static final int SUPER = 1024; + public static final int INTERFACE = 2; + public static final int FINAL = 4; + public static final int ENUM = 8; + public static final int ANNOTATION = 16; + public static final int SYNTHETIC = 32; + public static final int BRIDGE = 64; + public static final int DEPRECATED = 128; + public static final int NATIVE = 256; + public static final int STATIC = 512; + public static final int STRICT = 1024; public static final int SYNCHRONIZED = 2048; - public static final int SYNTHETIC = 4096; - public static final int TRANSIENT = 8192; - public static final int VARARGS = 16384; - public static final int VOLATILE = 32768; + public static final int TRANSIENT = 4096; + public static final int VARARGS = 8192; + public static final int VOLATILE = 16384; public static final int PACKAGE_PRIVATE = 0; public static final int PRIVATE = 1; @@ -56,31 +55,31 @@ public final class Flags { } // static - modifiers |= (flags >>> 5) & 8; + modifiers |= (flags >>> 6) & 8; // final - modifiers |= (flags >>> 1) & 16; + modifiers |= (flags << 2) & 16; // synchronized - modifiers |= (flags >>> 5) & 32; + modifiers |= (flags >>> 6) & 32; // volatile - modifiers |= (flags >>> 9) & 64; + modifiers |= (flags >>> 8) & 64; // transient - modifiers |= (flags >>> 6) & 128; + modifiers |= (flags >>> 5) & 128; // native - modifiers |= (flags << 1) & 256; + modifiers |= flags & 256; // interface - modifiers |= (flags << 3) & 512; + modifiers |= (flags << 8) & 512; // abstract modifiers |= (flags << 10) & 1024; // strict - modifiers |= (flags << 2) & 2048; + modifiers |= (flags << 1) & 2048; return modifiers; } diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java index 5ef0525c5..8dff9c424 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java @@ -20,6 +20,7 @@ import com.carrotsearch.hppc.ObjectIntMap; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -741,7 +742,12 @@ public class Renderer implements RenderingManager { return minifying ? RenderingUtil.indexToId(index) : "var_" + index; } - private void renderVirtualDeclarations(Iterable methods) throws NamingException, IOException { + private void renderVirtualDeclarations(Collection methods) throws NamingException, IOException { + if (methods.stream().noneMatch(this::isVirtual)) { + writer.append('0'); + return; + } + writer.append("["); boolean first = true; for (MethodReference method : methods) { diff --git a/core/src/main/java/org/teavm/model/ElementModifier.java b/core/src/main/java/org/teavm/model/ElementModifier.java index 341975532..4f51e37fa 100644 --- a/core/src/main/java/org/teavm/model/ElementModifier.java +++ b/core/src/main/java/org/teavm/model/ElementModifier.java @@ -25,18 +25,17 @@ import java.util.Set; */ public enum ElementModifier { ABSTRACT, + INTERFACE, + FINAL, + ENUM, ANNOTATION, + SYNTHETIC, BRIDGE, DEPRECATED, - ENUM, - FINAL, - INTERFACE, NATIVE, STATIC, STRICT, - SUPER, SYNCHRONIZED, - SYNTHETIC, TRANSIENT, VARARGS, VOLATILE; diff --git a/core/src/main/java/org/teavm/parsing/Parser.java b/core/src/main/java/org/teavm/parsing/Parser.java index fb29f3440..be89d9779 100644 --- a/core/src/main/java/org/teavm/parsing/Parser.java +++ b/core/src/main/java/org/teavm/parsing/Parser.java @@ -57,6 +57,9 @@ import org.teavm.model.util.PhiUpdater; import org.teavm.model.util.ProgramUtils; public class Parser { + private static final int DECL_CLASS = 0; + private static final int DECL_METHOD = 1; + private static final int DECL_FIELD = 2; private ReferenceCache referenceCache; public Parser(ReferenceCache referenceCache) { @@ -72,7 +75,7 @@ public class Parser { node = nodeWithoutJsr; ValueType[] signature = MethodDescriptor.parseSignature(node.desc); MethodHolder method = new MethodHolder(node.name, signature); - parseModifiers(node.access, method); + parseModifiers(node.access, method, DECL_METHOD); ProgramParser programParser = new ProgramParser(referenceCache); programParser.setFileName(fileName); @@ -227,7 +230,7 @@ public class Parser { public ClassHolder parseClass(ClassNode node) { ClassHolder cls = new ClassHolder(node.name.replace('/', '.')); - parseModifiers(node.access, cls); + parseModifiers(node.access, cls, DECL_CLASS); if (node.superName != null) { cls.setParent(node.superName.replace('/', '.')); } @@ -263,12 +266,12 @@ public class Parser { FieldHolder field = new FieldHolder(node.name); field.setType(ValueType.parse(node.desc)); field.setInitialValue(node.value); - parseModifiers(node.access, field); + parseModifiers(node.access, field, DECL_FIELD); parseAnnotations(field.getAnnotations(), node.visibleAnnotations, node.invisibleAnnotations); return field; } - public void parseModifiers(int access, ElementHolder member) { + public void parseModifiers(int access, ElementHolder member, int type) { if ((access & Opcodes.ACC_PRIVATE) != 0) { member.setLevel(AccessLevel.PRIVATE); } else if ((access & Opcodes.ACC_PROTECTED) != 0) { @@ -284,7 +287,9 @@ public class Parser { member.getModifiers().add(ElementModifier.ANNOTATION); } if ((access & Opcodes.ACC_BRIDGE) != 0) { - member.getModifiers().add(ElementModifier.BRIDGE); + if (type == DECL_METHOD) { + member.getModifiers().add(ElementModifier.BRIDGE); + } } if ((access & Opcodes.ACC_DEPRECATED) != 0) { member.getModifiers().add(ElementModifier.DEPRECATED); @@ -307,23 +312,28 @@ public class Parser { if ((access & Opcodes.ACC_STRICT) != 0) { member.getModifiers().add(ElementModifier.STRICT); } - if ((access & Opcodes.ACC_SUPER) != 0) { - member.getModifiers().add(ElementModifier.SUPER); - } if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { - member.getModifiers().add(ElementModifier.SYNCHRONIZED); + if (type == DECL_METHOD) { + member.getModifiers().add(ElementModifier.SYNCHRONIZED); + } } if ((access & Opcodes.ACC_SYNTHETIC) != 0) { member.getModifiers().add(ElementModifier.SYNTHETIC); } if ((access & Opcodes.ACC_TRANSIENT) != 0) { - member.getModifiers().add(ElementModifier.TRANSIENT); + if (type == DECL_FIELD) { + member.getModifiers().add(ElementModifier.TRANSIENT); + } } if ((access & Opcodes.ACC_VARARGS) != 0) { - member.getModifiers().add(ElementModifier.VARARGS); + if (type == DECL_FIELD) { + member.getModifiers().add(ElementModifier.VARARGS); + } } if ((access & Opcodes.ACC_VOLATILE) != 0) { - member.getModifiers().add(ElementModifier.VOLATILE); + if (type == DECL_FIELD) { + member.getModifiers().add(ElementModifier.VOLATILE); + } } } diff --git a/core/src/main/resources/org/teavm/backend/javascript/runtime.js b/core/src/main/resources/org/teavm/backend/javascript/runtime.js index 58a9642ff..80c188e6b 100644 --- a/core/src/main/resources/org/teavm/backend/javascript/runtime.js +++ b/core/src/main/resources/org/teavm/backend/javascript/runtime.js @@ -463,7 +463,7 @@ function $rt_metadata(data) { cls.prototype = {}; } var flags = data[i++]; - m.enum = (flags & 16) !== 0; + m.enum = (flags & 8) !== 0; m.flags = flags; m.primitive = false; m.item = null; @@ -476,14 +476,16 @@ function $rt_metadata(data) { cls.$clinit = clinit !== 0 ? clinit : function() {}; var virtualMethods = data[i++]; - for (j = 0; j < virtualMethods.length; j += 2) { - var name = virtualMethods[j]; - var func = virtualMethods[j + 1]; - if (typeof name === 'string') { - name = [name]; - } - for (var k = 0; k < name.length; ++k) { - cls.prototype[name[k]] = func; + if (virtualMethods !== 0) { + for (j = 0; j < virtualMethods.length; j += 2) { + var name = virtualMethods[j]; + var func = virtualMethods[j + 1]; + if (typeof name === 'string') { + name = [name]; + } + for (var k = 0; k < name.length; ++k) { + cls.prototype[name[k]] = func; + } } }