Eliot Miranda uploaded a new version of VMMakerUI to project VM Maker: http://source.squeak.org/VMMaker/VMMakerUI-eem.3.mcz ==================== Summary ==================== Name: VMMakerUI-eem.3 Author: eem Time: 23 December 2019, 5:27:28.251899 pm UUID: dc66cff5-f922-4813-82f8-31400bb26941 Ancestors: VMMakerUI-eem.2 Move UI only fiunctionality to VMMakerUI. Make a hierarchy of VMObjectInspectors. Expect a VMObjectInspector to respond to open, so that it may be creeated, initialized, and then opened. Add a proof-of-concept CogAbstractFrameInspector thyat works by parsing the output of printFrame:on:. This is a daft way of doing things but does prove the concept. The right way is of courser to refactor frame printing so that it can print on a text stream and add emphasis if desired. =============== Diff against VMMakerUI-eem.2 =============== Item was added: + CogVMObjectInspector subclass: #CogAbstractFrameInspector + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'VMMakerUI-SqueakInspectors'! Item was added: + ----- Method: CogAbstractFrameInspector>>addressFromString: (in category 'private') ----- + addressFromString: aString + ^(ExtendedNumberParser on: ((ReadStream on: aString) skipSeparators; yourself)) nextInteger! Item was added: + ----- Method: CogAbstractFrameInspector>>buildWith: (in category 'building') ----- + buildWith: builder + + | windowSpec frameTextSpec | + (windowSpec := builder pluggableWindowSpec new) + model: self; + label: #windowTitle; + extent: 400@200; + children: OrderedCollection new. + (frameTextSpec := builder pluggableTextSpec new) + model: self; + getText: #text; + frame: (0@0 corner: 1@1); + yourself. + windowSpec children add: frameTextSpec. + ^(builder build: windowSpec) + paneColor: (coInterpreter ifNotNil: [coInterpreter windowColorToUse] ifNil: [self defaultWindowColor]); + yourself! Item was added: + ----- Method: CogAbstractFrameInspector>>evalAttributeForFieldName:framePointer:value:addressString: (in category 'accessing - ui') ----- + evalAttributeForFieldName: frameField framePointer: framePointer value: valueString addressString: addressString + (frameField = 'caller ip' + or: [frameField = 'frame ip']) ifTrue: + [^PluggableTextAttribute evalBlock: [self interpretFrame: framePointer ip: frameField value: valueString at: (self addressFromString: addressString)]]. + frameField = 'saved fp' ifTrue: + [^PluggableTextAttribute evalBlock: [self interpretFramePointer: frameField value: valueString at: (self addressFromString: addressString)]]. + frameField = 'method' ifTrue: + [^PluggableTextAttribute evalBlock: [self interpretMethod: frameField value: valueString at: (self addressFromString: addressString)]]. + ^(frameField ~= 'mcfrm flags' and: [frameField ~= 'intfrm flags']) ifTrue: + [PluggableTextAttribute evalBlock: [self interpretOop: frameField value: valueString at: (self addressFromString: addressString)]]! Item was added: + ----- Method: CogAbstractFrameInspector>>text (in category 'accessing - ui') ----- + text + ^self textForFramePointer: self framePointer stackPointer: self stackPointer! Item was added: + ----- Method: CogAbstractFrameInspector>>textForFramePointer:stackPointer: (in category 'accessing - ui') ----- + textForFramePointer: framePointer stackPointer: stackPointer + "Print and emphasize the frame text as efficiently as possible, deferring as much interpretation until evaluation time." + | frameString frameText | + frameText := (String streamContents: [:fs| coInterpreter printFrame: framePointer WithSP: stackPointer on: fs]) allButFirst asText. + (frameString := frameText string) + findTokens: {Character cr} + indicesDo: + [:start :stop| | firstColonIndex fieldNameIndex fieldNameEndIndex valueIndex | + start = 1 + ifTrue: + [self windowTitle: (frameString copyFrom: 1 to: stop)] + ifFalse: + [fieldNameIndex := (firstColonIndex := frameString indexOf: $: startingAt: start + 1) + 1. + [(frameString at: fieldNameIndex) = Character space] whileTrue: + [fieldNameIndex := fieldNameIndex + 1]. + fieldNameEndIndex := (frameString indexOf: $: startingAt: fieldNameIndex + 1) - 1. + valueIndex := fieldNameEndIndex + 2. + [(frameString at: valueIndex) = Character space] whileTrue: + [valueIndex := valueIndex + 1]. + (self evalAttributeForFieldName: (frameString copyFrom: fieldNameIndex to: fieldNameEndIndex) + framePointer: framePointer + value: (frameString copyFrom: valueIndex to: stop) + addressString: (frameString copyFrom: start to: firstColonIndex - 1)) + ifNotNil: + [:attribute| frameText addAttribute: attribute from: fieldNameIndex to: fieldNameEndIndex]]]. + ^frameText! Item was added: + CogAbstractFrameInspector subclass: #CogFrameInspector + instanceVariableNames: 'framePointer stackPointer' + classVariableNames: '' + poolDictionaries: '' + category: 'VMMakerUI-SqueakInspectors'! Item was added: + ----- Method: CogFrameInspector>>framePointer (in category 'accessing') ----- + framePointer + + ^ framePointer! Item was added: + ----- Method: CogFrameInspector>>framePointer: (in category 'accessing') ----- + framePointer: anObject + + framePointer := anObject.! Item was added: + ----- Method: CogFrameInspector>>stackPointer (in category 'accessing') ----- + stackPointer + + ^ stackPointer! Item was added: + ----- Method: CogFrameInspector>>stackPointer: (in category 'accessing') ----- + stackPointer: anObject + + stackPointer := anObject.! Item was added: + CogAbstractFrameInspector subclass: #CogHeadFrameInspector + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'VMMakerUI-SqueakInspectors'! Item was changed: + CogVMObjectInspector subclass: #CogProcessorAlienInspector + instanceVariableNames: 'processor registerSelectors registerCache registerMap' - Model subclass: #CogProcessorAlienInspector - instanceVariableNames: 'cogit coInterpreter objectMemory processor registerSelectors windowTitle registerCache registerMap' classVariableNames: '' poolDictionaries: '' category: 'VMMakerUI-SqueakInspectors'! !CogProcessorAlienInspector commentStamp: 'eem 12/22/2019 08:27' prior: 0! A CogProcessorAlienInspector is an inspector for a CogProcessorAlien processor simulator that displays the processor simulator's register state. Instance Variables processor: <CogProcessorAlien> registerCache: <Array of Integer> registerSelectors: <Array of Symbol> windowTitle: <String>! Item was removed: - ----- Method: CogProcessorAlienInspector class>>open (in category 'instance creation') ----- - open - ^ToolBuilder open: - (self new - processor: (Cogit classPool at: #ProcessorClass) new; - yourself)! Item was removed: - ----- Method: CogProcessorAlienInspector class>>openFor: (in category 'instance creation') ----- - openFor: aCogit - ^ToolBuilder open: (self new cogit: aCogit; yourself)! Item was added: + ----- Method: CogProcessorAlienInspector class>>openOn:memory: (in category 'instance creation') ----- + openOn: aProcessor memory: anArrayOfBits + ^ToolBuilder open: + (self new + processor: aProcessor; + memory: anArrayOfBits; + yourself)! Item was changed: ----- Method: CogProcessorAlienInspector>>buildWith: (in category 'building') ----- buildWith: builder + | windowSpec registerTextSpec | + (windowSpec := builder pluggableWindowSpec new) - | window registers | - window := builder pluggableWindowSpec new. - window model: self; label: #windowTitle; extent: 400@200; children: OrderedCollection new. + (registerTextSpec := builder pluggableTextSpec new) - registers := builder pluggableTextSpec new. - registers model: self; font: Preferences standardFixedFont; getText: #text; frame: (0@0 corner: 1@1); yourself. + windowSpec children add: registerTextSpec. + ^(builder build: windowSpec) + paneColor: (coInterpreter ifNotNil: [coInterpreter windowColorToUse] ifNil: [self defaultWindowColor]); - window children add: registers. - ^(builder build: window) - paneColor: coInterpreter windowColorToUse; yourself! Item was added: + ----- Method: CogProcessorAlienInspector>>coInterpreter: (in category 'initialization') ----- + coInterpreter: aCoInterpreter + super coInterpreter: aCoInterpreter. + processor := cogit processor. + registerSelectors := processor registerStateGetters. + self computeRegisterMap. + windowTitle := nil. + self changed: #text; changed: #window! Item was changed: ----- Method: CogProcessorAlienInspector>>interpret: (in category 'evaluation') ----- interpret: registerSelector "Offer some ways of interpretation." | value options where choice | self flag: #updates. "mt: The cache value corresponds maybe to the value at interaction time. In case the register changes quickly and it takes the user some time to make a choice?" value := registerCache at: registerSelector. + coInterpreter + ifNil: + [options := OrderedDictionary newFrom: { + 'Integer' -> #interpret:asInteger:. + 'Character' -> #interpret:asCharacter:. + 'Machine Instruction' -> #interpret:asInstructionAt:. + }. + where := self printStringForRegisterContents: value] + ifNotNil: + [options := OrderedDictionary newFrom: { + 'Object' -> #interpret:asObject:. + 'Stack frame' -> #interpret:asStackFrame:. + 'Code address' -> #interpret:asCodeAddress:. + 'Machine Instruction' -> #interpret:asInstructionAt:. + 'Integer' -> #interpret:asInteger:. + 'Character' -> #interpret:asCharacter:. + }. + where := coInterpreter whereIs: value]. - options := OrderedDictionary newFrom: { - 'Object' -> #interpret:asObject:. - 'Stack frame' -> #interpret:asStackFrame:. - 'Code address' -> #interpret:asCodeAddress:. - 'Integer' -> #interpret:asInteger:. - 'Character' -> #interpret:asCharacter:. - }. - where := coInterpreter whereIs: value. choice := Project uiManager chooseFrom: options keys values: options values title: ('{1} {2}' format: {registerSelector asUppercase. (where beginsWith: ' ') ifTrue: [where allButFirst] ifFalse: [' = ', where]}). choice ifNotNil: [:selector | self perform: selector with: registerSelector with: value]! Item was added: + ----- Method: CogProcessorAlienInspector>>interpret:asInstructionAt: (in category 'evaluation') ----- + interpret: registerSelector asInstructionAt: registerValue + + UIManager default inform: registerSelector, ': ', (processor disassembleInstructionAt: registerValue In: memory)! Item was added: + ----- Method: CogProcessorAlienInspector>>memory: (in category 'accessing') ----- + memory: anArrayOfBits + memory := anArrayOfBits! Item was added: + ----- Method: CogProcessorAlienInspector>>printStringForRegisterContents: (in category 'accessing - ui') ----- + printStringForRegisterContents: value + | raw | + raw := value printStringBase: (2 raisedTo: self bitsPerDigit) length: processor class wordSize * 8 / self bitsPerDigit padded: true. + + ^(String streamContents: + [:s | + raw groupsOf: self digitsPerGroup atATimeCollect: + [:group | + s nextPutAll: group; space]])! Item was changed: ----- Method: CogProcessorAlienInspector>>registerTextAt: (in category 'accessing - ui') ----- registerTextAt: aRegisterSelector + | current last text | - - | raw current last text | current := processor perform: aRegisterSelector. last := registerCache at: aRegisterSelector ifAbsent: []. registerCache at: aRegisterSelector put: current. + text := (self printStringForRegisterContents: current) asText. - raw := String streamContents: - [:s | - current - printOn: s - base: (2 raisedTo: self bitsPerDigit) - length: processor class wordSize * 8 / self bitsPerDigit - padded: true]. - - text := (String streamContents: - [:s | - raw groupsOf: self digitsPerGroup atATimeCollect: - [:group | - s nextPutAll: group; space]]) - asText. last ~= current ifTrue: [text addAllAttributes: {TextEmphasis bold. TextColor color: Color salmon}]. ^text! Item was added: + VMObjectInspector subclass: #CogVMObjectInspector + instanceVariableNames: 'cogit' + classVariableNames: '' + poolDictionaries: '' + category: 'VMMakerUI-SqueakInspectors'! Item was added: + ----- Method: CogVMObjectInspector>>coInterpreter: (in category 'initialization') ----- + coInterpreter: aCoInterpreter + super coInterpreter: aCoInterpreter. + cogit := aCoInterpreter cogit! Item was added: + ----- Method: CogVMSimulator>>evaluatePrinter:on: (in category '*VMMakerUI-user interface') ----- + evaluatePrinter: aBlock on: aStream + "Hack to redirect printing to aStream, here to avoid reimplementing all the printing machinery." + | savedTraceOn savedTranscript | + savedTraceOn := traceOn. + savedTranscript := transcript. + traceOn := true. + transcript := aStream. + ^aBlock ensure: + [traceOn := savedTraceOn. transcript := savedTranscript]! Item was added: + ----- Method: CogVMSimulator>>printFrame:WithSP:on: (in category '*VMMakerUI-user interface') ----- + printFrame: theFP WithSP: theSP on: aStream + "Hack to print frames on streams, here to avoid reimplementing all the frame printing machinery." + ^self + evaluatePrinter: [self printFrame: theFP WithSP: theSP] + on: aStream! Item was added: + ----- Method: CogVMSimulator>>toggleTranscript (in category '*VMMakerUI-user interface') ----- + toggleTranscript + | transcriptPane | + transcript ifNil: [transcript := Transcript. ^self]. + displayView ifNil: [^self changed: #flash]. + transcriptPane := (displayView outermostMorphThat: [:m| m isSystemWindow]) + submorphThat: [:m| m model isStream] + ifNone: [^self changed: #flash]. + transcript := transcript = Transcript + ifTrue: [transcriptPane model] + ifFalse: [Transcript]! Item was added: + ----- Method: CogVMSimulator>>utilitiesMenu: (in category '*VMMakerUI-user interface') ----- + utilitiesMenu: aMenuMorph + aMenuMorph + add: 'toggle transcript' action: #toggleTranscript; + add: 'clone VM' action: #cloneSimulationWindow; + addLine; + add: 'print ext head frame' action: #printExternalHeadFrame; + add: 'print int head frame' action: #printHeadFrame; + add: 'print mc/cog head frame' action: [self printFrame: cogit processor fp WithSP: cogit processor sp]; + add: 'short print ext head frame & callers' action: [self shortPrintFrameAndCallers: framePointer]; + add: 'short print int head frame & callers' action: [self shortPrintFrameAndCallers: localFP]; + add: 'short print mc/cog head frame & callers' action: [self shortPrintFrameAndCallers: cogit processor fp]; + add: 'long print ext head frame & callers' action: [self printFrameAndCallers: framePointer SP: stackPointer]; + add: 'long print int head frame & callers' action: [self printFrameAndCallers: localFP SP: localSP]; + add: 'long print mc/cog head frame & callers' action: [self printFrameAndCallers: cogit processor fp SP: cogit processor sp]; + add: 'print frame...' action: [(self promptHex: 'print frame') ifNotNil: [:fp| self printFrame: fp]]; + add: 'print call stack' action: #printCallStack; + add: 'print stack call stack' action: #printStackCallStack; + add: 'print stack call stack of...' action: [(self promptHex: 'frame') ifNotNil: [:fp| self printStackCallStackOf: fp]]; + add: 'print call stack of...' action: [(self promptHex: 'context or process oop') ifNotNil: [:obj| self printCallStackOf: obj]]; + add: 'print call stack of frame...' action: [(self promptHex: 'frame') ifNotNil: [:fp| self printCallStackFP: fp]]; + add: 'print all stacks' action: #printAllStacks; + add: 'write back local ptrs' action: [stackPointer := localSP. framePointer := localFP. instructionPointer := localIP. + self writeBackHeadFramePointers]; + add: 'write back mc ptrs' action: [stackPointer := cogit processor sp. framePointer := cogit processor fp. instructionPointer := cogit processor pc. + self externalWriteBackHeadFramePointers]; + addLine; + add: 'print rump C stack' action: [objectMemory printMemoryFrom: cogit processor sp to: CFramePointer]; + add: 'print registers' action: [cogit processor printRegistersOn: transcript]; + add: 'print register map' action: [cogit printRegisterMapOn: transcript]; + add: 'disassemble method/trampoline...' action: [(self promptHex: 'pc') ifNotNil: [:pc| cogit disassembleCodeAt: pc]]; + add: 'disassemble method/trampoline at pc' action: + [cogit disassembleCodeAt: (((cogit codeEntryFor: cogit processor pc) isNil + and: [(cogit methodZone methodFor: cogit processor pc) = 0]) + ifTrue: [instructionPointer] + ifFalse: [cogit processor pc])]; + add: 'disassemble ext head frame method' action: [cogit disassembleMethod: (self frameMethod: framePointer)]; + add: 'print oop...' action: [(self promptHex: 'print oop') ifNotNil: [:oop| self printOop: oop]]; + add: 'long print oop...' action: [(self promptHex: 'print oop') ifNotNil: [:oop| self longPrintOop: oop]]; + add: 'print context...' action: [(self promptHex: 'print context') ifNotNil: [:oop| self printContext: oop]]; + add: 'symbolic method...' action: [(self promptHex: 'method bytecodes') ifNotNil: [:oop| self symbolicMethod: oop]]; + addLine; + add: 'inspect object memory' target: objectMemory action: #inspect; + add: 'run leak checker' action: [Cursor execute showWhile: [self runLeakChecker]]; + add: 'inspect cointerpreter' action: #inspect; + add: 'inspect cogit' target: cogit action: #inspect; + add: 'inspect method zone' target: cogit methodZone action: #inspect; + add: 'inspect processor' action: [CogProcessorAlienInspector openFor: self]. + self isThreadedVM ifTrue: + [aMenuMorph add: 'inspect thread manager' target: self threadManager action: #inspect]. + aMenuMorph + addLine; + add: 'print cog methods' target: cogMethodZone action: #printCogMethods; + add: 'print cog methods with prim...' action: + [(self promptNum: 'prim index') ifNotNil: [:pix| cogMethodZone printCogMethodsWithPrimitive: pix]]; + add: 'print cog methods with selector...' action: + [|s| s := UIManager default request: 'selector'. + s notEmpty ifTrue: + [s = 'nil' ifTrue: [s := nil]. + cogMethodZone methodsDo: + [:m| + (s ifNil: [m selector = objectMemory nilObject] + ifNotNil: [(objectMemory numBytesOf: m selector) = s size + and: [(self strncmp: s + _: (m selector + objectMemory baseHeaderSize) + _: (objectMemory numBytesOf: m selector)) = 0]]) ifTrue: + [cogit printCogMethod: m]]]]; + add: 'print cog methods with method...' action: + [(self promptHex: 'method') ifNotNil: [:methodOop| cogMethodZone printCogMethodsWithMethod: methodOop]]; + add: 'print cog method for...' action: [(self promptHex: 'pc') ifNotNil: [:pc| cogit printCogMethodFor: pc]]; + add: 'print cog method header for...' action: [(self promptHex: 'pc') ifNotNil: [:pc| cogit printCogMethodHeaderFor: pc]]; + add: 'print trampoline table' target: cogit action: #printTrampolineTable; + add: 'print prim trace log' action: #dumpPrimTraceLog; + add: 'report recent instructions' target: cogit action: #reportLastNInstructions; + add: (cogit printRegisters + ifTrue: ['no print registers each instruction'] + ifFalse: ['print registers each instruction']) + action: [cogit printRegisters: cogit printRegisters not]; + add: (cogit printInstructions + ifTrue: ['no print instructions each instruction'] + ifFalse: ['print instructions each instruction']) + action: [cogit printInstructions: cogit printInstructions not]; + addLine; + add: (cogit singleStep + ifTrue: ['no single step'] + ifFalse: ['single step']) + action: [cogit singleStep: cogit singleStep not]; + add: 'click step' action: [cogit setClickStepBreakBlock]; + add: 'set break pc', cogit breakPC menuPrompt, '...-ve to disable or remove' action: [cogit promptForBreakPC]; + add: 'set break count...' action: [|s| s := UIManager default request: 'break count (dec)'. + s notEmpty ifTrue: [breakCount := Integer readFrom: s readStream]]; + add: 'set break selector...' action: [|s| s := UIManager default request: 'break selector (MNU:foo for MNU)'. + s notEmpty ifTrue: + [(s size > 4 and: [s beginsWith: 'MNU:']) + ifTrue: [self setBreakMNUSelector: (s allButFirst: 4)] + ifFalse: [self setBreakSelector: s]]]; + add: 'set break block...' action: [|s| s := UIManager default request: 'break block' initialAnswer: '[:address| false]'. + s notEmpty ifTrue: [self setBreakBlockFromString: s]]; + add: 'set cogit break method...' action: [(self promptHex: 'cogit breakMethod') ifNotNil: [:bm| cogit setBreakMethod: bm]]; + add: (printBytecodeAtEachStep + ifTrue: ['no print bytecode each bytecode'] + ifFalse: ['print bytecode each bytecode']) + action: [self ensureDebugAtEachStepBlock. + printBytecodeAtEachStep := printBytecodeAtEachStep not]; + add: (printFrameAtEachStep + ifTrue: ['no print frame each bytecode'] + ifFalse: ['print frame each bytecode']) + action: [self ensureDebugAtEachStepBlock. + printFrameAtEachStep := printFrameAtEachStep not]. + ^aMenuMorph! Item was added: + ----- Method: CogVMSimulator>>windowColorToUse (in category '*VMMakerUI-InterpreterSimulation-Morphic') ----- + windowColorToUse + ^Color lightBlue! Item was added: + ----- Method: Cogit>>setClickStepBreakBlock (in category '*VMMakerUI-user interface') ----- + setClickStepBreakBlock + "Set the break block to present a confirmer, breaking if true, and restoring the previous break block. + If an open debugger on the receiver can be found, proceed it." + <doNotGenerate> + | previousBreakBlock previousAtEachStepBlock previousBreakPC previousSingleStep previousClickConfirm | + (breakBlock isNil or: [breakBlock method ~~ thisContext method]) ifTrue: + [previousBreakBlock := breakBlock. + previousAtEachStepBlock := coInterpreter atEachStepBlock. + previousBreakPC := breakPC. + previousSingleStep := singleStep. + previousClickConfirm := clickConfirm. + breakBlock := [:ign| + (processor pc ~= previousBreakPC + and: [UIManager confirm: 'step?']) + ifTrue: [false] + ifFalse: [breakBlock := previousBreakBlock. + coInterpreter atEachStepBlock: previousAtEachStepBlock. + breakPC := previousBreakPC. + singleStep := previousSingleStep. + clickConfirm := previousClickConfirm. + true]]. + coInterpreter atEachStepBlock: + [previousAtEachStepBlock value. + (coInterpreter localIP ~= previousBreakPC + and: [UIManager confirm: 'step?']) ifFalse: + [breakBlock := previousBreakBlock. + coInterpreter atEachStepBlock: previousAtEachStepBlock. + breakPC := previousBreakPC. + singleStep := previousSingleStep. + clickConfirm := previousClickConfirm. + self halt]]. + singleStep := breakPC := clickConfirm := true]. + (World submorphs + detect: + [:m| + m model isDebugger + and: [(m model interruptedProcess suspendedContext findContextSuchThat: + [:ctxt| + (ctxt receiver == self + and: [ctxt selector == #simulateCogCodeAt:]) + or: [ctxt receiver == coInterpreter + and: [ctxt selector == #interpret]]]) notNil]] + ifNone: []) ifNotNil: + [:debuggerWindow| + WorldState addDeferredUIMessage: + [debuggerWindow model proceed]]! Item was added: + ----- Method: StackInterpreterSimulator>>evaluatePrinter:on: (in category '*VMMakerUI-user interface') ----- + evaluatePrinter: aBlock on: aStream + "Hack to redirect printing to aStream, here to avoid reimplementing all the printing machinery." + | savedTraceOn savedTranscript | + savedTraceOn := traceOn. + savedTranscript := transcript. + traceOn := true. + transcript := aStream. + ^aBlock ensure: + [traceOn := savedTraceOn. transcript := savedTranscript]! Item was added: + ----- Method: StackInterpreterSimulator>>printFrame:WithSP:on: (in category '*VMMakerUI-user interface') ----- + printFrame: theFP WithSP: theSP on: aStream + "Hack to print frames on streams, here to avoid reimplementing all the frame printing machinery." + ^self + evaluatePrinter: [self printFrame: theFP WithSP: theSP] + on: aStream! Item was added: + ----- Method: StackInterpreterSimulator>>setClickStepBreakBlock (in category '*VMMakerUI-user interface') ----- + setClickStepBreakBlock + "Set the break block to present a confirmer, breaking if true, and restoring the previous break block. + If an open debugger on the receiver can be found, proceed it." + <doNotGenerate> + | previousAtEachStepBlock | + (atEachStepBlock isNil or: [atEachStepBlock method ~~ thisContext method]) ifTrue: + [previousAtEachStepBlock := atEachStepBlock. + atEachStepBlock := + [previousAtEachStepBlock value. + self changed: #byteCountText. + (UIManager confirm: 'step?') ifFalse: + [atEachStepBlock := previousAtEachStepBlock. + self halt]]]. + (World submorphs + detect: + [:m| + m model isDebugger + and: [(m model interruptedProcess suspendedContext findContextSuchThat: + [:ctxt| + ctxt receiver == self + and: [ctxt selector == #run]]) notNil]] + ifNone: []) ifNotNil: + [:debuggerWindow| + WorldState addDeferredUIMessage: + [debuggerWindow model proceed]]! Item was added: + ----- Method: StackInterpreterSimulator>>toggleTranscript (in category '*VMMakerUI-user interface') ----- + toggleTranscript + | transcriptPane | + transcript ifNil: [transcript := Transcript. ^self]. + displayView ifNil: [^self changed: #flash]. + transcriptPane := (displayView outermostMorphThat: [:m| m isSystemWindow]) + submorphThat: [:m| m model isStream] + ifNone: [^self changed: #flash]. + transcript := transcript = Transcript + ifTrue: [transcriptPane model] + ifFalse: [Transcript]! Item was added: + ----- Method: StackInterpreterSimulator>>toggleTranscriptForSimulatorMorph: (in category '*VMMakerUI-user interface') ----- + toggleTranscriptForSimulatorMorph: aTranscriptStreamOrTranscript + "tty think this through when not so tired" + self flag: 'tty'. + transcript ifNil: [transcript := Transcript. ^self]. + displayView ifNil: [^self changed: #flash]. + transcript := transcript = Transcript + ifTrue: [aTranscriptStreamOrTranscript] + ifFalse: [Transcript]! Item was added: + ----- Method: StackInterpreterSimulator>>utilitiesMenu: (in category '*VMMakerUI-user interface') ----- + utilitiesMenu: aMenuMorph + aMenuMorph + add: 'toggle transcript' action: #toggleTranscript; + add: 'clone VM' action: #cloneSimulationWindow; + addLine; + add: 'print ext head frame' action: #printExternalHeadFrame; + add: 'print int head frame' action: #printHeadFrame; + add: 'short print ext frame & callers' action: [self shortPrintFrameAndCallers: framePointer]; + add: 'short print int frame & callers' action: [self shortPrintFrameAndCallers: localFP]; + add: 'long print ext frame & callers' action: [self printFrameAndCallers: framePointer SP: stackPointer]; + add: 'long print int frame & callers' action: [self printFrameAndCallers: localFP SP: localSP]; + add: 'print frame...' action: [(self promptHex: 'print frame') ifNotNil: [:fp| self printFrame: fp]]; + add: 'print call stack' action: #printCallStack; + add: 'print stack call stack' action: #printStackCallStack; + add: 'print stack call stack of...' action: [(self promptHex: 'frame') ifNotNil: [:fp| self printStackCallStackOf: fp]]; + add: 'print call stack of...' action: [(self promptHex: 'context or process oop') ifNotNil: [:obj| self printCallStackOf: obj]]; + add: 'print call stack of frame...' action: [(self promptHex: 'frame') ifNotNil: [:fp| self printCallStackFP: fp]]; + add: 'print all stacks' action: #printAllStacks; + add: 'write back local ptrs' action: [stackPointer := localSP. framePointer := localFP. instructionPointer := localIP. + self writeBackHeadFramePointers]; + add: 'print prim trace log' action: #dumpPrimTraceLog; + addLine; + add: 'print oop...' action: [(self promptHex: 'print oop') ifNotNil: [:oop| self printOop: oop]]; + add: 'long print oop...' action: [(self promptHex: 'print oop') ifNotNil: [:oop| self longPrintOop: oop]]; + add: 'print context...' action: [(self promptHex: 'print context') ifNotNil: [:oop| self printContext: oop]]; + addLine; + add: 'inspect object memory' target: objectMemory action: #inspect; + add: 'run leak checker' action: [Cursor execute showWhile: [self runLeakChecker]]; + add: 'inspect interpreter' action: #inspect; + addLine; + add: 'set break count...' action: [|s| s := UIManager default request: 'break count (dec)'. + s notEmpty ifTrue: [breakCount := Integer readFrom: s readStream]]; + add: 'set break selector...' action: [|s| s := UIManager default request: 'break selector (MNU:foo for MNU)'. + s notEmpty ifTrue: + [(s size > 4 and: [s beginsWith: 'MNU:']) + ifTrue: [self setBreakMNUSelector: (s allButFirst: 4)] + ifFalse: [self setBreakSelector: s]]]; + add: 'turn valid exec ptrs assert o', (assertVEPAES ifTrue: ['ff'] ifFalse: ['n']) action: [assertVEPAES := assertVEPAES not]; + add: 'click step' action: [self setClickStepBreakBlock]; + add: (printSends + ifTrue: ['no print sends'] + ifFalse: ['print sends']) + action: [self ensureDebugAtEachStepBlock. + printSends := printSends not]; + "currently printReturns does nothing" + "add: (printReturns + ifTrue: ['no print returns'] + ifFalse: ['print returns']) + action: [self ensureDebugAtEachStepBlock. + printReturns := printReturns not];" + add: (printBytecodeAtEachStep + ifTrue: ['no print bytecode each bytecode'] + ifFalse: ['print bytecode each bytecode']) + action: [self ensureDebugAtEachStepBlock. + printBytecodeAtEachStep := printBytecodeAtEachStep not]; + add: (printFrameAtEachStep + ifTrue: ['no print frame each bytecode'] + ifFalse: ['print frame each bytecode']) + action: [self ensureDebugAtEachStepBlock. + printFrameAtEachStep := printFrameAtEachStep not]. + ^aMenuMorph! Item was added: + ----- Method: StackInterpreterSimulator>>windowColorToUse (in category '*VMMakerUI-InterpreterSimulation-Morphic') ----- + windowColorToUse + ^Color lightBlue! Item was changed: + Model subclass: #VMObjectInspector + instanceVariableNames: 'windowTitle memory coInterpreter objectMemory' - Inspector subclass: #VMObjectInspector - instanceVariableNames: 'memory coInterpreter objectMemory cogit' classVariableNames: '' poolDictionaries: '' category: 'VMMakerUI-SqueakInspectors'! Item was removed: - ----- Method: VMObjectInspector class>>memory:coInterpreter:objectMemory: (in category 'instance creation') ----- - memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory - ^self new memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: nil! Item was removed: - ----- Method: VMObjectInspector class>>memory:coInterpreter:objectMemory:cogit: (in category 'instance creation') ----- - memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: aCogit - ^self new memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: aCogit! Item was added: + ----- Method: VMObjectInspector class>>on: (in category 'instance creation') ----- + on: aCoInterpreter + ^self new coInterpreter: aCoInterpreter; yourself! Item was added: + ----- Method: VMObjectInspector class>>openFor: (in category 'instance creation') ----- + openFor: aCoInterpreter + ^ToolBuilder open: (self new coInterpreter: aCoInterpreter; yourself)! Item was added: + ----- Method: VMObjectInspector>>coInterpreter: (in category 'initialization') ----- + coInterpreter: aStackInterpreter + coInterpreter := aStackInterpreter. + objectMemory := aStackInterpreter objectMemory. + memory := objectMemory memory! Item was removed: - ----- Method: VMObjectInspector>>memory:coInterpreter:objectMemory:cogit: (in category 'initialization') ----- - memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: aCogit - memory := aByteArray. - coInterpreter := aStackInterpreter. - objectMemory := anObjectMemory. - cogit := aCogit! Item was added: + ----- Method: VMObjectInspector>>open (in category 'accessing - ui') ----- + open + ^ToolBuilder open: self! Item was added: + ----- Method: VMObjectInspector>>windowTitle (in category 'accessing - ui') ----- + windowTitle + + ^windowTitle ifNil: [self printString]! Item was added: + ----- Method: VMObjectInspector>>windowTitle: (in category 'accessing - ui') ----- + windowTitle: newTitle + + windowTitle = newTitle ifFalse: + [windowTitle := newTitle. + self changed: #windowTitle]! |
Free forum by Nabble | Edit this page |