fixed the bug not popping an argument in the _integer_inttostr primitive.
added a new primitive _processor_return_to_and_eval to support proper exception handling
This commit is contained in:
@ -55,10 +55,10 @@
|
||||
{
|
||||
## concatenate two strings.
|
||||
## TOOD: make this a primitive for performance.
|
||||
| newsize newstr self_ubound|
|
||||
| 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 contacated to a symbol at this moment.
|
||||
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)].
|
||||
|
@ -328,13 +328,15 @@ thisContext isExceptionHandlerContext dump.
|
||||
|
||||
#method ensure: aBlock
|
||||
{
|
||||
|
||||
## TODO: ensure that the ensured block is executed after exception handler...
|
||||
| value |
|
||||
value := self on: Exception do: [:ex | aBlock value. ex pass].
|
||||
## value := self valueAndResumeOnUnwind.
|
||||
| v |
|
||||
v := self on: Exception do: [:ex |
|
||||
aBlock value.
|
||||
ex pass
|
||||
].
|
||||
|
||||
aBlock value.
|
||||
^value
|
||||
^v
|
||||
}
|
||||
|
||||
#method ifCurtailed: aBlock
|
||||
@ -424,8 +426,21 @@ thisContext isExceptionHandlerContext dump.
|
||||
#method handleException
|
||||
{
|
||||
self.handlerContext notNil
|
||||
ifTrue: [
|
||||
Processor return: (self.handlerBlock value: self) to: (self.handlerContext sender)
|
||||
ifTrue: [
|
||||
##'RETURNING TO....' dump.
|
||||
##self.handlerContext dump.
|
||||
##self.handlerContext sender dump.
|
||||
##' ............' dump.
|
||||
|
||||
## arrange to execute the hander block after having returned
|
||||
## to the sender of the exception handler context.
|
||||
## if handler block is evaluated before returning, an
|
||||
## exception raised in the handler block causes a kind of
|
||||
## a recursive call to here.
|
||||
##Processor return: (self.handlerBlock value: self) to: (self.handlerContext sender)
|
||||
## so use a different primitive method that evaluate the block
|
||||
## after having returned to the given context.
|
||||
Processor returnTo: (self.handlerContext sender) andEval: (self.handlerBlock) with: self.
|
||||
]
|
||||
ifFalse: [
|
||||
('### EXCEPTION NOT HANDLED #### ', self class name, ' - ', self messageText) dump.
|
||||
@ -434,13 +449,6 @@ thisContext isExceptionHandlerContext dump.
|
||||
].
|
||||
}
|
||||
|
||||
## #method handlerContext
|
||||
## {
|
||||
## (self.handlerContext notNil) ifTrue: [ ^self.handlerContext ].
|
||||
## self findHandlerContextStartingFrom: self.signalContext.
|
||||
## ^self.handlerContext.
|
||||
## }
|
||||
|
||||
#method findHandlerContextStartingFrom: aContext
|
||||
{
|
||||
## Find exception handling context starting from a given context
|
||||
@ -448,19 +456,21 @@ thisContext isExceptionHandlerContext dump.
|
||||
|
||||
ctx := aContext.
|
||||
[ ctx notNil ] whileTrue: [
|
||||
##(ctx handles: self) ifTrue: [ ^ ctx ].
|
||||
(ctx isExceptionHandlerContext) ifTrue: [
|
||||
| blk |
|
||||
blk := ctx findExceptionHandlerBlock: (self class).
|
||||
(blk notNil) ifTrue: [
|
||||
self.handlerBlock := blk.
|
||||
self.handlerContext := ctx.
|
||||
^ctx
|
||||
].
|
||||
##ctx dump.
|
||||
##(ctx handles: self) ifTrue: [ ^ ctx ].
|
||||
(ctx isExceptionHandlerContext) ifTrue: [
|
||||
| blk |
|
||||
blk := ctx findExceptionHandlerBlock: (self class).
|
||||
(blk notNil) ifTrue: [
|
||||
self.handlerBlock := blk.
|
||||
self.handlerContext := ctx.
|
||||
##'-------------' dump.
|
||||
^ctx
|
||||
].
|
||||
ctx := ctx sender
|
||||
].
|
||||
|
||||
ctx := ctx sender
|
||||
].
|
||||
##'-------------' dump.
|
||||
## no handler is found
|
||||
self.handlerBlock := nil.
|
||||
self.handlerContext := nil.
|
||||
|
@ -401,6 +401,12 @@
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method returnTo: anObject andEval: aBlock with: arg
|
||||
{
|
||||
<primitive: #_processor_return_to_and_eval>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method forceContext: aContext
|
||||
{
|
||||
<primitive: #_processor_force_context>
|
||||
|
@ -25,6 +25,10 @@
|
||||
|
||||
#class Character(Magnitude)
|
||||
{
|
||||
## #method basicSize
|
||||
## {
|
||||
## ^0
|
||||
## }
|
||||
}
|
||||
|
||||
#class Number(Magnitude)
|
||||
@ -153,7 +157,7 @@
|
||||
|
||||
#method asString
|
||||
{
|
||||
self printStringRadix: 10
|
||||
^self printStringRadix: 10
|
||||
}
|
||||
|
||||
#method printStringRadix: aNumber
|
||||
@ -213,6 +217,10 @@
|
||||
|
||||
#class SmallInteger(Integer)
|
||||
{
|
||||
## #method basicSize
|
||||
## {
|
||||
## ^0
|
||||
## }
|
||||
}
|
||||
|
||||
#class(#liword) LargeInteger(Integer)
|
||||
|
@ -67,7 +67,7 @@
|
||||
}
|
||||
|
||||
|
||||
#method(#class) main
|
||||
#method(#class) main987
|
||||
{
|
||||
|t1 t2 s1 s2 s3|
|
||||
|
||||
@ -110,20 +110,43 @@
|
||||
s1 wait.
|
||||
"
|
||||
|
||||
|
||||
|
||||
"
|
||||
}
|
||||
|
||||
#method(#class) main
|
||||
{
|
||||
| v1 |
|
||||
'START OF MAIN' dump.
|
||||
##[1 xxx] ifCurtailed: ['XXXXXXXX CURTAILED XXXXXXXXX' dump].
|
||||
##['ENSURE TEST' dump] ensure: ['XXXXXXXXX ENSURE XXXXXXXXXXXXXx' dump].
|
||||
|
||||
v1 := [ ['kkk' dump.] ensure: ['XXXXXXXXX ENSURE XXXXXXXXXXXXXx' dump. 30] ] on: Exception do: [:ex | 'EXCEPTION OUTSIDE ENSURE...' dump. ].
|
||||
v1 dump.
|
||||
##v1 := [ ['kkk' dump.] ensure: ['XXXXXXXXX ENSURE XXXXXXXXXXXXXx' dump. 30] ] on: Exception do: [:ex | 'EXCEPTION OUTSIDE ENSURE...' dump. ].
|
||||
##v1 dump.
|
||||
|
||||
'END OF MAIN' dump."
|
||||
|
||||
##[ Exception signal: 'simulated error' ] on: Exception do: [:ex | 'CAUGHT...' dump. Exception signal: 'jjjjjjj' ].
|
||||
|
||||
"[
|
||||
[ Exception signal: 'simulated error' ] ensure: ['ensure 1' dump ].
|
||||
] on: Exception do: [:ex | ('EXCETION - ' , ex messageText) dump. Exception signal: 'qqq'. ]."
|
||||
|
||||
"[1 xxx] ifCurtailed: ['XXXXXXXX CURTAILED XXXXXXXXX' dump. Exception signal: 'jjjj']."
|
||||
|
||||
v1 := [
|
||||
| k |
|
||||
k := 99.
|
||||
[
|
||||
[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ', (k asString)) dump ].
|
||||
] ensure: ['ensure 2' dump ].
|
||||
] on: Exception do: [:ex |
|
||||
('EXCETION - ' , ex messageText) dump.
|
||||
## Exception signal: 'qqq'.
|
||||
].
|
||||
|
||||
'--------------------------------' dump.
|
||||
v1 dump.
|
||||
'END OF MAIN' dump.
|
||||
}
|
||||
|
||||
|
||||
#method(#class) main22222
|
||||
{
|
||||
|t1 t2 s1 s2 s3|
|
||||
|
@ -40,11 +40,19 @@
|
||||
#method(#class) main2
|
||||
{
|
||||
| k |
|
||||
'BEGINNING OF main2' dump.
|
||||
k := ['this is test-011' dump. Exception signal: 'main2 screwed...'. 8888 dump. ]
|
||||
on: Exception do: [ :ex | 'Exception occurred' dump. ex messageText dump. 'Getting back to....' dump. "ex return: 9999." ex pass. 'AFTER RETURN' dump. ].
|
||||
on: Exception do: [ :ex |
|
||||
'Exception occurred' dump.
|
||||
ex messageText dump.
|
||||
'Getting back to....' dump.
|
||||
"ex return: 9999."
|
||||
ex pass.
|
||||
'AFTER RETURN' dump.
|
||||
].
|
||||
|
||||
k dump.
|
||||
'END OF test-011' dump.
|
||||
'END OF main2' dump.
|
||||
}
|
||||
|
||||
#method(#class) raise_exception
|
||||
@ -138,33 +146,45 @@
|
||||
## exception is raised in a new process. it can't be captured
|
||||
## by an exception handler of a calling process.
|
||||
## exception handling must not cross the process boundary.
|
||||
'BEGINNING OF test11' dump.
|
||||
[
|
||||
|p |
|
||||
p := [Exception signal: 'Sample Exception' ] newProcess.
|
||||
p := [ Exception signal: 'Exception in a new process of test11'. ] newProcess.
|
||||
'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ' dump.
|
||||
p resume.
|
||||
] on: Exception do: [:ex | 'EXCEPTION ----------' dump. ex messageText dump ].
|
||||
'END OF test11' dump.
|
||||
}
|
||||
|
||||
#method(#class) test12
|
||||
{
|
||||
'BEGINNING OF test12' dump.
|
||||
[
|
||||
|p |
|
||||
p := [
|
||||
[ Exception signal: 'Sample Exception' ] on: Exception do: [:ex | 'EXCEPTION CAUGHT...' dump. ex messageText dump. ]
|
||||
[ Exception signal: 'Exception in a new process of test12' ]
|
||||
on: Exception do: [:ex |
|
||||
('EXCEPTION CAUGHT...in test12 ==> ', (ex messageText)) dump.
|
||||
]
|
||||
] newProcess.
|
||||
'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ' dump.
|
||||
p resume.
|
||||
] on: Exception do: [:ex | 'EXCEPTION ----------' dump. ex messageText dump ].
|
||||
'END OF test12' dump.
|
||||
}
|
||||
|
||||
|
||||
#method(#class) main
|
||||
{
|
||||
|
||||
'>>>>> BEGINNING OF MAIN' dump.
|
||||
|
||||
## [ self main2 ] on: Exception do: [ :ex | 'EXCEPTION CAUGHT IN MAIN....' dump. ex messageText dump. "ex pass." ex resume. ].
|
||||
[ self main2 ] on: Exception do: [ :ex |
|
||||
'EXCEPTION CAUGHT IN MAIN....' dump.
|
||||
ex messageText dump.
|
||||
"ex pass."
|
||||
'Returning back to where the exception has signalled in main2...' dump.
|
||||
ex resume.
|
||||
].
|
||||
|
||||
'##############################' dump.
|
||||
## self test3.
|
||||
@ -173,7 +193,7 @@
|
||||
## self test5.
|
||||
self test11.
|
||||
## self test12.
|
||||
##100 timesRepeat: ['>>>>> END OF MAIN' dump].
|
||||
## 100 timesRepeat: ['>>>>> END OF MAIN' dump].
|
||||
|
||||
|
||||
"(Exception isKindOf: Apex) dump.
|
||||
|
Reference in New Issue
Block a user