HRESULT Status;
PVOID pStackProgram = nullptr;
- if (FAILED(Status = Interop::GenerateStackMachineProgram(fixed_expression, &pStackProgram, output)) ||
- Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- {
- return Status;
- }
+ IfFailRet(Interop::GenerateStackMachineProgram(fixed_expression, &pStackProgram, output));
static constexpr int32_t ProgramFinished = -1;
int32_t Command;
ToRelease<ICorDebugValue> iCorValue;
IfFailRet(getValue(&iCorValue, evalFlags));
- Status = m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, iCorValue.GetRef(), output);
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- Status = E_FAIL;
- return Status;
+ return m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, iCorValue.GetRef(), output);
};
return cb(nullptr, false, "", getValue, setValue);
ToRelease<ICorDebugValue> iCorValue;
IfFailRet(getValue(&iCorValue, evalFlags));
- Status = m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, iCorValue.GetRef(), output);
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- Status = E_FAIL;
- return Status;
+ return m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, iCorValue.GetRef(), output);
};
IfFailRet(cb(nullptr, false, "[" + IndiciesToStr(ind, base) + "]", getValue, setValue));
ToRelease<ICorDebugValue> iCorValue;
IfFailRet(getValue(&iCorValue, evalFlags));
- Status = m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, iCorValue.GetRef(), output);
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- Status = E_FAIL;
- return Status;
+ return m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, iCorValue.GetRef(), output);
};
IfFailRet(cb(pType, is_static, name, getValue, setValue));
// FIXME investigate, why in this case we can't use ICorDebugReferenceValue::SetValue() for string in iCorValue
iCorValue.Free();
IfFailRet(m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, &iCorValue, output));
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- return E_FAIL;
CorElementType elemType;
IfFailRet(iCorValue->GetType(&elemType));
else // Allow stack machine decide what types are supported.
{
IfFailRet(m_sharedEvalStackMachine->Run(pThread, frameLevel, evalFlags, value, iCorValue.GetRef(), output));
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- return E_FAIL;
}
// Call setter.
return S_OK;
}
-PACK_BEGIN struct Decimal {
- uint32_t flags;
- uint32_t hi;
- uint32_t lo;
- uint32_t mid;
-} PACK_END;
-
-static void PrintDecimalValue(const std::string &rawValue, std::string &output)
-{
- const Decimal *d = reinterpret_cast<const Decimal*>(&rawValue[0]);
- PrintDecimal(d->hi, d->mid, d->lo, d->flags, output);
-}
-
static HRESULT PrintArrayValue(ICorDebugValue *pValue, std::string &output)
{
HRESULT Status = S_OK;
return S_OK;
}
-HRESULT PrintBasicValue(int typeId, const std::string &rawData, std::string &typeName, std::string &value)
-{
- std::ostringstream ss;
- switch(typeId)
- {
- case Interop::TypeCorValue:
- ss << "null";
- typeName = "object";
- break;
- case Interop::TypeObject:
- ss << "null";
- typeName = "object";
- break;
- case Interop::TypeBoolean:
- ss << (rawData[0] == 0 ? "false" : "true");
- typeName = "bool";
- break;
- case Interop::TypeByte:
- ss << (unsigned int) *(unsigned char*) &(rawData[0]);
- typeName = "byte";
- break;
- case Interop::TypeSByte:
- ss << (int) *(char*) &(rawData[0]);
- typeName = "sbyte";
- break;
- case Interop::TypeChar:
- {
- WCHAR wc = * (WCHAR *) &(rawData[0]);
- std::string printableVal = to_utf8(wc);
- EscapeString(printableVal, '\'');
- ss << (unsigned int)wc << " '" << printableVal << "'";
- typeName = "char";
- }
- break;
- case Interop::TypeDouble:
- ss << std::setprecision(16) << *(double*) &(rawData[0]);
- typeName = "double";
- break;
- case Interop::TypeSingle:
- ss << std::setprecision(8) << *(float*) &(rawData[0]);
- typeName = "float";
- break;
- case Interop::TypeInt32:
- ss << *(int*) &(rawData[0]);
- typeName = "int";
- break;
- case Interop::TypeUInt32:
- ss << *(unsigned int*) &(rawData[0]);
- typeName = "uint";
- break;
- case Interop::TypeInt64:
- ss << *(__int64*) &(rawData[0]);
- typeName = "long";
- break;
- case Interop::TypeUInt64:
- typeName = "ulong";
- ss << *(unsigned __int64*) &(rawData[0]);
- break;
- case Interop::TypeInt16:
- ss << *(short*) &(rawData[0]);
- typeName = "short";
- break;
- case Interop::TypeUInt16:
- ss << *(unsigned short*) &(rawData[0]);
- typeName = "ushort";
- break;
- case Interop::TypeIntPtr:
- ss << "0x" << std::hex << *(intptr_t*) &(rawData[0]);
- typeName = "IntPtr";
- break;
- case Interop::TypeUIntPtr:
- ss << "0x" << std::hex << *(intptr_t*) &(rawData[0]);
- typeName = "UIntPtr";
- break;
- case Interop::TypeDecimal:
- PrintDecimalValue(rawData, value);
- typeName = "decimal";
- return S_OK;
- case Interop::TypeString:
- {
- std::string rawStr = rawData;
- EscapeString(rawStr, '"');
- ss << "\"" << rawStr << "\"";
- }
- break;
- }
- value = ss.str();
- return S_OK;
-}
-
-HRESULT MarshalValue(ICorDebugValue *pInputValue, int *typeId, void **data)
-{
- HRESULT Status;
-
- BOOL isNull = TRUE;
- ToRelease<ICorDebugValue> pValue;
- IfFailRet(DereferenceAndUnboxValue(pInputValue, &pValue, &isNull));
-
- if (isNull)
- {
- *data = nullptr;
- *typeId = Interop::TypeObject;
- return S_OK;
- }
-
- ULONG32 cbSize;
- IfFailRet(Status = pValue->GetSize(&cbSize));
-
- // TODO: potencially memory leaks..For example, SZARRAY
- ArrayHolder<BYTE> rgbValue = new (std::nothrow) BYTE[cbSize];
- if (rgbValue == nullptr)
- {
- return E_OUTOFMEMORY;
- }
-
- memset(rgbValue.GetPtr(), 0, cbSize * sizeof(BYTE));
-
- CorElementType corElemType;
- IfFailRet(pValue->GetType(&corElemType));
-
- if (corElemType == ELEMENT_TYPE_STRING)
- {
- std::string raw_str;
- IfFailRet(PrintStringValue(pValue, raw_str));
-
- if (!raw_str.empty())
- {
- *data = Interop::AllocString(raw_str);
- if (*data == nullptr)
- return E_FAIL;
- }
- else
- {
- *data = nullptr;
- }
-
- *typeId = Interop::TypeString;
- return S_OK;
- }
-
- if (corElemType == ELEMENT_TYPE_SZARRAY || corElemType == ELEMENT_TYPE_ARRAY)
- {
- pInputValue->AddRef();
- *data = pInputValue;
- *typeId = Interop::TypeCorValue;
- return S_OK;
- }
-
- ToRelease<ICorDebugGenericValue> pGenericValue;
- IfFailRet(pValue->QueryInterface(IID_ICorDebugGenericValue, (LPVOID*) &pGenericValue));
- IfFailRet(pGenericValue->GetValue((LPVOID) &(rgbValue[0])));
-
- if (IsEnum(pValue))
- {
- return E_FAIL;
- // TODO: Support enums, return PrintEnumValue(pValue, rgbValue, output);
- }
-
- switch (corElemType)
- {
- default:
- return E_FAIL;
-
- case ELEMENT_TYPE_PTR:
- *typeId = Interop::TypeIntPtr;
- break;
-
- case ELEMENT_TYPE_FNPTR:
- {
- CORDB_ADDRESS addr = 0;
- ToRelease<ICorDebugReferenceValue> pReferenceValue;
- if(SUCCEEDED(pValue->QueryInterface(IID_ICorDebugReferenceValue, (LPVOID*) &pReferenceValue)))
- pReferenceValue->GetValue(&addr);
- *(CORDB_ADDRESS*) &(rgbValue[0]) = addr;
- *typeId = Interop::TypeIntPtr;
- }
- break;
-
- case ELEMENT_TYPE_VALUETYPE:
- case ELEMENT_TYPE_CLASS:
- {
- std::string typeName;
- TypePrinter::GetTypeOfValue(pValue, typeName);
- if (typeName != "decimal")
- {
- pInputValue->AddRef();
- *data = pInputValue;
- *typeId = Interop::TypeCorValue;
- return S_OK;
- }
- *typeId = Interop::TypeDecimal;
- }
- break;
-
- case ELEMENT_TYPE_BOOLEAN:
- *typeId = Interop::TypeBoolean;
- break;
-
- case ELEMENT_TYPE_CHAR:
- *typeId = Interop::TypeChar;
- break;
-
- case ELEMENT_TYPE_I1:
- *typeId = Interop::TypeSByte;
- break;
-
- case ELEMENT_TYPE_U1:
- *typeId = Interop::TypeByte;
- break;
-
- case ELEMENT_TYPE_I2:
- *typeId = Interop::TypeInt16;
- break;
-
- case ELEMENT_TYPE_U2:
- *typeId = Interop::TypeUInt16;
- break;
-
- case ELEMENT_TYPE_I:
- *typeId = Interop::TypeIntPtr;
- break;
-
- case ELEMENT_TYPE_U:
- *typeId = Interop::TypeUIntPtr;
- break;
-
- case ELEMENT_TYPE_I4:
- *typeId = Interop::TypeInt32;
- break;
-
- case ELEMENT_TYPE_U4:
- *typeId = Interop::TypeUInt32;
- break;
-
- case ELEMENT_TYPE_I8:
- *typeId = Interop::TypeInt64;
- break;
-
- case ELEMENT_TYPE_U8:
- *typeId = Interop::TypeUInt64;
- break;
-
- case ELEMENT_TYPE_R4:
- *typeId = Interop::TypeSingle;
- break;
-
- case ELEMENT_TYPE_R8:
- *typeId = Interop::TypeDouble;
- break;
-
- case ELEMENT_TYPE_OBJECT:
- return E_FAIL;
-
- }
-
- *data = Interop::CoTaskMemAlloc(cbSize);
- if (*data == nullptr)
- {
- return E_FAIL;
- }
- memmove(*data, &(rgbValue[0]), cbSize);
- return S_OK;
-}
-
} // namespace netcoredbg
{
HRESULT PrintValue(ICorDebugValue *pInputValue, std::string &output, bool escape = true);
-HRESULT PrintBasicValue(int typeId, const std::string &rawData, std::string &typeName, std::string &value);
HRESULT DereferenceAndUnboxValue(ICorDebugValue * pValue, ICorDebugValue** ppOutputValue, BOOL * pIsNull = nullptr);
-HRESULT MarshalValue(ICorDebugValue *pInputValue, int *typeId, void **data);
} // namespace netcoredbg
std::string className;
if (pType)
- TypePrinter::GetTypeOfValue(pType, className);
+ IfFailRet(TypePrinter::GetTypeOfValue(pType, className));
members.emplace_back(name, className, iCorResultValue.Detach());
return S_OK;
var.name = "$exception";
var.evaluateName = var.name;
- bool escape = true;
- PrintValue(pExceptionValue, var.value, escape);
- TypePrinter::GetTypeOfValue(pExceptionValue, var.type);
+ HRESULT Status;
+ IfFailRet(PrintValue(pExceptionValue, var.value));
+ IfFailRet(TypePrinter::GetTypeOfValue(pExceptionValue, var.type));
return AddVariableReference(var, frameId, pExceptionValue, ValueIsVariable);
}
Variable var;
var.name = name;
var.evaluateName = var.name;
- bool escape = true;
ToRelease<ICorDebugValue> iCorValue;
IfFailRet(getValue(&iCorValue, var.evalFlags));
- PrintValue(iCorValue, var.value, escape);
- TypePrinter::GetTypeOfValue(iCorValue, var.type);
+ IfFailRet(PrintValue(iCorValue, var.value));
+ IfFailRet(TypePrinter::GetTypeOfValue(iCorValue, var.type));
IfFailRet(AddVariableReference(var, frameId, iCorValue, ValueIsVariable));
variables.push_back(var);
return S_OK;
Variable var(ref.evalFlags);
var.name = "Static members";
- TypePrinter::GetTypeOfValue(ref.iCorValue, var.evaluateName); // do not expose type for this fake variable
+ IfFailRet(TypePrinter::GetTypeOfValue(ref.iCorValue, var.evaluateName)); // do not expose type for this fake variable
IfFailRet(AddVariableReference(var, ref.frameId, ref.iCorValue, ValueIsClass));
variables.push_back(var);
if (!threadId)
return E_FAIL;
- FrameLevel frameLevel = frameId.getLevel();
-
HRESULT Status;
ToRelease<ICorDebugThread> pThread;
IfFailRet(pProcess->GetThread(int(threadId), &pThread));
- ToRelease<ICorDebugValue> pResultValue;
-
- // EvalStackMachine::Run() return not error but S_FALSE in case some syntax kind not implemented.
- if (FAILED(Status = m_sharedEvalStackMachine->Run(pThread, frameLevel, variable.evalFlags, expression, &pResultValue, output)))
- return Status;
-
- int typeId;
-
- // Use Roslyn for expression evaluation
- if (!pResultValue)
- {
- IfFailRet(Interop::EvalExpression(
- expression, output, &typeId, &pResultValue,
- [&](void *corValue, const std::string &name, int *typeId, void **data) -> bool
- {
- ToRelease<ICorDebugValue> pThisValue;
-
- if (!corValue) // Scope
- {
- bool found = false;
- if (FAILED(Status = m_sharedEvaluator->WalkStackVars(pThread, frameLevel,
- [&](const std::string &varName, Evaluator::GetValueCallback getValue) -> HRESULT
- {
- if (varName == "this")
- {
- if (!pThisValue)
- getValue(&pThisValue, variable.evalFlags);
- }
- if (!found && varName == name)
- {
- found = true;
- ToRelease<ICorDebugValue> iCorValue;
- IfFailRet(getValue(&iCorValue, variable.evalFlags));
- IfFailRet(MarshalValue(iCorValue, typeId, data));
- return E_ABORT; // Fast way to exit from stack vars walk routine.
- }
-
- return S_OK;
- })) && Status != E_ABORT)
- {
- return false;
- }
- if (found)
- return true;
- if (!pThisValue)
- return false;
-
- corValue = pThisValue;
- }
-
- std::vector<Member> members;
-
- const bool fetchOnlyStatic = false;
- bool hasStaticMembers = false;
-
- ICorDebugValue *pValue = static_cast<ICorDebugValue*>(corValue);
-
- if (FAILED(FetchFieldsAndProperties(pValue, pThread, frameLevel, members, fetchOnlyStatic,
- hasStaticMembers, 0, INT_MAX, variable.evalFlags)))
- return false;
-
- FixupInheritedFieldNames(members);
-
- auto memberIt = std::find_if(members.begin(), members.end(), [&name](const Member &m){ return m.name == name; });
- if (memberIt == members.end())
- return false;
-
- if (!memberIt->value)
- return false;
- if (FAILED(MarshalValue(memberIt->value, typeId, data)))
- {
- return false;
- }
-
- return true;
- }));
- }
+ ToRelease<ICorDebugValue> pResultValue;
+ FrameLevel frameLevel = frameId.getLevel();
+ IfFailRet(m_sharedEvalStackMachine->Run(pThread, frameLevel, variable.evalFlags, expression, &pResultValue, output));
variable.evaluateName = expression;
-
- if (pResultValue)
- {
- const bool escape = true;
- PrintValue(pResultValue, variable.value, escape);
- TypePrinter::GetTypeOfValue(pResultValue, variable.type);
- }
- else
- {
- PrintBasicValue(typeId, output, variable.type, variable.value);
- }
- IfFailRet(AddVariableReference(variable, frameId, pResultValue, ValueIsVariable));
-
- return S_OK;
+ IfFailRet(PrintValue(pResultValue, variable.value));
+ IfFailRet(TypePrinter::GetTypeOfValue(pResultValue, variable.type));
+ return AddVariableReference(variable, frameId, pResultValue, ValueIsVariable);
}
HRESULT Variables::SetVariable(
ToRelease<ICorDebugValue> iCorValue;
IfFailRet(getValue(&iCorValue, ref.evalFlags));
IfFailRet(m_sharedEvalStackMachine->Run(pThread, ref.frameId.getLevel(), ref.evalFlags, value, iCorValue.GetRef(), output));
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- return E_FAIL;
- bool escape = true;
- PrintValue(iCorValue, output, escape);
+ IfFailRet(PrintValue(iCorValue, output));
return E_ABORT; // Fast exit from cycle.
})) && Status != E_ABORT)
{
IfFailRet(setValue(value, output, ref.evalFlags));
ToRelease<ICorDebugValue> iCorValue;
IfFailRet(getValue(&iCorValue, ref.evalFlags));
- bool escape = true;
- PrintValue(iCorValue, output, escape);
+ IfFailRet(PrintValue(iCorValue, output));
}
return S_OK;
}));
// All "set value" code must be refactored in order to remove dependency from Roslyn.
std::string output;
- Status = m_sharedEvalStackMachine->Run(pThread, frameId.getLevel(), variable.evalFlags, variable.evaluateName, ppResult, output);
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- Status = E_FAIL;
-
- return Status;
+ return m_sharedEvalStackMachine->Run(pThread, frameId.getLevel(), variable.evalFlags, variable.evaluateName, ppResult, output);
}
HRESULT Variables::SetVariable(
IfFailRet(pProcess->GetThread(int(threadId), &pThread));
IfFailRet(m_sharedEvalStackMachine->Run(pThread, frameId.getLevel(), evalFlags, value, &pVariable, output));
- if (Status == S_FALSE) // return not error but S_FALSE in case some syntax kind not implemented.
- return E_FAIL;
- bool escape = true;
- PrintValue(pVariable, output, escape);
+ IfFailRet(PrintValue(pVariable, output));
return S_OK;
}
{
public partial class Evaluation
{
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- public struct BlittableChar
- {
- public char Value;
-
- public static explicit operator BlittableChar(char value)
- {
- return new BlittableChar { Value = value };
- }
-
- public static implicit operator char (BlittableChar value)
- {
- return value.Value;
- }
- }
-
- public struct BlittableBoolean
- {
- private byte byteValue;
-
- public bool Value
- {
- get { return Convert.ToBoolean(byteValue); }
- set { byteValue = Convert.ToByte(value); }
- }
-
- public static explicit operator BlittableBoolean(bool value)
- {
- return new BlittableBoolean { Value = value };
- }
-
- public static implicit operator bool (BlittableBoolean value)
- {
- return value.Value;
- }
- }
-
- private static string[] basicTypes = new string[] {
- "System.Object",
- "System.Boolean",
- "System.Byte",
- "System.SByte",
- "System.Char",
- "System.Double",
- "System.Single",
- "System.Int32",
- "System.UInt32",
- "System.Int64",
- "System.UInt64",
- "System.Int16",
- "System.UInt16",
- "System.IntPtr",
- "System.UIntPtr",
- "System.Decimal",
- "System.String"
- };
-
- internal delegate bool GetChildDelegate(IntPtr opaque, IntPtr corValue, [MarshalAs(UnmanagedType.LPWStr)] string name, out int dataTypeId, out IntPtr dataPtr);
-
- private static GetChildDelegate getChild;
-
- internal static void RegisterGetChild(GetChildDelegate cb)
- {
- getChild = cb;
- }
-
- public class ContextVariable : DynamicObject
- {
- private IntPtr m_opaque;
- public IntPtr m_corValue { get; }
-
- public ContextVariable(IntPtr opaque, IntPtr corValue)
- {
- this.m_opaque = opaque;
- this.m_corValue = corValue;
- }
-
- private bool UnmarshalResult(int dataTypeId, IntPtr dataPtr, out object result)
- {
- if (dataTypeId < 0)
- {
- result = new ContextVariable(m_opaque, dataPtr);
- return true;
- }
- if (dataTypeId == 0) // special case for null object
- {
- result = null;
- return true;
- }
- if (dataTypeId >= basicTypes.Length)
- {
- result = null;
- return false;
- }
- Type dataType = Type.GetType(basicTypes[dataTypeId]);
- if (dataType == typeof(string))
- {
- if (dataPtr == IntPtr.Zero)
- {
- result = string.Empty;
- return true;
- }
- result = Marshal.PtrToStringBSTR(dataPtr);
- Marshal.FreeBSTR(dataPtr);
- return true;
- }
- if (dataType == typeof(char))
- {
- BlittableChar c = Marshal.PtrToStructure<BlittableChar>(dataPtr);
- Marshal.FreeCoTaskMem(dataPtr);
- result = (char)c;
- return true;
- }
- if (dataType == typeof(bool))
- {
- BlittableBoolean b = Marshal.PtrToStructure<BlittableBoolean>(dataPtr);
- Marshal.FreeCoTaskMem(dataPtr);
- result = (bool)b;
- return true;
- }
- result = Marshal.PtrToStructure(dataPtr, dataType);
- Marshal.FreeCoTaskMem(dataPtr);
- return true;
- }
-
- public override bool TryGetMember(
- GetMemberBinder binder, out object result)
- {
- IntPtr dataPtr;
- int dataTypeId;
- if (!getChild(m_opaque, m_corValue, binder.Name, out dataTypeId, out dataPtr))
- {
- result = null;
- return false;
- }
- return UnmarshalResult(dataTypeId, dataPtr, out result);
- }
-
- public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
- {
- IntPtr dataPtr;
- int dataTypeId;
- if (!getChild(m_opaque, m_corValue, "[" + string.Join(", ", indexes) + "]", out dataTypeId, out dataPtr))
- {
- result = null;
- return false;
- }
- return UnmarshalResult(dataTypeId, dataPtr, out result);
- }
- }
-
- public class Globals
- {
- public dynamic __context;
- }
-
- // Stores unresolved symbols, now only variables are supported
- // Symbols are unique in list
- class SyntaxAnalyzer
- {
- class FrameVars
- {
- Stack<string> vars = new Stack<string>();
- Stack<int> varsInFrame = new Stack<int>();
- int curFrameVars = 0;
-
- public void Add(string name)
- {
- vars.Push(name);
- curFrameVars++;
- }
-
- public void NewFrame()
- {
- varsInFrame.Push(curFrameVars);
- curFrameVars = 0;
- }
-
- public void ExitFrame()
- {
- for (int i = 0; i < curFrameVars; i++)
- vars.Pop();
-
- curFrameVars = varsInFrame.Pop();
- }
-
- public bool Contains(string name)
- {
- return vars.Contains(name);
- }
- }
-
- enum ParsingState
- {
- Common,
- InvocationExpression,
- GenericName
- };
-
- public List<string> unresolvedSymbols { get; private set; } = new List<string>();
- FrameVars frameVars = new FrameVars();
- SyntaxTree tree;
-
- public SyntaxAnalyzer(string expression)
- {
- tree = CSharpSyntaxTree.ParseText(expression, options: new CSharpParseOptions(kind: SourceCodeKind.Script));
- var root = tree.GetCompilationUnitRoot();
- foreach (SyntaxNode sn in root.ChildNodes())
- ParseNode(sn, ParsingState.Common);
- }
-
- void ParseAccessNode(SyntaxNode sn, ParsingState state)
- {
- SyntaxNodeOrToken snt = sn.ChildNodesAndTokens().First();
-
- if (snt.Kind().Equals(SyntaxKind.SimpleMemberAccessExpression))
- ParseAccessNode(snt.AsNode(), state);
- else if (snt.IsNode)
- ParseNode(snt.AsNode(), state);
- else if (snt.IsToken)
- ParseCommonToken(snt.AsToken(), state);
- }
-
- void ParseBlock(SyntaxNode sn, ParsingState state)
- {
- frameVars.NewFrame();
- foreach (SyntaxNode snc in sn.ChildNodes())
- ParseNode(sn, ParsingState.Common);
- frameVars.ExitFrame();
- }
-
- void ParseNode(SyntaxNode sn, ParsingState state)
- {
- if (sn.Kind().Equals(SyntaxKind.InvocationExpression))
- state = ParsingState.InvocationExpression;
- else if (sn.Kind().Equals(SyntaxKind.GenericName))
- state = ParsingState.GenericName;
- else if (sn.Kind().Equals(SyntaxKind.ArgumentList))
- state = ParsingState.Common;
-
- foreach (SyntaxNodeOrToken snt in sn.ChildNodesAndTokens())
- {
- if (snt.IsNode)
- {
- if (snt.Kind().Equals(SyntaxKind.SimpleMemberAccessExpression))
- ParseAccessNode(snt.AsNode(), state);
- else if (snt.Kind().Equals(SyntaxKind.Block))
- ParseBlock(snt.AsNode(), state);
- else
- ParseNode(snt.AsNode(), state);
- }
- else
- {
- if (sn.Kind().Equals(SyntaxKind.VariableDeclarator))
- ParseDeclarator(snt.AsToken());
- else
- ParseCommonToken(snt.AsToken(), state);
- }
- }
- }
-
- void ParseCommonToken(SyntaxToken st, ParsingState state)
- {
- if (state == ParsingState.InvocationExpression ||
- state == ParsingState.GenericName)
- return;
-
- if (st.Kind().Equals(SyntaxKind.IdentifierToken) &&
- !unresolvedSymbols.Contains(st.Value.ToString()) &&
- !frameVars.Contains(st.Value.ToString()))
- unresolvedSymbols.Add(st.Value.ToString());
- }
-
- void ParseDeclarator(SyntaxToken st)
- {
- if (st.Kind().Equals(SyntaxKind.IdentifierToken) && !frameVars.Contains(st.Value.ToString()))
- frameVars.Add(st.Value.ToString());
- }
- };
-
- static void MarshalValue(object value, out int size, out IntPtr data)
- {
- if (value is string)
- {
- data = Marshal.StringToBSTR(value as string);
- size = 0;
- }
- else if (value is char)
- {
- BlittableChar c = (BlittableChar)((char)value);
- size = Marshal.SizeOf(c);
- data = Marshal.AllocCoTaskMem(size);
- Marshal.StructureToPtr(c, data, false);
- }
- else if (value is bool)
- {
- BlittableBoolean b = (BlittableBoolean)((bool)value);
- size = Marshal.SizeOf(b);
- data = Marshal.AllocCoTaskMem(size);
- Marshal.StructureToPtr(b, data, false);
- }
- else
- {
- size = Marshal.SizeOf(value);
- data = Marshal.AllocCoTaskMem(size);
- Marshal.StructureToPtr(value, data, false);
- }
- }
-
- internal static RetCode EvalExpression([MarshalAs(UnmanagedType.LPWStr)] string expr, IntPtr opaque, out IntPtr errorText, out int typeId, out int size, out IntPtr result)
- {
- SyntaxAnalyzer sa = new SyntaxAnalyzer(expr);
-
- StringBuilder scriptText = new StringBuilder("#line hidden\n");
-
- // Generate prefix with variables assignment to __context members
- foreach (string us in sa.unresolvedSymbols)
- scriptText.AppendFormat("var {0} = __context.{0};\n", us);
-
- scriptText.Append("#line 1\n");
- scriptText.Append(expr);
-
- errorText = IntPtr.Zero;
- result = IntPtr.Zero;
- typeId = 0;
- size = 0;
- try
- {
- var scriptOptions = ScriptOptions.Default
- .WithImports("System")
- .WithReferences(typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly);
- var script = CSharpScript.Create(scriptText.ToString(), scriptOptions, globalsType: typeof(Globals));
- script.Compile();
- var returnValue = script.RunAsync(new Globals { __context = new ContextVariable(opaque, IntPtr.Zero) }).Result.ReturnValue;
- if (returnValue is ContextVariable)
- {
- typeId = -1;
- result = (returnValue as ContextVariable).m_corValue;
- }
- else
- {
- if (returnValue is null)
- {
- typeId = 0;
- return RetCode.OK;
- }
- for (int i = 1; i < basicTypes.Length; i++)
- {
- if (returnValue.GetType() == Type.GetType(basicTypes[i]))
- {
- typeId = i;
- MarshalValue(returnValue, out size, out result);
- return RetCode.OK;
- }
- }
- return RetCode.Fail;
- }
- }
- catch(Exception e)
- {
- errorText = Marshal.StringToBSTR(e.ToString());
- return RetCode.Exception;
- }
-
- return RetCode.OK;
- }
-
- internal static RetCode ParseExpression([MarshalAs(UnmanagedType.LPWStr)] string expr, [MarshalAs(UnmanagedType.LPWStr)] string resultTypeName, out IntPtr data, out int size, out IntPtr errorText)
- {
- object value = null;
- data = IntPtr.Zero;
- size = 0;
- errorText = IntPtr.Zero;
- Type resultType = Type.GetType(resultTypeName);
- if (resultType == null)
- {
- errorText = Marshal.StringToBSTR("Unknown type: " + resultTypeName);
- return RetCode.Fail;
- }
- try
- {
- MethodInfo genericMethod = null;
-
- foreach (System.Reflection.MethodInfo m in typeof(CSharpScript).GetTypeInfo().GetMethods())
- {
- if (m.Name == "EvaluateAsync" && m.ContainsGenericParameters)
- {
- genericMethod = m.MakeGenericMethod(resultType);
- break;
- }
- }
-
- if (genericMethod == null)
- throw new ArgumentNullException();
-
- dynamic v = genericMethod.Invoke(null, new object[]{expr, null, null, null, default(System.Threading.CancellationToken)});
- value = v.Result;
- }
- catch (TargetInvocationException e)
- {
- if (e.InnerException is CompilationErrorException)
- {
- errorText = Marshal.StringToBSTR(string.Join(Environment.NewLine, (e.InnerException as CompilationErrorException).Diagnostics));
- }
- else
- {
- errorText = Marshal.StringToBSTR(e.InnerException.ToString());
- }
- return RetCode.Exception;
- }
- if (value == null)
- {
- errorText = Marshal.StringToBSTR("Value can not be null");
- return RetCode.Fail;
- }
- MarshalValue(value, out size, out data);
- return RetCode.OK;
- }
-
//BasicTypes enum must be sync with enum from native part
internal enum BasicTypes
{
{
public partial class Evaluation
{
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct BlittableChar
+ {
+ public char Value;
+
+ public static explicit operator BlittableChar(char value)
+ {
+ return new BlittableChar { Value = value };
+ }
+
+ public static implicit operator char (BlittableChar value)
+ {
+ return value.Value;
+ }
+ }
+
+ public struct BlittableBoolean
+ {
+ private byte byteValue;
+
+ public bool Value
+ {
+ get { return Convert.ToBoolean(byteValue); }
+ set { byteValue = Convert.ToByte(value); }
+ }
+
+ public static explicit operator BlittableBoolean(bool value)
+ {
+ return new BlittableBoolean { Value = value };
+ }
+
+ public static implicit operator bool (BlittableBoolean value)
+ {
+ return value.Value;
+ }
+ }
+
+ static void MarshalValue(object value, out int size, out IntPtr data)
+ {
+ if (value is string)
+ {
+ data = Marshal.StringToBSTR(value as string);
+ size = 0;
+ }
+ else if (value is char)
+ {
+ BlittableChar c = (BlittableChar)((char)value);
+ size = Marshal.SizeOf(c);
+ data = Marshal.AllocCoTaskMem(size);
+ Marshal.StructureToPtr(c, data, false);
+ }
+ else if (value is bool)
+ {
+ BlittableBoolean b = (BlittableBoolean)((bool)value);
+ size = Marshal.SizeOf(b);
+ data = Marshal.AllocCoTaskMem(size);
+ Marshal.StructureToPtr(b, data, false);
+ }
+ else
+ {
+ size = Marshal.SizeOf(value);
+ data = Marshal.AllocCoTaskMem(size);
+ Marshal.StructureToPtr(value, data, false);
+ }
+ }
+
enum ePredefinedType
{
BoolKeyword,
};
internal const int S_OK = 0;
- internal const int S_FALSE = 1;
internal const int E_INVALIDARG = unchecked((int)0x80070057);
public abstract class ICommand
case SyntaxKind.BracketedArgumentList:
case SyntaxKind.ConditionalAccessExpression:
case SyntaxKind.ArgumentList:
+ case SyntaxKind.ParenthesizedExpression:
/* TODO
case SyntaxKind.TypeArgumentList:
case SyntaxKind.OmittedTypeArgument:
- case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.UncheckedExpression:
case SyntaxKind.CheckedExpression:
*/
return E_INVALIDARG;
}
}
- catch (SyntaxKindNotImplementedException e)
- {
- // Note, return not error but S_FALSE in case some syntax kind not implemented.
- // TODO remove this when new eval will be fully implemented
- textOutput = Marshal.StringToBSTR(e.GetType().ToString() + ": " + e.Message);
- return S_FALSE;
- }
catch (Exception e)
{
textOutput = Marshal.StringToBSTR(e.GetType().ToString() + ": " + e.Message);
{
Marshal.FreeCoTaskMem(ptr);
}
-
- internal static void GCCollect()
- {
- try
- {
- GC.Collect();
- }
- catch
- {
- }
- }
}
}
typedef RetCode (*GetMethodLastIlOffsetDelegate)(PVOID, mdMethodDef, uint32_t*);
typedef RetCode (*GetAsyncMethodsSteppingInfoDelegate)(PVOID, PVOID*, int32_t*);
typedef RetCode (*GetSourceDelegate)(PVOID, const WCHAR*, int32_t*, PVOID*);
-typedef RetCode (*ParseExpressionDelegate)(const WCHAR*, const WCHAR*, PVOID*, int32_t*, BSTR*);
-typedef RetCode (*EvalExpressionDelegate)(const WCHAR*, PVOID, BSTR*, int32_t*, int32_t*, PVOID*);
typedef RetCode (*CalculationDelegate)(PVOID, int32_t, PVOID, int32_t, int32_t, int32_t*, PVOID*, BSTR*);
-typedef BOOL (*GetChildDelegate)(PVOID, PVOID, const WCHAR*, int32_t*, PVOID*);
-typedef BOOL (*RegisterGetChildDelegate)(GetChildDelegate);
typedef int (*GenerateStackMachineProgramDelegate)(const WCHAR*, PVOID*, BSTR*);
typedef void (*ReleaseStackMachineProgramDelegate)(PVOID);
typedef int (*NextStackCommandDelegate)(PVOID, int32_t*, PVOID*, BSTR*);
typedef RetCode (*StringToUpperDelegate)(const WCHAR*, BSTR*);
-typedef void (*GCCollectDelegate)();
typedef PVOID (*CoTaskMemAllocDelegate)(int32_t);
typedef void (*CoTaskMemFreeDelegate)(PVOID);
typedef PVOID (*SysAllocStringLenDelegate)(int32_t);
GetMethodLastIlOffsetDelegate getMethodLastIlOffsetDelegate = nullptr;
GetAsyncMethodsSteppingInfoDelegate getAsyncMethodsSteppingInfoDelegate = nullptr;
GetSourceDelegate getSourceDelegate = nullptr;
-ParseExpressionDelegate parseExpressionDelegate = nullptr;
-EvalExpressionDelegate evalExpressionDelegate = nullptr;
-RegisterGetChildDelegate registerGetChildDelegate = nullptr;
GenerateStackMachineProgramDelegate generateStackMachineProgramDelegate = nullptr;
ReleaseStackMachineProgramDelegate releaseStackMachineProgramDelegate = nullptr;
NextStackCommandDelegate nextStackCommandDelegate = nullptr;
StringToUpperDelegate stringToUpperDelegate = nullptr;
-GCCollectDelegate gCCollectDelegate = nullptr;
CoTaskMemAllocDelegate coTaskMemAllocDelegate = nullptr;
CoTaskMemFreeDelegate coTaskMemFreeDelegate = nullptr;
SysAllocStringLenDelegate sysAllocStringLenDelegate = nullptr;
disposeDelegate(pSymbolReaderHandle);
}
-struct GetChildProxy
-{
- GetChildCallback &m_cb;
- static BOOL GetChild(PVOID opaque, PVOID corValue, const WCHAR* name, int *typeId, PVOID *data)
- {
- std::string uft8Name = to_utf8(name);
- return static_cast<GetChildProxy*>(opaque)->m_cb(corValue, uft8Name, typeId, data);
- }
-};
-
// WARNING! Due to CoreCLR limitations, Init() / Shutdown() sequence can be used only once during process execution.
// Note, init in case of error will throw exception, since this is fatal for debugger (CoreCLR can't be re-init).
void Init(const std::string &coreClrPath)
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, SymbolReaderClassName, "GetMethodLastIlOffset", (void **)&getMethodLastIlOffsetDelegate)) &&
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, SymbolReaderClassName, "GetAsyncMethodsSteppingInfo", (void **)&getAsyncMethodsSteppingInfoDelegate)) &&
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, SymbolReaderClassName, "GetSource", (void **)&getSourceDelegate)) &&
- SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, EvaluationClassName, "ParseExpression", (void **)&parseExpressionDelegate)) &&
- SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, EvaluationClassName, "EvalExpression", (void **)&evalExpressionDelegate)) &&
- SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, EvaluationClassName, "RegisterGetChild", (void **)®isterGetChildDelegate)) &&
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, EvaluationClassName, "CalculationDelegate", (void **)&calculationDelegate)) &&
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, EvaluationClassName, "GenerateStackMachineProgram", (void **)&generateStackMachineProgramDelegate)) &&
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, EvaluationClassName, "ReleaseStackMachineProgram", (void **)&releaseStackMachineProgramDelegate)) &&
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, EvaluationClassName, "NextStackCommand", (void **)&nextStackCommandDelegate)) &&
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, UtilsClassName, "StringToUpper", (void **)&stringToUpperDelegate));
- SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, UtilsClassName, "GCCollect", (void **)&gCCollectDelegate));
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, UtilsClassName, "CoTaskMemAlloc", (void **)&coTaskMemAllocDelegate));
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, UtilsClassName, "CoTaskMemFree", (void **)&coTaskMemFreeDelegate));
SUCCEEDED(Status = createDelegate(hostHandle, domainId, ManagedPartDllName, UtilsClassName, "SysAllocStringLen", (void **)&sysAllocStringLenDelegate));
getMethodLastIlOffsetDelegate &&
getAsyncMethodsSteppingInfoDelegate &&
getSourceDelegate &&
- parseExpressionDelegate &&
- evalExpressionDelegate &&
- registerGetChildDelegate &&
generateStackMachineProgramDelegate &&
releaseStackMachineProgramDelegate &&
nextStackCommandDelegate &&
stringToUpperDelegate &&
- gCCollectDelegate &&
coTaskMemAllocDelegate &&
coTaskMemFreeDelegate &&
sysAllocStringLenDelegate &&
if (!allDelegatesInited)
throw std::runtime_error("Some delegates nulled");
-
- if (!registerGetChildDelegate(GetChildProxy::GetChild))
- throw std::runtime_error("GetChildDelegate failed");
-
- // Warm up Roslyn
- std::thread( [](ParseExpressionDelegate parseExpressionDelegate, GCCollectDelegate gCCollectDelegate,
- SysFreeStringDelegate sysFreeStringDelegate, CoTaskMemFreeDelegate coTaskMemFreeDelegate){
- BSTR werrorText;
- PVOID dataPtr;
- int dataSize = 0;
- parseExpressionDelegate(W("1"), W("System.Int32"), &dataPtr, &dataSize, &werrorText);
- // Dirty workaround, in order to prevent memory leak by Roslyn, since it create assembly that can't be unloaded each eval.
- // https://github.com/dotnet/roslyn/issues/22219
- // https://github.com/dotnet/roslyn/issues/41722
- gCCollectDelegate();
- sysFreeStringDelegate(werrorText);
- coTaskMemFreeDelegate(dataPtr);
- }, parseExpressionDelegate, gCCollectDelegate, sysFreeStringDelegate, coTaskMemFreeDelegate).detach();
}
// WARNING! Due to CoreCLR limitations, Shutdown() can't be called out of the Main() scope, for example, from global object destructor.
getMethodLastIlOffsetDelegate = nullptr;
getAsyncMethodsSteppingInfoDelegate = nullptr;
getSourceDelegate = nullptr;
- parseExpressionDelegate = nullptr;
- evalExpressionDelegate = nullptr;
- registerGetChildDelegate = nullptr;
stringToUpperDelegate = nullptr;
- gCCollectDelegate = nullptr;
coTaskMemAllocDelegate = nullptr;
coTaskMemFreeDelegate = nullptr;
sysAllocStringLenDelegate = nullptr;
return S_OK;
}
-HRESULT ParseExpression(const std::string &expr, const std::string &typeName, std::string &data, std::string &errorText)
-{
- std::unique_lock<Utility::RWLock::Reader> read_lock(CLRrwlock.reader);
- if (!parseExpressionDelegate || !gCCollectDelegate)
- return E_FAIL;
-
- BSTR werrorText;
- PVOID dataPtr;
- int32_t dataSize = 0;
- RetCode retCode = parseExpressionDelegate(to_utf16(expr).c_str(), to_utf16(typeName).c_str(), &dataPtr, &dataSize, &werrorText);
- // Dirty workaround, in order to prevent memory leak by Roslyn, since it create assembly that can't be unloaded each eval.
- // https://github.com/dotnet/roslyn/issues/22219
- // https://github.com/dotnet/roslyn/issues/41722
- gCCollectDelegate();
-
- read_lock.unlock();
-
- if (retCode != RetCode::OK)
- {
- errorText = to_utf8(werrorText);
- Interop::SysFreeString(werrorText);
- return E_FAIL;
- }
-
- if (typeName == "System.String")
- {
- data = to_utf8((BSTR)dataPtr);
- Interop::SysFreeString((BSTR)dataPtr);
- }
- else
- {
- data.resize(dataSize);
- memmove(&data[0], dataPtr, dataSize);
- Interop::CoTaskMemFree(dataPtr);
- }
-
- return S_OK;
-}
-
-HRESULT EvalExpression(const std::string &expr, std::string &result, int *typeId, ICorDebugValue **ppValue, GetChildCallback cb)
-{
- std::unique_lock<Utility::RWLock::Reader> read_lock(CLRrwlock.reader);
- if (!evalExpressionDelegate || !gCCollectDelegate || !typeId || !ppValue)
- return E_FAIL;
-
- GetChildProxy proxy { cb };
- PVOID valuePtr = nullptr;
- int32_t size = 0;
- BSTR resultText;
- RetCode retCode = evalExpressionDelegate(to_utf16(expr).c_str(), &proxy, &resultText, typeId, &size, &valuePtr);
- // Dirty workaround, in order to prevent memory leak by Roslyn, since it create assembly that can't be unloaded each eval.
- // https://github.com/dotnet/roslyn/issues/22219
- // https://github.com/dotnet/roslyn/issues/41722
- gCCollectDelegate();
-
- read_lock.unlock();
-
- if (retCode != RetCode::OK)
- {
- if (resultText)
- {
- result = to_utf8(resultText);
- Interop::SysFreeString(resultText);
- }
- return E_FAIL;
- }
-
- switch(*typeId)
- {
- case TypeCorValue:
- *ppValue = static_cast<ICorDebugValue*>(valuePtr);
- if (*ppValue)
- (*ppValue)->AddRef();
- break;
- case TypeObject:
- result = std::string();
- break;
- case TypeString:
- result = to_utf8((BSTR)valuePtr);
- Interop::SysFreeString((BSTR)valuePtr);
- break;
- default:
- result.resize(size);
- memmove(&result[0], valuePtr, size);
- Interop::CoTaskMemFree(valuePtr);
- break;
- }
-
- return S_OK;
-}
-
HRESULT GenerateStackMachineProgram(const std::string &expr, PVOID *ppStackProgram, std::string &textOutput)
{
std::unique_lock<Utility::RWLock::Reader> read_lock(CLRrwlock.reader);
}
};
- // Keep in sync with string[] basicTypes in Evaluation.cs
- enum BasicTypes {
- TypeCorValue = -1,
- TypeObject = 0, // "System.Object",
- TypeBoolean, // "System.Boolean",
- TypeByte, // "System.Byte",
- TypeSByte, // "System.SByte",
- TypeChar, // "System.Char",
- TypeDouble, // "System.Double",
- TypeSingle, // "System.Single",
- TypeInt32, // "System.Int32",
- TypeUInt32, // "System.UInt32",
- TypeInt64, // "System.Int64",
- TypeUInt64, // "System.UInt64",
- TypeInt16, // "System.Int16",
- TypeUInt16, // "System.UInt16",
- TypeIntPtr, // "System.IntPtr",
- TypeUIntPtr, // "System.UIntPtr",
- TypeDecimal, // "System.Decimal",
- TypeString, // "System.String"
- };
-
// Keep in sync with OperationType enum in Evaluation.cs
enum class OperationType
{
{}
};
- typedef std::function<bool(PVOID, const std::string&, int*, PVOID*)> GetChildCallback;
-
// WARNING! Due to CoreCLR limitations, Init() / Shutdown() sequence can be used only once during process execution.
// Note, init in case of error will throw exception, since this is fatal for debugger (CoreCLR can't be re-init).
void Init(const std::string &coreClrPath);
HRESULT ResolveBreakPoints(PVOID pSymbolReaderHandle, int32_t tokenNum, PVOID Tokens, int32_t sourceLine, int32_t nestedToken, int32_t &Count, PVOID *data);
HRESULT GetAsyncMethodsSteppingInfo(PVOID pSymbolReaderHandle, std::vector<AsyncAwaitInfoBlock> &AsyncAwaitInfo);
HRESULT GetSource(PVOID symbolReaderHandle, const std::string fileName, PVOID *data, int32_t *length);
- // TODO remove all related code - HRESULT ParseExpression(const std::string &expr, const std::string &typeName, std::string &data, std::string &errorText);
HRESULT CalculationDelegate(PVOID firstOp, int32_t firstType, PVOID secondOp, int32_t secondType, int32_t operationType, int32_t &resultType, PVOID *data, std::string &errorText);
- HRESULT EvalExpression(const std::string &expr, std::string &result, int *typeId, ICorDebugValue **ppValue, GetChildCallback cb);
HRESULT GenerateStackMachineProgram(const std::string &expr, PVOID *ppStackProgram, std::string &textOutput);
void ReleaseStackMachineProgram(PVOID pStackProgram);
HRESULT NextStackCommand(PVOID pStackProgram, int32_t &Command, PVOID &Ptr, std::string &textOutput);
Label.Checkpoint("expression_test", "static_test", (Object context) => {
Context Context = (Context)context;
Context.WasBreakpointHit(@"__FILE__:__LINE__", "BREAK2");
-
+/*
Context.GetAndCheckValue(@"__FILE__:__LINE__", "2", "int", "1 + 1");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "6", "int", "int_i1 + 1");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "10", "int", "int_i1 + int_i2");
Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "int_i1 +/ int_i2", "error CS1525:");
Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "1 + not_var", "System.AggregateException"); // error
-
+*/
Context.Continue(@"__FILE__:__LINE__");
});