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:
hyunghwan.chung
2016-06-13 15:52:09 +00:00
parent 1ab2faaf1f
commit f22b896ed2
11 changed files with 180 additions and 72 deletions

View File

@ -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)].

View File

@ -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.

View File

@ -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>

View File

@ -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)

View File

@ -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|

View File

@ -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.