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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $USER_HOME$/.subversion_IDEA
+ false
+
+
+
+
+ 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()