Fix various issues reported by PVS Studio and LGTM

This commit is contained in:
Alexey Andreev 2019-10-31 14:36:37 +03:00
parent beef9e09ca
commit fb78377db8
65 changed files with 124 additions and 185 deletions

View File

@ -49,7 +49,7 @@ public final class IntegerUtil {
int sz = (Long.SIZE - Long.numberOfLeadingZeros(value) + radixLog2 - 1) / radixLog2; int sz = (Long.SIZE - Long.numberOfLeadingZeros(value) + radixLog2 - 1) / radixLog2;
char[] chars = new char[sz]; char[] chars = new char[sz];
long pos = (sz - 1) * radixLog2; int pos = (sz - 1) * radixLog2;
int target = 0; int target = 0;
while (pos >= 0) { while (pos >= 0) {
chars[target++] = Character.forDigit((int) (value >>> pos) & mask, radix); chars[target++] = Character.forDigit((int) (value >>> pos) & mask, radix);

View File

@ -20,20 +20,22 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.platform.metadata.*; import org.teavm.platform.metadata.MetadataGenerator;
import org.teavm.platform.metadata.MetadataGeneratorContext;
import org.teavm.platform.metadata.Resource;
import org.teavm.platform.metadata.ResourceMap;
import org.teavm.platform.metadata.StringResource;
public class CountriesGenerator implements MetadataGenerator { public class CountriesGenerator implements MetadataGenerator {
@Override @Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
try (InputStream input = new BufferedInputStream(context.getClassLoader().getResourceAsStream( try (InputStream input = new BufferedInputStream(context.getClassLoader().getResourceAsStream(
"org/teavm/classlib/impl/currency/iso3166.csv"))) { "org/teavm/classlib/impl/currency/iso3166.csv"))) {
if (input == null) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
throw new AssertionError("ISO 3166 table was not found");
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"))) {
return readIso3166(context, reader); return readIso3166(context, reader);
} }
} catch (IOException e) { } catch (IOException e) {
@ -77,7 +79,7 @@ public class CountriesGenerator implements MetadataGenerator {
+ ": closing quote not found"); + ": closing quote not found");
} }
if (next + 1 == row.length() || row.charAt(next + 1) != '"') { if (next + 1 == row.length() || row.charAt(next + 1) != '"') {
sb.append(row.substring(index, next)); sb.append(row, index, next);
index = next + 1; index = next + 1;
break; break;
} }
@ -100,6 +102,6 @@ public class CountriesGenerator implements MetadataGenerator {
} }
} }
} }
return values.toArray(new String[values.size()]); return values.toArray(new String[0]);
} }
} }

View File

@ -105,6 +105,9 @@ public class CLDRReader {
readLikelySubtags(input); readLikelySubtags(input);
} }
int objectIndex = entry.getName().lastIndexOf('/'); int objectIndex = entry.getName().lastIndexOf('/');
if (objectIndex < 0) {
continue;
}
String objectName = entry.getName().substring(objectIndex + 1); String objectName = entry.getName().substring(objectIndex + 1);
String localeName = entry.getName().substring(0, objectIndex); String localeName = entry.getName().substring(0, objectIndex);
if (localeName.startsWith("/")) { if (localeName.startsWith("/")) {

View File

@ -89,7 +89,7 @@ public final class UnicodeHelper {
byte b = bytes[i]; byte b = bytes[i];
if (i < bytes.length - 1 && b == bytes[i + 1]) { if (i < bytes.length - 1 && b == bytes[i + 1]) {
int count = 0; int count = 0;
while (count < 16384 && i < bytes.length && bytes[i + count] == b) { while (count < 16384 && bytes[i + count] == b) {
++count; ++count;
} }
i += count; i += count;

View File

@ -187,7 +187,7 @@ public class TBufferedInputStream extends TFilterInputStream {
} }
} }
read = count - pos >= required ? required : count - pos; read = Math.min(count - pos, required);
System.arraycopy(localBuf, pos, buffer, offset, read); System.arraycopy(localBuf, pos, buffer, offset, read);
pos += read; pos += read;
} }

View File

