/////////////////////////////////////////////////////////////////////// #region Private Methods private void TargetInterpreterDisposed( object @object ) { if ((@object != null) && Object.ReferenceEquals(@object, targetInterpreter)) { if ((sourceInterpreter != null) && !Object.ReferenceEquals( sourceInterpreter, targetInterpreter) && (nameToken != null)) { ReturnCode code; Result error = null; code = sourceInterpreter.RemoveAliasAndCommand( nameToken, null, false, ref error); if (code != ReturnCode.Ok) { DebugOps.Complain(sourceInterpreter, code, error); } } targetInterpreter = null; } }
/////////////////////////////////////////////////////////////////////// public static ReturnCode Unload( AppDomain appDomain, IClientData clientData, /* NOT USED */ ref Result error ) { if (appDomain != null) { try { AppDomain.Unload(appDomain); /* throw */ return(ReturnCode.Ok); } catch (Exception e) { error = e; } } else { error = "invalid application domain"; } // // NOTE: We do not really expect this method to fail; // therefore, output a complaint about it. // DebugOps.Complain(ReturnCode.Error, error); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////////////////////////////// private static ReturnCode WaitForSingleHandle( WaitHandle waitHandle, int milliseconds, bool userInterface, ref uint returnValue ) { ReturnCode code; Result error = null; code = WaitForSingleHandle( waitHandle, milliseconds, userInterface, ref returnValue, ref error); if (code != ReturnCode.Ok) { DebugOps.Complain(code, error); } if (traceWait) { TraceOps.DebugTrace(String.Format( "WaitForSingleHandle: exited, waitHandle = {0}, " + "milliseconds = {1}, userInterface = {2}, " + "returnValue = {3}, code = {4}, error = {5}", FormatOps.DisplayWaitHandle(waitHandle), milliseconds, userInterface, returnValue, code, FormatOps.WrapOrNull( true, true, error)), typeof(WindowOps).Name, TracePriority.NativeDebug); } return(code); }
/////////////////////////////////////////////////////////////////////// internal bool ResetValue( Interpreter interpreter, string key, bool zero ) { #if !MONO && NATIVE && WINDOWS object value; if (zero && (key != null) && TryGetValue(key, out value)) { if ((value is string) && (interpreter != null) && interpreter.HasZeroString()) { ReturnCode zeroCode; Result zeroError = null; zeroCode = StringOps.ZeroString( (string)value, ref zeroError); if (zeroCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, zeroCode, zeroError); } } } #endif if (key == null) { return(false); } return(Remove(key)); }
/////////////////////////////////////////////////////////////////////// #region Private Methods private void AddRange( IClientData clientData, TraceFlags traceFlags, IPlugin plugin, IEnumerable <TraceCallback> collection ) { foreach (TraceCallback item in collection) { if (item != null) { Result error = null; ITrace trace = ScriptOps.NewCoreTrace( item, clientData, traceFlags, plugin, ref error); if (trace != null) { this.Add(trace); } else { DebugOps.Complain(ReturnCode.Error, error); } } } }
/////////////////////////////////////////////////////////////////////// #region Debugger Interpreter Support Methods #if DEBUGGER public static Interpreter CreateInterpreter( string culture, CreateFlags createFlags, InitializeFlags initializeFlags, ScriptFlags scriptFlags, InterpreterFlags interpreterFlags, AppDomain appDomain, IHost host, string libraryPath, StringList autoPathList ) { Result result = null; Interpreter interpreter = CreateInterpreter( culture, createFlags, initializeFlags, scriptFlags, interpreterFlags, appDomain, host, libraryPath, autoPathList, ref result); if (interpreter == null) { DebugOps.Complain(interpreter, ReturnCode.Error, result); } return(interpreter); }
/////////////////////////////////////////////////////////////////////// #region Public Constructors public Debugger( bool isolated, string culture, CreateFlags createFlags, InitializeFlags initializeFlags, ScriptFlags scriptFlags, InterpreterFlags interpreterFlags, AppDomain appDomain, IHost host, string libraryPath, StringList autoPathList ) { interpreter = isolated ? DebuggerOps.CreateInterpreter( culture, createFlags, initializeFlags, scriptFlags, interpreterFlags, appDomain, host, libraryPath, autoPathList) : null; ReturnCode code; Result error = null; code = Initialize(ref error); if (code != ReturnCode.Ok) { DebugOps.Complain(interpreter, code, error); } }
/////////////////////////////////////////////////////////////////////// private /* protected virtual */ void Dispose( bool disposing ) { lock (syncRoot) /* TRANSACTIONAL */ { if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// // // NOTE: Get rid of the module file name. // fileName = null; // // NOTE: Get rid of other stuff... // clientData = null; description = null; // // NOTE: We do not own the interpreter, just // clear our reference to it. // interpreter = null; } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// ReturnCode unloadCode; Result unloadError = null; unloadCode = PrivateUnload(ref unloadError); if (unloadCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, unloadCode, unloadError); } // // NOTE: This object is now disposed. // disposed = true; } } }
/////////////////////////////////////////////////////////////////////// public IStringList ToList( string pattern, bool empty, bool noCase ) { StringPairList inputList; StringPairList outputList = new StringPairList(); if (empty) { inputList = this; } else { inputList = new StringPairList(); foreach (IPair <string> element in this) { if (element == null) { continue; } if (String.IsNullOrEmpty(element.X) && String.IsNullOrEmpty(element.Y)) { continue; } inputList.Add(element); } } ReturnCode code; Result error = null; code = GenericOps <IPair <string> > .FilterList( inputList, outputList, Index.Invalid, Index.Invalid, ToStringFlags.None, pattern, noCase, ref error); if (code != ReturnCode.Ok) { DebugOps.Complain(code, error); // // TODO: Return null in the error case here? // outputList = null; } return(outputList); }
/////////////////////////////////////////////////////////////////////// #region Private Download Event Handlers #region Download Data Event Handlers private static void DownloadDataAsyncCompleted( object sender, DownloadDataCompletedEventArgs e ) { try { if (e == null) { return; } ICallback callback = e.UserState as ICallback; if (callback == null) { return; } Uri uri = null; IClientData clientData = callback.ClientData; if (clientData != null) { IAnyPair <WebClient, Uri> anyPair = clientData.Data as IAnyPair <WebClient, Uri>; if (anyPair != null) { WebClient webClient = anyPair.X; if (webClient != null) { webClient.Dispose(); webClient = null; } uri = anyPair.Y; } clientData.Data = null; } /* NO RESULT */ callback.FireEventHandler(sender, e, GetAsyncCompletedArguments( uri, null, null, null, null, e)); } catch (Exception ex) { DebugOps.Complain(ReturnCode.Error, ex); } }
/////////////////////////////////////////////////////////////////////// #region Background Error Reporter private static void ReportBackgroundError( Interpreter interpreter, string handlerName, string description0, string description1, ReturnCode code1, Result result1, int errorLine1, string description2, ReturnCode code2, Result result2, int errorLine2 ) { bool[] haveDescription = { !String.IsNullOrEmpty(description0), !String.IsNullOrEmpty(description1), !String.IsNullOrEmpty(description2) }; Result bgReport = String.Concat( haveDescription[0] ? String.Format(description0, FormatOps.WrapOrNull(handlerName)) : String.Empty, haveDescription[0] ? Environment.NewLine : String.Empty, haveDescription[1] ? String.Format("{0}{1}: {2}", haveDescription[0] ? BackgroundErrorDetailIndent : String.Empty, description1, ResultOps.Format(code1, result1, errorLine1, false, true)) : String.Empty, haveDescription[1] ? Environment.NewLine : String.Empty, haveDescription[2] ? String.Format("{0}{1}: {2}", haveDescription[0] ? BackgroundErrorDetailIndent : String.Empty, description2, ResultOps.Format(code2, result2, errorLine2, false, true)) : String.Empty, haveDescription[2] ? Environment.NewLine : String.Empty); // // TODO: Something else here as well? // if ((bgReport != null) && !String.IsNullOrEmpty(bgReport)) { DebugOps.Complain(interpreter, code2, bgReport); } }
/////////////////////////////////////////////////////////////////////// #region Unsetting (Write) Values public static void UnsetAppSetting( string name /* in */ ) { Result error = null; if (!TryUnsetAppSetting(name, ref error)) { bool noComplain = GetNoComplain(ConfigurationOperation.Unset); if (!noComplain) { DebugOps.Complain(ReturnCode.Error, error); } } }
/////////////////////////////////////////////////////////////////////// private void AfterNameChange( string oldName, bool global ) { // // HACK: The qualified name of the global namespace cannot be // changed; however, we let the local name be changed. // if (!global) { ResetQualifiedName(); // // NOTE: For the rest of the steps in here, we want to make // sure that the name is actually different now. // if (!NamespaceOps.IsSame(oldName, name)) { // // HACK: Next, force all child namespaces to recompute // their qualified names as well. // ResetChildNames(null, true); // // HACK: Finally, "notify" the parent namespace that our // name has been changed (i.e. so it can update its // list of children). // if (parent != null) { ReturnCode renameCode; Result renameError = null; renameCode = parent.RenameChild( oldName, name, ref renameError); if (renameCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, renameCode, renameError); } } } } }
/////////////////////////////////////////////////////////////////////// #region Private Methods internal void ResetValue( Interpreter interpreter, bool zero ) { #if !MONO && NATIVE && WINDOWS if (zero && (value is string) && (interpreter != null) && interpreter.HasZeroString()) { ReturnCode zeroCode; Result zeroError = null; zeroCode = StringOps.ZeroString( (string)value, ref zeroError); if (zeroCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, zeroCode, zeroError); } } #endif value = null; #if CACHE_RESULT_TOSTRING #if !MONO && NATIVE && WINDOWS if (zero && (@string != null) && (interpreter != null) && interpreter.HasZeroString()) { ReturnCode zeroCode; Result zeroError = null; zeroCode = StringOps.ZeroString( @string, ref zeroError); if (zeroCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, zeroCode, zeroError); } } #endif @string = null; #endif }
/////////////////////////////////////////////////////////////////////// public static IntPtr GetHandle( EventWaitHandle @event ) { if (@event != null) { try { return(@event.Handle); } catch (Exception e) { DebugOps.Complain(ReturnCode.Error, e); } } return(IntPtr.Zero); }
/////////////////////////////////////////////////////////////////////// #region Private Methods internal void ResetValue( Interpreter interpreter, bool zero ) { #if !MONO && NATIVE && WINDOWS if (zero && (interpreter != null) && interpreter.HasZeroString()) { if (value is string) { ReturnCode zeroCode; Result zeroError = null; zeroCode = StringOps.ZeroString( (string)value, ref zeroError); if (zeroCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, zeroCode, zeroError); } } else if (value is Argument) { ((Argument)value).ResetValue(interpreter, zero); } else if (value is Result) { ((Result)value).ResetValue(interpreter, zero); } } #endif value = null; if (arrayValue != null) { arrayValue.ResetValue(interpreter, zero); arrayValue = null; } }
/////////////////////////////////////////////////////////////////////// internal void ResetValue( Interpreter interpreter, bool zero ) { #if !MONO && NATIVE && WINDOWS if (zero && (interpreter != null) && interpreter.HasZeroString()) { foreach (KeyValuePair <string, object> pair in this) { object value = pair.Value; if (value is string) { ReturnCode zeroCode; Result zeroError = null; zeroCode = StringOps.ZeroString( (string)value, ref zeroError); if (zeroCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, zeroCode, zeroError); } } else if (value is Argument) { ((Argument)value).ResetValue(interpreter, zero); } else if (value is Result) { ((Result)value).ResetValue(interpreter, zero); } } } #endif Clear(); }
/////////////////////////////////////////////////////////////////////// public static string GetAppSetting( string name, /* in */ string @default /* in */ ) { string value = null; Result error = null; if (!TryGetAppSetting(name, out value, ref error)) { bool noComplain = GetNoComplain(ConfigurationOperation.Get); if (!noComplain) { DebugOps.Complain(ReturnCode.Error, error); } return(@default); } return(value); }
/////////////////////////////////////////////////////////////////////// #region Upload Values Event Handlers private static void UploadValuesAsyncCompleted( object sender, UploadValuesCompletedEventArgs e ) { try { if (e == null) { return; } ICallback callback = e.UserState as ICallback; if (callback == null) { return; } Uri uri = null; string method = null; NameValueCollection collection = null; IClientData clientData = callback.ClientData; if (clientData != null) { IAnyTriplet <WebClient, Uri, IAnyPair <string, NameValueCollection> > anyTriplet = clientData.Data as IAnyTriplet <WebClient, Uri, IAnyPair <string, NameValueCollection> >; if (anyTriplet != null) { WebClient webClient = anyTriplet.X; if (webClient != null) { webClient.Dispose(); webClient = null; } uri = anyTriplet.Y; IAnyPair <string, NameValueCollection> anyPair = anyTriplet.Z; if (anyPair != null) { method = anyPair.X; collection = anyPair.Y; } } clientData.Data = null; } /* NO RESULT */ callback.FireEventHandler(sender, e, GetAsyncCompletedArguments( uri, method, null, collection, null, e)); } catch (Exception ex) { DebugOps.Complain(ReturnCode.Error, ex); } }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-nocommands", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-nofunctions", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-nopolicies", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-notraces", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-noprovide", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-noresources", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-verifiedonly", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-trustedonly", null), #if ISOLATED_PLUGINS new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-noisolated", null), #else new Option(null, OptionFlags.Unsafe | OptionFlags.Unsupported, Index.Invalid, Index.Invalid, "-noisolated", null), #endif new Option(null, OptionFlags.MustHaveObjectValue, Index.Invalid, Index.Invalid, "-clientdata", null), new Option(null, OptionFlags.MustHaveObjectValue, Index.Invalid, Index.Invalid, "-data", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { // // NOTE: There should be a minimum of one and a maximum // of three arguments after the final option. // if ((argumentIndex != Index.Invalid) && ((argumentIndex + 3) >= arguments.Count)) { string path = ((argumentIndex + 2) < arguments.Count) ? (string)arguments[argumentIndex + 2] : String.Empty; Interpreter slaveInterpreter = null; code = interpreter.GetNestedSlaveInterpreter( path, LookupFlags.Interpreter, false, ref slaveInterpreter, ref result); if (code == ReturnCode.Ok) { Variant value = null; IClientData localClientData = clientData; if (options.IsPresent("-clientdata", ref value)) { IObject @object = (IObject)value.Value; if ((@object.Value == null) || (@object.Value is IClientData)) { localClientData = (IClientData)@object.Value; } else { result = "option value has invalid clientData"; code = ReturnCode.Error; } } if (code == ReturnCode.Ok) { if (options.IsPresent("-data", ref value)) { IObject @object = (IObject)value.Value; if (@object != null) { localClientData = _Public.ClientData.WrapOrReplace( localClientData, @object.Value); } else { result = "option value has invalid data"; code = ReturnCode.Error; } } if (code == ReturnCode.Ok) { // // NOTE: All plugins loaded by this command are considered // as having been loaded "on demand". // PluginFlags pluginFlags = PluginFlags.Demand; // // NOTE: Add the plugin flags for the target interpreter. // pluginFlags |= slaveInterpreter.PluginFlags; #if ISOLATED_PLUGINS // // NOTE: Disable loading this plugin into an isolated // application domain (i.e. load it into the default // application domain for the target interpreter). // if (options.IsPresent("-noisolated")) { pluginFlags &= ~PluginFlags.Isolated; } #endif if (options.IsPresent("-nocommands")) { pluginFlags |= PluginFlags.NoCommands; } if (options.IsPresent("-nofunctions")) { pluginFlags |= PluginFlags.NoFunctions; } if (options.IsPresent("-nopolicies")) { pluginFlags |= PluginFlags.NoPolicies; } if (options.IsPresent("-notraces")) { pluginFlags |= PluginFlags.NoTraces; } if (options.IsPresent("-noprovide")) { pluginFlags |= PluginFlags.NoProvide; } if (options.IsPresent("-noresources")) { pluginFlags |= PluginFlags.NoResources; } if (options.IsPresent("-verifiedonly")) { pluginFlags |= PluginFlags.VerifiedOnly; } if (options.IsPresent("-trustedonly")) { pluginFlags |= PluginFlags.TrustedOnly; } string fileName = PathOps.ResolveFullPath( interpreter, arguments[argumentIndex]); if (!String.IsNullOrEmpty(fileName)) { string typeName = null; if ((argumentIndex + 1) < arguments.Count) { typeName = arguments[argumentIndex + 1]; } IPlugin plugin = null; long token = 0; try { code = slaveInterpreter.LoadPlugin( fileName, #if CAS_POLICY null, null, AssemblyHashAlgorithm.None, #endif typeName, localClientData, pluginFlags, ref plugin, ref result); if (code == ReturnCode.Ok) { code = slaveInterpreter.AddPlugin( plugin, localClientData, ref token, ref result); } } finally { if (code != ReturnCode.Ok) { if (token != 0) { // // NOTE: Terminate and remove the plugin now. // This does not unload the associated // AppDomain, if any. // ReturnCode removeCode; Result removeResult = null; removeCode = slaveInterpreter.RemovePlugin( token, localClientData, ref removeResult); if (removeCode != ReturnCode.Ok) { DebugOps.Complain( slaveInterpreter, removeCode, removeResult); } } if (plugin != null) { // // NOTE: Unload the plugin. This basically does // "nothing" unless the plugin was isolated. // In that case, it unloads the associated // AppDomain. // ReturnCode unloadCode; Result unloadResult = null; unloadCode = slaveInterpreter.UnloadPlugin( plugin, localClientData, pluginFlags | PluginFlags.SkipTerminate, ref unloadResult); if (unloadCode != ReturnCode.Ok) { DebugOps.Complain( slaveInterpreter, unloadCode, unloadResult); } } } } } else { result = "invalid file name"; code = ReturnCode.Error; } } } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"load ?options? fileName ?packageName? ?interp?\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"load ?options? fileName ?packageName? ?interp?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { if (interpreter == null) { result = "invalid interpreter"; return(ReturnCode.Error); } if (arguments == null) { result = "invalid argument list"; return(ReturnCode.Error); } if (arguments.Count < 2) { result = "wrong # args: should be \"uplevel ?level? arg ?arg ...?\""; return(ReturnCode.Error); } ReturnCode code; int currentLevel = 0; code = interpreter.GetInfoLevel( CallFrameOps.InfoLevelSubCommand, ref currentLevel, ref result); if (code != ReturnCode.Ok) { return(code); } bool mark = false; bool absolute = false; bool super = false; int level = 0; ICallFrame currentFrame = null; ICallFrame otherFrame = null; FrameResult frameResult = interpreter.GetCallFrame( arguments[1], ref mark, ref absolute, ref super, ref level, ref currentFrame, ref otherFrame, ref result); if (frameResult == FrameResult.Invalid) { return(ReturnCode.Error); } int argumentIndex = ((int)frameResult + 1); // // BUGFIX: The argument count needs to be checked again here. // if (argumentIndex >= arguments.Count) { result = "wrong # args: should be \"uplevel ?level? arg ?arg ...?\""; return(ReturnCode.Error); } if (mark) { code = CallFrameOps.MarkMatching( interpreter.CallStack, interpreter.CurrentFrame, absolute, level, CallFrameFlags.Variables, CallFrameFlags.Invisible | CallFrameFlags.NoVariables, CallFrameFlags.Invisible, false, false, true, ref result); } if (code == ReturnCode.Ok) { try { string name = StringList.MakeList("uplevel", arguments[1]); ICallFrame newFrame = interpreter.NewUplevelCallFrame( name, currentLevel, CallFrameFlags.None, mark, currentFrame, otherFrame); ICallFrame savedFrame = null; interpreter.PushUplevelCallFrame( currentFrame, newFrame, true, ref savedFrame); if ((argumentIndex + 1) >= arguments.Count) { code = interpreter.EvaluateScript( arguments[argumentIndex], ref result); } else { code = interpreter.EvaluateScript( arguments, argumentIndex, ref result); } if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (\"uplevel\" body line {1})", Environment.NewLine, Interpreter.GetErrorLine(interpreter))); } // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopUplevelCallFrame( currentFrame, newFrame, ref savedFrame); } finally { if (mark) { // // NOTE: We should not get an error at this point from // unmarking the call frames; however, if we do get // one, we need to complain loudly about it because // that means the interpreter state has probably been // corrupted somehow. // ReturnCode markCode; Result markResult = null; markCode = CallFrameOps.MarkMatching( interpreter.CallStack, interpreter.CurrentFrame, absolute, level, CallFrameFlags.Variables, CallFrameFlags.NoVariables, CallFrameFlags.Invisible, false, false, false, ref markResult); if (markCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, markCode, markResult); } } } } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 1) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-force", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-fail", null), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-message", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-current", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 1) { code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if ((argumentIndex == Index.Invalid) || ((argumentIndex + 1) == arguments.Count)) { bool force = false; if (options.IsPresent("-force")) { force = true; } bool fail = false; if (options.IsPresent("-fail")) { fail = true; } Variant value = null; string message = null; if (options.IsPresent("-message", ref value)) { message = value.ToString(); } // // NOTE: The default exit code is "success" (i.e. zero). // ExitCode exitCode = ResultOps.SuccessExitCode(); if (options.IsPresent("-current")) { exitCode = interpreter.ExitCode; } // // NOTE: Was an exit code specified in the command? // if (argumentIndex != Index.Invalid) { object enumValue = EnumOps.TryParseEnum( typeof(ExitCode), arguments[argumentIndex], true, true, ref result); if (enumValue is ExitCode) { exitCode = (ExitCode)enumValue; } else { result = ScriptOps.BadValue( null, "exit code", arguments[argumentIndex], Enum.GetNames(typeof(ExitCode)), null, ", or an integer"); code = ReturnCode.Error; } } // // NOTE: Make sure we succeeded at coverting the exit code to an integer. // if (code == ReturnCode.Ok) { // // NOTE: Make sure the interpreter host, if any, agrees to exit (i.e. it may deny the // request if the application is doing something that should not be interrupted). // code = interpreter.CanExit(exitCode, force, fail, message, ref result); if (code == ReturnCode.Ok) { // // NOTE: Exit the application (either by marking the current interpreter as "exited" // or physically exiting the containing process). // TraceOps.DebugTrace(String.Format( "Execute: {0}, interpreter = {1}, message = {2}", force && fail ? "forcibly failing" : force ? "forcibly exiting" : "exiting", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(message)), typeof(Exit).Name, TracePriority.Command); if (force) { #if !MONO if (fail && !CommonOps.Runtime.IsMono()) { try { // // NOTE: Using this method to exit a script is NOT recommended unless // you are trying to prevent damaging another part of the system. // // MONO: This method is not supported by the Mono runtime. // Environment.FailFast(message); /* NOT REACHED */ result = "failed to exit process"; code = ReturnCode.Error; } catch (Exception e) { result = e; code = ReturnCode.Error; } } else #endif { // // BUGFIX: Try to dispose our containing interpreter now. We must do // this to prevent it from being disposed on a random GC thread. // try { interpreter.Dispose(); interpreter = null; } catch (Exception e) { result = e; code = ReturnCode.Error; } // // NOTE: If we could not dispose the interpreter properly, complain; // however, keep exiting anyway. // if (code != ReturnCode.Ok) { DebugOps.Complain(interpreter, code, result); } try { // // NOTE: Using this method to exit a script is NOT recommended unless // you are running a standalone script in the Eagle Shell (i.e. // you are not hosted within another application). // Environment.Exit((int)exitCode); /* NOT REACHED */ result = "failed to exit process"; code = ReturnCode.Error; } catch (Exception e) { result = e; code = ReturnCode.Error; } } } else { interpreter.ExitCode = exitCode; interpreter.Exit = true; result = String.Empty; code = ReturnCode.Ok; } } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"exit ?options? ?returnCode?\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"exit ?options? ?returnCode?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region Upload File Event Handlers private static void UploadFileAsyncCompleted( object sender, UploadFileCompletedEventArgs e ) { try { if (e == null) { return; } ICallback callback = e.UserState as ICallback; if (callback == null) { return; } Uri uri = null; string method = null; string fileName = null; IClientData clientData = callback.ClientData; if (clientData != null) { IAnyTriplet <WebClient, Uri, IAnyPair <string, string> > anyTriplet = clientData.Data as IAnyTriplet <WebClient, Uri, IAnyPair <string, string> >; if (anyTriplet != null) { WebClient webClient = anyTriplet.X; if (webClient != null) { webClient.Dispose(); webClient = null; } uri = anyTriplet.Y; IAnyPair <string, string> anyPair = anyTriplet.Z; if (anyPair != null) { method = anyPair.X; fileName = anyPair.Y; } } clientData.Data = null; } ReturnCode code; Result result = null; code = callback.Invoke( GetAsyncCompletedArguments( uri, method, null, null, fileName, e), ref result); if (code != ReturnCode.Ok) { DebugOps.Complain(code, result); } } catch (Exception ex) { DebugOps.Complain(ReturnCode.Error, ex); } }
/////////////////////////////////////////////////////////////////////// public static ReturnCode UploadDataAsync( Interpreter interpreter, IClientData clientData, StringList arguments, CallbackFlags callbackFlags, Uri uri, string method, byte[] rawData, ref Result error ) { TraceOps.DebugTrace(String.Format( "UploadDataAsync: interpreter = {0}, clientData = {1}, " + "arguments = {2}, callbackFlags = {3}, uri = {4}, " + "method = {5}, rawData = {6}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(clientData), FormatOps.WrapOrNull(true, true, arguments), FormatOps.WrapOrNull(callbackFlags), FormatOps.WrapOrNull(uri), FormatOps.WrapOrNull(method), FormatOps.WrapOrNull(rawData)), typeof(WebOps).Name, TracePriority.NetworkDebug); ReturnCode code = ReturnCode.Ok; WebClient webClient = null; try { ICallback callback = CommandCallback.Create( MarshalFlags.Default, callbackFlags, ObjectFlags.Callback, ByRefArgumentFlags.None, interpreter, null, null, arguments, ref error); if (callback != null) { try { Result localError = null; webClient = CreateClient( interpreter, "UploadDataAsync", clientData, ref localError); if (webClient != null) { callback.ClientData = new ClientData( new AnyTriplet <WebClient, Uri, IAnyPair <string, byte[]> >( webClient, uri, new AnyPair <string, byte[]>(method, rawData))); webClient.UploadDataCompleted += new UploadDataCompletedEventHandler( UploadDataAsyncCompleted); /* NO RESULT */ webClient.UploadDataAsync( uri, method, rawData, callback); } else if (localError != null) { error = localError; code = ReturnCode.Error; } else { error = "could not create web client"; code = ReturnCode.Error; } } catch (Exception e) { error = e; code = ReturnCode.Error; } } else { code = ReturnCode.Error; } } finally { if ((code != ReturnCode.Ok) && (webClient != null)) { ReturnCode disposeCode; Result disposeError = null; disposeCode = ObjectOps.TryDispose( webClient, ref disposeError); if (disposeCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, disposeCode, disposeError); } } } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// private /* protected virtual */ void Dispose( bool disposing ) /* throw */ { TraceOps.DebugTrace(String.Format( "Dispose: called, disposing = {0}, disposed = {1}", disposing, disposed), typeof(TclBridge).Name, TracePriority.CleanupDebug); if (!disposed) { if (!this.disposing) { // // NOTE: We are now disposing this object (prevent re-entrancy). // this.disposing = true; // // NOTE: This method should not normally throw; however, if it does // we do not want our disposing flag to be stuck set to true. // try { //if (disposing) //{ // //////////////////////////////////// // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// // // NOTE: If necessary (and possible), delete the Tcl command via the // token we saved earlier (when the Tcl command was created). // ReturnCode deleteCode = ReturnCode.Ok; Result deleteError = null; // // NOTE: If we have a valid command token then we are still hooked to // Tcl via our inbound native delegates and we must unhook // successfully or throw to prevent our internal object state // from being made inconsistent. // if (token != IntPtr.Zero) { if (interpreter != null) { ITclApi tclApi = TclApi.GetTclApi(interpreter); // // BUGFIX: We want to force deletion of this bridged command // if the force flag was specified upon creation OR // if the command is not actively being used. // deleteCode = TclWrapper.DeleteCommandFromToken( tclApi, interp, forceDelete || (objCmdProcLevels == 0), ref token, ref deleteError); } else { deleteError = "invalid interpreter"; deleteCode = ReturnCode.Error; } } // // NOTE: Did we succeed in deleting the command from Tcl, if it // was necessary? // if (!noComplain && (deleteCode != ReturnCode.Ok)) { // // NOTE: If the command deletion was necessary and it failed // for any reason, complain very loudly. // DebugOps.Complain(interpreter, deleteCode, deleteError); // // BUGFIX: Also, we must throw an exception here to prevent // the delegates from being disposed while Tcl still // refers to them (tclLoad-1.2 GC race). // throw new ScriptException(deleteCode, deleteError); } // // NOTE: If necessary, release the GCHandle that is keeping this // object alive. // if (handle.IsAllocated) { handle.Free(); } // // NOTE: We do not own these objects; therefore, we just null out // the references to them (in case we are the only thing // keeping them alive). // interpreter = null; execute = null; clientData = null; // // NOTE: Zero out our Tcl interpreter. We do not delete it because // we do not own it. // interp = IntPtr.Zero; // // NOTE: Zero out our created Tcl command token. We should not need // to call Tcl to delete the actual command because by this time // it should already have been deleted. // token = IntPtr.Zero; // // NOTE: Finally, we should be able to safely remove our references // to the Tcl callback delegates at this point because we already // deleted the Tcl command related to them. // objCmdProc = null; cmdDeleteProc = null; // // NOTE: Zero out our command nesting level. // objCmdProcLevels = 0; // // NOTE: This object is now disposed. // disposed = true; } finally { // // NOTE: We are no longer disposing this object. // this.disposing = false; } } } }
/////////////////////////////////////////////////////////////////////// private /* protected virtual */ void Dispose( bool disposing ) { lock (syncRoot) /* TRANSACTIONAL */ { if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// // // NOTE: Get rid of our type references. // returnType = null; parameterTypes = null; type = null; // // NOTE: Get rid of the native function name and // address we looked up previously, if any. // functionName = null; address = IntPtr.Zero; // // NOTE: Get rid of other stuff... // name = null; clientData = null; description = null; // // NOTE: Get rid of the delegate object itself. // @delegate = null; } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// // // NOTE: Finally, unload our underlying native module. // if (module != null) { ReturnCode unloadCode; Result unloadError = null; unloadCode = UnloadModule( ref moduleLoaded, ref unloadError); if (unloadCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, unloadCode, unloadError); } module = null; } // // NOTE: We do not own the interpreter, just clear our // reference to it. // interpreter = null; // // NOTE: This object is now disposed. // disposed = true; } } }
/////////////////////////////////////////////////////////////////////// public static string GetPath( Interpreter interpreter, /* OPTIONAL */ Assembly assembly ) /* CANNOT RETURN NULL */ { // // NOTE: Fetch the base directory for the current application // domain. This will be used to check if the candidate // assembly paths are underneath it. It is now possible // to override the value used here via the environment. // string path0 = GetAnchorPath(); if (path0 == null) { path0 = GlobalState.GetAppDomainBaseDirectory(); } // // NOTE: First, try to use the current path to the assembly, // checking to make sure that it resides underneath the // base directory for the application domain. // string path1 = GetCurrentPath(assembly); if (PathOps.IsUnderPath(interpreter, path1, path0)) { return(path1); } // // NOTE: Second, try to use the original path to the assembly, // checking to make sure that it resides underneath the // base directory for the application domain. // string path2 = GetOriginalPath(assembly); if (PathOps.IsUnderPath(interpreter, path2, path0)) { return(path2); } // // NOTE: At this point, we have failed to figure out a path for // this assembly that actually resides within the current // application domain. This condition is not impossible; // however, it should not happen for the core library // assembly itself. // DebugOps.Complain(interpreter, ReturnCode.Error, String.Format( "could not determine a path for assembly {1} underneath " + "the application domain path {0}", FormatOps.DisplayPath( path0), FormatOps.DisplayAssemblyName(assembly))); // // NOTE: This method cannot return null; therefore, the legacy // return value will be used instead (i.e. the current // path to the assembly). // return(path1); }
/////////////////////////////////////////////////////////////////////// private /* protected virtual */ void Dispose( bool disposing ) { if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// if (children != null) { foreach (INamespace child in children.Values) { if (child == null) { continue; } IDisposable disposable = child as IDisposable; if (disposable != null) { disposable.Dispose(); disposable = null; } } children.Clear(); children = null; } /////////////////////////////////////////////////////////// if (exportNames != null) { exportNames.Clear(); exportNames = null; } /////////////////////////////////////////////////////////// if (imports != null) { ReturnCode removeCode; Result removeError = null; removeCode = RemoveImports( null, false, ref removeError); if (removeCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, removeCode, removeError); } imports.Clear(); imports = null; } /////////////////////////////////////////////////////////// if (interpreter != null) { interpreter = null; /* NOT OWNED */ } /////////////////////////////////////////////////////////// parent = null; /* NOT OWNED */ resolve = null; /* NOT OWNED */ /////////////////////////////////////////////////////////// if (variableFrame != null) { variableFrame.Free(true); variableFrame = null; } /////////////////////////////////////////////////////////// unknown = null; /////////////////////////////////////////////////////////// qualifiedName = null; referenceCount = 0; deleted = false; /////////////////////////////////////////////////////////// kind = IdentifierKind.None; id = Guid.Empty; name = null; group = null; description = null; clientData = null; } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// disposed = true; } }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { // // try {<tryBody>} // [finally {<finallyBody>}] // if ((arguments.Count == 2) || (arguments.Count == 4)) { if ((arguments.Count < 3) || (String.Compare(arguments[2], Try.Finally, StringOps.SystemStringComparisonType) == 0)) { string name = StringList.MakeList("try"); ICallFrame frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Try); interpreter.PushAutomaticCallFrame(frame); ReturnCode tryCode; Result tryResult = null; tryCode = interpreter.EvaluateScript(arguments[1], ref tryResult); if (tryCode == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, tryResult, String.Format("{0} (\"try\" body line {1})", Environment.NewLine, Interpreter.GetErrorLine(interpreter))); } // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); Result finallyResult = null; ReturnCode finallyCode = ReturnCode.Ok; if (arguments.Count == 4) { name = StringList.MakeList("finally"); frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Finally); interpreter.PushAutomaticCallFrame(frame); // // BUGFIX: Preserve any and all existing error related // information during evaluation of the finally // block. // Engine.SetNoResetError(interpreter, true); // // NOTE: If there was an error during the try block as well, // keep them somewhat organized in the final error // information. // if (tryCode == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, null, String.Format("{0} ... continued ...", Environment.NewLine)); } // // NOTE: If the appropriate flag is set, call into the // Engine.ResetCancel method (with "force" enabled) // prior to evaluating the finally block script. // It should be noted here that even though the // return code of this call is checked by the code, // it basically cannot fail at this point. // Result canceledResult = null; bool canceled = false; bool unwound = false; bool resetCancel = false; // // NOTE: If the appropriate flag is set, reset the Exit // property prior to evaluating the finally block // script. // bool exit = false; bool resetExit = false; try { if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyResetCancel, true)) { ReturnCode resetCode; Result resetError = null; resetCode = Engine.ResetCancel( interpreter, CancelFlags.TryBlock, ref canceledResult, ref canceled, ref unwound, ref resetCancel, ref resetError); if (resetCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, resetCode, resetError); } } if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyResetExit, true)) { exit = interpreter.Exit; if (exit) { interpreter.Exit = false; resetExit = true; } } ReturnCode timeoutCode; Result timeoutResult = null; timeoutCode = Interpreter.StartFinallyTimeoutThread( interpreter, false, true, ref timeoutResult); if (timeoutCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, timeoutCode, timeoutResult); } try { // // NOTE: Evaluate the finally block. // finallyCode = interpreter.EvaluateScript( arguments[3], ref finallyResult); } finally { timeoutCode = Interpreter.InterruptFinallyTimeoutThread( interpreter, false, ref timeoutResult); if (timeoutCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, timeoutCode, timeoutResult); } } } finally { if (exit && resetExit) { if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyRestoreExit, true)) { interpreter.Exit = true; } } if ((canceled || unwound) && resetCancel) { if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyRestoreCancel, true)) { CancelFlags cancelFlags = CancelFlags.FinallyBlock; if (unwound) { cancelFlags |= CancelFlags.Unwind; } ReturnCode cancelCode; Result cancelError = null; cancelCode = Engine.CancelEvaluate( interpreter, canceledResult, cancelFlags, ref cancelError); if (cancelCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, cancelCode, cancelError); } } } } if (finallyCode == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, finallyResult, String.Format("{0} (\"finally\" body line {1})", Environment.NewLine, Interpreter.GetErrorLine(interpreter))); } // // NOTE: Restore normal result reset semantics. // Engine.SetNoResetError(interpreter, false); // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); } // // NOTE: Initially, the overall command return code and result // is that of the try block; however, if the finally block // fails, that will be the return code and result. // if (finallyCode == ReturnCode.Ok) { result = tryResult; code = tryCode; } else { result = finallyResult; code = finallyCode; } } else { result = String.Format( "expected \"finally\" but got \"{0}\"", arguments[2]); code = ReturnCode.Error; } } else { result = "wrong # args: should be \"try script ?finally script?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; return(ReturnCode.Error); } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region Public Web Upload Methods #region Upload Data Methods public static ReturnCode UploadData( Interpreter interpreter, IClientData clientData, Uri uri, string method, byte[] rawData, bool trusted, ref byte[] bytes, ref Result error ) { bool wasTrusted = UpdateOps.IsTrusted(); TraceOps.DebugTrace(String.Format( "UploadData: interpreter = {0}, clientData = {1}, " + "uri = {2}, method = {3}, rawData = {4}, trusted = {5}, " + "wasTrusted = {6}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(clientData), FormatOps.WrapOrNull(uri), FormatOps.WrapOrNull(method), FormatOps.WrapOrNull(rawData), trusted, wasTrusted), typeof(WebOps).Name, TracePriority.NetworkDebug); ReturnCode code = trusted ? wasTrusted ? ReturnCode.Ok : UpdateOps.SetTrusted(trusted, ref error) : ReturnCode.Ok; if (code == ReturnCode.Ok) { try { try { Result localError = null; using (WebClient webClient = CreateClient( interpreter, "UploadData", clientData, ref localError)) { if (webClient != null) { bytes = webClient.UploadData( uri, method, rawData); return(ReturnCode.Ok); } else if (localError != null) { error = localError; } else { error = "could not create web client"; } } } catch (Exception e) { error = e; } } finally { if (trusted && !wasTrusted) { ReturnCode untrustCode; Result untrustError = null; untrustCode = UpdateOps.SetTrusted( false, ref untrustError); if (untrustCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, untrustCode, untrustError); } } } } return(ReturnCode.Error); }