The Inbox: Kernel-ct.1403.mcz

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

The Inbox: Kernel-ct.1403.mcz

A new version of Kernel was added to project The Inbox:

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

Name: Kernel-ct.1403
Author: ct
Time: 9 May 2021, 3:56:31.99261 am
UUID: 9eab7066-e3ce-1a4e-814c-8bf9403a0ea2
Ancestors: Kernel-nice.1402

Fixes a bug in the simulation of objects as methods (OaM) when the object implements #isCompiledMethod, e.g. via dynamic forwarding. We always must use mirror primitives to match the behavior of the VM.

Regression test and further explanation are in KernelTests-ct.405.

=============== Diff against Kernel-nice.1402 ===============

Item was changed:
  ----- Method: Context>>send:to:with:lookupIn: (in category 'controlling') -----
  send: selector to: rcvr with: arguments lookupIn: lookupClass
  "Simulate the action of sending a message with selector and arguments to rcvr. The argument, lookupClass, is the class in which to lookup the message. This is the receiver's class for normal messages, but for super messages it will be some specific class related to the source method."
+ | meth methClass primIndex val ctxt |
- | meth primIndex val ctxt |
  (meth := lookupClass lookupSelector: selector) ifNil:
  [selector == #doesNotUnderstand: ifTrue:
  [self error: 'Recursive message not understood!!' translated].
  ^self send: #doesNotUnderstand:
  to: rcvr
  with: {(Message selector: selector arguments: arguments) lookupClass: lookupClass}
  lookupIn: lookupClass].
+ ((methClass := self objectClass: meth) == CompiledMethod or: [methClass == CompiledBlock]) ifFalse:
- meth isCompiledMethod ifFalse:
  ["Object as Methods (OaM) protocol: 'The contract is that, when the VM encounters an ordinary object (rather than a compiled method) in the method dictionary during lookup, it sends it the special selector #run:with:in: providing the original selector, arguments, and receiver.'. DOI: 10.1145/2991041.2991062."
  ^self send: #run:with:in:
  to: meth
  with: {selector. arguments. rcvr}].
  meth numArgs = arguments size ifFalse:
  [^ self error: ('Wrong number of arguments in simulated message {1}' translated format: {selector})].
  (primIndex := meth primitive) > 0 ifTrue:
  [val := self doPrimitive: primIndex method: meth receiver: rcvr args: arguments.
  (self isPrimFailToken: val) ifFalse:
  (selector == #doesNotUnderstand: and: [lookupClass == ProtoObject]) ifTrue:
  [^self error: ('Simulated message {1} not understood' translated format: {arguments first selector})].
  ctxt := Context sender: self receiver: rcvr method: meth arguments: arguments.
  (primIndex isInteger and: [primIndex > 0]) ifTrue:
  [ctxt failPrimitiveWith: val].