Fix asynchronous instantiation via reflection. (#238)

Fix asynchronous instantiation via reflection. The generated code resumes
from a thread suspension event, but won't appropriately re-suspend if the
constructor suspends.
This commit is contained in:
davmac314 2017-02-09 13:29:50 +00:00 committed by Alexey Andreev
parent 9271d71906
commit 7fc035fd8a
3 changed files with 53 additions and 0 deletions

View File

@ -128,6 +128,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine();
writer.append("var $r = $rt_nativeThread().pop();").softNewLine();
writer.append(cls + ".$$constructor$$($r);").softNewLine();
writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine();
writer.append("return").ws().append("$rt_nativeThread().push($r);").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("return $r;").softNewLine();
writer.outdent().append("}").softNewLine();

View File

@ -117,6 +117,14 @@ public class ClassTest {
assertEquals(1, ((TestObject)instance).getCounter());
}
@Test
public void instanceCreatedThroughReflectionAsync() throws Exception {
Runnable instance = TestObjectAsync.class.newInstance();
instance.run();
assertEquals(TestObjectAsync.class, instance.getClass());
assertEquals(2, ((TestObjectAsync)instance).getCounter());
}
@Test
public void declaringClassFound() {
assertEquals(ClassTest.class, new A().getClass().getDeclaringClass());

View File

@ -0,0 +1,42 @@
/*
* Copyright 2017 Alexey Andreev.
*
* 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 org.teavm.classlib.java.lang;
public class TestObjectAsync extends Object implements Runnable {
private int counter;
public static Runnable r;
public TestObjectAsync() {
try {
Thread.sleep(1);
Thread.sleep(1);
counter = 1;
}
catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
}
@Override
public void run() {
++counter;
}
public int getCounter() {
return counter;
}
}