The Trunk: Kernel-ct.1383.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Kernel-ct.1383.mcz

commits-2
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1383.mcz

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

Name: Kernel-ct.1383
Author: ct
Time: 20 March 2021, 7:21:02.280742 pm
UUID: b1953f95-408a-aa4a-9108-cc1dc355e9d1
Ancestors: Kernel-mt.1381

Fixes simulation of the #perform:... primitives 83, 84, and 100 for all edge cases. If the primitive is called with the wrong arguments, the primitive must fail but not the simulator.

For further reference, see also the implementation of primitive 188 (primitiveExecuteMethodArgsArray) just a few lines below. :-)

Tests have been provided in KernelTests-ct.395. Reuploaded to fix mirror variant of primitive 100. Now it's finally possible to debug MirrorPrimitiveTests>>#testMirrorPerform. Replaces Kernel-ct.1367, which can be moved into the treated inbox.

=============== Diff against Kernel-mt.1381 ===============

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].
- [^self send: arguments first 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].
- [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (self objectClass: receiver)].
  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].
- [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (arguments at: 3)].
 
  "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: 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]!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ct.1383.mcz

Nicolas Cellier
Hi all,
it seems that it solves the failing tests for primitive 84 and 100.
But I still get a problem with testPrimitive83.
The test fails, and if I click on it in the TestRunner, the image
crash (SEGV) - at least on windows.
There is a SqueakDebug.log though, and it seems that we try to send
the message 83...
I don't know if you can reproduce or not, but help would be highly appreciated.
Christoph, do you have a clue?

Le mer. 14 avr. 2021 à 14:53, <[hidden email]> a écrit :

>
> Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-ct.1383.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-ct.1383
> Author: ct
> Time: 20 March 2021, 7:21:02.280742 pm
> UUID: b1953f95-408a-aa4a-9108-cc1dc355e9d1
> Ancestors: Kernel-mt.1381
>
> Fixes simulation of the #perform:... primitives 83, 84, and 100 for all edge cases. If the primitive is called with the wrong arguments, the primitive must fail but not the simulator.
>
> For further reference, see also the implementation of primitive 188 (primitiveExecuteMethodArgsArray) just a few lines below. :-)
>
> Tests have been provided in KernelTests-ct.395. Reuploaded to fix mirror variant of primitive 100. Now it's finally possible to debug MirrorPrimitiveTests>>#testMirrorPerform. Replaces Kernel-ct.1367, which can be moved into the treated inbox.
>
> =============== Diff against Kernel-mt.1381 ===============
>
> 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].
> -               [^self send: arguments first 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].
> -               [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (self objectClass: receiver)].
>         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].
> -               [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (arguments at: 3)].
>
>         "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: 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]!
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ct.1383.mcz

Christoph Thiede

Hi Nicolas, hi Eliot, hi all,


this appears to be a merge coordination error again.


Originally, in KernelTests-ct.382, I included a call to the primitive without arguments which makes the VM crash, see http://forum.world.st/The-Inbox-KernelTests-ct-382-mcz-tp5125776p5125777.html (the relevant line is + {}. "missing selector"). Others pointed out correctly that this was a nonsense test, so I uploaded KernelTests-ct.383 as a replacement which removed the relevant lines. But take attention to the diff in the mail on squeak-dev which appears to be erroneous. However, somehow the changes from KernelTests-ct.382 but not KernelTests-ct.383 have made their way into KernelTests-eem.396. Eliot, was this an incident or by attempt? :-)


Long story short: By merging KernelTests-ct.383 into the trunk, too, the CI should pass again. But please double-check the diff in Monticello before approving it. :-)


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Nicolas Cellier <[hidden email]>
Gesendet: Mittwoch, 14. April 2021 17:21:42
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] The Trunk: Kernel-ct.1383.mcz
 
Hi all,
it seems that it solves the failing tests for primitive 84 and 100.
But I still get a problem with testPrimitive83.
The test fails, and if I click on it in the TestRunner, the image
crash (SEGV) - at least on windows.
There is a SqueakDebug.log though, and it seems that we try to send
the message 83...
I don't know if you can reproduce or not, but help would be highly appreciated.
Christoph, do you have a clue?

