Trying to fix corrupted state stack when calling Class.newInstance.

See https://github.com/konsoletyper/teavm/issues/118
This commit is contained in:
Alexey Andreev 2015-05-26 22:27:33 +03:00
parent e150e2e44f
commit 3d95eb1a7e
3 changed files with 59 additions and 18 deletions

View File

@ -65,8 +65,7 @@ import org.teavm.classlib.impl.CharFlow;
* @since 1.0
*/
public class DateTimeZoneBuilder {
private static TimeZone GMT = TimeZone.getTimeZone("GMT+00:00");
private static TimeZone gmtCache;
private static StorableDateTimeZone buildFixedZone(String id, int wallOffset, int standardOffset) {
return new FixedDateTimeZone(id, wallOffset, standardOffset);
}
@ -78,6 +77,13 @@ public class DateTimeZoneBuilder {
iRuleSets = new ArrayList<>(10);
}
private static TimeZone getGMT() {
if (gmtCache == null) {
gmtCache = TimeZone.getTimeZone("GMT+00:00");
}
return gmtCache;
}
/**
* Adds a cutover for added rules. The standard offset at the cutover
* defaults to 0. Call setStandardOffset afterwards to change it.
@ -346,7 +352,7 @@ public class DateTimeZoneBuilder {
offset = 0;
}
Calendar calendar = Calendar.getInstance(GMT);
Calendar calendar = Calendar.getInstance(getGMT());
calendar.setTimeInMillis(0);
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, iMonthOfYear - 1);
@ -381,7 +387,7 @@ public class DateTimeZoneBuilder {
// Convert from UTC to local time.
instant += offset;
GregorianCalendar calendar = new GregorianCalendar(GMT);
GregorianCalendar calendar = new GregorianCalendar(getGMT());
calendar.setTimeInMillis(instant);
calendar.set(Calendar.MONTH, iMonthOfYear - 1);
calendar.set(Calendar.DATE, 1);
@ -427,7 +433,7 @@ public class DateTimeZoneBuilder {
// Convert from UTC to local time.
instant += offset;
GregorianCalendar calendar = new GregorianCalendar(GMT);
GregorianCalendar calendar = new GregorianCalendar(getGMT());
calendar.setTimeInMillis(instant);
calendar.set(Calendar.MONTH, iMonthOfYear - 1);
calendar.set(Calendar.DATE, 1);
@ -589,7 +595,7 @@ public class DateTimeZoneBuilder {
}
public long next(final long instant, int standardOffset, int saveMillis) {
Calendar calendar = Calendar.getInstance(GMT);
Calendar calendar = Calendar.getInstance(getGMT());
final int wallOffset = standardOffset + saveMillis;
long testInstant = instant;
@ -844,7 +850,7 @@ public class DateTimeZoneBuilder {
}
// Stop precalculating if year reaches some arbitrary limit.
Calendar c = Calendar.getInstance(GMT);
Calendar c = Calendar.getInstance(getGMT());
c.setTimeInMillis(nextMillis);
if (c.get(Calendar.YEAR) >= YEAR_LIMIT) {
return null;

View File

@ -18,8 +18,9 @@ package org.teavm.classlib.java.util;
import org.teavm.classlib.java.lang.TIllegalStateException;
import org.teavm.classlib.java.lang.TObject;
import org.teavm.classlib.java.lang.TString;
import org.teavm.platform.Platform;
import org.teavm.platform.PlatformRunnable;
import org.teavm.dom.browser.TimerHandler;
import org.teavm.dom.browser.Window;
import org.teavm.jso.JS;
/**
*
@ -45,19 +46,50 @@ public class TTimer extends TObject {
}
}
public void schedule(TTimerTask task, long delay) {
public void schedule(final TTimerTask task, long delay) {
if (cancelled || task.timer != null || task.nativeTimerId >= 0) {
throw new TIllegalStateException();
}
task.timer = this;
task.nativeTimerId = scheduleOnce(task, (int)delay);
task.nativeTimerId = ((Window)JS.getGlobal()).setTimeout(new TimerHandler() {
@Override
public void onTimer() {
new Thread() {
@Override
public void run() {
if (cancelled || task.timer == null) {
return;
}
private static int scheduleOnce(final TTimerTask task, int delay) {
return Platform.schedule(new PlatformRunnable() {
@Override public void run() {
TTimerTask.performOnce(task);
}
}, delay);
}.start();
}
}, (int)delay);
}
public void schedule(final TTimerTask task, long delay, final long period) {
if (cancelled || task.timer != null || task.nativeTimerId >= 0) {
throw new TIllegalStateException();
}
task.timer = this;
task.nativeTimerId = ((Window)JS.getGlobal()).setTimeout(new TimerHandler() {
@Override
public void onTimer() {
final TimerHandler self = this;
new Thread() {
@Override
public void run() {
if (cancelled || task.timer == null) {
return;
}
task.nativeTimerId = ((Window)JS.getGlobal()).setTimeout(self, (int)period);
TTimerTask.performOnce(task);
if (!cancelled) {
task.timer = TTimer.this;
}
}
}.start();
}
}, (int)delay);
}
}

View File

@ -112,11 +112,14 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
}
private void generateNewInstance(GeneratorContext context, SourceWriter writer) throws IOException {
String cls = context.getParameterName(1);
writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine();
writer.append("return $rt_nativeThread().pop();").softNewLine();
writer.append("var $r = $rt_nativeThread().pop();").softNewLine();
writer.append(cls + ".$$constructor$$($r);").softNewLine();
writer.append("return $r;").softNewLine();
writer.outdent().append("}").softNewLine();
String cls = context.getParameterName(1);
writer.append("if").ws().append("(!").append(cls).append(".hasOwnProperty('$$constructor$$'))")
.ws().append("{").indent().softNewLine();
writer.append("return null;").softNewLine();