synchronized method
This commit is contained in:
@@ -1403,7 +1403,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
public int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
||||||
if(resolvedCall != null) {
|
if(resolvedCall != null) {
|
||||||
return pushMethodArguments(resolvedCall, valueParameterTypes);
|
return pushMethodArguments(resolvedCall, valueParameterTypes);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public class IntrinsicMethods {
|
public class IntrinsicMethods {
|
||||||
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
||||||
@@ -89,6 +90,7 @@ public class IntrinsicMethods {
|
|||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("sure"), 0, new Sure());
|
||||||
|
declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 1, new StupidSync());
|
||||||
|
|
||||||
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
||||||
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.objectweb.asm.Label;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StupidSync implements IntrinsicMethod {
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver) {
|
||||||
|
receiver.put(receiver.type, v);
|
||||||
|
codegen.pushMethodArguments((JetCallExpression)element, Arrays.asList(JetTypeMapper.TYPE_FUNCTION0));
|
||||||
|
v.invokestatic("jet/runtime/Intrinsics", "stupidSync", "(Ljava/lang/Object;Ljet/Function0;)Ljava/lang/Object;");
|
||||||
|
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v);
|
||||||
|
return StackValue.onStack(expectedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,8 @@ namespace io {
|
|||||||
fun readLine() : String?
|
fun readLine() : String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <R> Any.synchronized(block : fun() : R) : R
|
||||||
|
|
||||||
fun Any?.identityEquals(other : Any?) : Boolean // = this === other
|
fun Any?.identityEquals(other : Any?) : Boolean // = this === other
|
||||||
|
|
||||||
// Can't write a body due to a bootstrapping problem (see JET-74)
|
// Can't write a body due to a bootstrapping problem (see JET-74)
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import java.util.concurrent.*
|
||||||
|
import java.util.concurrent.atomic.*
|
||||||
|
|
||||||
|
fun thread(block: fun():Unit ) {
|
||||||
|
val thread = object: Thread() {
|
||||||
|
override fun run() {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thread.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val ref = AtomicInteger()
|
||||||
|
val cdl = CountDownLatch(11)
|
||||||
|
for(i in 0..10) {
|
||||||
|
thread {
|
||||||
|
var current = 0
|
||||||
|
do {
|
||||||
|
current = ref.synchronized {
|
||||||
|
val v = ref.get() + 1
|
||||||
|
if(v < 100)
|
||||||
|
ref.set(v+1)
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(current < 100)
|
||||||
|
cdl.countDown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cdl.await()
|
||||||
|
return if(ref.get() == 100) "OK" else ref.get().toString()
|
||||||
|
}
|
||||||
@@ -238,6 +238,12 @@ public class ControlStructuresTest extends CodegenTestCase {
|
|||||||
|
|
||||||
public void testQuicksort() throws Exception {
|
public void testQuicksort() throws Exception {
|
||||||
blackBoxFile("controlStructures/quicksort.jet");
|
blackBoxFile("controlStructures/quicksort.jet");
|
||||||
|
// System.out.println(generateToText());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSynchronized() throws Exception {
|
||||||
|
createEnvironmentWithFullJdk();
|
||||||
|
blackBoxFile("controlStructures/sync.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package jet.runtime;
|
package jet.runtime;
|
||||||
|
|
||||||
|
import jet.Function0;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,6 +31,12 @@ public class Intrinsics {
|
|||||||
return (thisVal == anotherVal ? 0 : (anotherVal ? 1 : -1));
|
return (thisVal == anotherVal ? 0 : (anotherVal ? 1 : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <R> R stupidSync(Object lock, Function0<R> block) {
|
||||||
|
synchronized (lock) {
|
||||||
|
return block.invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Throwable sanitizeStackTrace(Throwable throwable) {
|
private static Throwable sanitizeStackTrace(Throwable throwable) {
|
||||||
StackTraceElement[] stackTrace = throwable.getStackTrace();
|
StackTraceElement[] stackTrace = throwable.getStackTrace();
|
||||||
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
|
ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
|
||||||
|
|||||||
Reference in New Issue
Block a user