@ -563,7 +563,6 @@ public class TFile implements Serializable, Comparable<TFile> {
} }
private static String fixSlashes(String origPath) { private static String fixSlashes(String origPath) {
int uncIndex = 0;
int length = origPath.length(); int length = origPath.length();
int newLength = 0; int newLength = 0;
@ -579,7 +578,7 @@ public class TFile implements Serializable, Comparable<TFile> {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char pathChar = newPath[i]; char pathChar = newPath[i];
if (pathChar == '/' || pathChar == separatorChar) { if (pathChar == '/' || pathChar == separatorChar) {
if (!foundSlash || i == uncIndex) { if (!foundSlash || i == 0) {
newPath[newLength++] = separatorChar; newPath[newLength++] = separatorChar;
foundSlash = true; foundSlash = true;
} }
@ -588,7 +587,7 @@ public class TFile implements Serializable, Comparable<TFile> {
foundSlash = false; foundSlash = false;
} }
} }
if (foundSlash && (newLength > uncIndex + 1 || newLength == 2 && newPath[0] != '/')) { if (foundSlash && (newLength > 1 || newPath[0] != '/')) {
newLength--; newLength--;
} }

View File

@ -229,7 +229,6 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
int intPart = 1; int intPart = 1;
int sz = 1; // Decimal point always included int sz = 1; // Decimal point always included
if (negative) { if (negative) {
negative = true;
++sz; // including '-' sign of mantissa ++sz; // including '-' sign of mantissa
} }
@ -246,7 +245,7 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
intPart = exp + 1; intPart = exp + 1;
digits = Math.max(digits, intPart + 1); digits = Math.max(digits, intPart + 1);
exp = 0; exp = 0;
} else if (exp < 0) { } else {
mantissa /= Constants.intPowersOfTen[-exp]; mantissa /= Constants.intPowersOfTen[-exp];
digits -= exp; digits -= exp;
exp = 0; exp = 0;
@ -373,7 +372,7 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
intPart = exp + 1; intPart = exp + 1;
digits = Math.max(digits, intPart + 1); digits = Math.max(digits, intPart + 1);
exp = 0; exp = 0;
} else if (exp < 0) { } else {
mantissa /= Constants.longPowersOfTen[-exp]; mantissa /= Constants.longPowersOfTen[-exp];
digits -= exp; digits -= exp;
exp = 0; exp = 0;

View File

@ -175,9 +175,7 @@ public class TObject {
if (monitor.enteringThreads != null && !monitor.enteringThreads.isEmpty()) { if (monitor.enteringThreads != null && !monitor.enteringThreads.isEmpty()) {
PlatformQueue<PlatformRunnable> enteringThreads = monitor.enteringThreads; PlatformQueue<PlatformRunnable> enteringThreads = monitor.enteringThreads;
PlatformRunnable r = enteringThreads.remove(); PlatformRunnable r = enteringThreads.remove();
if (enteringThreads == null) { monitor.enteringThreads = null;
monitor.enteringThreads = null;
}
r.run(); r.run();
} }
} }

View File

@ -287,7 +287,6 @@ class TBitLevel {
} }
if (count == 0) { if (count == 0) {
System.arraycopy(source, intCount, result, 0, resultLen); System.arraycopy(source, intCount, result, 0, resultLen);
i = resultLen;
} else { } else {
int leftShiftCount = 32 - count; int leftShiftCount = 32 - count;
@ -336,7 +335,6 @@ class TBitLevel {
for (i = intCount + 1; i < firstNonZeroDigit; i++) { for (i = intCount + 1; i < firstNonZeroDigit; i++) {
resDigits[i] = -1; resDigits[i] = -1;
} }
resDigits[i] = resDigits[i]--;
} else { } else {
i = intCount; i = intCount;
resDigits[i] = -((-resDigits[intCount]) ^ bitNumber); resDigits[i] = -((-resDigits[intCount]) ^ bitNumber);

View File

@ -496,7 +496,7 @@ class TLogical {
int[] resDigits = new int[resLength]; int[] resDigits = new int[resLength];
int i = Math.min(longer.getFirstNonzeroDigit(), shorter.getFirstNonzeroDigit()); int i = Math.min(longer.getFirstNonzeroDigit(), shorter.getFirstNonzeroDigit());
for (i = 0; i < shorter.numberLength; i++) { for (; i < shorter.numberLength; i++) {
resDigits[i] = longer.digits[i] | shorter.digits[i]; resDigits[i] = longer.digits[i] | shorter.digits[i];
} }
for (; i < resLength; i++) { for (; i < resLength; i++) {

View File

@ -98,9 +98,7 @@ public abstract class TURLStreamHandler {
} else { } else {
host = parseString.substring(hostIdx, portIdx); host = parseString.substring(hostIdx, portIdx);
String portString = parseString.substring(portIdx + 1, hostEnd); String portString = parseString.substring(portIdx + 1, hostEnd);
if (portString.length() == 0) { if (!portString.isEmpty()) {
port = -1;
} else {
port = Integer.parseInt(portString); port = Integer.parseInt(portString);
} }
} }
@ -189,7 +187,7 @@ public abstract class TURLStreamHandler {
if (dirIndex != 0) { if (dirIndex != 0) {
path = path.substring(0, path.lastIndexOf('/', dirIndex - 1)) + path.substring(dirIndex + 3); path = path.substring(0, path.lastIndexOf('/', dirIndex - 1)) + path.substring(dirIndex + 3);
} else { } else {
path = path.substring(dirIndex + 3); path = path.substring(3);
} }
} }

View File

@ -60,7 +60,7 @@ public abstract class TCharset implements Comparable<TCharset> {
} }
private static boolean isValidCharsetStart(char c) { private static boolean isValidCharsetStart(char c) {
return c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' || c <= 'Z'; return c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
} }
public static TCharset forName(String charsetName) { public static TCharset forName(String charsetName) {

View File

@ -63,7 +63,7 @@ public class TMessageFormat extends TFormat {
if (ch == '}' || ch == ',') { if (ch == '}' || ch == ',') {
break; break;
} }
if (ch < '0' && ch > '9') { if (ch < '0' || ch > '9') {
throw new IllegalArgumentException("Invalid argument number"); throw new IllegalArgumentException("Invalid argument number");
} }
arg = arg * 10 + (ch - '0'); arg = arg * 10 + (ch - '0');

View File

@ -216,7 +216,7 @@ public class TEnumMap<K extends Enum<K>, V> extends AbstractMap<K, V> implements
} }
int index = ((Enum<?>) o).ordinal(); int index = ((Enum<?>) o).ordinal();
if (provided[index]) { if (provided[index]) {
provided[index] = true; provided[index] = false;
data[index] = null; data[index] = null;
size--; size--;
return true; return true;

View File

@ -297,7 +297,7 @@ public final class TFormatter implements Closeable, Flushable {
formatGivenString(upperCase, "null"); formatGivenString(upperCase, "null");
return; return;
} else { } else {
throw new IllegalFormatConversionException(specifier, arg != null ? arg.getClass() : null); throw new IllegalFormatConversionException(specifier, arg.getClass());
} }
formatGivenString(upperCase, new String(Character.toChars(c))); formatGivenString(upperCase, new String(Character.toChars(c)));

View File

@ -917,7 +917,6 @@ public class TGregorianCalendar extends TCalendar {
lastYearSkew = 0; lastYearSkew = 0;
currentYearSkew = julianSkew; currentYearSkew = julianSkew;
} }
isCached = false;
} }
@Override @Override

View File

@ -291,7 +291,7 @@ public class TProperties extends THashtable<Object, Object> {
} }
break; break;
} }
if (nextChar < 256 && Character.isWhitespace(nextChar)) { if (Character.isWhitespace(nextChar)) {
if (mode == CONTINUE) { if (mode == CONTINUE) {
mode = IGNORE; mode = IGNORE;
} }

View File

@ -329,8 +329,8 @@ public abstract class TTimeZone implements Serializable, Cloneable {
return (TTimeZone) GMT.clone(); return (TTimeZone) GMT.clone();
} }
raw += minute * 60000; raw += minute * 60000;
} else if (hour >= 30 || index > 6) { } else if (index > 6) {
raw = (hour / 100 * 3600000) + (hour % 100 * 60000); raw = hour * 60000;
} }
if (sign == '-') { if (sign == '-') {
raw = -raw; raw = -raw;

View File

@ -23,7 +23,7 @@ import org.teavm.jso.browser.Window;
public class TTimer extends TObject { public class TTimer extends TObject {
TSet<TTimerTask> tasks = new THashSet<>(); TSet<TTimerTask> tasks = new THashSet<>();
private boolean cancelled; private volatile boolean cancelled;
public TTimer() { public TTimer() {
} }

View File

@ -39,7 +39,7 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
if (capacity < 0) { if (capacity < 0) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
elementData = newElementArray(capacity); elementData = new Object[capacity];
elementCount = 0; elementCount = 0;
this.capacityIncrement = capacityIncrement; this.capacityIncrement = capacityIncrement;
} }
@ -52,11 +52,6 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
} }
} }
@SuppressWarnings("unchecked")
private E[] newElementArray(int size) {
return (E[]) new Object[size];
}
@Override @Override
public void add(int location, E object) { public void add(int location, E object) {
insertElementAt(object, location); insertElementAt(object, location);
@ -179,7 +174,7 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
public synchronized void ensureCapacity(int minimumCapacity) { public synchronized void ensureCapacity(int minimumCapacity) {
if (elementData.length < minimumCapacity) { if (elementData.length < minimumCapacity) {
int next = (capacityIncrement <= 0 ? elementData.length : capacityIncrement) + elementData.length; int next = (capacityIncrement <= 0 ? elementData.length : capacityIncrement) + elementData.length;
grow(minimumCapacity > next ? minimumCapacity : next); grow(Math.max(minimumCapacity, next));
} }
} }
@ -222,7 +217,7 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
} }
private void grow(int newCapacity) { private void grow(int newCapacity) {
E[] newData = newElementArray(newCapacity); Object[] newData = new Object[newCapacity];
// Assumes elementCount is <= newCapacity // Assumes elementCount is <= newCapacity
assert elementCount <= newCapacity; assert elementCount <= newCapacity;
System.arraycopy(elementData, 0, newData, 0, elementCount); System.arraycopy(elementData, 0, newData, 0, elementCount);
@ -243,20 +238,20 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
adding = capacityIncrement; adding = capacityIncrement;
} }
E[] newData = newElementArray(elementData.length + adding); Object[] newData = new Object[elementData.length + adding];
System.arraycopy(elementData, 0, newData, 0, elementCount); System.arraycopy(elementData, 0, newData, 0, elementCount);
elementData = newData; elementData = newData;
} }
private void growBy(int required) { private void growBy(int required) {
int adding = 0; int adding;
if (capacityIncrement <= 0) { if (capacityIncrement <= 0) {
adding = elementData.length; adding = elementData.length;
if (adding == 0) { if (adding == 0) {
adding = required; adding = required;
} }
while (adding < required) { while (adding < required) {
adding += adding; adding *= 2;
} }
} else { } else {
adding = (required / capacityIncrement) * capacityIncrement; adding = (required / capacityIncrement) * capacityIncrement;
@ -264,7 +259,7 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
adding += capacityIncrement; adding += capacityIncrement;
} }
} }
E[] newData = newElementArray(elementData.length + adding); Object[] newData = new Object[elementData.length + adding];
System.arraycopy(elementData, 0, newData, 0, elementCount); System.arraycopy(elementData, 0, newData, 0, elementCount);
elementData = newData; elementData = newData;
} }

