Further development

This commit is contained in:
Alexey Andreev 2015-03-10 19:33:34 +04:00
parent 32deaf2716
commit 56c5fefae4
21 changed files with 117 additions and 46 deletions

View File

@ -127,7 +127,7 @@ public class TObject {
o.monitor.enteringThreads.remove().run(); o.monitor.enteringThreads.remove().run();
} }
} }
}); }, false);
} else { } else {
o.isEmptyMonitor(); o.isEmptyMonitor();
} }
@ -203,7 +203,7 @@ public class TObject {
while (!listeners.isEmpty()) { while (!listeners.isEmpty()) {
NotifyListener listener = listeners.remove(); NotifyListener listener = listeners.remove();
if (!listener.expired()) { if (!listener.expired()) {
Platform.startThread(listener); Platform.startThread(listener, false);
break; break;
} }
} }
@ -219,7 +219,7 @@ public class TObject {
while (!listeners.isEmpty()) { while (!listeners.isEmpty()) {
NotifyListener listener = listeners.remove(); NotifyListener listener = listeners.remove();
if (!listener.expired()) { if (!listener.expired()) {
Platform.startThread(listener); Platform.startThread(listener, false);
} }
} }
} }
@ -279,7 +279,7 @@ public class TObject {
@Override @Override
public void onTimer() { public void onTimer() {
if (!expired()) { if (!expired()) {
Platform.startThread(this); Platform.startThread(this, false);
} }
} }

View File

@ -71,7 +71,7 @@ public class TThread extends TObject implements TRunnable {
setCurrentThread(mainThread); setCurrentThread(mainThread);
} }
} }
}); }, true);
} }
static void setCurrentThread(TThread thread) { static void setCurrentThread(TThread thread) {
@ -116,7 +116,7 @@ public class TThread extends TObject implements TRunnable {
setCurrentThread(thread); setCurrentThread(thread);
callback.complete(null); callback.complete(null);
} }
}); }, false);
} }
private static void yieldImpl() { private static void yieldImpl() {

View File

@ -315,10 +315,18 @@ public class AstIO {
} }
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(SaveStatement statement) {
try { try {
output.writeByte(18); output.writeByte(18);
output.writeShort(statement.getAsyncTarget() != null ? 0 : statement.getAsyncTarget()); } catch (IOException e) {
throw new IOExceptionWrapper(e);
}
}
@Override
public void visit(MonitorEnterStatement statement) {
try {
output.writeByte(19);
writeExpr(statement.getObjectRef()); writeExpr(statement.getObjectRef());
} catch (IOException e) { } catch (IOException e) {
throw new IOExceptionWrapper(e); throw new IOExceptionWrapper(e);
@ -328,7 +336,7 @@ public class AstIO {
@Override @Override
public void visit(MonitorExitStatement statement) { public void visit(MonitorExitStatement statement) {
try { try {
output.writeByte(19); output.writeByte(20);
writeExpr(statement.getObjectRef()); writeExpr(statement.getObjectRef());
} catch (IOException e) { } catch (IOException e) {
throw new IOExceptionWrapper(e); throw new IOExceptionWrapper(e);

View File

@ -262,6 +262,10 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache {
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {

View File

@ -117,6 +117,10 @@ class BreakToContinueReplacer implements StatementVisitor {
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
} }

View File

@ -112,6 +112,10 @@ class CertainBlockCountVisitor implements StatementVisitor {
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
} }

View File

@ -22,6 +22,7 @@ import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.spi.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.spi.InjectedBy; import org.teavm.javascript.spi.InjectedBy;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.model.instructions.InvokeInstruction;
import org.teavm.model.util.AsyncProgramSplitter; import org.teavm.model.util.AsyncProgramSplitter;
import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.ProgramUtils;
@ -294,7 +295,6 @@ public class Decompiler {
int tmp = indexer.nodeAt(next); int tmp = indexer.nodeAt(next);
generator.nextBlock = tmp >= 0 && next < indexer.size() ? program.basicBlockAt(tmp) : null; generator.nextBlock = tmp >= 0 && next < indexer.size() ? program.basicBlockAt(tmp) : null;
generator.statements.clear(); generator.statements.clear();
generator.asyncTarget = null;
InstructionLocation lastLocation = null; InstructionLocation lastLocation = null;
NodeLocation nodeLocation = null; NodeLocation nodeLocation = null;
List<Instruction> instructions = generator.currentBlock.getInstructions(); List<Instruction> instructions = generator.currentBlock.getInstructions();
@ -307,11 +307,17 @@ public class Decompiler {
if (insn.getLocation() != null) { if (insn.getLocation() != null) {
generator.setCurrentLocation(nodeLocation); generator.setCurrentLocation(nodeLocation);
} }
if (targetBlocks[node] >= 0 && j == instructions.size() - 1) {
generator.asyncTarget = targetBlocks[node];
}
insn.acceptVisitor(generator); insn.acceptVisitor(generator);
if (j == 0 && insn instanceof InvokeInstruction) {
generator.statements.add(new SaveStatement());
}
} }
if (targetBlocks[node] >= 0) {
GotoPartStatement stmt = new GotoPartStatement();
stmt.setPart(targetBlocks[node]);
generator.statements.add(stmt);
}
for (TryCatchBlock tryCatch : generator.currentBlock.getTryCatchBlocks()) { for (TryCatchBlock tryCatch : generator.currentBlock.getTryCatchBlocks()) {
TryCatchStatement tryCatchStmt = new TryCatchStatement(); TryCatchStatement tryCatchStmt = new TryCatchStatement();
tryCatchStmt.setExceptionType(tryCatch.getExceptionType()); tryCatchStmt.setExceptionType(tryCatch.getExceptionType());

View File

@ -191,6 +191,10 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
if (async) { if (async) {

View File

@ -619,6 +619,11 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
resultStmt = statement; resultStmt = statement;
} }
@Override
public void visit(SaveStatement statement) {
resultStmt = statement;
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
statement.getObjectRef().acceptVisitor(this); statement.getObjectRef().acceptVisitor(this);

View File

@ -122,6 +122,10 @@ class RedundantLabelEliminator implements StatementVisitor {
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
} }

View File

@ -116,6 +116,10 @@ class ReferenceCountingVisitor implements StatementVisitor {
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
} }

View File

@ -716,6 +716,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.softNewLine(); writer.softNewLine();
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
writer.append("while").ws().append("(true)").ws().append("{").indent().softNewLine();
writer.append("$main: switch").ws().append("($ptr)").ws().append('{').softNewLine(); writer.append("$main: switch").ws().append("($ptr)").ws().append('{').softNewLine();
for (int i = 0; i < methodNode.getBody().size(); ++i) { for (int i = 0; i < methodNode.getBody().size(); ++i) {
writer.append("case ").append(i).append(":").indent().softNewLine(); writer.append("case ").append(i).append(":").indent().softNewLine();
@ -724,6 +725,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.outdent(); writer.outdent();
} }
writer.append("}").softNewLine(); writer.append("}").softNewLine();
writer.outdent().append("}").softNewLine();
} catch (IOException e) { } catch (IOException e) {
throw new RenderingException("IO error occured", e); throw new RenderingException("IO error occured", e);
} }
@ -1956,23 +1958,26 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
} }
} }
@Override @Override
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
try { try {
gotoPart(statement.getPart()); writer.append("$ptr").ws().append("=").ws().append(statement.getPart()).append(";")
.softNewLine();
writer.append("break $main;").softNewLine();
} catch (IOException ex){ } catch (IOException ex){
throw new RenderingException("IO error occured", ex); throw new RenderingException("IO error occured", ex);
} }
} }
private void gotoPart(int part) throws IOException { @Override
writer.append("$ptr").ws().append("=").ws().append(part).append(";") public void visit(SaveStatement statement) {
.softNewLine(); try {
writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine();
writer.append("return $save();").softNewLine(); writer.append("return $save();").softNewLine();
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
writer.append("break $main;").softNewLine(); } catch (IOException ex){
throw new RenderingException("IO error occured", ex);
}
} }
@Override @Override
@ -1984,9 +1989,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.appendMethodBody(monitorEnterRef).append("("); writer.appendMethodBody(monitorEnterRef).append("(");
statement.getObjectRef().acceptVisitor(this); statement.getObjectRef().acceptVisitor(this);
writer.append(");").softNewLine(); writer.append(");").softNewLine();
if (statement.getAsyncTarget() != null) { writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine();
gotoPart(statement.getAsyncTarget()); writer.append("return $save();").softNewLine();
} writer.outdent().append("}").softNewLine();
} else { } else {
MethodReference monitorEnterRef = new MethodReference( MethodReference monitorEnterRef = new MethodReference(
Object.class, "monitorEnterSync", Object.class, void.class); Object.class, "monitorEnterSync", Object.class, void.class);

View File

@ -37,7 +37,6 @@ class StatementGenerator implements InstructionVisitor {
Program program; Program program;
ClassHolderSource classSource; ClassHolderSource classSource;
private NodeLocation currentLocation; private NodeLocation currentLocation;
Integer asyncTarget;
public void setCurrentLocation(NodeLocation currentLocation) { public void setCurrentLocation(NodeLocation currentLocation) {
this.currentLocation = currentLocation; this.currentLocation = currentLocation;
@ -557,11 +556,6 @@ class StatementGenerator implements InstructionVisitor {
stmt.setLocation(currentLocation); stmt.setLocation(currentLocation);
statements.add(stmt); statements.add(stmt);
} }
if (asyncTarget != null) {
GotoPartStatement gotoStmt = new GotoPartStatement();
gotoStmt.setPart(asyncTarget);
statements.add(gotoStmt);
}
} }
@Override @Override
@ -662,7 +656,6 @@ class StatementGenerator implements InstructionVisitor {
MonitorEnterStatement stmt = new MonitorEnterStatement(); MonitorEnterStatement stmt = new MonitorEnterStatement();
stmt.setLocation(currentLocation); stmt.setLocation(currentLocation);
stmt.setObjectRef(Expr.var(insn.getObjectRef().getIndex())); stmt.setObjectRef(Expr.var(insn.getObjectRef().getIndex()));
stmt.setAsyncTarget(asyncTarget);
statements.add(stmt); statements.add(stmt);
} }

View File

@ -115,6 +115,10 @@ class TryCatchFinder implements StatementVisitor {
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
} }

