Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2857.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2857 Author: eem Time: 28 October 2020, 1:17:30.27409 am UUID: 4f72a34b-cd5d-4e2c-9eae-45498349bad6 Ancestors: VMMaker.oscog-eem.2856 IA32ABIPlugin: make most of the simple acessors simulate. This makes it possible to simulate the simulator ;-) Refactor sizeFieldOfAlien:, putting it in the object memories, allowing their simulators to cast the size field to a signed integer of the right size. SImulation: make SmartSyntaxPluginSimulator>>computeSignatureMap inheritance savvy. Slang: generate neater code for pointer indirection. Instead of indexing with zero, dereference with *. Fix a bug in CoInterpreterMT>>wakeHighestPriority. =============== Diff against VMMaker.oscog-eem.2856 =============== Item was changed: ----- Method: CCodeGenerator>>generateAt:on:indent: (in category 'C translation') ----- generateAt: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream." + (msgNode args first isConstant + and: [msgNode args first value isZero + and: [msgNode receiver isSend + and: [(#(cCoerceSimple:to: cCoerce:to:) includes: msgNode receiver selector) + and: [msgNode receiver args last value last == $*]]]]) + ifTrue: + [aStream nextPutAll: '(*'. + msgNode receiver emitCCodeAsExpressionOn: aStream level: 0 generator: self. + aStream nextPut: $)] + ifFalse: + [self emitCExpression: msgNode receiver on: aStream. + aStream nextPut: $[. + msgNode args first emitCCodeAsExpressionOn: aStream level: level + 1 generator: self. + aStream nextPut: $]]! - self emitCExpression: msgNode receiver on: aStream. - aStream nextPut: $[. - msgNode args first emitCCodeAsExpressionOn: aStream level: level + 1 generator: self. - aStream nextPut: $]! Item was changed: ----- Method: CCodeGenerator>>generateAtPut:on:indent: (in category 'C translation') ----- generateAtPut: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream." + (msgNode args first isConstant + and: [msgNode args first value isZero + and: [msgNode receiver isSend + and: [(#(cCoerceSimple:to: cCoerce:to:) includes: msgNode receiver selector) + and: [msgNode receiver args last value last == $*]]]]) + ifTrue: + [aStream nextPutAll: '(*'. + msgNode receiver emitCCodeAsExpressionOn: aStream level: 0 generator: self. + aStream nextPutAll: ' = '. + msgNode args last emitCCodeAsExpressionOn: aStream level: 0 generator: self. + aStream nextPut: $)] + ifFalse: + [self emitCExpression: msgNode receiver on: aStream. + aStream nextPut: $[. + msgNode args first emitCCodeAsExpressionOn: aStream level: level + 1 generator: self. + aStream nextPutAll: '] = '. + self emitCExpression: msgNode args last on: aStream]! - self emitCExpression: msgNode receiver on: aStream. - aStream nextPut: $[. - msgNode args first emitCCodeAsExpressionOn: aStream level: level + 1 generator: self. - aStream nextPutAll: '] = '. - self emitCExpression: msgNode args last on: aStream! Item was changed: ----- Method: CoInterpreterMT>>wakeHighestPriority (in category 'process primitive support') ----- wakeHighestPriority "Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the highest priority runnable process. If this variable is 0 then the VM does not know the highest priority and must search all lists. Override to answer nil when there is no runnable process instead of aborting. In the threaded VM the abort test is done in transferTo:from: becaue there may be some thread waiting to own the VM. The transfer to the thread shouldn't be done here because not all clients call this in the right context (allowing a longjmp back to the threadSchedulingLoop)." | schedLists p processList proc ctxt | + self externalWriteBackHeadFramePointers. schedLists := objectMemory fetchPointer: ProcessListsIndex ofObject: self schedulerPointer. p := highestRunnableProcessPriority = 0 ifTrue: [objectMemory numSlotsOf: schedLists] ifFalse: [highestRunnableProcessPriority]. [(p := p - 1) >= 0] whileTrue: [processList := objectMemory fetchPointer: p ofObject: schedLists. [self isEmptyList: processList] whileFalse: ["Only answer processes with a runnable suspendedContext. Discard those that aren't; the VM would crash otherwise." proc := self removeFirstLinkOfList: processList. ctxt := objectMemory fetchPointer: SuspendedContextIndex ofObject: proc. (self isLiveContext: ctxt) ifTrue: [highestRunnableProcessPriority := p + 1. ^proc]. self cppIf: SPURVM ifTrue: ["This is uncommon, so we can deal with forwarders here instead of assuming there isn't." (self isOopForwarded: ctxt) ifTrue: [ctxt := self fixFollowedField: SuspendedContextIndex ofObject: proc withInitialValue: ctxt]. (self isLiveContext: ctxt) ifTrue: [highestRunnableProcessPriority := p + 1. ^proc].]. self warning: 'evicted zombie process from run queue']]. ^nil! Item was changed: ----- Method: IA32ABIPlugin>>primSignedByteAt (in category 'primitives-accessing') ----- primSignedByteAt "Answer the signed 8-bit integer starting at the given byte offset (little endian)." "<Alien> unsignedByteAt: index <Integer> ^<Integer> <primitive: 'primSignedByteAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr value valueOop | <export: true> + <var: #value type: #'signed char'> - <var: #value type: 'signed char '> byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 1 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [self byteAt: startAddr + byteOffset] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedByteAt: byteOffset + 1]. + ^interpreterProxy methodReturnInteger: value! - addr := startAddr + byteOffset. - value := self byteAt: addr. - valueOop := interpreterProxy signed32BitIntegerFor: value. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSignedByteAtPut (in category 'primitives-accessing') ----- primSignedByteAtPut "Store a signed integer into 8 bits starting at the given byte offset (little endian)." "<Alien> signedByteAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primSignedByteAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value valueOop | - | byteOffset rcvr startAddr addr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. value := interpreterProxy signed32BitValueOf: valueOop. (interpreterProxy failed or: [value < -128 or: [value > 127]]) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 1 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [self byteAt: startAddr + byteOffset put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedByteAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - self byteAt: addr put: value. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSignedLongAt (in category 'primitives-accessing') ----- primSignedLongAt "Answer the signed 32-bit integer starting at the given byte offset (little endian)." "<Alien> signedLongAt: index <Integer> ^<Integer> <primitive: 'primSignedLongAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr value valueOop | <export: true> byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 4 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [self long32At: startAddr + byteOffset] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedLongAt: byteOffset + 1]. + ^interpreterProxy methodReturnValue: (interpreterProxy signed32BitIntegerFor: value)! - addr := startAddr + byteOffset. - value := self long32At: addr. - valueOop := interpreterProxy signed32BitIntegerFor: value. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSignedLongAtPut (in category 'primitives-accessing') ----- primSignedLongAtPut "Store a signed integer into 32 bits starting at the given byte offset (little endian)." "<Alien> signedLongAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primSignedLongAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value valueOop | - | byteOffset rcvr startAddr addr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. value := interpreterProxy signed32BitValueOf: valueOop. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 4 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [self long32At: startAddr + byteOffset put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedLongAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - self long32At: addr put: value. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSignedLongLongAt (in category 'primitives-accessing') ----- primSignedLongLongAt "Answer the signed 64-bit integer starting at the given byte offset (little endian)." "<Alien> signedLongLongAt: index <Integer> ^<Integer> <primitive: 'primSignedLongLongAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr valueOop signedlonglongvaluePtr signedlonglongvalue | <export: true> - <var: 'signedlonglongvalue' declareC: 'long long signedlonglongvalue'> - <var: 'signedlonglongvaluePtr' declareC: 'long long *signedlonglongvaluePtr'> - signedlonglongvaluePtr := 0. - self touch: signedlonglongvaluePtr. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 8 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [(self cCoerce: startAddr + byteOffset to: #'long long *') at: 0] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedLongLongAt: byteOffset + 1]. + ^interpreterProxy methodReturnValue: (interpreterProxy signed64BitIntegerFor: value)! - addr := startAddr + byteOffset. - signedlonglongvaluePtr := self cCoerce: addr to: 'long long*'. - signedlonglongvalue := self cCode: '*signedlonglongvaluePtr'. - valueOop := interpreterProxy signed64BitIntegerFor: signedlonglongvalue. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSignedLongLongAtPut (in category 'primitives-accessing') ----- primSignedLongLongAtPut "Store a signed integer into 64 bits starting at the given byte offset (little endian)." "<Alien> signedLongLongAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primSignedLongLongAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr valueOop value | - | byteOffset rcvr startAddr addr valueOop signedlonglongvalue signedlonglongvaluePtr | <export: true> - <var: 'signedlonglongvalue' declareC: 'long long signedlonglongvalue'> - <var: 'signedlonglongvaluePtr' declareC: 'long long *signedlonglongvaluePtr'> - signedlonglongvaluePtr := 0. - self touch: signedlonglongvaluePtr. valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. + value := interpreterProxy signed64BitValueOf: valueOop. - signedlonglongvalue := interpreterProxy signed64BitValueOf: valueOop. - self touch: signedlonglongvalue. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 8 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [(self cCoerce: startAddr + byteOffset to: #'long long *') at: 0 put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedLongLongAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - signedlonglongvaluePtr := self cCoerce: addr to: 'long long*'. - self cCode: '*signedlonglongvaluePtr = signedlonglongvalue'. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSignedShortAt (in category 'primitives-accessing') ----- primSignedShortAt "Answer the signed 32-bit integer starting at the given byte offset (little endian)." "<Alien> signedShortAt: index <Integer> ^<Integer> <primitive: 'primSignedShortAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr value valueOop | <export: true> + <var: #value type: #short> - <var: #value type: 'short '> byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 2 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [self shortAt: startAddr + byteOffset] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedShortAt: byteOffset + 1]. + ^interpreterProxy methodReturnInteger: value! - addr := startAddr + byteOffset. - value := self shortAt: addr. - valueOop := interpreterProxy signed32BitIntegerFor: value. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSignedShortAtPut (in category 'primitives-accessing') ----- primSignedShortAtPut "Store a signed integer into 16 bits starting at the given byte offset (little endian)." "<Alien> signedShortAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primSignedShortAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value valueOop | - | byteOffset rcvr startAddr addr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. value := interpreterProxy signed32BitValueOf: valueOop. (interpreterProxy failed or: [value < -32768 or: [value > 32767]]) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 2 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [self shortAt: startAddr + byteOffset put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) signedShortAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - self shortAt: addr put: value. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primSizeFieldPut (in category 'primitives-accessing') ----- primSizeFieldPut "Store a signed integer into the size field (the first 32 bit field; little endian)." "<Alien> sizeFieldPut: value <Integer> ^<Integer> <primitive: 'primSizeFieldPut' error: errorCode module: 'IA32ABI'>" | rcvr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. rcvr := interpreterProxy stackValue: 1. value := interpreterProxy signedMachineIntegerValueOf: valueOop. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. + interpreterProxy wordSize = 8 - (self cppIf: interpreterProxy bytesPerOop = 8 ifTrue: [self longAt: rcvr + interpreterProxy baseHeaderSize put: value signedIntToLong64] + ifFalse: [self longAt: rcvr + interpreterProxy baseHeaderSize put: value signedIntToLong]. - ifFalse: [self longAt: rcvr + interpreterProxy baseHeaderSize put: value signedIntToLong]). ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedByteAt (in category 'primitives-accessing') ----- primUnsignedByteAt "Answer the unsigned 8-bit integer starting at the given byte offset (little endian)." "<Alien> unsignedByteAt: index <Integer> ^<Integer> <primitive: 'primUnsignedByteAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr value valueOop | <export: true> <var: #value type: 'unsigned char '> byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 1 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [self byteAt: startAddr + byteOffset] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedByteAt: byteOffset + 1]. + ^interpreterProxy methodReturnInteger: value! - addr := startAddr + byteOffset. - value := self byteAt: addr. - valueOop := interpreterProxy positive32BitIntegerFor: value. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedByteAtPut (in category 'primitives-accessing') ----- primUnsignedByteAtPut "Store an unsigned integer into 8 bits starting at the given byte offset (little endian)." "<Alien> unsignedByteAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primUnsignedByteAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value valueOop | - | byteOffset rcvr startAddr addr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. value := interpreterProxy positive32BitValueOf: valueOop. (interpreterProxy failed or: [value > 255]) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 1 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [self byteAt: startAddr + byteOffset put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedByteAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - self byteAt: addr put: value. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedLongAt (in category 'primitives-accessing') ----- primUnsignedLongAt "Answer the unsigned 32-bit integer starting at the given byte offset (little endian)." "<Alien> unsignedLongAt: index <Integer> ^<Integer> <primitive: 'primUnsignedLongAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr value valueOop | <export: true> byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 4 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [self long32At: startAddr + byteOffset] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedLongAt: byteOffset + 1]. + ^interpreterProxy methodReturnValue: (interpreterProxy positive32BitIntegerFor: value)! - addr := startAddr + byteOffset. - value := self long32At: addr. - valueOop := interpreterProxy positive32BitIntegerFor: value. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedLongAtPut (in category 'primitives-accessing') ----- primUnsignedLongAtPut "Store an unsigned integer into 32 bits starting at the given byte offset (little endian)." "<Alien> unsignedLongAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primUnsignedLongAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value valueOop | - | byteOffset rcvr startAddr addr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. value := interpreterProxy positive32BitValueOf: valueOop. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 4 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [self long32At: startAddr + byteOffset put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedLongAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - self long32At: addr put: value. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedLongLongAt (in category 'primitives-accessing') ----- primUnsignedLongLongAt "Answer the unsigned 64-bit integer starting at the given byte offset (little endian)." "<Alien>unsignedLongLongAt: index <Integer> ^<Integer> <primitive: 'primUnsignedLongLongAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr valueOop unsignedlonglongvaluePtr unsignedlonglongvalue | <export: true> - <var: 'unsignedlonglongvalue' declareC: 'unsigned long long unsignedlonglongvalue'> - <var: 'unsignedlonglongvaluePtr' declareC: 'unsigned long long *unsignedlonglongvaluePtr'> - unsignedlonglongvaluePtr := 0. - self touch: unsignedlonglongvaluePtr. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 8 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [(self cCoerce: startAddr + byteOffset to: #'unsigned long long *') at: 0] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedLongLongAt: byteOffset + 1]. + ^interpreterProxy methodReturnValue: (interpreterProxy positive64BitIntegerFor: value)! - addr := startAddr + byteOffset. - unsignedlonglongvaluePtr := self cCoerce: addr to: 'unsigned long long*'. - unsignedlonglongvalue := self cCode: '*unsignedlonglongvaluePtr'. - valueOop := interpreterProxy positive64BitIntegerFor: unsignedlonglongvalue. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedLongLongAtPut (in category 'primitives-accessing') ----- primUnsignedLongLongAtPut "Store a signed integer into 64 bits starting at the given byte offset (little endian)." "<Alien> unsignedLongLongAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primUnSignedLongLongAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr valueOop value | - | byteOffset rcvr startAddr addr valueOop unsignedlonglongvalue unsignedlonglongvaluePtr | <export: true> - <var: 'unsignedlonglongvalue' declareC: 'unsigned long long unsignedlonglongvalue'> - <var: 'unsignedlonglongvaluePtr' declareC: 'unsigned long long *unsignedlonglongvaluePtr'> - unsignedlonglongvaluePtr := 0. - self touch: unsignedlonglongvaluePtr. - valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. + value := interpreterProxy positive64BitValueOf: valueOop. - unsignedlonglongvalue := interpreterProxy positive64BitValueOf: valueOop. - self touch: unsignedlonglongvalue. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 8 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [(self cCoerce: startAddr + byteOffset to: #'unsigned long long *') at: 0 put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedLongLongAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - unsignedlonglongvaluePtr := self cCoerce: addr to: 'unsigned long long*'. - self cCode: '*unsignedlonglongvaluePtr = unsignedlonglongvalue'. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedShortAt (in category 'primitives-accessing') ----- primUnsignedShortAt "Answer the unsigned 16-bit integer starting at the given byte offset (little endian)." "<Alien> unsignedShortAt: index <Integer> ^<Integer> <primitive: 'primUnsignedShortAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr value valueOop | <export: true> <var: #value type: 'unsigned short'> byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 2 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [self shortAt: startAddr + byteOffset] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedShortAt: byteOffset + 1]. + ^interpreterProxy methodReturnInteger: value! - addr := startAddr + byteOffset. - value := self shortAt: addr. - valueOop := interpreterProxy positive32BitIntegerFor: value. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedShortAtPut (in category 'primitives-accessing') ----- primUnsignedShortAtPut "Store an unsigned integer into 16 bits starting at the given byte offset (little endian)." "<Alien> unsignedShortAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value valueOop | - | byteOffset rcvr startAddr addr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. value := interpreterProxy positive32BitValueOf: valueOop. (interpreterProxy failed or: [value > 65535]) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: 2 inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [self shortAt: startAddr + byteOffset put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedShortAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - self shortAt: addr put: value. ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedWordAt (in category 'primitives-accessing') ----- primUnsignedWordAt "Answer the unsigned word starting at the given byte offset (little endian)." "<Alien> unsignedWordAt: index <Integer> ^<Integer> <primitive: 'primUnsignedWordAt' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value | - | byteOffset rcvr startAddr addr value valueOop | <export: true> byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 0) - 1. rcvr := interpreterProxy stackObjectValue: 1. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: interpreterProxy bytesPerOop inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + value := self cCode: [self longAt: startAddr + byteOffset] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedWordAt: byteOffset + 1]. + ^interpreterProxy methodReturnValue: (interpreterProxy positiveMachineIntegerFor: value)! - addr := startAddr + byteOffset. - value := self longAt: addr. - valueOop := interpreterProxy positiveMachineIntegerFor: value. - ^interpreterProxy methodReturnValue: valueOop! Item was changed: ----- Method: IA32ABIPlugin>>primUnsignedWordAtPut (in category 'primitives-accessing') ----- primUnsignedWordAtPut "Store an unsigned integer into 32 bits starting at the given byte offset (little endian)." "<Alien> unsignedWordAt: index <Integer> put: value <Integer> ^<Integer> <primitive: 'primUnsignedWordAtPut' error: errorCode module: 'IA32ABI'>" + | byteOffset rcvr startAddr value valueOop | - | byteOffset rcvr startAddr addr value valueOop | <export: true> valueOop := interpreterProxy stackValue: 0. byteOffset := (interpreterProxy stackPositiveMachineIntegerValue: 1) - 1. rcvr := interpreterProxy stackObjectValue: 2. value := interpreterProxy positiveMachineIntegerValueOf: valueOop. interpreterProxy failed ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]. (self index: byteOffset length: interpreterProxy bytesPerOop inRange: rcvr) ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadIndex]. (interpreterProxy isOopImmutable: rcvr) ifTrue: [^interpreterProxy primitiveFailFor: PrimErrNoModification]. (startAddr := self startOfData: rcvr) = 0 ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadReceiver]. + self cCode: [self longAt: startAddr + byteOffset put: value] + inSmalltalk: [(self alienFor: rcvr at: startAddr) unsignedWordAt: byteOffset + 1 put: value]. - addr := startAddr + byteOffset. - self longAt: addr put: value. ^interpreterProxy methodReturnValue: valueOop! Item was added: + ----- Method: IA32ABIPluginSimulator>>alienFor:at: (in category 'simulation support') ----- + alienFor: alienObj at: addr + | size | + size := interpreterProxy sizeFieldOfAlien: alienObj. + size > 0 ifTrue: + [self error: 'cannot easily simulate internal aliens']. + ^Alien forPointer: addr! Item was added: + ----- Method: IA32ABIPluginSimulator>>cCode: (in category 'simulation support') ----- + cCode: thing + "These we want to rewrite into functional simulation code..." + self halt! Item was added: + ----- Method: IA32ABIPluginSimulator>>sizeField: (in category 'simulation support') ----- + sizeField: alienOop + "This way correctly coerces to a signed integer..." + ^interpreterProxy sizeFieldOfAlien: alienOop! Item was changed: ----- Method: InterpreterPlugin>>doesNotUnderstand: (in category 'simulation support') ----- doesNotUnderstand: aMessage <doNotGenerate> "Override doesNotUnderstand: to iuntercept sends of translated primitive selectors. The translated primitives are primitives derived from the primitive methods themselves translating their failure code/method body into Slang code." (self methodAndTypesOrNilForTranslatedPrimitiveSelector: aMessage selector) ifNil: [^super doesNotUnderstand: aMessage] ifNotNil: [:tuple| | method | + "First check the cache for validity; if the last element of the tuple is the actual method - "First check the cache for validity; if the ast element of the tuple is the actual method then the cache is up-to-date. if it is not, the method has changed and should be regenerated." method := tuple last. method == (method methodClass >> method selector) ifFalse: [translatedMethodCache removeKey: aMessage selector. ^self doesNotUnderstand: aMessage]. method := tuple first. tuple second ifNil: [interpreterProxy primitiveFail] ifNotNil: [:types| self tryToRunTranslatedPrimitive: method types: types subsidiaries: tuple third]. (#( compare:with:collated: findFirstInString:inSet:startingAt: findSubstring:in:startingAt:matchTable: hashBytes:startingWith: indexOfAscii:inString:startingAt: translate:from:to:table: compress:toByteArray: decompress:fromByteArray:at:) includes: method selector) ifFalse: [interpreterProxy transcript print: method; cr. interpreterProxy coInterpreter printExternalHeadFrame]. interpreterProxy failed ifTrue: [interpreterProxy transcript nextPutAll: 'WARNING!! Failing translated primitive '; nextPutAll: aMessage selector; nextPutAll: ' implemented by '; nextPutAll: method methodClass name; nextPutAll: '>>'; nextPutAll: method selector; cr; flush]]! Item was changed: ----- Method: InterpreterPlugin>>sizeField: (in category 'alien support') ----- sizeField: alienOop "Answer the size field of an alienOop which is assumed to be an Alien of at least 8 bytes (32-bits) or 16 bytes (64 bits)" <inline: true> + ^interpreterProxy wordSize = 8 + ifTrue: [(interpreterProxy longAt: alienOop + interpreterProxy baseHeaderSize) signedIntFromLong64] + ifFalse: [(interpreterProxy longAt: alienOop + interpreterProxy baseHeaderSize) signedIntFromLong]! - ^self longAt: alienOop + interpreterProxy baseHeaderSize! Item was changed: ----- Method: InterpreterPlugin>>startOfData: (in category 'alien support') ----- startOfData: alienOop "Answer the start of an Alien's data. For direct aliens this is the address of the second field. For indirect and pointer aliens it is what the second field points to." ^(self sizeField: alienOop) > 0 ifTrue: [alienOop + interpreterProxy baseHeaderSize + interpreterProxy bytesPerOop] + ifFalse: [interpreterProxy longAt: alienOop + interpreterProxy baseHeaderSize + interpreterProxy bytesPerOop]! - ifFalse: [self longAt: alienOop + interpreterProxy baseHeaderSize + interpreterProxy bytesPerOop]! Item was changed: ----- Method: InterpreterPrimitives>>isDirectAlien: (in category 'primitive support') ----- isDirectAlien: oop + ^(objectMemory sizeFieldOfAlien: oop) > 0! - ^(self sizeFieldOfAlien: oop) > 0! Item was changed: ----- Method: InterpreterPrimitives>>isIndirectAlien: (in category 'primitive support') ----- isIndirectAlien: oop + ^(objectMemory sizeFieldOfAlien: oop) < 0! - ^(self sizeFieldOfAlien: oop) < 0! Item was changed: ----- Method: InterpreterPrimitives>>isPointerAlien: (in category 'primitive support') ----- isPointerAlien: oop + ^(objectMemory sizeFieldOfAlien: oop) = 0! - ^(self sizeFieldOfAlien: oop) = 0! Item was removed: - ----- Method: InterpreterPrimitives>>sizeFieldOfAlien: (in category 'primitive support') ----- - sizeFieldOfAlien: alienObj - "Answer the first field of alienObj which is assumed to be an Alien of at least 8 bytes" - <inline: true> - ^objectMemory longAt: alienObj + objectMemory baseHeaderSize! Item was changed: ----- Method: InterpreterPrimitives>>sizeOfAlienData: (in category 'primitive support') ----- sizeOfAlienData: oop "Answer the start of the Alien's data or fail if oop is not an Alien." <api> <returnTypeC: #usqInt> - | size | (self is: oop KindOfClass: (objectMemory splObj: ClassAlien)) ifFalse: [self primitiveFailFor: PrimErrBadArgument. ^0]. + ^(objectMemory sizeFieldOfAlien: oop) abs! - size := self sizeFieldOfAlien: oop. - ^size abs! Item was added: + ----- Method: NewCoObjectMemorySimulator>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 8 bytes" + <inline: #always> + ^(super sizeFieldOfAlien: alienObj) signedIntFromLong! Item was added: + ----- Method: NewObjectMemory>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 8 bytes" + <inline: #always> + ^self longAt: alienObj + self baseHeaderSize! Item was added: + ----- Method: NewObjectMemory>>stackPositiveMachineIntegerValue: (in category 'simulation only') ----- + stackPositiveMachineIntegerValue: offset + "hack around the CoInterpreter/ObjectMemory split refactoring" + <doNotGenerate> + ^coInterpreter stackPositiveMachineIntegerValue: offset! Item was added: + ----- Method: NewObjectMemorySimulator>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 8 bytes" + <inline: #always> + ^(super sizeFieldOfAlien: alienObj) signedIntFromLong! Item was changed: ----- Method: SmartSyntaxPluginSimulator>>computeSignatureMap (in category 'initialize') ----- computeSignatureMap forMap := true. "true only while we compute the signatureMap" signatureMap := Dictionary new. + (pluginClass withAllSuperclasses copyUpTo: SmartSyntaxInterpreterPlugin) do: + [:theClass| + theClass selectorsAndMethodsDo: + [:s :m| + (m messages includesAnyOf: #(primitive: primitive:parameters: primitive:parameters:receiver:)) + ifTrue: [self getPrimitiveSignatureFor: s] + ifFalse: + [(m pragmaAt: #export:) ifNotNil: + [:exportPragma| + (exportPragma argumentAt: 1) ifTrue: + [self computeSignatureFor: s from: { #forMap. s. #(). nil }]]]]]. - pluginClass selectorsAndMethodsDo: - [:s :m| - (m messages includesAnyOf: #(primitive: primitive:parameters: primitive:parameters:receiver:)) - ifTrue: [self getPrimitiveSignatureFor: s] - ifFalse: - [(m pragmaAt: #export:) ifNotNil: - [:exportPragma| - (exportPragma argumentAt: 1) ifTrue: - [self computeSignatureFor: s from: { #forMap. s. #(). nil }]]]]. forMap := false! Item was added: + ----- Method: Spur32BitMMLECoSimulator>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 8 bytes" + <inline: #always> + ^(super sizeFieldOfAlien: alienObj) signedIntFromLong! Item was added: + ----- Method: Spur32BitMMLESimulator>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 8 bytes" + <inline: #always> + ^(super sizeFieldOfAlien: alienObj) signedIntFromLong! Item was added: + ----- Method: Spur64BitMMLECoSimulator>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 16 bytes" + <inline: #always> + ^(super sizeFieldOfAlien: alienObj) signedIntFromLong64! Item was added: + ----- Method: Spur64BitMMLESimulator>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 16 bytes" + <inline: #always> + ^(super sizeFieldOfAlien: alienObj) signedIntFromLong64! Item was added: + ----- Method: SpurMemoryManager>>sizeFieldOfAlien: (in category 'interpreter access') ----- + sizeFieldOfAlien: alienObj + "Answer the first field of alienObj which is assumed to be an Alien of at least 8/16 bytes, depending on word size" + <inline: #always> + ^self longAt: alienObj + self baseHeaderSize! Item was added: + ----- Method: SpurMemoryManager>>stackPositiveMachineIntegerValue: (in category 'simulation only') ----- + stackPositiveMachineIntegerValue: offset + "hack around the CoInterpreter/ObjectMemory split refactoring" + <doNotGenerate> + ^coInterpreter stackPositiveMachineIntegerValue: offset! Item was changed: ----- Method: StackInterpreter>>printOop: (in category 'debug printing') ----- printOop: oop | cls fmt lastIndex startIP bytecodesPerLine column | <inline: false> (objectMemory isImmediate: oop) ifTrue: [^self shortPrintOop: oop]. self printHex: oop. (objectMemory addressCouldBeObj: oop) ifFalse: [(oop bitAnd: objectMemory allocationUnit - 1) ~= 0 ifTrue: [^self print: ' is misaligned'; cr]. ((objectMemory isInNewSpace: oop) and: [objectMemory isForwarded: oop]) ifTrue: [self printForwarder: oop]. ^self print: (self whereIs: oop); cr]. (objectMemory isFreeObject: oop) ifTrue: [self print: ' is a free chunk of size '; printNum: (objectMemory sizeOfFree: oop). objectMemory hasSpurMemoryManagerAPI ifTrue: [self print: ' 0th: '; printHex: (objectMemory fetchPointer: 0 ofFreeChunk: oop). objectMemory printHeaderTypeOf: oop]. ^self cr]. (objectMemory isForwarded: oop) ifTrue: [^self printForwarder: oop]. self print: ': a(n) '. self printNameOfClass: (cls := objectMemory fetchClassOfNonImm: oop) count: 5. cls = (objectMemory splObj: ClassFloat) ifTrue: [^self cr; printFloat: (objectMemory dbgFloatValueOf: oop); cr]. fmt := objectMemory formatOf: oop. fmt > objectMemory lastPointerFormat ifTrue: [self print: ' nbytes '; printNum: (objectMemory numBytesOf: oop)]. self cr. (fmt between: objectMemory firstLongFormat and: objectMemory firstCompiledMethodFormat - 1) ifTrue: ["This will answer false if splObj: ClassAlien is nilObject" (self is: oop KindOfClass: (objectMemory splObj: ClassAlien)) ifTrue: + [self print: ' datasize '; printNum: (objectMemory sizeFieldOfAlien: oop). - [self print: ' datasize '; printNum: (self sizeOfAlienData: oop). self print: ((self isIndirectAlien: oop) ifTrue: [' indirect @ '] ifFalse: [(self isPointerAlien: oop) ifTrue: [' pointer @ '] ifFalse: [' direct @ ']]). ^self printHex: (self startOfAlienData: oop) asUnsignedInteger; cr]. (objectMemory isWordsNonImm: oop) ifTrue: [lastIndex := 64 min: ((objectMemory numBytesOf: oop) / objectMemory wordSize). lastIndex > 0 ifTrue: [1 to: lastIndex do: [:index| self space; printHex: (self cCoerceSimple: (objectMemory fetchLong32: index - 1 ofObject: oop) to: #'unsigned int'). (index \\ self elementsPerPrintOopLine) = 0 ifTrue: [self cr]]. (lastIndex \\ self elementsPerPrintOopLine) = 0 ifFalse: [self cr]]. ^self]. ^self printStringOf: oop; cr]. "this is nonsense. apologies." startIP := (objectMemory lastPointerOf: oop) + objectMemory bytesPerOop - objectMemory baseHeaderSize / objectMemory bytesPerOop. lastIndex := 256 min: startIP. lastIndex > 0 ifTrue: [1 to: lastIndex do: [:index| self cCode: [self printHex: (objectMemory fetchPointer: index - 1 ofObject: oop); space] inSmalltalk: [self space; printHex: (objectMemory fetchPointer: index - 1 ofObject: oop); space. self print: (self shortPrint: (objectMemory fetchPointer: index - 1 ofObject: oop))]. (index \\ self elementsPerPrintOopLine) = 0 ifTrue: [self cr]]. (lastIndex \\ self elementsPerPrintOopLine) = 0 ifFalse: [self cr]]. (objectMemory isCompiledMethod: oop) ifFalse: [startIP > 64 ifTrue: [self print: '...'; cr]] ifTrue: [startIP := startIP * objectMemory wordSize + 1. lastIndex := objectMemory lengthOf: oop. lastIndex - startIP > 100 ifTrue: [lastIndex := startIP + 100]. bytecodesPerLine := 8. column := 1. startIP to: lastIndex do: [:index| | byte | column = 1 ifTrue: [self cCode: 'printf("0x%08" PRIxSQPTR ": ", (usqIntptr_t)(oop+BaseHeaderSize+index-1))' inSmalltalk: [self print: (oop+objectMemory baseHeaderSize+index-1) hex; print: ': ']]. byte := objectMemory fetchByte: index - 1 ofObject: oop. self cCode: 'printf(" %02x/%-3d", (int)byte,(int)byte)' inSmalltalk: [self space; print: (byte radix: 16); printChar: $/; printNum: byte]. column := column + 1. column > bytecodesPerLine ifTrue: [column := 1. self cr]]. column = 1 ifFalse: [self cr]]! |
Free forum by Nabble | Edit this page |