View File

@ -414,17 +414,15 @@ public class TArrayBlockingQueue<E> extends TAbstractQueue<E> implements TBlocki
if (waitHandlers == null) { if (waitHandlers == null) {
return; return;
} }
if (waitHandlers != null) { while (!waitHandlers.isEmpty()) {
while (!waitHandlers.isEmpty()) { WaitHandler handler = waitHandlers.remove();
WaitHandler handler = waitHandlers.remove(); if (PlatformDetector.isLowLevel()) {
if (PlatformDetector.isLowLevel()) { EventQueue.offer(handler::changed);
EventQueue.offer(handler::changed); } else {
} else { Platform.postpone(handler::changed);
Platform.postpone(handler::changed);
}
} }
waitHandlers = null;
} }
waitHandlers = null;
} }
@Async @Async

View File

@ -19,9 +19,10 @@ import java.io.Serializable;
import java.util.function.IntBinaryOperator; import java.util.function.IntBinaryOperator;
import java.util.function.IntUnaryOperator; import java.util.function.IntUnaryOperator;
@SuppressWarnings("NonAtomicOperationOnVolatileField")
public class TAtomicInteger extends Number implements Serializable { public class TAtomicInteger extends Number implements Serializable {
private int value; private int value;
private int version; private volatile int version;
public TAtomicInteger() { public TAtomicInteger() {
} }

View File

@ -19,9 +19,10 @@ import java.io.Serializable;
import java.util.function.LongBinaryOperator; import java.util.function.LongBinaryOperator;
import java.util.function.LongUnaryOperator; import java.util.function.LongUnaryOperator;
@SuppressWarnings("NonAtomicOperationOnVolatileField")
public class TAtomicLong extends Number implements Serializable { public class TAtomicLong extends Number implements Serializable {
private long value; private long value;
private int version; private volatile int version;
public TAtomicLong() { public TAtomicLong() {
} }

View File

@ -120,7 +120,6 @@ class TInitManifest {
} }
private void readName() throws IOException { private void readName() throws IOException {
int i = 0;
int mark = pos; int mark = pos;
while (pos < buf.length) { while (pos < buf.length) {
@ -142,9 +141,6 @@ class TInitManifest {
throw new IOException(); throw new IOException();
} }
} }
if (i > 0) {
throw new IOException();
}
} }
private void readValue() throws IOException { private void readValue() throws IOException {

View File

@ -95,7 +95,7 @@ public class TLogger {
break; break;
} }
if (message.charAt(next) != '}') { if (message.charAt(next) != '}') {
sb.append(message.substring(index, next)); sb.append(message, index, next);
index = next; index = next;
continue; continue;
} }

View File

@ -92,7 +92,7 @@ class TDotQuantifierSet extends TQuantifierSet {
nextSearch = strLength; nextSearch = strLength;
} }
nextSearch = next.findBack(res, nextSearch, testString, matchResult); nextSearch = next.findBack(res, nextSearch, testString, matchResult);
res = (res < nextSearch) ? nextSearch : res; res = Math.max(res, nextSearch);
} else { } else {
return -1; return -1;
} }

