Initial support for message sends.
authorJan Vrany <jan.vrany@fit.cvut.cz>
Thu, 23 Jun 2016 22:26:37 +0100
changeset 29 5693302d4e24
parent 28 4bdee0ee3d83
child 30 cfe81a04e380
Initial support for message sends. For now, the C1 compiler uses simple `__SSENDx`s so no need to bother with inline caches. This can (and will) be addressed in a future.
c1/DragonFly__C1Compiler.st
c1/DragonFly__C1CompilerTests.st
c1/DragonFly__C1LLVMTypes.st
--- a/c1/DragonFly__C1Compiler.st	Mon Jun 20 09:38:10 2016 +0100
+++ b/c1/DragonFly__C1Compiler.st	Thu Jun 23 22:26:37 2016 +0100
@@ -134,6 +134,16 @@
     "Created: / 17-06-2016 / 23:25:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+function__SSEND: nArgs
+    | name |
+
+    self assert: (nArgs between: 0 and:15).
+    name := '__SSEND', nArgs printString.
+    ^ self functionNamed: name type: (TySSENDSs at: nArgs + 1).
+
+    "Created: / 23-06-2016 / 22:04:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 method
     ^ method
 !
@@ -445,6 +455,20 @@
     "Created: / 17-06-2016 / 23:38:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!C1Compiler methodsFor:'private-sends'!
+
+emitSend: selector to: receiver with: arguments
+    self assert: (arguments size between: 0 and: 15) description: 'Invalid number of arguments. VM supports max 15 args'.
+
+    ^ asm call: (self function__SSEND: arguments size) _: {
+        receiver .                  "/ receiver
+        self loadLiteral: selector ."/ selector
+        LLVMConstant sint32: 0.     "/ lineNr (no line info for now)
+        } , arguments
+
+    "Created: / 23-06-2016 / 22:17:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !C1Compiler methodsFor:'private-testing'!
 
 isNilObject: value
--- a/c1/DragonFly__C1CompilerTests.st	Mon Jun 20 09:38:10 2016 +0100
+++ b/c1/DragonFly__C1CompilerTests.st	Thu Jun 23 22:26:37 2016 +0100
@@ -41,8 +41,62 @@
 "
 ! !
 
+!C1CompilerTests methodsFor:'helpers'!
+
+sum: a and: b
+    ^ a + b
+
+    "Created: / 23-06-2016 / 22:21:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !C1CompilerTests methodsFor:'tests - building blocks'!
 
+test_emitSend_01
+    | method compiler asm |
+
+    method := Method new.
+    method numberOfArgs: 0.
+    method numberOfVars: 0.
+    method stackSize: 0.
+
+    compiler := C1Compiler new.
+    compiler method: method.
+    compiler prepare.
+
+    asm := compiler instVarNamed: #asm.
+    asm ret: (compiler emitSend: #sum:and: to: (compiler loadLiteral: self) with: { compiler loadLiteral: 1 . compiler loadLiteral: 2 }).
+
+    compiler finish.
+
+    self assert: method code notNil.
+    self assert: (method valueWithReceiver:nil arguments: #()) == 3
+
+    "Created: / 23-06-2016 / 22:21:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_emitSend_02
+    | method compiler asm |
+
+    method := Method new.
+    method numberOfArgs: 0.
+    method numberOfVars: 0.
+    method stackSize: 0.
+
+    compiler := C1Compiler new.
+    compiler method: method.
+    compiler prepare.
+
+    asm := compiler instVarNamed: #asm.
+    asm ret: (compiler emitSend: #yourself to: (compiler loadLiteral: self) with: #()).
+
+    compiler finish.
+
+    self assert: method code notNil.
+    self assert: (method valueWithReceiver:nil arguments: #()) == self
+
+    "Created: / 23-06-2016 / 22:28:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 test_isSmallIntegerObject
     | compiler module function asm jit test |
 
--- a/c1/DragonFly__C1LLVMTypes.st	Mon Jun 20 09:38:10 2016 +0100
+++ b/c1/DragonFly__C1LLVMTypes.st	Thu Jun 23 22:26:37 2016 +0100
@@ -29,7 +29,7 @@
 		TyContextFieldIndexSelector TyContextFieldIndexSearchClass
 		TyContextFieldIndexMethod TyContextFieldIndexLineNr
 		TyContextFieldIndexRetvalTemp TyContextFieldIndexHandleS
-		TyMKREALCONTEXT5'
+		TyMKREALCONTEXT5 TySSENDSs'
 	poolDictionaries:''
 	category:'DragonFly-C1'
 !
@@ -245,9 +245,123 @@
         } returning: TyOBJ .
     }.
 
-    TyMKREALCONTEXT5 := LLVMType function: { TyOBJ } returning: TyOBJ
+    TyMKREALCONTEXT5 := LLVMType function: { TyOBJ } returning: TyOBJ.
 
-    "Modified: / 19-06-2016 / 09:45:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    TySSENDSs := {
+        "/ 0 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+        } returning: TyOBJ .
+        "/ 1 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ .
+        } returning: TyOBJ .
+        "/ 2 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 3 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 4 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 5 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 6 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 7 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 8 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 9 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 10 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 11 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 12 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 13 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 14 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+        "/ 16 args
+        LLVMType function: {
+            TyOBJ.                      "/ self
+            TyOBJ.                      "/ selector
+            LLVMType int32.             "/ lineNr
+            TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ . TyOBJ .
+        } returning: TyOBJ .
+    }.
+
+    "Modified: / 23-06-2016 / 22:08:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !C1LLVMTypes class methodsFor:'accessing'!