added more code for process scheduling
This commit is contained in:
		@ -7,12 +7,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	#method(#class) dump
 | 
						#method(#class) dump
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #dump>
 | 
							<primitive: #_dump>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method dump
 | 
						#method dump
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #dump>
 | 
							<primitive: #_dump>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
@ -31,16 +31,39 @@
 | 
				
			|||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method(#class) basicNew
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_basic_new>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method(#class) basicNew: anInteger
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_basic_new_with_size>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method(#class) new
 | 
						#method(#class) new
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #new>
 | 
							| x |
 | 
				
			||||||
		self primitiveFailed.
 | 
							x := self basicNew.
 | 
				
			||||||
 | 
							x initialize. "TODO: assess if it's good to call 'initialize' from new."
 | 
				
			||||||
 | 
							^x.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method(#class) new: anInteger
 | 
						#method(#class) new: anInteger
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #newWithSize>
 | 
							| x |
 | 
				
			||||||
		self primitiveFailed.
 | 
							x := self basicNew: anInteger.
 | 
				
			||||||
 | 
							x initialize. "TODO: assess if it's good to call 'initialize' from new."
 | 
				
			||||||
 | 
							^x.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method initialize
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							"a subclass may override this method."
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							^self.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
@ -48,12 +71,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	#method class
 | 
						#method class
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #class>
 | 
							<primitive: #_class>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method(#class) class
 | 
						#method(#class) class
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #class>
 | 
							<primitive: #_class>
 | 
				
			||||||
		^Class
 | 
							^Class
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -62,37 +85,38 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	#method basicSize
 | 
						#method basicSize
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #basicSize>
 | 
							<primitive: #_basic_size>
 | 
				
			||||||
		^0
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method(#class) basicSize
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_basic_size>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method basicAt: anInteger
 | 
						#method basicAt: anInteger
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #basicAt>
 | 
							<primitive: #_basic_at>
 | 
				
			||||||
		self error: 'out of range'.
 | 
							self error: 'out of range'.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method basicAt: anInteger put: anObject
 | 
						#method basicAt: anInteger put: anObject
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #basicAtPut>
 | 
							<primitive: #_basic_at_put>
 | 
				
			||||||
		self error: 'out of range'.
 | 
							self error: 'out of range'.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method(#class) basicSize
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #basicSize>
 | 
					 | 
				
			||||||
		^0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method(#class) basicAt: anInteger
 | 
						#method(#class) basicAt: anInteger
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #basicAt>
 | 
							<primitive: #_basic_at>
 | 
				
			||||||
		self error: 'out of range'.
 | 
							self error: 'out of range'.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method(#class) basicAt: anInteger put: anObject
 | 
						#method(#class) basicAt: anInteger put: anObject
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #basicAtPut>
 | 
							<primitive: #_basic_at_put>
 | 
				
			||||||
		self error: 'out of range'.
 | 
							self error: 'out of range'.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -103,12 +127,12 @@
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		"check if the receiver is identical to anObject.
 | 
							"check if the receiver is identical to anObject.
 | 
				
			||||||
		 this doesn't compare the contents"
 | 
							 this doesn't compare the contents"
 | 
				
			||||||
		<primitive: #identical>
 | 
							<primitive: #_identical>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method ~~ anObject
 | 
						#method ~~ anObject
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #notIdentical>
 | 
							<primitive: #_not_identical>
 | 
				
			||||||
		^(self == anObject) not.
 | 
							^(self == anObject) not.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -116,12 +140,12 @@
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		"check if the receiver is identical to anObject.
 | 
							"check if the receiver is identical to anObject.
 | 
				
			||||||
		 this doesn't compare the contents"
 | 
							 this doesn't compare the contents"
 | 
				
			||||||
		<primitive: #identical>
 | 
							<primitive: #_identical>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method(#class) ~~ anObject
 | 
						#method(#class) ~~ anObject
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #notIdentical>
 | 
							<primitive: #_not_identical>
 | 
				
			||||||
		^(self == anObject) not.
 | 
							^(self == anObject) not.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										186
									
								
								stix/kernel/Context.st
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								stix/kernel/Context.st
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,186 @@
 | 
				
			|||||||
 | 
					#class(#pointer) Context(Apex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#class(#pointer) MethodContext(Context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#dcl sender ip sp ntmprs method receiver home origin.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method pc
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^ip
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method pc: anInteger
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ip := anInteger.
 | 
				
			||||||
 | 
							"sp := sp - 1."  "whould this always work??? "
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method sp
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^sp.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						#method sp: anInteger
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							sp := anInteger.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method pc: aPC sp: aSP
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ip := aPC.
 | 
				
			||||||
 | 
							sp := aSP.
 | 
				
			||||||
 | 
							##sp := sp - 1.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#class(#pointer) BlockContext(Context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#dcl caller ip sp ntmprs nargs source  home origin.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method fork
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							"crate a new process in the runnable state"
 | 
				
			||||||
 | 
					## TODO
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method newProcess
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							"create a new process in the suspended state"
 | 
				
			||||||
 | 
					## TODO
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method newProcessWith: anArray
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							"create a new process in the suspended state passing the elements
 | 
				
			||||||
 | 
							 of anArray as block arguments"
 | 
				
			||||||
 | 
					## TODO
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method value
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_block_value>
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method value: a 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_block_value>
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method value: a value: b
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_block_value>
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method value: a value: b value: c
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_block_value>
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method ifTrue: aBlock
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^(self value) ifTrue: aBlock.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method ifFalse: aBlock
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^(self value) ifFalse: aBlock.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method ifTrue: trueBlock ifFalse: falseBlock
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^(self value) ifTrue: trueBlock ifFalse: falseBlock
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method whileTrue: aBlock
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
					## http://stackoverflow.com/questions/2500483/is-there-a-way-in-a-message-only-language-to-define-a-whiletrue-message-without
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##		^(self value) ifTrue: [aBlock value. self whileTrue: aBlock].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							## less block context before whileTrue: is recursively sent.
 | 
				
			||||||
 | 
							## whileTrue: is sent in a method context.
 | 
				
			||||||
 | 
					##		(self value) ifFalse: [^nil].
 | 
				
			||||||
 | 
					##		aBlock value. 
 | 
				
			||||||
 | 
					##		self whileTrue: aBlock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
							| pc sp xsp |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sp := thisContext sp.
 | 
				
			||||||
 | 
							sp := sp - 1. "decrement sp by 1 becuase thisContext pushed above affects the sp method"
 | 
				
			||||||
 | 
							pc := thisContext pc.
 | 
				
			||||||
 | 
							self value ifFalse: [ ^nil "^self" ].
 | 
				
			||||||
 | 
							aBlock value.
 | 
				
			||||||
 | 
							##thisContext pc: pc - 3 sp: sp.
 | 
				
			||||||
 | 
							##thisContext pc: pc + 2 sp: sp.   
 | 
				
			||||||
 | 
							thisContext pc: pc + 1 sp: sp.   
 | 
				
			||||||
 | 
							## this +2 or - 3 above is dependent on the byte code instruction size used for 'store'  
 | 
				
			||||||
 | 
							## +2 to skip STORE_INTO_TEMP(pc) and POP_STACKTOP.
 | 
				
			||||||
 | 
							## TODO: make it independent of the byte code size 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##        #<label>:
 | 
				
			||||||
 | 
					##		thisContext pc: #<label> sp: sp.
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					##		| pc |
 | 
				
			||||||
 | 
					##		pc := thisContext pc.
 | 
				
			||||||
 | 
					##		^self value ifTrue: [aBlock value. thisContext pc: pc]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##		self value ifTrue: [ aBlock value. thisContext restart. ].
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method pc
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^ip
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method pc: anInteger
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ip := anInteger.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						#method sp
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^sp
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method sp: anInteger
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							sp := anInteger.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method restart
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ip := source pc.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"------ TODO: -------------------------------------"
 | 
				
			||||||
 | 
						#method on: anError do: anExceptionBlock
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							"TODO: handle if anError is an ErrorSet .."
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method ensure: aBlock
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method ifCurtailed: aBlock
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"------ TODO: -------------------------------------"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										80
									
								
								stix/kernel/Process.st
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								stix/kernel/Process.st
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					#class(#pointer) Process(Object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#dcl sp state prev next.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method prev
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^self.prev.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method next
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^self.next.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method next: aProcess
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							self.next := aProcess.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method prev: aProcess
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							self.prev := aProcess.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#class ProcessScheduler(Object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#dcl tally head tail active.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method new
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							"instantiation is not allowed"
 | 
				
			||||||
 | 
							^nil. "TODO: raise an exception"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method activeProcess
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							^self.active.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method add: aProcess
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_scheduler_add>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							(self.tally = 0)
 | 
				
			||||||
 | 
								ifTrue: [
 | 
				
			||||||
 | 
									self.head := aProcess.
 | 
				
			||||||
 | 
									self.tail := aProcess.
 | 
				
			||||||
 | 
									self.tally := 1.
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
								ifFalse: [
 | 
				
			||||||
 | 
									aProcess next: self.head.
 | 
				
			||||||
 | 
									self.head prev: aProcess.
 | 
				
			||||||
 | 
									self.head := aProcess.
 | 
				
			||||||
 | 
									self.tally := self.tally + 1.
 | 
				
			||||||
 | 
								].
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method remove: aProcess
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							"<primitive: #_scheduler_remove>"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"TODO: "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"
 | 
				
			||||||
 | 
						#method yield
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #processYield>
 | 
				
			||||||
 | 
							self primitiveFailed
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method enter: aContext
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #processEnter>
 | 
				
			||||||
 | 
							self primitiveFailed
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -29,41 +29,61 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#class Number(Magnitude)
 | 
					#class Number(Magnitude)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	#method add: aNumber
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #integerAdd>
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method + aNumber
 | 
						#method + aNumber
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #integerAdd>
 | 
							<primitive: #_integer_add>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method - aNumber
 | 
						#method - aNumber
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #integerSub>
 | 
							<primitive: #_integer_sub>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method * aNumber
 | 
						#method * aNumber
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #integerMul>
 | 
							<primitive: #_integer_mul>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method = aNumber
 | 
						#method = aNumber
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #integerEQ>
 | 
							<primitive: #_integer_eq>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method ~= aNumber
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_integer_ne>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method < aNumber
 | 
						#method < aNumber
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #integerLT>
 | 
							<primitive: #_integer_lt>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method > aNumber
 | 
						#method > aNumber
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #integerGT>
 | 
							<primitive: #_integer_gt>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method <= aNumber
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_integer_le>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#method >= aNumber
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							<primitive: #_integer_ge>
 | 
				
			||||||
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method to: end by: step do: aBlock
 | 
						#method to: end by: step do: aBlock
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -100,169 +120,13 @@
 | 
				
			|||||||
#include 'Collection-Array.st'.
 | 
					#include 'Collection-Array.st'.
 | 
				
			||||||
#include 'Collection-Set.st'.
 | 
					#include 'Collection-Set.st'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#class(#pointer) Context(Apex)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#class(#pointer) MethodContext(Context)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	#dcl sender ip sp ntmprs method receiver home origin.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method pc
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^ip
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method pc: anInteger
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ip := anInteger.
 | 
					 | 
				
			||||||
		"sp := sp - 1."  "whould this always work??? "
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method sp
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^sp.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	#method sp: anInteger
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		sp := anInteger.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method pc: aPC sp: aSP
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ip := aPC.
 | 
					 | 
				
			||||||
		sp := aSP.
 | 
					 | 
				
			||||||
		##sp := sp - 1.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#class(#pointer) BlockContext(Context)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	#dcl caller ip sp ntmprs nargs source  home origin.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method value
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #blockValue>
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method value: a 
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #blockValue>
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method value: a value: b
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #blockValue>
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method value: a value: b value: c
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #blockValue>
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method whileTrue: aBlock
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
## http://stackoverflow.com/questions/2500483/is-there-a-way-in-a-message-only-language-to-define-a-whiletrue-message-without
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
##		^(self value) ifTrue: [aBlock value. self whileTrue: aBlock].
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		## less block context before whileTrue: is recursively sent.
 | 
					 | 
				
			||||||
		## whileTrue: is sent in a method context.
 | 
					 | 
				
			||||||
##		(self value) ifFalse: [^nil].
 | 
					 | 
				
			||||||
##		aBlock value. 
 | 
					 | 
				
			||||||
##		self whileTrue: aBlock.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
		| pc sp xsp |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sp := thisContext sp.
 | 
					 | 
				
			||||||
		sp := sp - 1. "decrement sp by 1 becuase thisContext pushed above affects the sp method"
 | 
					 | 
				
			||||||
		pc := thisContext pc.
 | 
					 | 
				
			||||||
		self value ifFalse: [ ^nil "^self" ].
 | 
					 | 
				
			||||||
		aBlock value.
 | 
					 | 
				
			||||||
		##thisContext pc: pc - 3 sp: sp.
 | 
					 | 
				
			||||||
		##thisContext pc: pc + 2 sp: sp.   
 | 
					 | 
				
			||||||
		thisContext pc: pc + 1 sp: sp.   
 | 
					 | 
				
			||||||
		## this +2 or - 3 above is dependent on the byte code instruction size used for 'store'  
 | 
					 | 
				
			||||||
		## +2 to skip STORE_INTO_TEMP(pc) and POP_STACKTOP.
 | 
					 | 
				
			||||||
		## TODO: make it independent of the byte code size 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
##        #<label>:
 | 
					 | 
				
			||||||
##		thisContext pc: #<label> sp: sp.
 | 
					 | 
				
			||||||
##
 | 
					 | 
				
			||||||
##		| pc |
 | 
					 | 
				
			||||||
##		pc := thisContext pc.
 | 
					 | 
				
			||||||
##		^self value ifTrue: [aBlock value. thisContext pc: pc]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## ----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
##		self value ifTrue: [ aBlock value. thisContext restart. ].
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method pc
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^ip
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method pc: anInteger
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ip := anInteger.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	#method sp
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^sp
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method sp: anInteger
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		sp := anInteger.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method restart
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ip := source pc.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"------ TODO: -------------------------------------"
 | 
					 | 
				
			||||||
	#method on: anError do: anExceptionBlock
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		"TODO: handle if anError is an ErrorSet .."
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method ensure: aBlock
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#method ifCurtailed: aBlock
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"------ TODO: -------------------------------------"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#class(#pointer) CompiledMethod(Object)
 | 
					#class(#pointer) CompiledMethod(Object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	#dcl owner preamble preamble_data_1 preamble_data_2 ntmprs nargs code source.
 | 
						#dcl owner preamble preamble_data_1 preamble_data_2 ntmprs nargs code source.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#class(#pointer) Process(Object)
 | 
					#include 'Context.st'.
 | 
				
			||||||
{
 | 
					#include 'Process.st'.
 | 
				
			||||||
	#dcl state.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#class FFI(Object)
 | 
					#class FFI(Object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -313,23 +177,23 @@ f isNil ifTrue: [ self error: 'No such function' ].
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	#method privateOpen: aString
 | 
						#method privateOpen: aString
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #ffiOpen>
 | 
							<primitive: #_ffi_open>
 | 
				
			||||||
		^nil. ## TODO: Error signal: 'can not open'
 | 
							^nil. ## TODO: Error signal: 'can not open'
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method privateClose: aHandle
 | 
						#method privateClose: aHandle
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #ffiClose>
 | 
							<primitive: #_ffi_close>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method privateCall: aSymbol withSig: aString withArgs: anArray
 | 
						#method privateCall: aSymbol withSig: aString withArgs: anArray
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #ffiCall>
 | 
							<primitive: #_ffi_call>
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#method privateGetSymbol: aString in: aHandle
 | 
						#method privateGetSymbol: aString in: aHandle
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #ffiGetSym>
 | 
							<primitive: #_ffi_getsym>
 | 
				
			||||||
		^nil.
 | 
							^nil.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -240,9 +240,11 @@
 | 
				
			|||||||
		## ffi call: #puts withSig: 'i|s' withArgs: #('hello world').
 | 
							## ffi call: #puts withSig: 'i|s' withArgs: #('hello world').
 | 
				
			||||||
		ffi close.
 | 
							ffi close.
 | 
				
			||||||
"
 | 
					"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self abc.
 | 
							self abc.
 | 
				
			||||||
		self abc.
 | 
							self abc.
 | 
				
			||||||
		self abc.
 | 
							self abc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"
 | 
					"
 | 
				
			||||||
		FFI isNil dump.
 | 
							FFI isNil dump.
 | 
				
			||||||
		FFI notNil dump.
 | 
							FFI notNil dump.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										151
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							
							
						
						
									
										151
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							@ -334,7 +334,6 @@ static int activate_initial_context (stix_t* stix, const stix_ucs_t* objname, co
 | 
				
			|||||||
	 *    push Stix
 | 
						 *    push Stix
 | 
				
			||||||
	 *    send #main
 | 
						 *    send #main
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					 | 
				
			||||||
	stix_oop_context_t ctx;
 | 
						stix_oop_context_t ctx;
 | 
				
			||||||
	stix_oop_association_t ass;
 | 
						stix_oop_association_t ass;
 | 
				
			||||||
	stix_oop_method_t mth;
 | 
						stix_oop_method_t mth;
 | 
				
			||||||
@ -364,7 +363,7 @@ TODO: overcome this problem
 | 
				
			|||||||
	/* the initial context starts the life of the entire VM
 | 
						/* the initial context starts the life of the entire VM
 | 
				
			||||||
	 * and is not really worked on except that it is used to call the
 | 
						 * and is not really worked on except that it is used to call the
 | 
				
			||||||
	 * initial method. so it doesn't really require any extra stack space.
 | 
						 * initial method. so it doesn't really require any extra stack space.
 | 
				
			||||||
	 * TODO: verify my theory above is true */
 | 
						 * TODO: verify this theory of mine. */
 | 
				
			||||||
	stix->ip = 0;
 | 
						stix->ip = 0;
 | 
				
			||||||
	stix->sp = -1;
 | 
						stix->sp = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -385,7 +384,7 @@ TODO: overcome this problem
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ------------------------------------------------------------------------- */
 | 
					/* ------------------------------------------------------------------------- */
 | 
				
			||||||
static int primitive_dump (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_dump (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_ooi_t i;
 | 
						stix_ooi_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -406,7 +405,7 @@ static int primitive_dump (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1; /* success */
 | 
						return 1; /* success */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_identical (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_identical (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg, b;
 | 
						stix_oop_t rcv, arg, b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -422,7 +421,7 @@ static int primitive_identical (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_not_identical (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_not_identical (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg, b;
 | 
						stix_oop_t rcv, arg, b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -438,7 +437,7 @@ static int primitive_not_identical (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_class (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_class (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, c;
 | 
						stix_oop_t rcv, c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -449,7 +448,7 @@ static int primitive_class (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1; /* success */
 | 
						return 1; /* success */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_new (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_basic_new (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, obj;
 | 
						stix_oop_t rcv, obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -471,7 +470,7 @@ static int primitive_new (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1; /* success */
 | 
						return 1; /* success */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_new_with_size (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_basic_new_with_size (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, szoop, obj;
 | 
						stix_oop_t rcv, szoop, obj;
 | 
				
			||||||
	stix_oow_t size;
 | 
						stix_oow_t size;
 | 
				
			||||||
@ -515,7 +514,7 @@ static int primitive_new_with_size (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1; /* success */
 | 
						return 1; /* success */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_basic_size (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_basic_size (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv;
 | 
						stix_oop_t rcv;
 | 
				
			||||||
	STIX_ASSERT (nargs == 0);
 | 
						STIX_ASSERT (nargs == 0);
 | 
				
			||||||
@ -526,7 +525,7 @@ static int primitive_basic_size (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_basic_at (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, pos, v;
 | 
						stix_oop_t rcv, pos, v;
 | 
				
			||||||
	stix_ooi_t idx;
 | 
						stix_ooi_t idx;
 | 
				
			||||||
@ -587,7 +586,7 @@ static int primitive_basic_at (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_basic_at_put (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, pos, val;
 | 
						stix_oop_t rcv, pos, val;
 | 
				
			||||||
	stix_ooi_t idx;
 | 
						stix_ooi_t idx;
 | 
				
			||||||
@ -670,7 +669,7 @@ static int primitive_basic_at_put (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_block_value (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_block_value (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_context_t blkctx, org_blkctx;
 | 
						stix_oop_context_t blkctx, org_blkctx;
 | 
				
			||||||
	stix_ooi_t local_ntmprs, i;
 | 
						stix_ooi_t local_ntmprs, i;
 | 
				
			||||||
@ -772,7 +771,7 @@ printf ("<<ENTERING BLOCK>>\n");
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_add (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_add (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_ooi_t tmp;
 | 
						stix_ooi_t tmp;
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
@ -796,7 +795,7 @@ static int primitive_integer_add (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_sub (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_sub (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_ooi_t tmp;
 | 
						stix_ooi_t tmp;
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
@ -820,7 +819,7 @@ static int primitive_integer_sub (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_mul (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_mul (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_ooi_t tmp;
 | 
						stix_ooi_t tmp;
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
@ -844,7 +843,7 @@ static int primitive_integer_mul (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_eq (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_eq (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -872,7 +871,7 @@ static int primitive_integer_eq (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_ne (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_ne (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -899,7 +898,7 @@ static int primitive_integer_ne (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
/* TODO: handle LargeInteger */
 | 
					/* TODO: handle LargeInteger */
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static int primitive_integer_lt (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_lt (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -927,7 +926,7 @@ static int primitive_integer_lt (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_gt (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_gt (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -955,7 +954,7 @@ static int primitive_integer_gt (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_le (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_le (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -983,7 +982,7 @@ static int primitive_integer_le (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_integer_ge (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_integer_ge (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1011,7 +1010,18 @@ static int primitive_integer_ge (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_ffi_open (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_scheduler_add (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int prim_scheduler_remove (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int prim_ffi_open (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
	void* handle;
 | 
						void* handle;
 | 
				
			||||||
@ -1049,7 +1059,7 @@ static int primitive_ffi_open (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_ffi_close (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_ffi_close (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, arg;
 | 
						stix_oop_t rcv, arg;
 | 
				
			||||||
	void* handle;
 | 
						void* handle;
 | 
				
			||||||
@ -1074,7 +1084,7 @@ static int primitive_ffi_close (stix_t* stix, stix_ooi_t nargs)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_ffi_call (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_ffi_call (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, fun, sig, args;
 | 
						stix_oop_t rcv, fun, sig, args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1243,7 +1253,7 @@ printf ("CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int primitive_ffi_getsym (stix_t* stix, stix_ooi_t nargs)
 | 
					static int prim_ffi_getsym (stix_t* stix, stix_ooi_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_t rcv, hnd, fun;
 | 
						stix_oop_t rcv, hnd, fun;
 | 
				
			||||||
	void* sym;
 | 
						void* sym;
 | 
				
			||||||
@ -1286,43 +1296,47 @@ printf ("wrong function name...\n");
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct primitive_t
 | 
					struct prim_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_ooi_t          nargs; /* expected number of arguments */
 | 
						stix_ooi_t          nargs;   /* expected number of arguments */
 | 
				
			||||||
	stix_prim_impl_t    handler;
 | 
						stix_prim_impl_t    handler;
 | 
				
			||||||
	const char*         name; /* the name is supposed to be 7-bit ascii only */
 | 
						const char*         name;    /* the name is supposed to be 7-bit ascii only */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct primitive_t primitive_t;
 | 
					typedef struct prim_t prim_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static primitive_t primitives[] =
 | 
					static prim_t primitives[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	{  -1,   primitive_dump,                 "dump"          },
 | 
						{  -1,   prim_dump,                 "_dump"                },
 | 
				
			||||||
	{   1,   primitive_identical,            "identical"     },
 | 
						{   1,   prim_identical,            "_identical"           },
 | 
				
			||||||
	{   1,   primitive_not_identical,        "notIdentical"  },
 | 
						{   1,   prim_not_identical,        "_not_identical"       },
 | 
				
			||||||
	{   0,   primitive_class,                "class"         },
 | 
						{   0,   prim_class,                "_class"               },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{   0,   primitive_new,                  "new"           },
 | 
						{   0,   prim_basic_new,            "_basic_new"           },
 | 
				
			||||||
	{   1,   primitive_new_with_size,        "newWithSize"   },
 | 
						{   1,   prim_basic_new_with_size,  "_basic_new_with_size" },
 | 
				
			||||||
	{   0,   primitive_basic_size,           "basicSize"     },
 | 
						{   0,   prim_basic_size,           "_basic_size"          },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{   1,   primitive_basic_at,             "basicAt"       },
 | 
						{   1,   prim_basic_at,             "_basic_at"            },
 | 
				
			||||||
	{   2,   primitive_basic_at_put,         "basicAtPut"    },
 | 
						{   2,   prim_basic_at_put,         "_basic_at_put"        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{  -1,   primitive_block_value,          "blockValue"    },
 | 
						{  -1,   prim_block_value,          "_block_value"         },
 | 
				
			||||||
	{   1,   primitive_integer_add,          "integerAdd"    },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_sub,          "integerSub"    },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_mul,          "integerMul"    },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_eq,           "integerEQ"     },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_ne,           "integerNE"     },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_lt,           "integerLT"     },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_gt,           "integerGT"     },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_le,           "integerLE"     },
 | 
					 | 
				
			||||||
	{   1,   primitive_integer_ge,           "integerGE"     },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{   1,   primitive_ffi_open,             "ffiOpen"       },
 | 
						{   1,   prim_integer_add,          "_integer_add"         },
 | 
				
			||||||
	{   1,   primitive_ffi_close,            "ffiClose"      },
 | 
						{   1,   prim_integer_sub,          "_integer_sub"         },
 | 
				
			||||||
	{   2,   primitive_ffi_getsym,           "ffiGetSym"     },
 | 
						{   1,   prim_integer_mul,          "_integer_mul"         },
 | 
				
			||||||
	{   3,   primitive_ffi_call,             "ffiCall"       }
 | 
						{   1,   prim_integer_eq,           "_integer_eq"          },
 | 
				
			||||||
 | 
						{   1,   prim_integer_ne,           "_integer_ne"          },
 | 
				
			||||||
 | 
						{   1,   prim_integer_lt,           "_integer_lt"          },
 | 
				
			||||||
 | 
						{   1,   prim_integer_gt,           "_integer_gt"          },
 | 
				
			||||||
 | 
						{   1,   prim_integer_le,           "_integer_le"          },
 | 
				
			||||||
 | 
						{   1,   prim_integer_ge,           "_integer_ge"          },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{   1,   prim_scheduler_add,        "_scheduler_add"       },
 | 
				
			||||||
 | 
						{   1,   prim_scheduler_remove,     "_scheduler_remove"    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{   1,   prim_ffi_open,             "_ffi_open"            },
 | 
				
			||||||
 | 
						{   1,   prim_ffi_close,            "_ffi_close"           },
 | 
				
			||||||
 | 
						{   2,   prim_ffi_getsym,           "_ffi_getsym"          },
 | 
				
			||||||
 | 
						{   3,   prim_ffi_call,             "_ffi_call"            }
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1342,14 +1356,7 @@ int stix_getprimno (stix_t* stix, const stix_ucs_t* name)
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct stix_prim_mod_data_t 
 | 
					static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_uch_t* name, stix_oow_t len)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	void* handle;
 | 
					 | 
				
			||||||
	stix_prim_mod_t mod;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct stix_prim_mod_data_t stix_prim_mod_data_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static stix_prim_impl_t query_primitive_module (stix_t* stix, const stix_uch_t* name, stix_oow_t len)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_rbt_pair_t* pair;
 | 
						stix_rbt_pair_t* pair;
 | 
				
			||||||
	stix_prim_mod_data_t* mdp;
 | 
						stix_prim_mod_data_t* mdp;
 | 
				
			||||||
@ -1396,6 +1403,8 @@ static stix_prim_impl_t query_primitive_module (stix_t* stix, const stix_uch_t*
 | 
				
			|||||||
#if defined(STIX_ENABLE_STATIC_MODULE)
 | 
					#if defined(STIX_ENABLE_STATIC_MODULE)
 | 
				
			||||||
		/* attempt to find a statically linked module */
 | 
							/* attempt to find a statically linked module */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*TODO: CHANGE THIS PART */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* TODO: binary search ... */
 | 
							/* TODO: binary search ... */
 | 
				
			||||||
		for (n = 0; n < STIX_COUNTOF(static_modtab); n++)
 | 
							for (n = 0; n < STIX_COUNTOF(static_modtab); n++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -1474,18 +1483,14 @@ static stix_prim_impl_t query_primitive_module (stix_t* stix, const stix_uch_t*
 | 
				
			|||||||
		mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair);
 | 
							mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair);
 | 
				
			||||||
		if (load (stix, &mdp->mod) <= -1)
 | 
							if (load (stix, &mdp->mod) <= -1)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* stix->errnum = STIX_ENOENT; TODO: proper error code and handling */
 | 
								stix->errnum = STIX_ENOENT; /* TODO: proper error code and handling */
 | 
				
			||||||
			stix_rbt_delete (&stix->pmtable, name, mod_name_len);
 | 
								stix_rbt_delete (&stix->pmtable, name, mod_name_len);
 | 
				
			||||||
			stix->vmprim.mod_close (stix, mdp->handle);
 | 
								stix->vmprim.mod_close (stix, mdp->handle);
 | 
				
			||||||
			return STIX_NULL;
 | 
								return STIX_NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!mdp->mod.query)
 | 
							/* the module loader must ensure to set a proper query handler */
 | 
				
			||||||
		{
 | 
							STIX_ASSERT (mdp->mod.query != STIX_NULL);
 | 
				
			||||||
			/* the module must be at fault */
 | 
					 | 
				
			||||||
			stix->errnum = STIX_EINVAL; /* TODO: proper error code and handling */
 | 
					 | 
				
			||||||
			return STIX_NULL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
@ -2133,7 +2138,7 @@ printf ("]\n");
 | 
				
			|||||||
						/* merge two SmallIntegers to get a full pointer */
 | 
											/* merge two SmallIntegers to get a full pointer */
 | 
				
			||||||
						handler = (stix_oow_t)STIX_OOP_TO_SMINT(newmth->preamble_data[0]) << (STIX_OOW_BITS / 2) | 
 | 
											handler = (stix_oow_t)STIX_OOP_TO_SMINT(newmth->preamble_data[0]) << (STIX_OOW_BITS / 2) | 
 | 
				
			||||||
						          (stix_oow_t)STIX_OOP_TO_SMINT(newmth->preamble_data[1]);
 | 
											          (stix_oow_t)STIX_OOP_TO_SMINT(newmth->preamble_data[1]);
 | 
				
			||||||
						if (!handler) handler = query_primitive_module (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name));
 | 
											if (!handler) handler = query_prim_module (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						if (handler)
 | 
											if (handler)
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
@ -2344,7 +2349,7 @@ printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				/* the block context object created here is used
 | 
									/* the block context object created here is used
 | 
				
			||||||
				 * as a base object for block context activation.
 | 
									 * as a base object for block context activation.
 | 
				
			||||||
				 * primitive_block_value() clones a block 
 | 
									 * prim_block_value() clones a block 
 | 
				
			||||||
				 * context and activates the cloned context.
 | 
									 * context and activates the cloned context.
 | 
				
			||||||
				 * this base block context is created with no 
 | 
									 * this base block context is created with no 
 | 
				
			||||||
				 * stack for this reason. */
 | 
									 * stack for this reason. */
 | 
				
			||||||
@ -2397,7 +2402,7 @@ printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				/* the block context object created here is used
 | 
									/* the block context object created here is used
 | 
				
			||||||
				 * as a base object for block context activation.
 | 
									 * as a base object for block context activation.
 | 
				
			||||||
				 * primitive_block_value() clones a block 
 | 
									 * prim_block_value() clones a block 
 | 
				
			||||||
				 * context and activates the cloned context.
 | 
									 * context and activates the cloned context.
 | 
				
			||||||
				 * this base block context is created with no 
 | 
									 * this base block context is created with no 
 | 
				
			||||||
				 * stack for this reason. */
 | 
									 * stack for this reason. */
 | 
				
			||||||
@ -2412,7 +2417,7 @@ printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
 | 
				
			|||||||
				/* [NOTE]
 | 
									/* [NOTE]
 | 
				
			||||||
				 *  blkctx->caller is left to nil. it is set to the 
 | 
									 *  blkctx->caller is left to nil. it is set to the 
 | 
				
			||||||
				 *  active context before it gets activated. see
 | 
									 *  active context before it gets activated. see
 | 
				
			||||||
				 *  primitive_block_value().
 | 
									 *  prim_block_value().
 | 
				
			||||||
				 *
 | 
									 *
 | 
				
			||||||
				 *  blkctx->home is set here to the active context.
 | 
									 *  blkctx->home is set here to the active context.
 | 
				
			||||||
				 *  it's redundant to have them pushed to the stack
 | 
									 *  it's redundant to have them pushed to the stack
 | 
				
			||||||
@ -2496,6 +2501,8 @@ oops:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int stix_invoke (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthname)
 | 
					int stix_invoke (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						/*stix_oop_process_t proc;*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (activate_initial_context (stix, objname, mthname) <= -1) return -1;
 | 
						if (activate_initial_context (stix, objname, mthname) <= -1) return -1;
 | 
				
			||||||
	return stix_execute (stix);
 | 
						return stix_execute (stix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -285,12 +285,14 @@ void stix_gc (stix_t* stix)
 | 
				
			|||||||
	stix->_method_context    = stix_moveoop (stix, stix->_method_context);
 | 
						stix->_method_context    = stix_moveoop (stix, stix->_method_context);
 | 
				
			||||||
	stix->_block_context     = stix_moveoop (stix, stix->_block_context);
 | 
						stix->_block_context     = stix_moveoop (stix, stix->_block_context);
 | 
				
			||||||
	stix->_process           = stix_moveoop (stix, stix->_process);
 | 
						stix->_process           = stix_moveoop (stix, stix->_process);
 | 
				
			||||||
 | 
						stix->_process_scheduler = stix_moveoop (stix, stix->_process_scheduler);
 | 
				
			||||||
	stix->_true_class        = stix_moveoop (stix, stix->_true_class);
 | 
						stix->_true_class        = stix_moveoop (stix, stix->_true_class);
 | 
				
			||||||
	stix->_false_class       = stix_moveoop (stix, stix->_false_class);
 | 
						stix->_false_class       = stix_moveoop (stix, stix->_false_class);
 | 
				
			||||||
	stix->_character         = stix_moveoop (stix, stix->_character);
 | 
						stix->_character         = stix_moveoop (stix, stix->_character);
 | 
				
			||||||
	stix->_small_integer     = stix_moveoop (stix, stix->_small_integer);
 | 
						stix->_small_integer     = stix_moveoop (stix, stix->_small_integer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stix->sysdic = (stix_oop_set_t) stix_moveoop (stix, (stix_oop_t)stix->sysdic);
 | 
						stix->sysdic = (stix_oop_set_t) stix_moveoop (stix, (stix_oop_t)stix->sysdic);
 | 
				
			||||||
 | 
						stix->scheduler = (stix_oop_process_scheduler_t) stix_moveoop (stix, (stix_oop_t)stix->scheduler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < stix->tmp_count; i++)
 | 
						for (i = 0; i < stix->tmp_count; i++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
				
			|||||||
@ -135,6 +135,7 @@ static int ignite_1 (stix_t* stix)
 | 
				
			|||||||
	stix->_method_context    = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
 | 
						stix->_method_context    = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
 | 
				
			||||||
	stix->_block_context     = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
 | 
						stix->_block_context     = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CONTEXT_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
 | 
				
			||||||
	stix->_process           = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_PROCESS_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
 | 
						stix->_process           = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_PROCESS_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP));
 | 
				
			||||||
 | 
						stix->_process_scheduler = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_PROCESS_SCHEDULER_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP));
 | 
				
			||||||
	stix->_true_class        = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
 | 
						stix->_true_class        = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
 | 
				
			||||||
	stix->_false_class       = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
 | 
						stix->_false_class       = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP));
 | 
				
			||||||
	/* TOOD: what is a proper spec for Character and SmallInteger?
 | 
						/* TOOD: what is a proper spec for Character and SmallInteger?
 | 
				
			||||||
@ -152,7 +153,9 @@ static int ignite_1 (stix_t* stix)
 | 
				
			|||||||
	    !stix->_namespace         || !stix->_pool_dictionary   ||
 | 
						    !stix->_namespace         || !stix->_pool_dictionary   ||
 | 
				
			||||||
	    !stix->_method_dictionary || !stix->_method            || !stix->_association ||
 | 
						    !stix->_method_dictionary || !stix->_method            || !stix->_association ||
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    !stix->_method_context    || !stix->_block_context     || !stix->_process ||
 | 
						    !stix->_method_context    || !stix->_block_context     || 
 | 
				
			||||||
 | 
						    !stix->_process           || !stix->_process_scheduler ||
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    !stix->_true_class        || !stix->_false_class       || 
 | 
						    !stix->_true_class        || !stix->_false_class       || 
 | 
				
			||||||
	    !stix->_character         || !stix->_small_integer) return -1;
 | 
						    !stix->_character         || !stix->_small_integer) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -189,6 +192,10 @@ static int ignite_2 (stix_t* stix)
 | 
				
			|||||||
	if (!tmp) return -1;
 | 
						if (!tmp) return -1;
 | 
				
			||||||
	stix->sysdic = (stix_oop_set_t)tmp;
 | 
						stix->sysdic = (stix_oop_set_t)tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = (stix_oop_t)stix_instantiate (stix, stix->_process_scheduler, STIX_NULL, 0);
 | 
				
			||||||
 | 
						if (!tmp) return -1;
 | 
				
			||||||
 | 
						stix->scheduler = (stix_oop_process_scheduler_t)tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Export the system dictionary via the first class variable of the Stix class */
 | 
						/* Export the system dictionary via the first class variable of the Stix class */
 | 
				
			||||||
	((stix_oop_class_t)stix->_apex)->slot[0] = (stix_oop_t)stix->sysdic;
 | 
						((stix_oop_class_t)stix->_apex)->slot[0] = (stix_oop_t)stix->sysdic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -225,6 +232,7 @@ static int ignite_3 (stix_t* stix)
 | 
				
			|||||||
		{ 13, { 'M','e','t','h','o','d','C','o','n','t','e','x','t'              } },
 | 
							{ 13, { 'M','e','t','h','o','d','C','o','n','t','e','x','t'              } },
 | 
				
			||||||
		{ 12, { 'B','l','o','c','k','C','o','n','t','e','x','t'                  } },
 | 
							{ 12, { 'B','l','o','c','k','C','o','n','t','e','x','t'                  } },
 | 
				
			||||||
		{  7, { 'P','r','o','c','e','s','s'                                      } },
 | 
							{  7, { 'P','r','o','c','e','s','s'                                      } },
 | 
				
			||||||
 | 
							{ 16, { 'P','r','o','c','e','s','s','S','c','h','e','d','u','l','e','r'  } },
 | 
				
			||||||
		{  4, { 'T','r','u','e'                                                  } },
 | 
							{  4, { 'T','r','u','e'                                                  } },
 | 
				
			||||||
		{  5, { 'F','a','l','s','e'                                              } },
 | 
							{  5, { 'F','a','l','s','e'                                              } },
 | 
				
			||||||
		{  9, { 'C','h','a','r','a','c','t','e','r'                              } },
 | 
							{  9, { 'C','h','a','r','a','c','t','e','r'                              } },
 | 
				
			||||||
@ -232,6 +240,7 @@ static int ignite_3 (stix_t* stix)
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static stix_uch_t str_stix[] = { 'S','t','i','x' };
 | 
						static stix_uch_t str_stix[] = { 'S','t','i','x' };
 | 
				
			||||||
 | 
						static stix_uch_t str_scheduler[] = { 'S', 'c', 'h', 'e', 'd', 'u', 'l', 'e', 'r' };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stix_oow_t i;
 | 
						stix_oow_t i;
 | 
				
			||||||
	stix_oop_t sym;
 | 
						stix_oop_t sym;
 | 
				
			||||||
@ -251,10 +260,16 @@ static int ignite_3 (stix_t* stix)
 | 
				
			|||||||
		stix_ptr++;
 | 
							stix_ptr++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make the system dictionary available as the global name 'Stix' */
 | 
				
			||||||
	sym = stix_makesymbol (stix, str_stix, 4);
 | 
						sym = stix_makesymbol (stix, str_stix, 4);
 | 
				
			||||||
	if (!sym) return -1;
 | 
						if (!sym) return -1;
 | 
				
			||||||
	if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->sysdic)) return -1;
 | 
						if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->sysdic)) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make the process scheduler avaialble as the global name 'Scheduler' */
 | 
				
			||||||
 | 
						sym = stix_makesymbol (stix, str_scheduler, 4);
 | 
				
			||||||
 | 
						if (!sym) return -1;
 | 
				
			||||||
 | 
						if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->scheduler)) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -27,8 +27,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "stix-prv.h"
 | 
					#include "stix-prv.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stix_oop_process_t stix_addnewproc (stix_t* stix)
 | 
				
			||||||
stix_oop_process_t stix_makeproc (stix_t* stix)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_oop_process_t proc;
 | 
						stix_oop_process_t proc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,6 +35,18 @@ stix_oop_process_t stix_makeproc (stix_t* stix)
 | 
				
			|||||||
	if (!proc) return STIX_NULL;
 | 
						if (!proc) return STIX_NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	proc->state = STIX_OOP_FROM_SMINT(0);
 | 
						proc->state = STIX_OOP_FROM_SMINT(0);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	STIX_ASSERT (STIX_OBJ_GET_SIZE(proc) == STIX_PROCESS_NAMED_INSTVARS + stix->option.dfl_procstk_size);
 | 
						STIX_ASSERT (STIX_OBJ_GET_SIZE(proc) == STIX_PROCESS_NAMED_INSTVARS + stix->option.dfl_procstk_size);
 | 
				
			||||||
	return proc;
 | 
						return proc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void stix_schedproc (stix_t* stix, stix_oop_process_t proc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: if scheduled, don't add */
 | 
				
			||||||
 | 
						/*proc->next = stix->_active_process;
 | 
				
			||||||
 | 
						proc->_active_process = proc;*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void stix_unschedproc (stix_t* stix, stix_oop_process_t proc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -80,6 +80,18 @@ oops:
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static stix_rbt_walk_t unload_primitive_module (stix_rbt_t* rbt, stix_rbt_pair_t* pair, void* ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stix_t* stix = (stix_t*)ctx;
 | 
				
			||||||
 | 
						stix_prim_mod_data_t* md;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						md = STIX_RBT_VPTR(pair);
 | 
				
			||||||
 | 
						if (md->mod.unload) md->mod.unload (stix, &md->mod);
 | 
				
			||||||
 | 
						if (md->handle) stix->vmprim.mod_close (stix, md->handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return STIX_RBT_WALK_FORWARD;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void stix_fini (stix_t* stix)
 | 
					void stix_fini (stix_t* stix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stix_cb_t* cb;
 | 
						stix_cb_t* cb;
 | 
				
			||||||
@ -89,6 +101,7 @@ void stix_fini (stix_t* stix)
 | 
				
			|||||||
		if (cb->fini) cb->fini (stix);
 | 
							if (cb->fini) cb->fini (stix);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stix_rbt_walk (&stix->pmtable, unload_primitive_module, stix);
 | 
				
			||||||
	stix_rbt_fini (&stix->pmtable);
 | 
						stix_rbt_fini (&stix->pmtable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stix_killheap (stix, stix->newheap);
 | 
						stix_killheap (stix, stix->newheap);
 | 
				
			||||||
 | 
				
			|||||||
@ -467,14 +467,28 @@ struct stix_context_t
 | 
				
			|||||||
	stix_oop_t         slot[1]; /* stack */
 | 
						stix_oop_t         slot[1]; /* stack */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STIX_PROCESS_SCHEDULER_NAMED_INSTVARS 4
 | 
				
			||||||
 | 
					typedef struct stix_process_scheduler_t stix_process_scheduler_t;
 | 
				
			||||||
 | 
					typedef struct stix_process_scheduler_t* stix_oop_process_scheduler_t;
 | 
				
			||||||
 | 
					struct stix_process_scheduler_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						STIX_OBJ_HEADER;
 | 
				
			||||||
 | 
						stix_oop_t tally;
 | 
				
			||||||
 | 
						stix_oop_t head;
 | 
				
			||||||
 | 
						stix_oop_t tail;
 | 
				
			||||||
 | 
						stix_oop_t active;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STIX_PROCESS_NAMED_INSTVARS 1
 | 
					#define STIX_PROCESS_NAMED_INSTVARS 4
 | 
				
			||||||
typedef struct stix_process_t stix_process_t;
 | 
					typedef struct stix_process_t stix_process_t;
 | 
				
			||||||
typedef struct stix_process_t* stix_oop_process_t;
 | 
					typedef struct stix_process_t* stix_oop_process_t;
 | 
				
			||||||
struct stix_process_t
 | 
					struct stix_process_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	STIX_OBJ_HEADER;
 | 
						STIX_OBJ_HEADER;
 | 
				
			||||||
 | 
						stix_oop_t  sp;
 | 
				
			||||||
	stix_oop_t  state;
 | 
						stix_oop_t  state;
 | 
				
			||||||
 | 
						stix_oop_t  prev;
 | 
				
			||||||
 | 
						stix_oop_t  next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* == variable indexed part == */
 | 
						/* == variable indexed part == */
 | 
				
			||||||
	stix_oop_t slot[1]; /* process stack */
 | 
						stix_oop_t slot[1]; /* process stack */
 | 
				
			||||||
@ -586,6 +600,13 @@ struct stix_prim_mod_t
 | 
				
			|||||||
	void*                  ctx;
 | 
						void*                  ctx;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct stix_prim_mod_data_t 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void* handle;
 | 
				
			||||||
 | 
						stix_prim_mod_t mod;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct stix_prim_mod_data_t stix_prim_mod_data_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* =========================================================================
 | 
					/* =========================================================================
 | 
				
			||||||
 * STIX VM
 | 
					 * STIX VM
 | 
				
			||||||
 * ========================================================================= */
 | 
					 * ========================================================================= */
 | 
				
			||||||
@ -644,6 +665,7 @@ struct stix_t
 | 
				
			|||||||
	stix_oop_t _method_context; /* MethodContext */
 | 
						stix_oop_t _method_context; /* MethodContext */
 | 
				
			||||||
	stix_oop_t _block_context; /* BlockContext */
 | 
						stix_oop_t _block_context; /* BlockContext */
 | 
				
			||||||
	stix_oop_t _process; /* Process */
 | 
						stix_oop_t _process; /* Process */
 | 
				
			||||||
 | 
						stix_oop_t _process_scheduler; /* ProcessScheduler */
 | 
				
			||||||
	stix_oop_t _true_class; /* True */
 | 
						stix_oop_t _true_class; /* True */
 | 
				
			||||||
	stix_oop_t _false_class; /* False */
 | 
						stix_oop_t _false_class; /* False */
 | 
				
			||||||
	stix_oop_t _character; /* Character */
 | 
						stix_oop_t _character; /* Character */
 | 
				
			||||||
@ -653,6 +675,7 @@ struct stix_t
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	stix_oop_set_t symtab; /* system-wide symbol table. instance of SymbolSet */
 | 
						stix_oop_set_t symtab; /* system-wide symbol table. instance of SymbolSet */
 | 
				
			||||||
	stix_oop_set_t sysdic; /* system dictionary. instance of SystemDictionary */
 | 
						stix_oop_set_t sysdic; /* system dictionary. instance of SystemDictionary */
 | 
				
			||||||
 | 
						stix_oop_process_scheduler_t scheduler; /* instance of ProcessScheduler */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stix_oop_t* tmp_stack[256]; /* stack for temporaries */
 | 
						stix_oop_t* tmp_stack[256]; /* stack for temporaries */
 | 
				
			||||||
	stix_oow_t tmp_count;
 | 
						stix_oow_t tmp_count;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user