GDBVariableObject.st
changeset 106 12c96f17fc53
parent 104 4add55336dfe
child 107 7a315f1c9260
--- a/GDBVariableObject.st	Sun Feb 04 21:18:15 2018 +0000
+++ b/GDBVariableObject.st	Sun Feb 04 23:37:35 2018 +0000
@@ -21,8 +21,8 @@
 "{ NameSpace: Smalltalk }"
 
 GDBDebuggerObject subclass:#GDBVariableObject
-	instanceVariableNames:'parent name exp thread_id value type numchild has_more children
-		changed'
+	instanceVariableNames:'parent name exp thread frame value type numchild has_more
+		children changed inScope'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'GDB-Core'
@@ -51,6 +51,14 @@
 "
 ! !
 
+!GDBVariableObject class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
 !GDBVariableObject class methodsFor:'accessing - GDB value descriptors'!
 
 description
@@ -72,6 +80,7 @@
 !GDBVariableObject methodsFor:'accessing'!
 
 children
+    self isValid ifFalse:[ ^ #() ].
     children isNil ifTrue:[ 
         self hasChildren ifTrue:[
             | result |
@@ -86,7 +95,7 @@
     ^ children
 
     "Created: / 27-01-2018 / 22:53:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 28-01-2018 / 21:53:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-02-2018 / 10:07:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 expression
@@ -107,15 +116,33 @@
     "Created: / 28-01-2018 / 21:35:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+thread
+    "
+    If a variable object is bound to a specific thread, returns
+    that thread (as GDBThread). Otherwise, `nil` is returned.
+    "
+    | threadId |
+    thread isInteger ifTrue:[ 
+        threadId := thread.
+        thread := debugger threadForId: threadId.
+    ].
+    ^ thread
+
+    "Created: / 04-02-2018 / 21:35:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2018 / 18:38:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 type
     ^ type
 !
 
 value
     changed value. "/ to force update if necessary
+    self isValid ifFalse:[ ^ self class classResources string: '<invalid>' ].
+    self inScope ifFalse:[ ^ self class classResources string: '<out-of-scope>' ].
     ^ value
 
-    "Modified (comment): / 01-02-2018 / 22:31:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2018 / 22:00:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !GDBVariableObject methodsFor:'displaying'!
@@ -161,7 +188,58 @@
     "Created: / 28-01-2018 / 23:21:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
-!GDBVariableObject methodsFor:'initialization'!
+!GDBVariableObject methodsFor:'initialization & release'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    super initialize.
+    inScope := true.
+
+    "Modified: / 12-02-2018 / 22:07:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+release
+    "Releases the variable object and all its children. Once released, 
+     the variable object is invalid (i.e., `#isValid` would return `false`) 
+     and should not be used anymore."
+
+    self release: true
+
+    "Created: / 04-02-2018 / 23:21:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-02-2018 / 09:37:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+release: delete
+    "Releases the variable object and all its children. If 
+     `delete` is `true`, send `-var-delete -c`."
+
+    self assert: debugger notNil.
+    self assert: (delete not or:[ parent isNil ]) description: 'Only top-level objects can be deleted (for now)'.
+
+    "/ Release all children first, but not not 'delete' them 
+    "/ in GDB (will be done later)
+    children notEmptyOrNil ifTrue:[ 
+        children do: [ :child | child release:false ].
+    ].
+    children := nil.
+    changed := [ changed := false. true ]. 
+
+    "/ Now 'delete' the variable and all its children
+    "/ in GDB
+    delete ifTrue:[ 
+        self unregisterForFinalization.
+        debugger isConnected ifTrue:[
+            debugger send: (GDBMI_var_delete arguments: (Array with: '-c' with: name))
+        ].
+    ].
+
+    "/ Finally, clear the debugger instvar (it's tested in
+    "/ `#isValid`
+    debugger := nil.
+
+    "Created: / 13-02-2018 / 09:36:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
 
 setDebugger: aGDBDebugger
     super setDebugger: aGDBDebugger.
@@ -184,6 +262,12 @@
 
     "Created: / 27-01-2018 / 22:54:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 01-02-2018 / 09:29:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+thread_id: anInteger
+    thread := anInteger
+
+    "Created: / 04-02-2018 / 21:25:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 
@@ -206,12 +290,31 @@
     ^ changed value
 
     "Created: / 30-01-2018 / 00:27:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-02-2018 / 22:16:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 hasChildren
-    ^ numchild > 0
+    ^ self isValid and:[numchild > 0 ]
 
     "Created: / 27-01-2018 / 22:47:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-02-2018 / 22:09:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBVariableObject methodsFor:'testing'!
+
+inScope
+   changed value. "/ to force update if necessary
+    ^ inScope
+
+    "Created: / 12-02-2018 / 21:56:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isValid
+    changed value. "/ to force update if necessary
+    ^ debugger notNil
+
+    "Created: / 04-02-2018 / 21:33:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2018 / 22:28:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !GDBVariableObject methodsFor:'updating'!
@@ -219,6 +322,15 @@
 updateChanged
     "Check for updates and update all changed variables accordingly."
 
+    debugger isNil ifTrue:[ 
+        changed := false.
+        ^ false.
+    ].
+    (self thread notNil and:[ self thread isValid not]) ifTrue:[ 
+        self release.
+        ^ true
+    ].
+
     parent notNil ifTrue:[ 
         parent updateChanged
     ] ifFalse:[
@@ -226,11 +338,12 @@
 
         result := debugger send: (GDBMI_var_update arguments: (Array with: '--all-values' with: name)).
         changelist := result propertyAt: #changelist.
-        self updateChanged: changelist.
+        self updateChanged: changelist.        
     ].
     ^ false
 
     "Created: / 30-01-2018 / 01:08:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2018 / 23:09:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 updateChanged: changelist
@@ -240,6 +353,11 @@
     change := changelist detect: [ :each | each id = self id ] ifNone:[nil].
     change notNil ifTrue:[ 
         value := change value.
+        inScope := change inScope.
+        inScope = 'invalid' ifTrue:[ 
+            self release.
+            ^ self.
+        ].
         changed value: true.
         changelist remove: change.
         changelist isEmptyOrNil ifTrue:[ ^ self ].
@@ -251,7 +369,7 @@
     ].
 
     "Created: / 30-01-2018 / 01:09:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 01-02-2018 / 22:42:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2018 / 22:29:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !GDBVariableObject class methodsFor:'documentation'!