migrated some primitives from Processor to System.
Fixed a bug in manipulating moo->sem_io_wait_count. Experimenting to add a shortcut exception handling syntax
This commit is contained in:
@ -57,7 +57,7 @@ TODO: can i convert 'thisProcess primError' to a relevant exception?
|
||||
|
||||
self.signalContext := thisContext.
|
||||
exctx := (thisContext sender) findExceptionContext.
|
||||
|
||||
|
||||
##[exctx notNil] whileTrue: [
|
||||
while (exctx notNil)
|
||||
{
|
||||
@ -69,7 +69,7 @@ TODO: can i convert 'thisProcess primError' to a relevant exception?
|
||||
exctx basicAt: actpos put: false.
|
||||
[ retval := exblk value: self ] ensure: [ exctx basicAt: actpos put: true ].
|
||||
thisContext unwindTo: (exctx sender) return: nil.
|
||||
Processor return: retval to: (exctx sender).
|
||||
System return: retval to: (exctx sender).
|
||||
}.
|
||||
exctx := (exctx sender) findExceptionContext.
|
||||
}.
|
||||
@ -113,7 +113,7 @@ System logNl: '== END OF BACKTRACE =='.
|
||||
|
||||
method return: value
|
||||
{
|
||||
if (self.handlerContext notNil) { Processor return: value to: self.handlerContext }
|
||||
if (self.handlerContext notNil) { System return: value to: self.handlerContext }
|
||||
}
|
||||
|
||||
method retry
|
||||
@ -122,7 +122,7 @@ System logNl: '== END OF BACKTRACE =='.
|
||||
if (self.handlerContext notNil)
|
||||
{
|
||||
self.handlerContext pc: 0.
|
||||
Processor return: self to: self.handlerContext.
|
||||
System return: self to: self.handlerContext.
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ System logNl: '== END OF BACKTRACE =='.
|
||||
ctx := self.signalContext sender.
|
||||
self.signalContext := nil.
|
||||
self.handlerContext := nil.
|
||||
Processor return: value to: ctx.
|
||||
System return: value to: ctx.
|
||||
}.
|
||||
}
|
||||
|
||||
@ -212,31 +212,45 @@ extend Context
|
||||
}
|
||||
|
||||
##============================================================================
|
||||
pooldic MethodContext.Preamble
|
||||
{
|
||||
## this must follow MOO_METHOD_PREAMBLE_EXCEPTION in moo.h
|
||||
EXCEPTION := 13.
|
||||
|
||||
## this must follow MOO_METHOD_PREAMBLE_ENSURE in moo.h
|
||||
ENSURE := 14.
|
||||
}
|
||||
|
||||
pooldic MethodContext.Index
|
||||
{
|
||||
## [ value-block ] ensure: [ ensure-block ]
|
||||
## assuming ensure block is a parameter the ensure: method to a
|
||||
## block context, the first parameter is placed after the fixed
|
||||
## instance variables of the method context. As MethodContex has
|
||||
## instance variables, the ensure block must be at the 9th position
|
||||
## which translates to index 8
|
||||
ENSURE := 8.
|
||||
|
||||
|
||||
## [ ... ] on: Exception: do: [:ex | ... ]
|
||||
FIRST_ON := 8.
|
||||
}
|
||||
|
||||
extend MethodContext
|
||||
{
|
||||
method isExceptionContext
|
||||
{
|
||||
## 12 - MOO_METHOD_PREAMBLE_EXCEPTION in VM.
|
||||
^self.method preambleCode == 13.
|
||||
^self.method preambleCode == MethodContext.Preamble.EXCEPTION.
|
||||
}
|
||||
|
||||
method isEnsureContext
|
||||
{
|
||||
## 13 - MOO_METHOD_PREAMBLE_ENSURE in VM.
|
||||
^self.method preambleCode == 14
|
||||
^self.method preambleCode == MethodContext.Preamble.ENSURE.
|
||||
}
|
||||
|
||||
method ensureBlock
|
||||
{
|
||||
## TODO: change 8 to a constant when moo is enhanced to support constant definition
|
||||
|
||||
(* [ value-block ] ensure: [ ensure-block ]
|
||||
* assuming ensure block is a parameter the ensure: method to a
|
||||
* block context, the first parameter is placed after the fixed
|
||||
* instance variables of the method context. As MethodContex has
|
||||
* 8 instance variables, the ensure block must be at the 9th position
|
||||
* which translates to index 8 *)
|
||||
^if (self.method preambleCode == 14) { self basicAt: 8 } else { nil }
|
||||
^if (self.method preambleCode == MethodContext.Preamble.ENSURE) { self basicAt: MethodContext.Index.ENSURE } else { nil }
|
||||
}
|
||||
|
||||
|
||||
@ -250,10 +264,7 @@ extend MethodContext
|
||||
* basicAt: 8 must be the on: argument.
|
||||
* basicAt: 9 must be the do: argument *)
|
||||
|
||||
## TODO: change 8 to a constant when moo is enhanced to support constant definition
|
||||
## or calcuate the minimum size using the class information.
|
||||
|
||||
| size exc |
|
||||
| size exc i |
|
||||
|
||||
if (self isExceptionContext)
|
||||
{
|
||||
@ -262,10 +273,20 @@ extend MethodContext
|
||||
* those must be skipped from scanning. *)
|
||||
|
||||
size := self basicSize.
|
||||
8 priorTo: size by: 2 do: [ :i |
|
||||
##8 priorTo: size by: 2 do: [ :i |
|
||||
## exc := self basicAt: i.
|
||||
## if ((exception_class == exc) or: [exception_class inheritsFrom: exc]) { ^self basicAt: (i + 1) }.
|
||||
##]
|
||||
i := MethodContext.Index.FIRST_ON.
|
||||
while (i < size)
|
||||
{
|
||||
exc := self basicAt: i.
|
||||
if ((exception_class == exc) or: [exception_class inheritsFrom: exc]) { ^self basicAt: (i + 1) }.
|
||||
]
|
||||
if ((exception_class == exc) or: [exception_class inheritsFrom: exc])
|
||||
{
|
||||
^self basicAt: (i + 1).
|
||||
}.
|
||||
i := i + 2.
|
||||
}.
|
||||
}.
|
||||
^nil.
|
||||
}
|
||||
@ -319,7 +340,7 @@ extend MethodContext
|
||||
* [ [Exception signal: 'xxx'] ensure: [20] ] on: Exception do: [:ex | ...]
|
||||
* ---------------------------------------------------------------- *)
|
||||
thisContext unwindTo: self.sender return: nil.
|
||||
Processor return: retval to: self.sender.
|
||||
System return: retval to: self.sender.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,6 +239,54 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
||||
^x
|
||||
}
|
||||
|
||||
method _waitWithTimeout: seconds
|
||||
{
|
||||
| s r |
|
||||
|
||||
## create an internal semaphore for timeout notification.
|
||||
s := Semaphore _new.
|
||||
if (s isError) { ^s }.
|
||||
|
||||
## grant the partial membership to the internal semaphore.
|
||||
## it's partial because it's not added to self.semarr.
|
||||
##s _group: self.
|
||||
if ((r := (self addSemaphore: s)) isError) { ^r }.
|
||||
|
||||
## arrange the processor to notify upon timeout.
|
||||
if ((r := (System _signal: s after: seconds)) isError) { ^r }.
|
||||
|
||||
if ((r := self _wait) isError)
|
||||
{
|
||||
System _unsignal: s.
|
||||
^r.
|
||||
}.
|
||||
|
||||
## if the internal semaphore has been signaled,
|
||||
## arrange to return nil to indicate timeout.
|
||||
if (r == s) { r := nil }
|
||||
elsif (r signalAction notNil) { r signalAction value: r }.
|
||||
|
||||
## nullify the membership
|
||||
self _removeSemaphore: s.
|
||||
|
||||
## cancel the notification arrangement in case it didn't time out.
|
||||
System _unsignal: s.
|
||||
|
||||
^r.
|
||||
}
|
||||
|
||||
method waitWithTimeout: seconds
|
||||
{
|
||||
| r |
|
||||
r := self _waitWithTimeout: seconds.
|
||||
if (r isError)
|
||||
{
|
||||
Exception signal: 'Error has occurred...' error: r.
|
||||
}.
|
||||
^r
|
||||
}
|
||||
|
||||
(*
|
||||
method waitWithTimeout: seconds
|
||||
{
|
||||
| s r |
|
||||
@ -254,8 +302,13 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
||||
## arrange the processor to notify upon timeout.
|
||||
System signal: s after: seconds.
|
||||
|
||||
## wait on the semaphore group.
|
||||
r := self wait.
|
||||
[
|
||||
## wait on the semaphore group.
|
||||
r := self wait.
|
||||
] on: Exception do: [:ex |
|
||||
System _unsignal: s.
|
||||
ex throw
|
||||
].
|
||||
|
||||
## if the internal semaphore has been signaled,
|
||||
## arrange to return nil to indicate timeout.
|
||||
@ -270,6 +323,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
||||
|
||||
^r.
|
||||
}
|
||||
*)
|
||||
}
|
||||
|
||||
class SemaphoreHeap(Object)
|
||||
@ -471,10 +525,4 @@ class(#final,#limited) ProcessScheduler(Object)
|
||||
].
|
||||
*)
|
||||
}
|
||||
|
||||
method return: object to: context
|
||||
{
|
||||
<primitive: #_processor_return_to>
|
||||
self primitiveFailed.
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ class System(Apex)
|
||||
|
||||
method(#class,#primitive) _popCollectable.
|
||||
method(#class,#primitive) collectGarbage.
|
||||
method(#class,#primitive) return: object to: context.
|
||||
|
||||
## =======================================================================================
|
||||
|
||||
|
Reference in New Issue
Block a user