Minor improvements

This commit is contained in:
konsoletyper 2015-02-14 23:52:28 +04:00
parent 0cdf960ba5
commit 9d112817b8
9 changed files with 77 additions and 103 deletions

View File

@ -124,7 +124,8 @@ public class TObject {
}
@Rename("notify")
public final void notify0(){
public final void notify0() {
TThread thread = TThread.currentThread();
if (notifyListeners != null) {
while (notifyListeners.getLength() > 0 && notifyListeners.shift().handleNotify()) {
// repeat loop
@ -133,6 +134,7 @@ public class TObject {
notifyListeners = null;
}
}
TThread.setCurrentThread(thread);
}
@Rename("notifyAll")
@ -167,8 +169,7 @@ public class TObject {
if (notifyListeners == null) {
notifyListeners = window.newArray();
}
final TThread currentThread = TThread.currentThread();
final NotifyListenerImpl listener = new NotifyListenerImpl(callback, currentThread);
final NotifyListenerImpl listener = new NotifyListenerImpl(callback);
notifyListeners.push(listener);
if (timeout == 0 && nanos == 0) {
return;
@ -178,13 +179,12 @@ public class TObject {
private static class NotifyListenerImpl implements NotifyListener, TimerHandler {
final AsyncCallback<Void> callback;
final TThread currentThread;
final TThread currentThread = TThread.currentThread();
int timerId = -1;
boolean finished;
public NotifyListenerImpl(AsyncCallback<Void> callback, TThread currentThread) {
public NotifyListenerImpl(AsyncCallback<Void> callback) {
this.callback = callback;
this.currentThread = currentThread;
}
@Override

View File

@ -264,7 +264,9 @@ public class TeaVMTool {
if (mainClass != null) {
MethodDescriptor mainMethodDesc = new MethodDescriptor("main", String[].class, void.class);
vm.entryPoint("main", new MethodReference(mainClass, mainMethodDesc))
.withValue(1, "java.lang.String").async();
.withValue(1, "[java.lang.String")
.withArrayValue(1, "java.lang.String")
.async();
}
for (ClassAlias alias : classAliases) {
vm.exportType(alias.getAlias(), alias.getClassName());
@ -300,7 +302,7 @@ public class TeaVMTool {
return;
}
if (mainClass != null) {
writer.append("main = $rt_rootInvocationAdapter(main);\n");
writer.append("main = $rt_mainWrapper(main);\n");
}
ProblemProvider problemProvider = vm.getProblemProvider();
if (problemProvider.getProblems().isEmpty()) {

View File

@ -431,28 +431,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
listener.begin(renderer, target);
}
sourceWriter.append("\"use strict\";").newLine();
// Keep track of current running thread by overriding setTimeout
sourceWriter.append("function $rt_setTimeout(f,interval){").indent().softNewLine();
MethodReference currentThreadRef = new MethodReference(
Thread.class, "currentThread", Thread.class);
MethodReference setCurrentThreadRef = new MethodReference(
Thread.class, "setCurrentThread", Thread.class, void.class);
MethodReference getMainThreadRef = new MethodReference(Thread.class, "getMainThread", Thread.class);
sourceWriter.append("var currThread = ").appendMethodBody(currentThreadRef).append("();").softNewLine();
sourceWriter.append("var callback = function(){").indent().softNewLine();
sourceWriter.appendMethodBody(setCurrentThreadRef).append("(currThread);").softNewLine();
sourceWriter.append("try{f();} finally {").softNewLine();
sourceWriter.appendMethodBody(setCurrentThreadRef).append("(").
appendMethodBody(getMainThreadRef).append("());}").softNewLine();
sourceWriter.outdent().append("};").softNewLine();
sourceWriter.append("setTimeout(callback, interval);").softNewLine();
sourceWriter.outdent().append("};").softNewLine();
// END Thread stuff
renderer.renderRuntime();
renderer.render(clsNodes);
renderer.renderStringPool();

View File

@ -97,6 +97,14 @@ public class TeaVMEntryPoint {
return this;
}
public TeaVMEntryPoint withArrayValue(int argument, String type) {
if (argument > reference.parameterCount()) {
throw new IllegalArgumentException("Illegal argument #" + argument + " of " + reference.parameterCount());
}
method.getVariable(argument).getArrayItem().propagate(method.getDependencyAgent().getType(type));
return this;
}
public TeaVMEntryPoint async() {
this.async = true;
return this;

View File

@ -481,6 +481,18 @@ function $rt_rootInvocationAdapter(f) {
return f.apply(this, args);
}
}
function $rt_mainWrapper(f) {
return function(args) {
if (!args) {
args = [];
}
var javaArgs = $rt_createArray($rt_objcls(), args.length);
for (var i = 0; i < args.length; ++i) {
javaArgs.data[i] = $rt_str(args[i]);
}
$rt_rootInvocationAdapter(f)(javaArgs);
};
}
var $rt_stringPool_instance;
function $rt_stringPool(strings) {
$rt_stringPool_instance = new Array(strings.length);

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-shared-configuration>
<!--
This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
-->
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!--
Properties that influence various parts of the IDE, especially code formatting and the like.
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
That way multiple projects can share the same settings (useful for formatting rules for example).
Any value defined here will override the pom.xml file value but is only applicable to the current project.
-->
<ca-weblite-netbeans-mirah.project_5f_type>maven</ca-weblite-netbeans-mirah.project_5f_type>
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>gfv3ee6</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>
</properties>
</project-shared-configuration>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<actionName>build</actionName>
<packagings>
<packaging>*</packaging>
</packagings>
<goals>
<goal>install</goal>
</goals>
<properties>
<skipTests>true</skipTests>
<jpda.listen>maven</jpda.listen>
</properties>
</action>
</actions>

View File

@ -15,20 +15,25 @@
*/
package org.teavm.samples.async;
import java.util.Arrays;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public final class AsyncProgram {
private static long start = System.currentTimeMillis();
private AsyncProgram() {
}
public static void main(String[] args) throws InterruptedException {
report(Arrays.toString(args));
withoutAsync();
System.out.println();
report("");
withAsync();
System.out.println();
report("");
final Object lock = new Object();
Thread t = new Thread(new Runnable() {
@Override
@ -36,7 +41,7 @@ public final class AsyncProgram {
try {
doRun(lock);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
report("Exception caught: " + ex.getMessage());
}
}
@ -49,82 +54,87 @@ public final class AsyncProgram {
try {
doRun(lock);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
report("Exception caught: " + ex.getMessage());
}
}
}, "Test Thread 2");
t2.start();
System.out.println("Should be main -> Current thread is " + Thread.currentThread().getName());
System.out.println("Now trying wait...");
report("Should be main");
report("Now trying wait...");
lock.wait(20000);
System.out.println("Finished waiting");
synchronized (lock) {
lock.wait(20000);
}
report("Finished main thread");
}
private static void report(String message) {
long current = System.currentTimeMillis() - start;
System.out.println("[" + Thread.currentThread().getName() + "]/" + current + ": " + message);
}
private static void doRun(Object lock) throws InterruptedException {
System.out.println("Current thread is " + Thread.currentThread().getName());
System.out.println("Executing timer task");
report("Executing timer task");
Thread.sleep(2000);
System.out.println("Current thread is " + Thread.currentThread().getName());
System.out.println("Calling lock.notify()");
lock.notify();
System.out.println("Current thread is " + Thread.currentThread().getName());
System.out.println("Finished calling lock.notify()");
report("Calling lock.notify()");
synchronized (lock) {
lock.notify();
}
report("Finished calling lock.notify()");
report("Waiting 5 seconds");
Thread.sleep(5000);
System.out.println("Current thread is " + Thread.currentThread().getName());
System.out.println("Finished another 5 second sleep");
report("Finished another 5 second sleep");
synchronized (lock) {
System.out.println("Inside locked section of thread " + Thread.currentThread().getName());
report("Sleep inside locked section");
Thread.sleep(2000);
System.out.println("Finished locked section of thread " + Thread.currentThread().getName());
report("Finished locked section");
}
}
private static void withoutAsync() {
System.out.println("Start sync");
report("Start sync");
for (int i = 0; i < 20; ++i) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j <= i; ++j) {
System.out.print(j);
System.out.print(' ');
sb.append(j);
sb.append(' ');
}
System.out.println();
report(sb.toString());
}
System.out.println("Complete sync");
report("Complete sync");
}
private static void withAsync() throws InterruptedException {
System.out.println("Start async");
report("Start async");
for (int i = 0; i < 20; ++i) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j <= i; ++j) {
System.out.print(j);
System.out.print(' ');
sb.append(j);
sb.append(' ');
}
System.out.println();
report(sb.toString());
if (i % 3 == 0) {
System.out.println("Suspend for a second");
report("Suspend for a second");
Thread.sleep(1000);
}
}
System.out.println("2nd Thread.sleep in same method");
report("2nd Thread.sleep in same method");
Thread.sleep(1000);
System.out.println("Complete async");
System.out.println("Throwing exception");
report("Throwing exception");
try {
throwException();
} catch (IllegalStateException e) {
System.out.println("Exception caught");
report("Exception caught");
}
report("Complete async");
}
private static void throwException() {
Thread.yield();
System.out.println("Thread.yield called");
report("Thread.yield called");
throw new IllegalStateException();
}
}

View File

@ -21,7 +21,7 @@
<script type="text/javascript" charset="utf-8" src="teavm/runtime.js"></script>
<script type="text/javascript" charset="utf-8" src="teavm/classes.js"></script>
</head>
<body onload="main(null)">
<body onload="main()">
<p>Please, open developer's console to view program's output</p>
</body>
</html>