removed the ensure_block field from the context object and added the <ensure> code to the preamble field of a method.
This commit is contained in:
@ -56,12 +56,15 @@
|
||||
## concatenate two strings.
|
||||
## TOOD: make this a primitive for performance.
|
||||
| newsize newstr self_ubound |
|
||||
|
||||
newsize := self basicSize + aString basicSize.
|
||||
##newstr := self class basicNew: newsize.
|
||||
newstr := String basicNew: newsize. ## TODO: redefine , for symbol... it's a work arouind... symbols are not concatenated to a symbol at this moment.
|
||||
self_ubound := self ubound.
|
||||
0 to: self_ubound do: [:i | newstr at: i put: (self at: i)].
|
||||
0 to: (aString ubound) do: [:i | newstr at: (i + self_ubound + 1) put: (aString at: i)].
|
||||
|
||||
0 to: self_ubound do: [:i | newstr at: i put: (self at: i) ].
|
||||
0 to: (aString ubound) do: [:i | newstr at: (i + self_ubound + 1) put: (aString at: i) ].
|
||||
|
||||
^newstr
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#class(#pointer) Context(Apex)
|
||||
{
|
||||
#dcl sender ip sp ntmprs ensure_block.
|
||||
#dcl sender ip sp ntmprs.
|
||||
|
||||
#method sender
|
||||
{
|
||||
@ -19,9 +19,14 @@
|
||||
^false
|
||||
}
|
||||
|
||||
#method hasEnsureBlock
|
||||
{
|
||||
^false
|
||||
}
|
||||
|
||||
#method ensureBlock
|
||||
{
|
||||
^self.ensure_block
|
||||
^nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +80,22 @@
|
||||
#method isExceptionHandlerContext
|
||||
{
|
||||
## 10 - STIX_METHOD_PREAMBLE_EXCEPTION in VM.
|
||||
^self.method preambleCode == 10.
|
||||
^self.method preambleCode == 10.
|
||||
}
|
||||
|
||||
#method hasEnsureBlock
|
||||
{
|
||||
## 10 - STIX_METHOD_PREAMBLE_ENSURE in VM.
|
||||
^self.method preambleCode == 11
|
||||
}
|
||||
|
||||
#method ensureBlock
|
||||
{
|
||||
## TODO: 9 is the number of named instance variables of a context.
|
||||
## TODO: change 9 to a constant when stix is enhanced to support constant definition
|
||||
|
||||
(self.method preambleCode == 11) ifFalse: [^nil].
|
||||
^self basicAt: 8.
|
||||
}
|
||||
|
||||
#method findExceptionHandlerBlock: anExceptionClass
|
||||
@ -92,22 +112,38 @@
|
||||
| bound exc |
|
||||
## NOTE: if on:do: has a temporary varible, bound must be adjusted to reflect it.
|
||||
bound := self basicSize - 1.
|
||||
## TODO: change 9 to a constant when stix is enhanced to support constant definition
|
||||
## TODO: change 8 to a constant when stix is enhanced to support constant definition
|
||||
## or calcuate the minimum size using the class information.
|
||||
9 to: bound by: 2 do: [ :i |
|
||||
8 to: bound by: 2 do: [ :i |
|
||||
exc := self basicAt: i.
|
||||
((anExceptionClass == exc) or: [anExceptionClass inheritsFrom: exc]) ifTrue: [^self basicAt: (i + 1)].
|
||||
]
|
||||
].
|
||||
^nil.
|
||||
}
|
||||
|
||||
#method unwindTo: aContext return: anObject
|
||||
{
|
||||
## private: called by VM upon unwinding
|
||||
| ctx eb |
|
||||
ctx := self.
|
||||
[ctx ~~ aContext] whileTrue: [
|
||||
eb := ctx ensureBlock.
|
||||
(eb notNil) ifTrue: [eb value].
|
||||
ctx := ctx sender.
|
||||
].
|
||||
eb := ctx ensureBlock.
|
||||
(eb notNil) ifTrue: [eb value].
|
||||
|
||||
^anObject
|
||||
}
|
||||
}
|
||||
|
||||
#class(#pointer) BlockContext(Context)
|
||||
{
|
||||
#dcl nargs source home origin.
|
||||
|
||||
#method fork
|
||||
#method fork
|
||||
{
|
||||
"crate a new process in the runnable state"
|
||||
^self newProcess resume.
|
||||
@ -337,47 +373,31 @@ thisContext isExceptionHandlerContext dump.
|
||||
|
||||
#method ensure: aBlock
|
||||
{
|
||||
## TODO: ensure that the ensured block is executed after exception handler...
|
||||
| v |
|
||||
self.ensure_block := aBlock.
|
||||
v := self on: Exception do: [:ex |
|
||||
aBlock value.
|
||||
ex pass
|
||||
].
|
||||
<ensure>
|
||||
"v := self on: Exception do: [:ex | aBlock value. ex pass ]."
|
||||
v := self value.
|
||||
aBlock value.
|
||||
^v
|
||||
}
|
||||
|
||||
#method ifCurtailed: aBlock
|
||||
{
|
||||
^self on: Exception do: [:ex | aBlock value. ex pass ]
|
||||
}
|
||||
| v ok |
|
||||
|
||||
|
||||
#method unwindTo: aContext return: anObject
|
||||
{
|
||||
## private: called by VM upon unwinding
|
||||
| ctx eb |
|
||||
ctx := self.
|
||||
[ctx ~~ aContext] whileTrue: [
|
||||
eb := ctx ensureBlock.
|
||||
(eb notNil) ifTrue: [eb value].
|
||||
ctx := ctx sender.
|
||||
].
|
||||
eb := ctx ensureBlock.
|
||||
(eb notNil) ifTrue: [eb value].
|
||||
|
||||
^anObject
|
||||
ok := false.
|
||||
[ v := self value. ok := true. ] ensure: [ ok ifFalse: [aBlock value] ].
|
||||
^v.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
##
|
||||
## TODO: is it better to inherit from Object???
|
||||
## or treat Exception specially like UndefinedObject or Class???
|
||||
##
|
||||
#extend Exception
|
||||
{
|
||||
|
||||
|
||||
#method(#class) signal
|
||||
{
|
||||
self new signal
|
||||
|
@ -401,7 +401,7 @@
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method returnTo: anObject andEval: aBlock with: arg
|
||||
#method returnTo: aContext andEval: aBlock with: arg
|
||||
{
|
||||
<primitive: #_processor_return_to_and_eval>
|
||||
self primitiveFailed.
|
||||
|
@ -176,13 +176,13 @@
|
||||
[ i <= end ] whileTrue: [
|
||||
aBlock value: i.
|
||||
i := i + step.
|
||||
]
|
||||
].
|
||||
]
|
||||
ifFalse: [
|
||||
[ i >= end ] whileTrue: [
|
||||
aBlock value: i.
|
||||
i := i - step.
|
||||
]
|
||||
].
|
||||
].
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@
|
||||
[
|
||||
[
|
||||
##[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ', (k asString)) dump ].
|
||||
[ ^20 ] ensure: [('ensure 1 ', (k asString)) dump ].
|
||||
[ ^ 20 ] ensure: [ ('ensure 1 ', (k asString)) dump. ].
|
||||
] ensure: ['ensure 2' dump ].
|
||||
] ensure: ['ensure 3' dump ].
|
||||
] on: Exception do: [:ex |
|
||||
@ -163,9 +163,11 @@
|
||||
## Exception signal: 'qqq'.
|
||||
].
|
||||
"
|
||||
|
||||
v1 := self aaa_123.
|
||||
'--------------------------------' dump.
|
||||
v1 dump.
|
||||
'--------------------------------' dump.
|
||||
'END OF MAIN' dump.
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user