View File

@ -229,6 +229,10 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
} }
@Override
public void visit(SaveStatement statement) {
}
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
statement.getObjectRef().acceptVisitor(this); statement.getObjectRef().acceptVisitor(this);

View File

@ -22,7 +22,6 @@ package org.teavm.javascript.ast;
public class MonitorEnterStatement extends Statement { public class MonitorEnterStatement extends Statement {
private NodeLocation location; private NodeLocation location;
private Expr objectRef; private Expr objectRef;
private Integer asyncTarget;
@Override @Override
public void acceptVisitor(StatementVisitor visitor) { public void acceptVisitor(StatementVisitor visitor) {
@ -44,12 +43,4 @@ public class MonitorEnterStatement extends Statement {
public void setObjectRef(Expr objectRef) { public void setObjectRef(Expr objectRef) {
this.objectRef = objectRef; this.objectRef = objectRef;
} }
public Integer getAsyncTarget() {
return asyncTarget;
}
public void setAsyncTarget(Integer asyncTarget) {
this.asyncTarget = asyncTarget;
}
} }

View File

@ -197,12 +197,14 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor {
} }
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(SaveStatement statement) {
}
@Override
public void visit(MonitorEnterStatement statement) {
} }
@Override @Override
public void visit(MonitorExitStatement statement) { public void visit(MonitorExitStatement statement) {
} }
} }

