Browse Source

Initial code of boo console

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1557 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 19 years ago
parent
commit
065c2284c4
  1. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  2. 84
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Boo/InterpreterWrapper.cs
  3. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs
  4. 117
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.CallFunctionEval.cs
  5. 57
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.NewStringEval.cs
  6. 119
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs
  7. 12
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs
  8. 48
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs

4
src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj

@ -379,6 +379,9 @@ @@ -379,6 +379,9 @@
<Compile Include="Src\Variables\PersistentValue.cs" />
<Compile Include="Src\Variables\PersistentValueEventArgs.cs" />
<Compile Include="Src\Debugger\IExpirable.cs" />
<Compile Include="Src\Boo\InterpreterWrapper.cs" />
<Compile Include="Src\Variables\Evals\Eval.CallFunctionEval.cs" />
<Compile Include="Src\Variables\Evals\Eval.NewStringEval.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="README.TXT" />
@ -391,6 +394,7 @@ @@ -391,6 +394,7 @@
<Folder Include="Src\Wrappers\MetaData" />
<Folder Include="docs" />
<Content Include="docs\Stepping.txt" />
<Folder Include="Src\Boo" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>

84
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Boo/InterpreterWrapper.cs

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
/*
* Created by SharpDevelop.
* User: User
* Date: 10/07/2006
* Time: 01:47
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using Debugger.Wrappers.CorDebug;
using Debugger.Wrappers.MetaData;
namespace Debugger
{
public class InterpreterWrapper
{
const string booDll = "Boo.Lang.Interpreter.dll";
NDebugger debugger;
PersistentValue interpreter;
public NDebugger Debugger {
get {
return debugger;
}
}
public static InterpreterWrapper InjectBooInterpreter(NDebugger debugger, string booPath)
{
return new InterpreterWrapper(debugger, booPath);
}
private InterpreterWrapper(NDebugger debugger, string booInterpreterPath)
{
this.debugger = debugger;
PersistentValue assemblyPath = Eval.NewString(debugger, booInterpreterPath).EvaluateNow();
PersistentValue assembly = Eval.CallFunction(debugger, "mscorlib.dll", "System.Reflection.Assembly", "LoadFrom", false, null, new PersistentValue[] {assemblyPath}).EvaluateNow();
PersistentValue interpreterType = Eval.NewString(debugger, "Boo.Lang.Interpreter.InteractiveInterpreter").EvaluateNow();
interpreter = Eval.CallFunction(debugger, "mscorlib.dll", "System.Reflection.Assembly", "CreateInstance", false, assembly, new PersistentValue[] {interpreterType}).EvaluateNow();
RunCommand("interpreter.RememberLastValue = true");
// Testing:
RunCommand("1 + 2");
PersistentValue res = GetLastValue();
SetValue("a", res);
RunCommand("a = a + 100");
PersistentValue a = GetValue("a");
PersistentValue sug = SuggestCodeCompletion("interpreter.__codecomplete__");
}
public void RunCommand(string code)
{
PersistentValue cmd = Eval.NewString(debugger, code).EvaluateNow();
Eval.CallFunction(debugger, booDll, "Boo.Lang.Interpreter.InteractiveInterpreter", "LoopEval", false, interpreter, new PersistentValue[] {cmd}).EvaluateNow();
}
public void SetValue(string valueName, PersistentValue newValue)
{
PersistentValue name = Eval.NewString(debugger, valueName).EvaluateNow();
Eval.CallFunction(debugger, booDll, "Boo.Lang.Interpreter.InteractiveInterpreter", "SetValue", false, interpreter, new PersistentValue[] {name, newValue}).EvaluateNow();
}
public PersistentValue GetValue(string valueName)
{
PersistentValue name = Eval.NewString(debugger, valueName).EvaluateNow();
return Eval.CallFunction(debugger, booDll, "Boo.Lang.Interpreter.InteractiveInterpreter", "GetValue", false, interpreter, new PersistentValue[] {name}).EvaluateNow();
}
public PersistentValue GetLastValue()
{
return Eval.CallFunction(debugger, booDll, "Boo.Lang.Interpreter.InteractiveInterpreter", "get_LastValue", false, interpreter, new PersistentValue[] {}).EvaluateNow();
}
public PersistentValue SuggestCodeCompletion(string code)
{
PersistentValue cmd = Eval.NewString(debugger, code).EvaluateNow();
return Eval.CallFunction(debugger, booDll, "Boo.Lang.Interpreter.AbstractInterpreter", "SuggestCodeCompletion", false, interpreter, new PersistentValue[] {cmd}).EvaluateNow();
}
}
}

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs

@ -119,6 +119,12 @@ namespace Debugger @@ -119,6 +119,12 @@ namespace Debugger
}
}
internal ICorDebugFunction GetMethod(string type, string name, int paramCount)
{
uint token = MetaData.GetMethod(type, name, paramCount).Token;
return corModule.GetFunctionFromToken(token);
}
internal Module(NDebugger debugger, ICorDebugModule pModule)
{
this.debugger = debugger;

117
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.CallFunctionEval.cs

@ -0,0 +1,117 @@ @@ -0,0 +1,117 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision: 1556 $</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Debugger.Wrappers.CorDebug;
namespace Debugger
{
public partial class Eval
{
class CallFunctionEval: Eval
{
string moduleName;
string containgType;
string functionName;
ICorDebugFunction corFunction;
PersistentValue thisValue;
PersistentValue[] args;
static List<T> MergeLists<T>(IEnumerable<T> a, IEnumerable<T> b)
{
List<T> newList = new List<T>();
if (a != null) newList.AddRange(a);
if (b != null) newList.AddRange(b);
return newList;
}
public CallFunctionEval(NDebugger debugger, string moduleName, string containgType, string functionName, bool reevaluateAfterDebuggeeStateChange, PersistentValue thisValue, PersistentValue[] args)
:this(debugger, null, reevaluateAfterDebuggeeStateChange, thisValue, args)
{
this.moduleName = moduleName;
this.containgType = containgType;
this.functionName = functionName;
}
public CallFunctionEval(NDebugger debugger, ICorDebugFunction corFunction, bool reevaluateAfterDebuggeeStateChange, PersistentValue thisValue, PersistentValue[] args)
:base(debugger, reevaluateAfterDebuggeeStateChange, thisValue == null? args : MergeLists(new PersistentValue[] {thisValue}, args).ToArray())
{
this.corFunction = corFunction;
this.thisValue = thisValue;
this.args = args;
}
internal override bool SetupEvaluation(Thread targetThread)
{
debugger.AssertPaused();
if (targetThread.IsLastFunctionNative) {
OnError("Can not evaluate because native frame is on top of stack");
return false;
}
if (corFunction == null) {
try {
Module module = debugger.GetModule(moduleName);
corFunction = module.GetMethod(containgType, functionName, args.Length);
} catch (DebuggerException) {
// Error thrown later on
}
}
List<ICorDebugValue> corArgs = new List<ICorDebugValue>();
try {
if (thisValue != null) {
Value val = thisValue.Value;
if (!(val is ObjectValue)) {
OnError("Can not evaluate on a value which is not an object");
return false;
}
if (corFunction != null && !((ObjectValue)val).IsSuperClass(corFunction.Class)) {
OnError("Can not evaluate because the object does not contain specified function");
return false;
}
corArgs.Add(thisValue.SoftReference);
}
foreach(PersistentValue arg in args) {
corArgs.Add(arg.SoftReference);
}
} catch (CannotGetValueException e) {
OnError(e.Message);
return false;
}
if (corFunction == null) {
OnError("Can not find or load function " + functionName);
return false;
}
// TODO: What if this thread is not suitable?
corEval = targetThread.CorThread.CreateEval();
try {
corEval.CallFunction(corFunction, (uint)corArgs.Count, corArgs.ToArray());
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131C26) {
OnError("Can not evaluate in optimized code");
return false;
}
}
EvalState = EvalState.Evaluating;
OnEvalStarted(new EvalEventArgs(this));
return true;
}
}
}
}

57
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.NewStringEval.cs

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision: 1556 $</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Debugger.Wrappers.CorDebug;
namespace Debugger
{
public partial class Eval
{
class NewStringEval: Eval
{
string textToCreate;
public NewStringEval(NDebugger debugger, string textToCreate):base(debugger, false, new IExpirable[] {})
{
this.textToCreate = textToCreate;
}
internal override bool SetupEvaluation(Thread targetThread)
{
debugger.AssertPaused();
if (targetThread.IsLastFunctionNative) {
OnError("Can not evaluate because native frame is on top of stack");
return false;
}
// TODO: What if this thread is not suitable?
corEval = targetThread.CorThread.CreateEval();
try {
corEval.NewString(textToCreate);
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131C26) {
OnError("Can not evaluate in optimized code");
return false;
}
}
EvalState = EvalState.Evaluating;
OnEvalStarted(new EvalEventArgs(this));
return true;
}
}
}
}

119
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs

@ -19,18 +19,14 @@ namespace Debugger @@ -19,18 +19,14 @@ namespace Debugger
/// <summary>
/// This class holds information about function evaluation.
/// </summary>
public class Eval
public abstract partial class Eval
{
NDebugger debugger;
PersistentValue pValue;
ICorDebugEval corEval;
ICorDebugFunction corFunction;
bool reevaluateAfterDebuggeeStateChange;
PersistentValue thisValue;
PersistentValue[] args;
EvalState evalState = EvalState.WaitingForRequest;
ICorDebugValue result;
DebugeeState debugeeStateOfResult;
@ -49,7 +45,7 @@ namespace Debugger @@ -49,7 +45,7 @@ namespace Debugger
get {
return evalState;
}
set {
protected set {
evalState = value;
if (Evaluated) {
debugeeStateOfResult = debugger.DebugeeState;
@ -68,7 +64,7 @@ namespace Debugger @@ -68,7 +64,7 @@ namespace Debugger
}
}
public PersistentValue PersistentValue {
public PersistentValue Result {
get {
return pValue;
}
@ -80,33 +76,42 @@ namespace Debugger @@ -80,33 +76,42 @@ namespace Debugger
}
}
internal Eval(NDebugger debugger, ICorDebugFunction corFunction, bool reevaluateAfterDebuggeeStateChange, PersistentValue thisValue, PersistentValue[] args)
protected Eval(NDebugger debugger, bool reevaluateAfterDebuggeeStateChange, IExpirable[] dependencies)
{
this.debugger = debugger;
this.corFunction = corFunction;
this.reevaluateAfterDebuggeeStateChange = reevaluateAfterDebuggeeStateChange;
this.thisValue = thisValue;
this.args = args;
List<PersistentValue> dependencies = new List<PersistentValue>();
if (thisValue != null) dependencies.Add(thisValue);
dependencies.AddRange(args);
pValue = new PersistentValue(debugger,
dependencies.ToArray(),
dependencies,
delegate { return GetCorValue(); });
foreach(PersistentValue dependency in dependencies) {
dependency.ValueChanged += delegate { EvalState = EvalState.WaitingForRequest; };
foreach(IExpirable dependency in dependencies) {
if (dependency is PersistentValue) {
((PersistentValue)dependency).ValueChanged += delegate { EvalState = EvalState.WaitingForRequest; };
}
}
if (reevaluateAfterDebuggeeStateChange) {
debugger.DebuggeeStateChanged += delegate { EvalState = EvalState.WaitingForRequest; };
}
}
public static Eval CallFunction(NDebugger debugger, string moduleName, string containgType, string functionName, bool reevaluateAfterDebuggeeStateChange, PersistentValue thisValue, PersistentValue[] args)
{
return new CallFunctionEval(debugger, moduleName, containgType, functionName, reevaluateAfterDebuggeeStateChange, thisValue, args);
}
public static Eval CallFunction(NDebugger debugger, ICorDebugFunction corFunction, bool reevaluateAfterDebuggeeStateChange, PersistentValue thisValue, PersistentValue[] args)
{
return new CallFunctionEval(debugger, corFunction, reevaluateAfterDebuggeeStateChange, thisValue, args);
}
public static Eval NewString(NDebugger debugger, string textToCreate)
{
return new NewStringEval(debugger, textToCreate);
}
ICorDebugValue GetCorValue()
{
if (Evaluated && reevaluateAfterDebuggeeStateChange && debugger.DebugeeState != debugeeStateOfResult) {
ScheduleEvaluation();
}
switch(this.EvalState) {
case EvalState.WaitingForRequest: ScheduleEvaluation(); goto case EvalState.EvaluationScheduled;
case EvalState.EvaluationScheduled: throw new CannotGetValueException("Evaluation pending");
@ -119,67 +124,31 @@ namespace Debugger @@ -119,67 +124,31 @@ namespace Debugger
}
}
void ScheduleEvaluation()
public void ScheduleEvaluation()
{
debugger.AddEval(this);
debugger.MTA2STA.AsyncCall(delegate {
if (debugger.IsPaused) debugger.StartEvaluation();
});
EvalState = EvalState.EvaluationScheduled;
if (Evaluated || EvalState == EvalState.WaitingForRequest) {
debugger.AddEval(this);
debugger.MTA2STA.AsyncCall(delegate {
if (debugger.IsPaused) debugger.StartEvaluation();
});
EvalState = EvalState.EvaluationScheduled;
}
}
/// <returns>True if setup was successful</returns>
internal bool SetupEvaluation(Thread targetThread)
internal abstract bool SetupEvaluation(Thread targetThread);
public PersistentValue EvaluateNow()
{
debugger.AssertPaused();
if (targetThread.IsLastFunctionNative) {
OnError("Can not evaluate because native frame is on top of stack");
return false;
}
List<ICorDebugValue> corArgs = new List<ICorDebugValue>();
try {
if (thisValue != null) {
Value val = thisValue.Value;
if (!(val is ObjectValue)) {
OnError("Can not evaluate on a value which is not an object");
return false;
}
if (!((ObjectValue)val).IsSuperClass(corFunction.Class)) {
OnError("Can not evaluate because the object does not contain specified function");
return false;
}
corArgs.Add(thisValue.SoftReference);
}
foreach(PersistentValue arg in args) {
corArgs.Add(arg.SoftReference);
}
} catch (CannotGetValueException e) {
OnError(e.Message);
return false;
}
// TODO: What if this thread is not suitable?
corEval = targetThread.CorThread.CreateEval();
try {
corEval.CallFunction(corFunction, (uint)corArgs.Count, corArgs.ToArray());
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131C26) {
OnError("Can not evaluate in optimized code");
return false;
}
while (EvalState == EvalState.WaitingForRequest) {
ScheduleEvaluation();
debugger.WaitForPause();
debugger.WaitForPause();
}
EvalState = EvalState.Evaluating;
OnEvalStarted(new EvalEventArgs(this));
return true;
return Result;
}
void OnError(string msg)
protected void OnError(string msg)
{
error = msg;
EvalState = EvalState.EvaluatedError;

12
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs

@ -194,15 +194,15 @@ namespace Debugger @@ -194,15 +194,15 @@ namespace Debugger
foreach(MethodProps m in Methods) {
MethodProps method = m; // One per scope/delegate
if (method.HasSpecialName && method.Name.StartsWith("get_") && method.Name != "get_Item") {
Eval eval = new Eval(debugger,
Module.CorModule.GetFunctionFromToken(method.Token),
true, // reevaluateAfterDebuggeeStateChange
method.IsStatic? null : this.PersistentValue,
new PersistentValue[] {});
Eval eval = Eval.CallFunction(debugger,
Module.CorModule.GetFunctionFromToken(method.Token),
true, // reevaluateAfterDebuggeeStateChange
method.IsStatic? null : this.PersistentValue,
new PersistentValue[] {});
yield return new Variable(method.Name.Remove(0, 4),
method.IsStatic,
method.IsPublic,
eval.PersistentValue);
eval.Result);
}
}
}

48
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs

@ -127,6 +127,21 @@ namespace Debugger.Wrappers.MetaData @@ -127,6 +127,21 @@ namespace Debugger.Wrappers.MetaData
}
}
public IEnumerable<MethodProps> EnumMethodsWithName(uint typeToken, string name)
{
IntPtr enumerator = IntPtr.Zero;
while(true) {
uint methodToken;
uint methodsFetched;
metaData.EnumMethodsWithName(ref enumerator, typeToken, name, out methodToken, 1, out methodsFetched);
if (methodsFetched == 0) {
metaData.CloseEnum(enumerator);
break;
}
yield return GetMethodProps(methodToken);
}
}
public unsafe MethodProps GetMethodProps(uint methodToken)
{
MethodProps methodProps = new MethodProps();
@ -152,6 +167,28 @@ namespace Debugger.Wrappers.MetaData @@ -152,6 +167,28 @@ namespace Debugger.Wrappers.MetaData
return methodProps;
}
public IEnumerable<uint> EnumParams(uint mb)
{
IntPtr enumerator = IntPtr.Zero;
while(true) {
uint token;
uint fetched;
metaData.EnumParams(ref enumerator, mb, out token, 1, out fetched);
if (fetched == 0) {
metaData.CloseEnum(enumerator);
break;
}
yield return token;
}
}
public int GetParamCount(uint methodToken)
{
int count = 0;
foreach(uint param in EnumParams(methodToken)) count++;
return count;
}
public ParamProps GetParamForMethodIndex(uint methodToken, uint parameterSequence)
{
uint paramToken = 0;
@ -186,5 +223,16 @@ namespace Debugger.Wrappers.MetaData @@ -186,5 +223,16 @@ namespace Debugger.Wrappers.MetaData
metaData.FindTypeDefByName(typeName, enclosingClassToken, out typeDefToken);
return GetTypeDefProps(typeDefToken);
}
public MethodProps GetMethod(string type, string name, int paramCount)
{
TypeDefProps typeDefProps = FindTypeDefByName(type, 0);
foreach(MethodProps method in EnumMethodsWithName(typeDefProps.Token, name)) {
if (GetParamCount(method.Token) == paramCount) {
return method;
}
}
throw new DebuggerException("Not found");
}
}
}

Loading…
Cancel
Save