Le mer. 14 avr. 2021 à 14:53, <[hidden email]> a écrit :
>
> Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-ct.1383.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-ct.1383
> Author: ct
> Time: 20 March 2021, 7:21:02.280742 pm
> UUID: b1953f95-408a-aa4a-9108-cc1dc355e9d1
> Ancestors: Kernel-mt.1381
>
> Fixes simulation of the #perform:... primitives 83, 84, and 100 for all edge cases. If the primitive is called with the wrong arguments, the primitive must fail but not the simulator.
>
> For further reference, see also the implementation of primitive 188 (primitiveExecuteMethodArgsArray) just a few lines below. :-)
>
> Tests have been provided in KernelTests-ct.395. Reuploaded to fix mirror variant of primitive 100. Now it's finally possible to debug MirrorPrimitiveTests>>#testMirrorPerform. Replaces Kernel-ct.1367, which can be moved into the treated inbox.
>
> =============== Diff against Kernel-mt.1381 ===============
>
> 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].
> -               [^self send: arguments first 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].
> -               [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (self objectClass: receiver)].
>         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].
> -               [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (arguments at: 3)].
>
>         "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: 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]!
>
>



Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-ct.1383.mcz

Nicolas Cellier
Thank you Christoph, done.
I remember the discussion now.
In the interim, I had moved Kernel-ct.1383.mcz to inbox because Eliot
already merged...

Le mer. 14 avr. 2021 à 18:21, Thiede, Christoph
<[hidden email]> a écrit :

>
> Hi Nicolas, hi Eliot, hi all,
>
>
> this appears to be a merge coordination error again.
>
>
> Originally, in KernelTests-ct.382, I included a call to the primitive without arguments which makes the VM crash, see http://forum.world.st/The-Inbox-KernelTests-ct-382-mcz-tp5125776p5125777.html (the relevant line is + {}. "missing selector"). Others pointed out correctly that this was a nonsense test, so I uploaded KernelTests-ct.383 as a replacement which removed the relevant lines. But take attention to the diff in the mail on squeak-dev which appears to be erroneous. However, somehow the changes from KernelTests-ct.382 but not KernelTests-ct.383 have made their way into KernelTests-eem.396. Eliot, was this an incident or by attempt? :-)
>
>
> Long story short: By merging KernelTests-ct.383 into the trunk, too, the CI should pass again. But please double-check the diff in Monticello before approving it. :-)
>
>
> Best,
>
> Christoph
>
> ________________________________
> Von: Squeak-dev <[hidden email]> im Auftrag von Nicolas Cellier <[hidden email]>
> Gesendet: Mittwoch, 14. April 2021 17:21:42
> An: The general-purpose Squeak developers list
> Betreff: Re: [squeak-dev] The Trunk: Kernel-ct.1383.mcz
>
> Hi all,
> it seems that it solves the failing tests for primitive 84 and 100.
> But I still get a problem with testPrimitive83.
> The test fails, and if I click on it in the TestRunner, the image
> crash (SEGV) - at least on windows.
> There is a SqueakDebug.log though, and it seems that we try to send
> the message 83...
> I don't know if you can reproduce or not, but help would be highly appreciated.
> Christoph, do you have a clue?
>
> Le mer. 14 avr. 2021 à 14:53, <[hidden email]> a écrit :
> >
> > Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> > http://source.squeak.org/trunk/Kernel-ct.1383.mcz
> >
> > ==================== Summary ====================
> >
> > Name: Kernel-ct.1383
> > Author: ct
> > Time: 20 March 2021, 7:21:02.280742 pm
> > UUID: b1953f95-408a-aa4a-9108-cc1dc355e9d1
> > Ancestors: Kernel-mt.1381
> >
> > Fixes simulation of the #perform:... primitives 83, 84, and 100 for all edge cases. If the primitive is called with the wrong arguments, the primitive must fail but not the simulator.
> >
> > For further reference, see also the implementation of primitive 188 (primitiveExecuteMethodArgsArray) just a few lines below. :-)
> >
> > Tests have been provided in KernelTests-ct.395. Reuploaded to fix mirror variant of primitive 100. Now it's finally possible to debug MirrorPrimitiveTests>>#testMirrorPerform. Replaces Kernel-ct.1367, which can be moved into the treated inbox.
> >
> > =============== Diff against Kernel-mt.1381 ===============
> >
> > 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].
> > -               [^self send: arguments first 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].
> > -               [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (self objectClass: receiver)].
> >         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].
> > -               [^self send: arguments first to: receiver with: (arguments at: 2) lookupIn: (arguments at: 3)].
> >
> >         "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: 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]!
> >
> >
>
>