[squeak-dev] The Inbox: Kernel-ct.1420.mcz

Thiede, Christoph Christoph.Thiede at student.hpi.uni-potsdam.de
Wed Dec 1 16:05:10 UTC 2021


Hi Marcel,


not sure whether error codes are actually an implementation detail. But it is interesting that the VM does not emit symbols for this primitive like for most other primitives. My goal was to mimic the VM behavior to make simulation transparent to the executed code.


Best,

Christoph

________________________________
Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von Taeumel, Marcel
Gesendet: Mittwoch, 1. Dezember 2021 16:22:47
An: squeak-dev
Betreff: Re: [squeak-dev] The Inbox: Kernel-ct.1420.mcz

Hmm... that "-3" looks strange. Like exposing an implementation detail from the VM. There are all kinds of symbols used in combination with #primitiveFailTokenFor:. I agree that "nil" is too generic. But why don't you use a symbol instead of leaking a VM detail?

Best,
Marcel

Am 10.11.2021 14:11:41 schrieb commits at source.squeak.org <commits at source.squeak.org>:

A new version of Kernel was added to project The Inbox:
http://source.squeak.org/inbox/Kernel-ct.1420.mcz

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

Name: Kernel-ct.1420
Author: ct
Time: 10 November 2021, 1:47:10.350242 am
UUID: 8f2e7a27-2c7b-534a-9c78-a90c968e45c5
Ancestors: Kernel-eem.1418

Aligns the error code for primitive 118 during simulation with what the VM returns. See KernelTests-ct.409/#testPrimitive118/{6. 'not a primitive'. {7}},{6. 9. 'not an array'}.

=============== Diff against Kernel-eem.1418 ===============

Item was changed:
----- Method: Context>>doPrimitive:method:receiver:args: (in category 'private') -----
doPrimitive: primitiveIndex method: meth receiver: receiver args: arguments
"Simulate a primitive method whose index is primitiveIndex. The simulated receiver and
arguments are given as arguments to this message. If successful, push result and return
resuming context, else ^ {errCode, PrimitiveFailToken}. Any primitive which provokes
execution needs to be intercepted and simulated to avoid execution running away."

| value |
"Judicious use of primitive 19 (a null primitive that doesn't do anything) prevents
the debugger from entering various run-away activities such as spawning a new
process, etc. Injudicious use results in the debugger not being able to debug
interesting code, such as the debugger itself. Hence use primitive 19 with care :-)"
"SystemNavigation new browseAllSelect: [:m| m primitive = 19]"
primitiveIndex = 19 ifTrue: [
[self notify: ('The code being simulated is trying to control a process ({1}). Process controlling cannot be simulated. If you proceed, things may happen outside the observable area of the simulator.' translated format: {meth reference})]
ifCurtailed: [self push: nil "Cheap fix of the context's internal state"]].

((primitiveIndex between: 201 and: 222)
and: [(self objectClass: receiver) includesBehavior: BlockClosure]) ifTrue:
[(primitiveIndex = 206
or: [primitiveIndex = 208]) ifTrue: "[Full]BlockClosure>>valueWithArguments:"
[^receiver simulateValueWithArguments: arguments first caller: self].
((primitiveIndex between: 201 and: 209) "[Full]BlockClosure>>value[:value:...]"
or: [primitiveIndex between: 221 and: 222]) ifTrue: "[Full]BlockClosure>>valueNoContextSwitch[:]"
[^receiver simulateValueWithArguments: arguments caller: self]].

