[Vm-dev] VM Maker: VMMaker.oscog-eem.3104.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Nov 21 06:34:17 UTC 2021

Eliot Miranda uploaded a new version of VMMaker to project VM Maker:

==================== Summary ====================

Name: VMMaker.oscog-eem.3104
Author: eem
Time: 20 November 2021, 10:34:06.672086 pm
UUID: 09dd3ad9-d9df-4efc-bda5-e63d27fbc9e5
Ancestors: VMMaker.oscog-eem.3103

Fix a crash in recursive invocations of primitive 118, [receiver:]tryPrimitive:withArgs:.  THis is a bit of a hack.  The primtiive failure wsill not be unwound correctly.  We may have to revisit this, but at least the simple case of
	6 tryPrimitive: 118 withArgs: {9. {}}
no longer crashes the VM.

This is tye justification for the many changes in VMMaker.oscog-eem.3103.  WIthout those changes the real VM crashes while the simulator carried on without identifying the null pointer violation; an unacceptable infelicity.

=============== Diff against VMMaker.oscog-eem.3103 ===============

Item was changed:
  ----- Method: StackInterpreterPrimitives>>primitiveDoPrimitiveWithArgs (in category 'control primitives') -----
  	"Implement either ProtoObject>>tryPrimitive: primIndex withArgs: argArray
  	 or Context>>receiver: anObject tryPrimitive: primIndex withArgs: argArray.
  	 If this primitive fails, arrange that its error code is a negative integer, to
  	 distinguish between this failing and the primitive it invokes failing."
  	| argumentArray arraySize index primIdx savedNumArgs rcvr |
  	objectMemory hasSpurMemoryManagerAPI ifTrue: "See checkForAndFollowForwardedPrimitiveState"
  		[metaAccessorDepth := -2].
  	(argumentCount between: 2 and: 3) ifFalse:
  		[^self primitiveFailFor: PrimErrUnsupported negated].
  	argumentArray := self stackTop.
  	primIdx := self stackValue: 1.
  	((objectMemory isArray: argumentArray)
  	 and: [objectMemory isIntegerObject: primIdx]) ifFalse:
  		[^self primitiveFailFor: PrimErrBadArgument negated].
  	arraySize := objectMemory numSlotsOf: argumentArray.
  	(self roomToPushNArgs: arraySize) ifFalse:
  		[^self primitiveFailFor: PrimErrLimitExceeded negated].
  	primIdx := objectMemory integerValueOf: primIdx.
  	primitiveFunctionPointer := self functionPointerFor: primIdx inClass: nil.
  	primitiveFunctionPointer = 0 ifTrue:
  		[primitiveFunctionPointer := #primitiveDoPrimitiveWithArgs.
  		 ^self primitiveFailFor: PrimErrBadIndex negated].
  	"Pop primIndex and argArray, then push args in place..."
  	(savedNumArgs := argumentCount) = 3
  		ifTrue: "...and receiver if the three arg form"
  			[tempOop2 := self stackValue: 4. "actual receiver"
  			 rcvr := self stackValue: 3. "receiver for primitive"
  			 (objectMemory isOopForwarded: rcvr) ifTrue:
  				[rcvr := objectMemory followForwarded: rcvr].
  			 self pop: 4; push: rcvr] "use first arg as receiver"
  			[self pop: 2].
  	argumentCount := arraySize.
  	index := 1.
  	[index <= arraySize] whileTrue:
  		[self push: (objectMemory fetchPointer: index - 1 ofObject: argumentArray).
  		 index := index + 1].
  	self isPrimitiveFunctionPointerAnIndex ifTrue:
  		[self externalQuickPrimitiveResponse.
  		 tempOop2 := 0.
  	"We use tempOop instead of pushRemappableOop:/popRemappableOop here because in
  	 the Cogit primitiveEnterCriticalSection, primitiveSignal, primitiveResume et al longjmp back
  	 to either the interpreter or machine code, depending on the process activated.  So if we're
  	 executing one of these primitives, control won't actually return here and the matching
  	 popRemappableOop: wouldn't occur, potentially overflowing the remap buffer.
  	 Note that while recursion could occur (nil tryPrimitive: 118 withArgs: #(118 #(110 #())))
  	 it counts as shooting oneself in the foot."
  	tempOop := argumentArray. "prim might alloc/gc"
  	"Run the primitive (sets primFailCode)"
  	objectMemory hasSpurMemoryManagerAPI ifTrue: "See checkForAndFollowForwardedPrimitiveState"
  		[metaAccessorDepth := primitiveAccessorDepthTable at: primIdx].
  	self slowPrimitiveResponse.
  	self successful ifFalse: "If primitive failed, then restore state for failure code"
+ 		[tempOop = 0 ifTrue: "the primitive failed in a recursive invocation.  can't fix things with no value..."
+ 			[^self].
+ 		 self pop: arraySize.
- 		[self pop: arraySize.
  		 savedNumArgs = 3 ifTrue:
  			[rcvr := self stackTop.
  			 self stackTopPut: tempOop2.
  			 self push: rcvr].
  		 self pushInteger: primIdx.
  		 self push: tempOop.
  		 primitiveFunctionPointer := #primitiveDoPrimitiveWithArgs.
  		 argumentCount := savedNumArgs].
  	tempOop := tempOop2 := 0!

More information about the Vm-dev mailing list