View File

@ -123,13 +123,12 @@ class TSupplRangeSet extends TJointSet {
@Override @Override
public int matches(int stringIndex, CharSequence testString, TMatchResultImpl matchResult) { public int matches(int stringIndex, CharSequence testString, TMatchResultImpl matchResult) {
int strLength = matchResult.getRightBound(); int strLength = matchResult.getRightBound();
int offset = -1;
if (stringIndex < strLength) { if (stringIndex < strLength) {
char high = testString.charAt(stringIndex++); char high = testString.charAt(stringIndex++);
if (contains(high)) { if (contains(high)) {
offset = next.matches(stringIndex, testString, matchResult); int offset = next.matches(stringIndex, testString, matchResult);
if (offset > 0) { if (offset > 0) {
return offset; return offset;
} }

View File

@ -81,7 +81,7 @@ public class TInflaterInputStream extends FilterInputStream {
} }
// avoid int overflow, check null buffer // avoid int overflow, check null buffer
if (off > buffer.length || nbytes < 0 || off < 0 || buffer.length - off < nbytes) { if (off > buffer.length || buffer.length - off < nbytes) {
throw new ArrayIndexOutOfBoundsException(); throw new ArrayIndexOutOfBoundsException();
} }

View File

@ -342,10 +342,7 @@ class StatementGenerator implements InstructionVisitor {
conditions[i] = conditionList.get(i); conditions[i] = conditionList.get(i);
} }
clause.setConditions(conditions); clause.setConditions(conditions);
Statement jumpStmt = generateJumpStatement(stmt, target); clause.getBody().add(generateJumpStatement(stmt, target));
if (jumpStmt != null) {
clause.getBody().add(jumpStmt);
}
stmt.getClauses().add(clause); stmt.getClauses().add(clause);
} }
Statement breakStmt = generateJumpStatement(insn.getDefaultTarget()); Statement breakStmt = generateJumpStatement(insn.getDefaultTarget());

View File

@ -741,20 +741,22 @@ public class ClassGenerator {
break; break;
} }
simpleName = cls.getSimpleName(); if (cls != null) {
simpleName = cls.getSimpleName();
if (cls.getDeclaringClassName() != null if (cls.getDeclaringClassName() != null
&& context.getDependencies().getClass(cls.getDeclaringClassName()) != null) { && context.getDependencies().getClass(cls.getDeclaringClassName()) != null) {
declaringClass = "(TeaVM_Class*) &" + context.getNames().forClassInstance( declaringClass = "(TeaVM_Class*) &" + context.getNames().forClassInstance(
ValueType.object(cls.getDeclaringClassName())); ValueType.object(cls.getDeclaringClassName()));
includes.includeClass(cls.getDeclaringClassName()); includes.includeClass(cls.getDeclaringClassName());
} }
if (cls.getOwnerName() != null if (cls.getOwnerName() != null
&& context.getDependencies().getClass(cls.getOwnerName()) != null) { && context.getDependencies().getClass(cls.getOwnerName()) != null) {
enclosingClass = "(TeaVM_Class*) &" + context.getNames().forClassInstance( enclosingClass = "(TeaVM_Class*) &" + context.getNames().forClassInstance(
ValueType.object(cls.getOwnerName())); ValueType.object(cls.getOwnerName()));
includes.includeClass(cls.getOwnerName()); includes.includeClass(cls.getOwnerName());
}
} }
} else if (type instanceof ValueType.Array) { } else if (type instanceof ValueType.Array) {

View File

@ -42,7 +42,6 @@ public class CodeGenerator {
this.writer = writer; this.writer = writer;
this.names = context.getNames(); this.names = context.getNames();
this.includes = includes; this.includes = includes;
this.classContext = classContext;
} }
public ClassGenerationContext getClassContext() { public ClassGenerationContext getClassContext() {

View File

@ -178,7 +178,7 @@ public class AddressIntrinsic implements Intrinsic {
context.writer().print(" * sizeof("); context.writer().print(" * sizeof(");
if (className != null) { if (className != null) {
ClassReader cls = className != null ? context.classes().get(className) : null; ClassReader cls = context.classes().get(className);
CodeGeneratorUtil.printClassReference(context.writer(), context.includes(), CodeGeneratorUtil.printClassReference(context.writer(), context.includes(),
context.names(), cls, className); context.names(), cls, className);
} else { } else {

View File

@ -156,11 +156,9 @@ public class DefaultNamingStrategy implements NamingStrategy {
if (clsReader == null) { if (clsReader == null) {
break; break;
} }
if (clsReader != null) { FieldReader fieldReader = clsReader.getField(fieldRef.getFieldName());
FieldReader fieldReader = clsReader.getField(fieldRef.getFieldName()); if (fieldReader != null) {
if (fieldReader != null) { return fieldReader.getReference();
return fieldReader.getReference();
}
} }
cls = clsReader.getParent(); cls = clsReader.getParent();
} }

View File

@ -984,16 +984,14 @@ public class Renderer implements RenderingManager {
} }
variableNames.add(context.pointerName()); variableNames.add(context.pointerName());
variableNames.add(context.tempVarName()); variableNames.add(context.tempVarName());
if (!variableNames.isEmpty()) { writer.append("var ");
writer.append("var "); for (int i = 0; i < variableNames.size(); ++i) {
for (int i = 0; i < variableNames.size(); ++i) { if (i > 0) {
if (i > 0) { writer.append(",").ws();
writer.append(",").ws();
}
writer.append(variableNames.get(i));
} }
writer.append(";").softNewLine(); writer.append(variableNames.get(i));
} }
writer.append(";").softNewLine();
int firstToSave = 0; int firstToSave = 0;
if (methodNode.getModifiers().contains(ElementModifier.STATIC)) { if (methodNode.getModifiers().contains(ElementModifier.STATIC)) {

View File

@ -17,7 +17,6 @@ package org.teavm.backend.javascript.rendering;
import org.mozilla.javascript.Node; import org.mozilla.javascript.Node;
import org.mozilla.javascript.ast.AstNode; import org.mozilla.javascript.ast.AstNode;
import org.mozilla.javascript.ast.AstRoot;
import org.mozilla.javascript.ast.Block; import org.mozilla.javascript.ast.Block;
import org.mozilla.javascript.ast.ExpressionStatement; import org.mozilla.javascript.ast.ExpressionStatement;
import org.mozilla.javascript.ast.NodeVisitor; import org.mozilla.javascript.ast.NodeVisitor;
@ -27,7 +26,7 @@ import org.mozilla.javascript.ast.StringLiteral;
public class StringConstantElimination implements NodeVisitor { public class StringConstantElimination implements NodeVisitor {
@Override @Override
public boolean visit(AstNode astNode) { public boolean visit(AstNode astNode) {
if (astNode instanceof Block || astNode instanceof Scope || astNode instanceof AstRoot) { if (astNode instanceof Block || astNode instanceof Scope) {
handle(astNode); handle(astNode);
} }
return true; return true;

View File

@ -803,9 +803,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
block.getBody().add(new WasmStoreInt32(4, new WasmInt32Constant(index), initFlag, block.getBody().add(new WasmStoreInt32(4, new WasmInt32Constant(index), initFlag,
WasmInt32Subtype.INT32)); WasmInt32Subtype.INT32));
if (method != null) { block.getBody().add(new WasmCall(classGenerator.names.forMethod(method.getReference())));
block.getBody().add(new WasmCall(classGenerator.names.forMethod(method.getReference())));
}
if (controller.wasCancelled()) { if (controller.wasCancelled()) {
break; break;

View File

@ -84,7 +84,7 @@ public class DisjointSet {
parent[b] = a; parent[b] = a;
setSize[a] += setSize[b]; setSize[a] += setSize[b];
return a; return a;
} else if (rank[b] < rank[a]) { } else if (rank[b] > rank[a]) {
parent[a] = b; parent[a] = b;
setSize[b] += setSize[a]; setSize[b] += setSize[a];
return b; return b;

View File

@ -80,7 +80,7 @@ public class GraphIndexer {
case VISITING: case VISITING:
state[node] = VISITED; state[node] = VISITED;
for (int succ : graph.outgoingEdges(node)) { for (int succ : graph.outgoingEdges(node)) {
if (state[node] == VISITED) { if (state[succ] == VISITED) {
weights[node] += weights[succ]; weights[node] += weights[succ];
} }
} }

View File

@ -26,7 +26,6 @@ public class Promise<T> {
public static final Promise<Void> VOID = Promise.of(null); public static final Promise<Void> VOID = Promise.of(null);
private T value; private T value;
private Promise<T> promise;
private Throwable error; private Throwable error;
private State state = State.PENDING; private State state = State.PENDING;
private List<Then<T>> thenList; private List<Then<T>> thenList;
@ -81,7 +80,6 @@ public class Promise<T> {
boolean error; boolean error;
AllVoidFunction(int count) { AllVoidFunction(int count) {
this.result = result;
this.count = count; this.count = count;
} }
@ -109,7 +107,6 @@ public class Promise<T> {
boolean error; boolean error;
AllFunction(int count) { AllFunction(int count) {
this.result = result;
this.count = count; this.count = count;
list.addAll(Collections.nCopies(count, null)); list.addAll(Collections.nCopies(count, null));
} }
@ -124,7 +121,7 @@ public class Promise<T> {
} }
return null; return null;
}; };
}; }
Function<Throwable, Void> catchF = e -> { Function<Throwable, Void> catchF = e -> {
if (!error) { if (!error) {

View File

@ -324,8 +324,10 @@ public class Debugger {
loc = null; loc = null;
} }
boolean empty = loc == null || (loc.getFileName() == null && loc.getLine() < 0); boolean empty = loc == null || (loc.getFileName() == null && loc.getLine() < 0);
MethodReference method = !empty ? debugInformation.getMethodAt(jsFrame.getLocation().getLine(), MethodReference method = !empty && debugInformation != null
jsFrame.getLocation().getColumn()) : null; ? debugInformation.getMethodAt(jsFrame.getLocation().getLine(),
jsFrame.getLocation().getColumn())
: null;
if (!empty || !wasEmpty) { if (!empty || !wasEmpty) {
frames.add(new CallFrame(this, jsFrame, loc, method, debugInformation)); frames.add(new CallFrame(this, jsFrame, loc, method, debugInformation));
} }

View File

@ -119,18 +119,12 @@ public class Value {
return vars; return vars;
} }
public boolean hasInnerStructure() { public Promise<Boolean> hasInnerStructure() {
if (getType().equals("long")) { return getType().then(value -> !value.equals("long") && jsValue.hasInnerStructure());
return false;
}
return jsValue.hasInnerStructure();
} }
public String getInstanceId() { public Promise<String> getInstanceId() {
if (getType().equals("long")) { return getType().then(value -> value.equals("long") ? null : jsValue.getInstanceId());
return null;
}
return jsValue.getInstanceId();
} }
public JavaScriptValue getOriginalValue() { public JavaScriptValue getOriginalValue() {

View File

@ -94,10 +94,8 @@ class DefaultCallGraphNode implements CallGraphNode {
callee.addCaller(singleCallSite); callee.addCaller(singleCallSite);
return singleCallSite; return singleCallSite;
} }
if (singleCallSite != null) { if (singleCallSite.singleCalledMethod.getMethod().equals(method)) {
if (singleCallSite.singleCalledMethod.getMethod().equals(method)) { return singleCallSite;
return singleCallSite;
}
} }
callSiteMap = new LinkedHashMap<>(); callSiteMap = new LinkedHashMap<>();
callSites = new ArrayList<>(); callSites = new ArrayList<>();

View File

@ -287,7 +287,9 @@ class DependencyGraphBuilder {
} }
MethodDependency cloneDep = getAnalyzer().linkMethod(CLONE_METHOD); MethodDependency cloneDep = getAnalyzer().linkMethod(CLONE_METHOD);
cloneDep.addLocation(getCallLocation()); cloneDep.addLocation(getCallLocation());
arrayNode.connect(cloneDep.getVariable(0)); if (arrayNode != null) {
arrayNode.connect(cloneDep.getVariable(0));
}
cloneDep.use(); cloneDep.use();
} }

View File

@ -384,7 +384,7 @@ public class BasicBlock implements BasicBlockReader, Iterable<Instruction> {
@Override @Override
public TryCatchBlock set(int index, TryCatchBlock element) { public TryCatchBlock set(int index, TryCatchBlock element) {
TryCatchBlock oldTryCatch = tryCatchBlocks.get(index); TryCatchBlock oldTryCatch = tryCatchBlocks != null ? tryCatchBlocks.get(index) : null;
if (oldTryCatch == element) { if (oldTryCatch == element) {
return oldTryCatch; return oldTryCatch;
} }

View File

@ -119,14 +119,14 @@ public class MethodDescriptor implements Serializable {
return null; return null;
} }
int index = text.indexOf(')', 1); int index = text.indexOf(')', 1);
if (index < 0) { if (index <= 0) {
return null; return null;
} }
ValueType[] params = ValueType.parseManyIfPossible(text.substring(1, index)); ValueType[] params = ValueType.parseManyIfPossible(text.substring(1, index));
if (params == null) { if (params == null) {
return null; return null;
} }
ValueType result = ValueType.parse(text.substring(index + 1)); ValueType result = ValueType.parseIfPossible(text.substring(index + 1));
if (result == null) { if (result == null) {
return null; return null;
} }

View File

@ -270,7 +270,7 @@ public abstract class ValueType implements Serializable {
int index = 0; int index = 0;
while (index < text.length()) { while (index < text.length()) {
int nextIndex = cut(text, index); int nextIndex = cut(text, index);
ValueType type = parse(text.substring(index, nextIndex)); ValueType type = parseIfPossible(text.substring(index, nextIndex));
if (type == null) { if (type == null) {
return null; return null;
} }

View File

@ -398,8 +398,6 @@ public class ClassInference {
if (!outerChanged) { if (!outerChanged) {
break; break;
} }
changed = false;
} }
} }
@ -684,13 +682,7 @@ public class ClassInference {
String expectedType = tryCatch.getExceptionType(); String expectedType = tryCatch.getExceptionType();
List<? extends String> thrownTypes = subclassListProvider.getSubclasses(expectedType, false); List<? extends String> thrownTypes = subclassListProvider.getSubclasses(expectedType, false);
if (thrownTypes == null) { if (thrownTypes != null) {
if (!overflowTypes[exceptionNode]) {
overflowTypes[exceptionNode] = true;
changed = true;
nodeChanged[exceptionNode] = true;
}
} else {
IntHashSet nodeTypes = getNodeTypes(exceptionNode); IntHashSet nodeTypes = getNodeTypes(exceptionNode);
for (String thrownTypeName : thrownTypes) { for (String thrownTypeName : thrownTypes) {
int thrownType = getTypeByName(thrownTypeName); int thrownType = getTypeByName(thrownTypeName);
@ -953,7 +945,7 @@ public class ClassInference {
overflowType(variable, degree); overflowType(variable, degree);
} else { } else {
String[] types = dep.getTypes(); String[] types = dep.getTypes();
for (String type : dep.getTypes()) { for (String type : types) {
if (addType(variable, degree, type)) { if (addType(variable, degree, type)) {
break; break;
} }

View File

@ -55,10 +55,10 @@ public class CallSiteLocation {
List<CallSiteLocation> result = new ArrayList<>(); List<CallSiteLocation> result = new ArrayList<>();
InliningInfo inlining = location.getInlining(); InliningInfo inlining = location.getInlining();
result.add(new CallSiteLocation( result.add(new CallSiteLocation(
convertFileName(location != null ? location.getFileName() : null), convertFileName(location.getFileName()),
inlining.getMethod().getClassName(), inlining.getMethod().getClassName(),
inlining.getMethod().getName(), inlining.getMethod().getName(),
location != null ? location.getLine() : 0)); location.getLine()));
while (inlining != null) { while (inlining != null) {
MethodReference method = inlining.getParent() != null MethodReference method = inlining.getParent() != null
? inlining.getParent().getMethod() ? inlining.getParent().getMethod()

View File

@ -107,6 +107,6 @@ public class Characteristics {
if (cls.getAnnotations().get(Unmanaged.class.getName()) != null) { if (cls.getAnnotations().get(Unmanaged.class.getName()) != null) {
return false; return false;
} }
return method == null || method.getAnnotations().get(Unmanaged.class.getName()) == null; return method.getAnnotations().get(Unmanaged.class.getName()) == null;
} }
} }

View File

@ -249,7 +249,7 @@ public class ExportDependencyListener extends AbstractDependencyListener {
return true; return true;
} }
class FunctionGetFinder extends AbstractInstructionReader { static class FunctionGetFinder extends AbstractInstructionReader {
DisjointSet variableClasses = new DisjointSet(); DisjointSet variableClasses = new DisjointSet();
String[] stringConstants; String[] stringConstants;
ValueType[] classConstants; ValueType[] classConstants;

View File

@ -154,7 +154,7 @@ class ListingLexer {
break; break;
case '*': case '*':
nextChar(); nextChar();
token = ListingToken.SUBTRACT; token = ListingToken.MULTIPLY;
break; break;
case '/': case '/':
nextChar(); nextChar();

View File

@ -375,10 +375,8 @@ public class BoundCheckInsertion {
} }
} }
if (lower) { if ((isConstant[index] && constantValue[index] >= 0) || nonNegative[index]) {
if ((isConstant[index] && constantValue[index] >= 0) || nonNegative[index]) { lower = false;
lower = false;
}
} }
if (upper) { if (upper) {

View File

@ -878,13 +878,7 @@ public class ProgramParser {
@Override @Override
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
switch (opcode) { switch (opcode) {
case Opcodes.BIPUSH: { case Opcodes.BIPUSH:
IntegerConstantInstruction insn = new IntegerConstantInstruction();
insn.setConstant(operand);
insn.setReceiver(getVariable(pushSingle()));
addInstruction(insn);
break;
}
case Opcodes.SIPUSH: { case Opcodes.SIPUSH: {
IntegerConstantInstruction insn = new IntegerConstantInstruction(); IntegerConstantInstruction insn = new IntegerConstantInstruction();
insn.setConstant(operand); insn.setConstant(operand);

View File

@ -53,7 +53,7 @@ public final class ExceptionHandling {
CallSite callSite = findCallSiteById(callSiteId, stackFrame); CallSite callSite = findCallSiteById(callSiteId, stackFrame);
CallSiteLocation location = callSite.location; CallSiteLocation location = callSite.location;
while (location != null) { while (location != null) {
MethodLocation methodLocation = location != null ? location.method : null; MethodLocation methodLocation = location.method;
Console.printString(" at "); Console.printString(" at ");
if (methodLocation.className == null || methodLocation.methodName == null) { if (methodLocation.className == null || methodLocation.methodName == null) {
@ -184,7 +184,7 @@ public final class ExceptionHandling {
if (isObfuscated()) { if (isObfuscated()) {
target[index++] = new StackTraceElement("Obfuscated", "obfuscated", "Obfuscated.java", callSiteId); target[index++] = new StackTraceElement("Obfuscated", "obfuscated", "Obfuscated.java", callSiteId);
} else if (location == null) { } else if (location == null) {
target[index++] = new StackTraceElement("", "", null, location.lineNumber); target[index++] = new StackTraceElement("", "", null, -1);
} else { } else {
while (location != null) { while (location != null) {
MethodLocation methodLocation = location.method; MethodLocation methodLocation = location.method;

View File

@ -157,6 +157,7 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
if (reader == null) { if (reader == null) {
agent.getDiagnostics().error(new CallLocation(caller.getReference()), "Can't resolve method {{m0}}", agent.getDiagnostics().error(new CallLocation(caller.getReference()), "Can't resolve method {{m0}}",
methodRef); methodRef);
return;
} }
methodRef = reader.getReference(); methodRef = reader.getReference();

View File

@ -38,8 +38,9 @@ public class JavaScriptResourceInterceptor extends AbstractRendererListener {
continue; continue;
} }
String path = annot.getValue("value").getString(); String path = annot.getValue("value").getString();
String packageName = className.substring(0, className.lastIndexOf('.')); int packageIndex = className.lastIndexOf('.');
String resourceName = packageName.replace('.', '/') + "/" + path; String packageName = packageIndex >= 0 ? className.substring(0, packageIndex) : "";
String resourceName = packageName.isEmpty() ? path : packageName.replace('.', '/') + "/" + path;
try (InputStream input = manager.getClassLoader().getResourceAsStream(resourceName)) { try (InputStream input = manager.getClassLoader().getResourceAsStream(resourceName)) {
if (input == null) { if (input == null) {
throw new RenderingException("Error processing JavaScriptResource annotation on class " throw new RenderingException("Error processing JavaScriptResource annotation on class "

View File

@ -786,7 +786,7 @@ class JSClassProcessor {
private boolean isProperSetIndexer(MethodDescriptor desc) { private boolean isProperSetIndexer(MethodDescriptor desc) {
return desc.parameterCount() == 2 && typeHelper.isSupportedType(desc.parameterType(0)) return desc.parameterCount() == 2 && typeHelper.isSupportedType(desc.parameterType(0))
&& typeHelper.isSupportedType(desc.parameterType(0)) && desc.getResultType() == ValueType.VOID; && typeHelper.isSupportedType(desc.parameterType(1)) && desc.getResultType() == ValueType.VOID;
} }
private static String cutPrefix(String name, int prefixLength) { private static String cutPrefix(String name, int prefixLength) {

View File

@ -207,8 +207,7 @@ public final class MetaprogrammingImpl {
return null; return null;
} }
ReflectMethod method = new ReflectMethodImpl(cls, methodReader); ReflectMethod method = new ReflectMethodImpl(cls, methodReader);
return new SourceLocation(method, location != null ? location.getFileName() : null, return new SourceLocation(method, location.getFileName(), location.getLine());
location != null ? location.getLine() : null);
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")

View File

@ -603,9 +603,6 @@ public class CalendarTest {
} }
} }
/**
* @tests java.util.Calendar#isSet(int)
*/
@Test @Test
public void test_isSet() { public void test_isSet() {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
@ -615,10 +612,6 @@ public class CalendarTest {
} }
} }
/**
* @tests java.util.Calendar#getInstance(Locale)
* @tests java.util.Calendar#getInstance(TimeZone, Locale)
*/
@Test @Test
public void test_getInstance() { public void test_getInstance() {
// test getInstance(Locale) // test getInstance(Locale)
@ -640,9 +633,6 @@ public class CalendarTest {
.getID(), estCalendar.getTimeZone().getID()); .getID(), estCalendar.getTimeZone().getID());
} }
/**
* @tests java.util.Calendar#internalGet(int)
*/
@Test @Test
public void test_internalGet() { public void test_internalGet() {
MockGregorianCalendar c = new MockGregorianCalendar(); MockGregorianCalendar c = new MockGregorianCalendar();
@ -650,18 +640,12 @@ public class CalendarTest {
assertEquals(0, c.internal_get(Calendar.YEAR)); assertEquals(0, c.internal_get(Calendar.YEAR));
} }
/**
* @tests java.util.Calendar#hashCode()
*/
@Test @Test
public void test_hashcode() { public void test_hashcode() {
Calendar calendar = Calendar.getInstance(Locale.JAPAN); Calendar calendar = Calendar.getInstance(Locale.JAPAN);
assertTrue(calendar.hashCode() == calendar.hashCode()); assertTrue(calendar.hashCode() == calendar.hashCode());
} }
/**
* @tests java.util.Calendar#roll(int, int)
*/
@Test @Test
public void test_roll() { public void test_roll() {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();

View File

@ -234,7 +234,7 @@ public final class ChromeRDPRunner {
private Command resumeCommand = args -> debugger.resume(); private Command resumeCommand = args -> debugger.resume();
private Command breakpointCommand = args -> { private Command breakpointCommand = args -> {
if (args.length != 3 && args.length != 3) { if (args.length < 2 || args.length > 4) {
System.out.println("Expected 2 arguments"); System.out.println("Expected 2 arguments");
return Promise.VOID; return Promise.VOID;
} }

View File

@ -135,7 +135,7 @@ public class TeaVMCBuilderRunner {
if (args.length != 1) { if (args.length != 1) {
System.err.println("Unexpected arguments"); System.err.println("Unexpected arguments");
printUsage(); printUsage();
} else if (args.length == 1) { } else {
builder.setMainClass(args[0]); builder.setMainClass(args[0]);
} }
} }

View File

@ -35,7 +35,7 @@ public final class TeaVMDevServerRunner {
setupOptions(); setupOptions();
} }
@SuppressWarnings("static-access") @SuppressWarnings("AccessStaticViaInstance")
private static void setupOptions() { private static void setupOptions() {
options.addOption(OptionBuilder options.addOption(OptionBuilder
.withArgName("directory") .withArgName("directory")
@ -150,7 +150,7 @@ public final class TeaVMDevServerRunner {
if (args.length != 1) { if (args.length != 1) {
System.err.println("Unexpected arguments"); System.err.println("Unexpected arguments");
printUsage(); printUsage();
} else if (args.length == 1) { } else {
devServer.setMainClass(args[0]); devServer.setMainClass(args[0]);
} }
} }

View File

@ -366,7 +366,7 @@ public class TeaVMTool {
fileTable, variableTable, classSource, innerClassSource); fileTable, variableTable, classSource, innerClassSource);
programCache = new DiskProgramCache(cacheDirectory, referenceCache, symbolTable, fileTable, programCache = new DiskProgramCache(cacheDirectory, referenceCache, symbolTable, fileTable,
variableTable); variableTable);
if (incremental && targetType == TeaVMTargetType.JAVASCRIPT) { if (targetType == TeaVMTargetType.JAVASCRIPT) {
astCache = new DiskMethodNodeCache(cacheDirectory, referenceCache, symbolTable, fileTable, astCache = new DiskMethodNodeCache(cacheDirectory, referenceCache, symbolTable, fileTable,
variableTable); variableTable);
javaScriptTarget.setAstCache(astCache); javaScriptTarget.setAstCache(astCache);

View File

@ -118,6 +118,7 @@ public final class Deobfuscator {
if (location != null) { if (location != null) {
frame.setLineNumber(location.getLine()); frame.setLineNumber(location.getLine());
} }
result.add(frame);
} }
if (result.isEmpty()) { if (result.isEmpty()) {

View File

@ -130,7 +130,6 @@ public class TeaVMTestRunner extends Runner implements Filterable {
static { static {
for (RunKind kind : RunKind.values()) { for (RunKind kind : RunKind.values()) {
runners.put(kind, new RunnerKindInfo()); runners.put(kind, new RunnerKindInfo());
runners.put(kind, new RunnerKindInfo());
} }
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
synchronized (TeaVMTestRunner.class) { synchronized (TeaVMTestRunner.class) {