primitiveIndex = 83 ifTrue: "afr 9/11/1998 19:50" "Object>>perform:[with:...]"
[| selector |
selector := arguments at: 1 ifAbsent:
[^ self class primitiveFailTokenFor: #'bad argument'].
arguments size - 1 = selector numArgs ifFalse:
[^ self class primitiveFailTokenFor: #'bad number of arguments'].
^self send: selector to: receiver with: arguments allButFirst].
primitiveIndex = 84 ifTrue: "afr 9/11/1998 19:50 & eem 8/18/2009 17:04" "Object>>perform:withArguments:"
[| selector args |
arguments size = 2 ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
selector := arguments first.
args := arguments second.
args isArray ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
args size = selector numArgs ifFalse:
[^ self class primitiveFailTokenFor: #'bad number of arguments'].
^self send: selector to: receiver with: args].
primitiveIndex = 100 ifTrue: "eem 8/18/2009 16:57" "Object>>perform:withArguments:inSuperclass:"
[| rcvr selector args superclass |
arguments size
caseOf: {
[3] -> [
rcvr := receiver.
selector := arguments first.
args := arguments second.
superclass := arguments third].
[4] -> ["mirror primitive"
rcvr := arguments first.
selector := arguments second.
args := arguments third.
superclass := arguments fourth] }
otherwise: [^ self class primitiveFailTokenFor: #'bad argument'].
args isArray ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
args size = selector numArgs ifFalse:
[^ self class primitiveFailTokenFor: #'bad number of arguments'].
((self objectClass: rcvr) includesBehavior: superclass) ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
^self send: selector to: rcvr with: args lookupIn: superclass].

"Mutex>>primitiveEnterCriticalSection
Mutex>>primitiveTestAndSetOwnershipOfCriticalSection"
(primitiveIndex = 186 or: [primitiveIndex = 187]) ifTrue:
[| effective |
effective := Processor activeProcess effectiveProcess.
"active == effective"
value := primitiveIndex = 186
ifTrue: [receiver primitiveEnterCriticalSectionOnBehalfOf: effective]
ifFalse: [receiver primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf: effective].
^(self isPrimFailToken: value)
ifTrue: [value]
ifFalse: [self push: value]].

primitiveIndex = 188 ifTrue: "Object>>withArgs:executeMethod:
CompiledMethod class>>receiver:withArguments:executeMethod:
VMMirror>>ifFail:object:with:executeMethod: et al"
[| n args methodArg thisReceiver |
((n := arguments size) between: 2 and: 4) ifFalse:
[^self class primitiveFailTokenFor: #'unsupported operation'].
((self objectClass: (args := arguments at: n - 1)) == Array
and: [(self objectClass: (methodArg := arguments at: n)) includesBehavior: CompiledMethod]) ifFalse:
[^self class primitiveFailTokenFor: #'bad argument'].
methodArg numArgs = args size ifFalse:
[^self class primitiveFailTokenFor: #'bad number of arguments'].
thisReceiver := arguments at: n - 2 ifAbsent: [receiver].
methodArg primitive > 0 ifTrue:
[methodArg isQuick ifTrue:
[^self push: (methodArg valueWithReceiver: thisReceiver arguments: args)].
^self doPrimitive: methodArg primitive method: meth receiver: thisReceiver args: args].
^Context
sender: self
receiver: thisReceiver
method: methodArg
arguments: args].

primitiveIndex = 118 ifTrue: "[receiver:]tryPrimitive:withArgs:; avoid recursing in the VM"
[(arguments size = 3
and: [(self objectClass: arguments second) == SmallInteger
and: [(self objectClass: arguments last) == Array]]) ifTrue:
[^self doPrimitive: arguments second method: meth receiver: arguments first args: arguments last].
(arguments size = 2
and: [(self objectClass: arguments first) == SmallInteger
and: [(self objectClass: arguments last) == Array]]) ifFalse:
+ [^self class primitiveFailTokenFor: -3].
- [^self class primitiveFailTokenFor: nil].
^self doPrimitive: arguments first method: meth receiver: receiver args: arguments last].

value := primitiveIndex = 120 "FFI method"
ifTrue: [(meth literalAt: 1) tryInvokeWithArguments: arguments]
ifFalse:
[primitiveIndex = 117 "named primitives"
ifTrue: [self tryNamedPrimitiveIn: meth for: receiver withArgs: arguments]
ifFalse: "should use self receiver: receiver tryPrimitive: primitiveIndex withArgs: arguments but this is only in later VMs (and appears to be broken)"
[receiver tryPrimitive: primitiveIndex withArgs: arguments]].

^(self isPrimFailToken: value)
ifTrue: [value]
ifFalse: [self push: value]!


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/a4c66aa6/attachment.html>


More information about the Squeak-dev mailing list