Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1002.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1002 Author: eem Time: 27 December 2014, 5:07:33.563 pm UUID: 6b1f3f75-19bc-4453-be2f-bf7067898bbf Ancestors: VMMaker.oscog-eem.1001
Send cannotReturn for sideways return attemps when there's an unwind-protect. Old code would erroneously answer unwind-protect even if home could not be found.
e.g. This should raise cannot return:
| b | b := [ ^ 42 ]. [ [b value] ensure: [1] ] fork. Processor yield
just as this does:
| b | b := [ ^ 42 ]. [ b value ] fork. Processor yield
=============== Diff against VMMaker.oscog-eem.1001 ===============
Item was changed: ----- Method: StackInterpreter>>findMethodWithPrimitive:FromContext:UpToContext: (in category 'handler search') ----- findMethodWithPrimitive: primitive FromContext: senderContext UpToContext: homeContext "See findUnwindThroughContext:. Alas this is mutually recursive with findMethodWithPrimitive:FromFP:SP:ThroughContext: instead of iterative. We're doing the simplest thing that could possibly work. Niceties can wait." | theContext theMethod | self assert: (senderContext = objectMemory nilObject or: [objectMemory isContext: senderContext]). self assert: (homeContext = objectMemory nilObject or: [objectMemory isContext: homeContext]). theContext := senderContext. [theContext = objectMemory nilObject ifTrue: [^theContext]. self isMarriedOrWidowedContext: theContext] whileFalse: [theContext = homeContext ifTrue: [^0]. + (primitive = 0 + or: [(objectMemory fetchPointer: ClosureIndex ofObject: theContext) ~= objectMemory nilObject]) ifFalse: - (objectMemory fetchPointer: ClosureIndex ofObject: theContext) = objectMemory nilObject ifTrue: [theMethod := objectMemory fetchPointer: MethodIndex ofObject: theContext. + (self primitiveIndexOf: theMethod) = primitive ifTrue: - (self primitiveIndexOf: theMethod) == primitive ifTrue: [^theContext]]. theContext := objectMemory fetchPointer: SenderIndex ofObject: theContext]. (self isWidowedContext: theContext) ifTrue: [^objectMemory nilObject]. ^self findMethodWithPrimitive: primitive FromFP: (self frameOfMarriedContext: theContext) UpToContext: homeContext!
Item was changed: ----- Method: StackInterpreter>>findMethodWithPrimitive:FromFP:UpToContext: (in category 'handler search') ----- findMethodWithPrimitive: primitive FromFP: startFP UpToContext: homeContext "See findUnwindThroughContext:. Alas this is mutually recursive with findMethodWithPrimitive:FromContext:ThroughContext: instead of iterative. We're doing the simplest thing that could possibly work. Niceties can wait." | theFP theFPAbove theSP theMethod senderContext | <var: #startFP type: #'char *'> <var: #theFP type: #'char *'> <var: #theFPAbove type: #'char *'> <var: #theSP type: #'char *'> theFP := startFP. theFPAbove := startFP. [((self frameHasContext: theFP) and: [homeContext = (self frameContext: theFP)]) ifTrue: [^0]. + (primitive = 0 + or: [self frameIsBlockActivation: theFP]) ifFalse: - (self frameIsBlockActivation: theFP) ifFalse: [theMethod := self frameMethodObject: theFP. + (self primitiveIndexOf: theMethod) = primitive ifTrue: - (self primitiveIndexOf: theMethod) == primitive ifTrue: [theFP = theFPAbove ifTrue: [theSP := self findSPOf: theFP on: (stackPages stackPageFor: theFP)] ifFalse: [theSP := self frameCallerStackPointer: theFPAbove]. ^self ensureFrameIsMarried: theFP SP: theSP]]. theFPAbove := theFP. theFP := self frameCallerFP: theFP. theFP ~= 0] whileTrue. senderContext := self frameCallerContext: theFPAbove. (objectMemory isContext: senderContext) ifFalse: [^objectMemory nilObject]. ^self findMethodWithPrimitive: primitive FromContext: senderContext UpToContext: homeContext!
Item was changed: ----- Method: StackInterpreter>>findUnwindThroughContext: (in category 'return bytecodes') ----- findUnwindThroughContext: homeContext "Search for either an unwind-protect (activation of method with primitive 198) + or homeContext along the sender chain, which ever is found first. Return values: + 0 home context was found on sender chain with no intervening unwind-protects + nilObj home context could not be found => cannotReturn + context the context of an intervening unwind-protect implies home context was found" - or homeContext along the sender chain, which ever is found first. If homeContext - is not found answer nilObj, indicating cannotReturn:. If homeContext is found - answer 0. If homeContext is itself an unwind-protect answer the context, not 0." | ctxtOrNilOrZero theMethod | "Since nothing changes we don't need to internalize." ctxtOrNilOrZero := self findMethodWithPrimitive: 198 FromFP: framePointer UpToContext: homeContext. ctxtOrNilOrZero = 0 ifTrue: [theMethod := objectMemory fetchPointer: MethodIndex ofObject: homeContext. + (self primitiveIndexOf: theMethod) = 198 ifTrue: + [^homeContext]. + ^0]. + ctxtOrNilOrZero = objectMemory nilObject ifFalse: + [(self findMethodWithPrimitive: 0 FromContext: ctxtOrNilOrZero UpToContext: homeContext) + = objectMemory nilObject ifTrue: + [^objectMemory nilObject]]. - (self primitiveIndexOf: theMethod) == 198 ifTrue: - [^homeContext]]. ^ctxtOrNilOrZero!