View File

@ -0,0 +1,27 @@
/*
* Copyright 2015 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.javascript.ast;
/**
*
* @author Alexey Andreev
*/
public class SaveStatement extends Statement {
@Override
public void acceptVisitor(StatementVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -49,4 +49,6 @@ public interface StatementVisitor {
void visit(MonitorEnterStatement statement); void visit(MonitorEnterStatement statement);
void visit(MonitorExitStatement statement); void visit(MonitorExitStatement statement);
void visit(SaveStatement statement);
} }

View File

@ -74,7 +74,7 @@ public class AsyncProgramSplitter {
// If we met asynchronous invocation... // If we met asynchronous invocation...
// Copy portion of current block from last occurrence (or from start) to i'th instruction. // Copy portion of current block from last occurrence (or from start) to i'th instruction.
targetBlock.getInstructions().addAll(ProgramUtils.copyInstructions(sourceBlock, targetBlock.getInstructions().addAll(ProgramUtils.copyInstructions(sourceBlock,
last, i + 1, targetBlock.getProgram())); last, i, targetBlock.getProgram()));
targetBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(sourceBlock, targetBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(sourceBlock,
targetBlock.getProgram())); targetBlock.getProgram()));
for (TryCatchBlock tryCatch : targetBlock.getTryCatchBlocks()) { for (TryCatchBlock tryCatch : targetBlock.getTryCatchBlocks()) {
@ -85,7 +85,7 @@ public class AsyncProgramSplitter {
queue.add(next); queue.add(next);
} }
} }
last = i + 1; last = i;
// If this instruction already separates program, end with current block and refer to the // If this instruction already separates program, end with current block and refer to the
// existing part // existing part

View File

@ -107,7 +107,7 @@ public final class Platform {
@GeneratedBy(PlatformGenerator.class) @GeneratedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class)
public static native void startThread(PlatformRunnable runnable); public static native void startThread(PlatformRunnable runnable, boolean newNativeThread);
private static void launchThread(PlatformRunnable runnable) { private static void launchThread(PlatformRunnable runnable) {
runnable.run(); runnable.run();