diff --git a/.idea/modules.xml b/.idea/modules.xml index 759d4087723..6b7e7872bbd 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -7,6 +7,7 @@ + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 94f066ccb20..91f40851950 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -115,8 +115,7 @@ public abstract class ClassBodyCodegen { private void generateStaticInitializer() { if (staticInitializerChunks.size() > 0) { - final MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, - "", "()V", null, null); + final MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,"", "()V", null, null); if (v.generateCode()) { mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 68426aab20c..bdad028593b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -207,6 +207,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { @Override protected void generateSyntheticParts() { + generateGetTypeInfo(); + generateFieldForObjectInstance(); generateFieldForClassObject(); @@ -220,8 +222,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { throw new RuntimeException("Error generating primary constructor of class " + myClass.getName() + " with kind " + kind, e); } - generateGetTypeInfo(); - generateAccessors(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 5f21e8f80f3..167dbc2f0e8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -679,7 +679,7 @@ public class JetTypeMapper { return new CallableMethod(owner, method, INVOKESPECIAL); } - static int getAccessModifiers(DeclarationDescriptorWithVisibility p, int defaultFlags) { + public static int getAccessModifiers(DeclarationDescriptorWithVisibility p, int defaultFlags) { DeclarationDescriptor declaration = p.getContainingDeclaration(); if(CodegenUtil.isInterface(declaration)) { return ACC_PUBLIC; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 980c3f009fd..45c648d9225 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -71,7 +71,7 @@ public class PropertyCodegen { modifiers = access | Opcodes.ACC_STATIC; } else { - modifiers = Opcodes.ACC_PRIVATE; + modifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0); } if (!propertyDescriptor.isVar()) { modifiers |= Opcodes.ACC_FINAL; diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index 1b0311b49a6..6d15cfc9d09 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -9,6 +9,7 @@ fun typeinfo() : TypeInfo fun typeinfo(expression : T) : TypeInfo annotation class volatile +annotation class atomic fun synchronized(lock: Any, block : () -> R) : R diff --git a/examples/example-actors/.idea/.name b/examples/example-actors/.idea/.name new file mode 100644 index 00000000000..69ccd3fbc40 --- /dev/null +++ b/examples/example-actors/.idea/.name @@ -0,0 +1 @@ +example-actors \ No newline at end of file diff --git a/examples/example-actors/.idea/ant.xml b/examples/example-actors/.idea/ant.xml new file mode 100644 index 00000000000..2581ca3fe84 --- /dev/null +++ b/examples/example-actors/.idea/ant.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/example-actors/.idea/compiler.xml b/examples/example-actors/.idea/compiler.xml new file mode 100644 index 00000000000..a1b41c52c72 --- /dev/null +++ b/examples/example-actors/.idea/compiler.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/examples/example-actors/.idea/copyright/profiles_settings.xml b/examples/example-actors/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000000..3572571ad83 --- /dev/null +++ b/examples/example-actors/.idea/copyright/profiles_settings.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/examples/example-actors/.idea/encodings.xml b/examples/example-actors/.idea/encodings.xml new file mode 100644 index 00000000000..e206d70d859 --- /dev/null +++ b/examples/example-actors/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/example-actors/.idea/misc.xml b/examples/example-actors/.idea/misc.xml new file mode 100644 index 00000000000..97320410eec --- /dev/null +++ b/examples/example-actors/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/examples/example-actors/.idea/modules.xml b/examples/example-actors/.idea/modules.xml new file mode 100644 index 00000000000..55408c99d7a --- /dev/null +++ b/examples/example-actors/.idea/modules.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/examples/example-actors/.idea/scopes/scope_settings.xml b/examples/example-actors/.idea/scopes/scope_settings.xml new file mode 100644 index 00000000000..922003b8433 --- /dev/null +++ b/examples/example-actors/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/examples/example-actors/.idea/uiDesigner.xml b/examples/example-actors/.idea/uiDesigner.xml new file mode 100644 index 00000000000..3b000203088 --- /dev/null +++ b/examples/example-actors/.idea/uiDesigner.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/example-actors/.idea/vcs.xml b/examples/example-actors/.idea/vcs.xml new file mode 100644 index 00000000000..def6a6a1845 --- /dev/null +++ b/examples/example-actors/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/example-actors/.idea/workspace.xml b/examples/example-actors/.idea/workspace.xml new file mode 100644 index 00000000000..63cad3dacd2 --- /dev/null +++ b/examples/example-actors/.idea/workspace.xml @@ -0,0 +1,822 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + + + 1328088553763 + 1328088553763 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No facets are configured + + + + + + + + + + + + + + + 1.6 + + + + + + + + example-actors + + + + + + + + 1.6 + + + + + + + + + + + + + + + + diff --git a/examples/example-actors/example-actors.iml b/examples/example-actors/example-actors.iml new file mode 100644 index 00000000000..b2b23eed2a5 --- /dev/null +++ b/examples/example-actors/example-actors.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/examples/example-actors/src/org/jetbrains/examples/actors/Actors.kt b/examples/example-actors/src/org/jetbrains/examples/actors/Actors.kt new file mode 100644 index 00000000000..a116da31848 --- /dev/null +++ b/examples/example-actors/src/org/jetbrains/examples/actors/Actors.kt @@ -0,0 +1,65 @@ +package org.jetbrains.examples.actors + +import std.concurrent.* +import std.util.* + +import java.util.concurrent.* +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater +import java.util.Date + +class App() : Actor(Executors.newFixedThreadPool(10).sure()) { + private val logger = executor.actor { message -> + println("${Date()}:\t\t$message") + } + + private val actors = Array(100, { createChild(it) }); + + private var finishedChildren = actors.size + + override fun onMessage(message: Any) { + when(message) { + "start" -> { + logger post "app started" + for(a in actors) { + a post "start" + } + } + "child finished" -> { + if(--finishedChildren == 0) { + logger send "app finished" + (executor as ExecutorService).shutdown() + } + } + else -> { + logger post "unknown message $message" + } + } + } + + private fun createChild(index: Int) : Actor = actor { message -> + val next = (index + 1) % actors.size + when(message) { + "start" -> { + logger post "$index started" + actors[next] post #(index, 0) + } + is Tuple2 -> { + logger post "$index received $message" + val from = message._1 + val value = message._2 + if(next != from) { + actors[next] post #(from, value+1) + } + else { + logger post "$index finished" + this@App post "child finished" + } + } + else -> {} + } + } +} + +fun main(args: Array) { + App() post "start" +} \ No newline at end of file diff --git a/stdlib/ktSrc/JavaLang.kt b/stdlib/ktSrc/JavaLang.kt index 687208ae694..bbdbf76245a 100644 --- a/stdlib/ktSrc/JavaLang.kt +++ b/stdlib/ktSrc/JavaLang.kt @@ -7,4 +7,7 @@ val T.javaClass : Class get() = jet.runtime.Intrinsics.getJavaClass(this) as Class val TypeInfo.javaClassForType : Class - get() = (this as org.jetbrains.jet.rt.TypeInfoImpl).getJavaClass().sure() + get() { + println(this) + return (this as org.jetbrains.jet.rt.TypeInfoImpl).getJavaClass().sure() + } diff --git a/stdlib/ktSrc/concurrent/Actors.kt b/stdlib/ktSrc/concurrent/Actors.kt new file mode 100644 index 00000000000..cae87659523 --- /dev/null +++ b/stdlib/ktSrc/concurrent/Actors.kt @@ -0,0 +1,130 @@ +package std.concurrent + +import std.concurrent.* +import std.util.* + +import java.util.concurrent.* +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater +import java.util.Date + +/* +Message handling class which process only one message at any given moment + +Three main ways to use it +- post and forget +- post and await result +- post and assign callback when message processed +*/ +abstract class Actor(protected val executor: Executor) { + // we can not do it private or protected + // otherwise updater defined in class object will not be able to access it + volatile var queue : FunctionalQueue = emptyQueue + + /* + Handle message and return result + This method guaranteed to be executed only one per object at any given time + */ + protected abstract fun onMessage(message: Any) : Any? + + /* + Post message to the actor. + The method returns immediately and the message itself will be processed later + */ + fun post(message: Any) { + while(true) { + val q = queue + if(q.empty) { + if(queueUpdater.compareAndSet(this, q, busyEmptyQueue)) { + executor.execute { process(message) } + break + } + } + else { + val newQueue = (if(q == busyEmptyQueue) emptyQueue else q) add message + if(queueUpdater.compareAndSet(this, q, newQueue)) { + break + } + } + } + } + + /* + Post message to the actor and schedule callback to be executed on given executor when message processed + */ + fun post(message: Any, executor: Executor = this.executor, callback: (Any?)->Unit) = + post(Callback(message, executor, callback)) + + /* + Send message to the actor and await result + */ + fun send(message: Any) : Any? { + val request = Request(message) + post(request) + request.await() + return request.result + } + + private fun nextMessage() { + while(true) { + val q = queue + if(q == busyEmptyQueue) { + if(queueUpdater.compareAndSet(this, busyEmptyQueue, emptyQueue)) { + break; + } + } + else { + val removed = q.removeFirst() + val newQueue = if(removed._2.empty) busyEmptyQueue else removed._2 + if(queueUpdater.compareAndSet(this, q, newQueue)) { + executor.execute { process(removed._1) } + break; + } + } + } + } + + private fun process(message: Any) { + when(message) { + is Request -> { + message.result = onMessage(message.message) + message.countDown() + } + is Callback -> { + val result = onMessage(message.message) + message.executor execute { + val callback = message.callback; + callback(result) + } + } + else -> onMessage(message) + } + + nextMessage() + } + + /* + Create actor on the same executor + */ + fun actor(handler: (Any)->Any?) = executor.actor(handler) + + class object { + val queueUpdater = AtomicReferenceFieldUpdater.newUpdater(typeinfo.javaClassForType,typeinfo>().javaClassForType, "queue").sure() + val emptyQueue = FunctionalQueue() + val busyEmptyQueue = FunctionalQueue() add "busy empty queue" + + class Request(val message: Any) : java.util.concurrent.CountDownLatch(1) { + var result: Any? = null + } + + class Callback(val message: Any, val executor: Executor, val callback: (Any?) -> Unit) + } +} + +fun Executor.actor(handler: (Any)->Any?) : Actor = object: Actor(this) { + override fun onMessage(message: Any) { + handler(message) + } +} + +fun singleThreadActor(handler: (Any)->Any?) : Actor = Executors.newSingleThreadExecutor().sure().actor(handler) + diff --git a/stdlib/ktSrc/concurrent/Thread.kt b/stdlib/ktSrc/concurrent/Thread.kt index 5860d9426cb..a6ecf1eaee3 100644 --- a/stdlib/ktSrc/concurrent/Thread.kt +++ b/stdlib/ktSrc/concurrent/Thread.kt @@ -3,7 +3,8 @@ package std.concurrent import java.lang.* import java.util.concurrent.Executor -inline val currentThread = Thread.currentThread().sure() +inline val currentThread : Thread + get() = Thread.currentThread().sure() inline var Thread.name : String get() = getName().sure()