Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

2005-09-08 Martin Baulig <martin@ximian.com>

	* interfaces/ITargetObject.cs
	(ITargetObject.IsNull): New property.

	* interfaces/ILanguage.cs
	(ILanguage.CreateNullObject): New method.

	* backends/mono/MonoNullObject.cs: New file.

	* backends/mono/MonoVariable.cs (MonoVariable.GetObject): Return a
	`MonoNullObject' if the location is null.

	* frontend/CSharpExpressionParser.jay (constant): Added `NULL'.

	* frontend/Expression.cs (NullExpression): New expression.

	* test/TestNull.cs, test/mono-debugger.test/TestNull.exp: Added
	tests for `null' handling.


svn path=/trunk/debugger/; revision=49701
  • Loading branch information...
commit 12e3a2491456d7e1a98ff0a4809f6051f4290ef9 1 parent d8da200
Martin Baulig authored
View
20 ChangeLog
@@ -1,5 +1,25 @@
2005-09-08 Martin Baulig <martin@ximian.com>
+ * interfaces/ITargetObject.cs
+ (ITargetObject.IsNull): New property.
+
+ * interfaces/ILanguage.cs
+ (ILanguage.CreateNullObject): New method.
+
+ * backends/mono/MonoNullObject.cs: New file.
+
+ * backends/mono/MonoVariable.cs (MonoVariable.GetObject): Return a
+ `MonoNullObject' if the location is null.
+
+ * frontend/CSharpExpressionParser.jay (constant): Added `NULL'.
+
+ * frontend/Expression.cs (NullExpression): New expression.
+
+ * test/TestNull.cs, test/mono-debugger.test/TestNull.exp: Added
+ tests for `null' handling.
+
+2005-09-08 Martin Baulig <martin@ximian.com>
+
* interfaces/ITargetArrayObject.cs (ITargetArrayObject.this): Take
an `int[] indices' arguments (not a `params' one) and added setter.
View
24 backends/Inferior.cs
@@ -641,33 +641,49 @@ public long ReadLongInteger (TargetAddress address)
public TargetAddress ReadAddress (TargetAddress address)
{
check_disposed ();
+ TargetAddress res;
switch (TargetAddressSize) {
case 4:
- return new TargetAddress (AddressDomain, (uint) ReadInteger (address));
+ res = new TargetAddress (AddressDomain, (uint) ReadInteger (address));
+ break;
case 8:
- return new TargetAddress (AddressDomain, ReadLongInteger (address));
+ res = new TargetAddress (AddressDomain, ReadLongInteger (address));
+ break;
default:
throw new TargetMemoryException (
"Unknown target address size " + TargetAddressSize);
}
+
+ if (res.Address == 0)
+ return TargetAddress.Null;
+ else
+ return res;
}
public TargetAddress ReadGlobalAddress (TargetAddress address)
{
check_disposed ();
+ TargetAddress res;
switch (TargetAddressSize) {
case 4:
- return new TargetAddress (GlobalAddressDomain, (uint) ReadInteger (address));
+ res = new TargetAddress (GlobalAddressDomain, (uint) ReadInteger (address));
+ break;
case 8:
- return new TargetAddress (GlobalAddressDomain, ReadLongInteger (address));
+ res = new TargetAddress (GlobalAddressDomain, ReadLongInteger (address));
+ break;
default:
throw new TargetMemoryException (
"Unknown target address size " + TargetAddressSize);
}
+
+ if (res.Address == 0)
+ return TargetAddress.Null;
+ else
+ return res;
}
public string ReadString (TargetAddress address)
View
7 backends/classes/MonoVariableLocation.cs
@@ -37,8 +37,11 @@ void update ()
long contents = reg.Value;
- address = new TargetAddress (
- TargetMemoryInfo.AddressDomain, contents + regoffset);
+ if (contents == 0)
+ address = TargetAddress.Null;
+ else
+ address = new TargetAddress (
+ TargetMemoryInfo.AddressDomain, contents + regoffset);
if (is_byref && is_regoffset)
address = TargetMemoryAccess.ReadAddress (address);
View
3  backends/classes/TargetLocation.cs
@@ -116,6 +116,9 @@ public virtual TargetAddress ReadAddress ()
else
throw new InternalError ();
+ if (address == 0)
+ return TargetAddress.Null;
+
return new TargetAddress (TargetMemoryInfo.AddressDomain, address);
}
View
3  backends/mono/MonoArrayObject.cs
@@ -116,6 +116,9 @@ int GetArrayOffset (int[] indices)
dynamic_location.GetLocationAtOffset (
offset, type.Type.ElementType.IsByRef);
+ if (new_location.HasAddress && new_location.Address.IsNull)
+ return new MonoNullObject (type.ElementType, new_location);
+
return type.ElementType.GetObject (new_location);
}
View
13 backends/mono/MonoLanguageBackend.cs
@@ -807,7 +807,7 @@ public ITargetPointerObject CreatePointer (StackFrame frame, TargetAddress addre
public ITargetObject CreateObject (ITargetAccess target, TargetAddress address)
{
- TargetLocation location = new AbsoluteTargetLocation (null, target, address);
+ TargetLocation location = new AbsoluteTargetLocation (target, address);
MonoObjectObject obj = (MonoObjectObject)builtin_types.ObjectType.GetTypeInfo().GetObject (location);
if (obj == null)
return null;
@@ -818,6 +818,17 @@ public ITargetObject CreateObject (ITargetAccess target, TargetAddress address)
return obj;
}
+ public ITargetObject CreateNullObject (ITargetAccess target, ITargetType type)
+ {
+ TargetLocation location = new AbsoluteTargetLocation (target, TargetAddress.Null);
+
+ IMonoTypeInfo tinfo = ((MonoType) type).GetTypeInfo ();
+ if (tinfo == null)
+ tinfo = builtin_types.ObjectType;
+
+ return new MonoNullObject (tinfo, location);
+ }
+
ITargetFundamentalType ILanguage.IntegerType {
get { return builtin_types.Int32Type; }
}
View
17 backends/mono/MonoNullObject.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Mono.Debugger.Languages.Mono
+{
+ internal class MonoNullObject : MonoObject
+ {
+ public MonoNullObject (IMonoTypeInfo type, TargetLocation location)
+ : base (type, location)
+ { }
+
+ protected override long GetDynamicSize (TargetBlob blob, TargetLocation location,
+ out TargetLocation dynamic_location)
+ {
+ throw new InvalidOperationException ();
+ }
+ }
+}
View
11 backends/mono/MonoObject.cs
@@ -41,7 +41,16 @@ public MonoObject (IMonoTypeInfo type_info, TargetLocation location)
public bool IsValid {
get {
- return is_valid && (location != null);
+ return is_valid;
+ }
+ }
+
+ public bool IsNull {
+ get {
+ if (!location.HasAddress)
+ return false;
+ else
+ return location.Address.IsNull;
}
}
View
2  backends/mono/MonoStringObject.cs
@@ -42,6 +42,8 @@ protected override object GetObject (TargetBlob blob, TargetLocation location)
public override string Print ()
{
+ if (location.Address.IsNull)
+ return "null";
object obj = GetObject ();
return '"' + (string) obj + '"';
}
View
4 backends/mono/MonoVariable.cs
@@ -120,6 +120,10 @@ public ITargetObject GetObject (StackFrame frame)
if (location == null)
throw new LocationInvalidException ();
+ if (location.HasAddress && location.Address.IsNull)
+ return backend.MonoLanguage.CreateNullObject (
+ frame.TargetAccess, type);
+
IMonoTypeInfo tinfo = type.GetTypeInfo ();
if (tinfo == null)
return null;
View
7 backends/native/NativeLanguage.cs
@@ -79,7 +79,12 @@ public ITargetFundamentalObject CreateInstance (ITargetAccess target, int value)
public ITargetObject CreateObject (ITargetAccess target, TargetAddress address)
{
- return null;
+ throw new NotSupportedException ();
+ }
+
+ public ITargetObject CreateNullObject (ITargetAccess target, ITargetType type)
+ {
+ throw new NotSupportedException ();
}
private bool disposed = false;
View
11 backends/native/NativeObject.cs
@@ -35,7 +35,16 @@ public NativeObject (ITargetType type, TargetLocation location)
public bool IsValid {
get {
- return is_valid && (location != null);
+ return is_valid;
+ }
+ }
+
+ public bool IsNull {
+ get {
+ if (!location.HasAddress)
+ return false;
+ else
+ return location.Address.IsNull;
}
}
View
21 classes/TargetMemoryException.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.Serialization;
namespace Mono.Debugger
{
@@ -21,6 +22,16 @@ public TargetMemoryException (TargetAddress address, int size)
: this (String.Format ("Cannot read {1} bytes from target memory at address {0:x}",
address, size))
{ }
+
+ protected TargetMemoryException (SerializationInfo info, StreamingContext context)
+ : base (info, context)
+ {
+ }
+
+ public override void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData (info, context);
+ }
}
[Serializable]
@@ -34,5 +45,15 @@ public TargetMemoryReadOnlyException (TargetAddress address)
: base (String.Format ("Can't write to target memory at address 0x{0:x}: {1}",
address, "the current target's memory is read-only"))
{ }
+
+ protected TargetMemoryReadOnlyException (SerializationInfo info, StreamingContext context)
+ : base (info, context)
+ {
+ }
+
+ public override void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData (info, context);
+ }
}
}
View
6 frontend/CSharpExpressionParser.jay
@@ -150,11 +150,15 @@ constant
{
$$ = new NumberExpression ((decimal) $1);
}
-
| STRING
{
$$ = new StringExpression ((string) $1);
}
+ | NULL
+ {
+ $$ = new NullExpression ();
+ }
+ ;
expression
: constant
View
2  frontend/CSharpTokenizer.cs
@@ -71,7 +71,7 @@ static void InitTokens ()
keywords.Add ("false", Token.FALSE);
keywords.Add ("True", Token.TRUE);
keywords.Add ("False", Token.FALSE);
- keywords.Add ("null", Token.FALSE);
+ keywords.Add ("null", Token.NULL);
}
public string error {
View
24 frontend/Expression.cs
@@ -363,6 +363,30 @@ protected override ITargetObject DoEvaluateVariable (ScriptingContext context)
}
}
+ public class NullExpression : Expression
+ {
+ public override string Name {
+ get { return "null"; }
+ }
+
+ protected override Expression DoResolve (ScriptingContext context)
+ {
+ resolved = true;
+ return this;
+ }
+
+ protected override object DoEvaluate (ScriptingContext context)
+ {
+ return null;
+ }
+
+ protected override ITargetObject DoEvaluateVariable (ScriptingContext context)
+ {
+ StackFrame frame = context.CurrentFrame.Frame;
+ return frame.Language.CreateObject (frame.TargetAccess, TargetAddress.Null);
+ }
+ }
+
public class ThisExpression : Expression
{
public override string Name {
View
2  frontend/ScriptingContext.cs
@@ -181,8 +181,6 @@ public ITargetObject GetVariable (IVariable var)
{
if (!var.IsAlive (frame.TargetAddress))
throw new ScriptingException ("Variable out of scope.");
- if (!var.CheckValid (frame))
- throw new ScriptingException ("Variable cannot be accessed.");
return var.GetObject (frame);
}
View
15 frontend/Style.cs
@@ -413,6 +413,9 @@ protected string DoFormatObject (ITargetObject obj, bool recursed)
protected string DoFormatObjectRecursed (ITargetObject obj)
{
+ if (obj.IsNull)
+ return "null";
+
switch (obj.Kind) {
case TargetObjectKind.Class:
case TargetObjectKind.Struct:
@@ -460,6 +463,9 @@ protected string DoFormatArray (ITargetArrayObject aobj)
protected string DoFormatObject (ITargetObject obj)
{
+ if (obj.IsNull)
+ return "null";
+
switch (obj.Kind) {
case TargetObjectKind.Array:
return DoFormatArray ((ITargetArrayObject) obj);
@@ -505,14 +511,11 @@ protected string DoFormatObject (ITargetObject obj)
public override string PrintVariable (IVariable variable, StackFrame frame)
{
+ string contents;
ITargetObject obj = null;
- try {
- obj = variable.GetObject (frame);
- } catch {
- }
- string contents;
try {
+ obj = variable.GetObject (frame);
if (obj != null)
contents = DoFormatObject (obj, false);
else
@@ -520,7 +523,7 @@ public override string PrintVariable (IVariable variable, StackFrame frame)
} catch {
contents = "<cannot display object>";
}
-
+
return String.Format (
"{0} = ({1}) {2}", variable.Name, variable.Type.Name, contents);
}
View
2  interfaces/ILanguage.cs
@@ -41,6 +41,8 @@ public interface ILanguage : IDisposable
ITargetPointerObject CreatePointer (StackFrame frame, TargetAddress address);
ITargetObject CreateObject (ITargetAccess target, TargetAddress address);
+
+ ITargetObject CreateNullObject (ITargetAccess target, ITargetType type);
}
}
View
4 interfaces/ITargetObject.cs
@@ -25,6 +25,10 @@ public interface ITargetObject
get;
}
+ bool IsNull {
+ get;
+ }
+
// <summary>
// Returns the raw contents of this object. For objects with dynamic size,
// this returns a buffer of `Type.Size' bytes which is just enough to get
View
4 test/Makefile.am
@@ -7,7 +7,7 @@ MCS_FLAGS=-debug
noinst_SCRIPTS = \
TestManagedTypes.exe TestAssembly.exe TestNamespace.exe TestModule.dll \
MultiThread.exe TestInvocation.exe TestInheritance.exe Simple.exe TestException.exe \
- TestRestart.exe TestDelegate.exe
+ TestRestart.exe TestDelegate.exe TestNull.exe
noinst_LTLIBRARIES=libfoo.la
@@ -16,7 +16,7 @@ noinst_PROGRAMS = testnativetypes module
EXTRA_DIST = \
TestManagedTypes.cs TestAssembly.cs TestNamespace.cs TestModule.cs \
MultiThread.cs TestInvocation.cs TestInheritance.cs Simple.cs TestException.cs mdb.exp \
- TestRestart.cs TestDelegate.cs
+ TestRestart.cs TestDelegate.cs TestNull.cs
RUNTESTFLAGS = --ignore "MultiThread.exp module.exp start-restart.exp TestModule.exp TestAssembly.exp"
View
28 test/TestNull.cs
@@ -0,0 +1,28 @@
+using System;
+
+public class X
+{
+ public readonly long Foo;
+
+ public X (long foo)
+ {
+ this.Foo = foo;
+ }
+
+ public static void Main ()
+ {
+ string hello = null;
+ X x = null;
+ int[] int_array = null;
+ X[] x_array = null;
+ X[] y_array = new X [1];
+ X[] z_array = new X [] { new X (5) };
+
+ Console.WriteLine (hello == null);
+ Console.WriteLine (x == null);
+ Console.WriteLine (int_array == null);
+ Console.WriteLine (x_array == null);
+ Console.WriteLine (y_array == null);
+ Console.WriteLine (z_array == null);
+ }
+}
View
41 test/mono-debugger.tests/TestNull.exp
@@ -0,0 +1,41 @@
+#!/usr/bin/expect -f
+#
+
+source $srcdir/mdb.exp
+
+set bpt_main 14
+set bpt_1 21
+set file $srcdir/TestNull.cs
+
+mdb_start "TestNull.exe"
+mdb_expect_frame 0 "X.Main()" $file $bpt_main
+mdb_send "break $bpt_1"
+set breakpoint [mdb_expect_breakpoint]
+mdb_send "continue"
+mdb_expect_stopped 0 "X.Main()" $file $bpt_1
+
+mdb_send_and_expect "p x" "(X) null"
+mdb_send_and_expect "p hello" "(System.String) null"
+mdb_send_and_expect "p int_array" "(System.Int32\[\]) null"
+mdb_send_and_expect "p x_array" "(X\[\]) null"
+mdb_send_and_expect "p y_array" "(X\[\]) \[ null \]"
+mdb_send_and_expect "p z_array" "(X\[\]) \[ { Foo = 5 } \]"
+
+mdb_send "set y_array \[0\] = new X (9)"
+mdb_expect_prompt
+mdb_send "set z_array \[0\] = null"
+mdb_expect_prompt
+
+mdb_send_and_expect "p y_array" "(X\[\]) \[ { Foo = 9 } \]"
+mdb_send_and_expect "p z_array" "(X\[\]) \[ null \]"
+
+mdb_send "continue"
+mdb_expect_line "True"
+mdb_expect_line "True"
+mdb_expect_line "True"
+mdb_expect_line "True"
+mdb_expect_line "False"
+mdb_expect_line "False"
+mdb_expect_line "Process @4 terminated normally."
+mdb_expect_prompt
+mdb_send "quit"
Please sign in to comment.
Something went wrong with that request. Please try again.