edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Driver.cs;C1597865 File: Driver.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Driver.cs;C1597865 (server) 2/26/2010 5:26 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Driver.cs;RbHAPI @@ -30,6 +30,7 @@ using System.Text; using System.Globalization; using System.Threading; +using Microsoft.Scripting.Hosting.Providers; namespace IronRuby.Tests { public class TestCase { @@ -89,7 +90,7 @@ _runtime = Ruby.CreateRuntime(runtimeSetup); _engine = Ruby.GetEngine(_runtime); - _context = Ruby.GetExecutionContext(_engine); + _context = (RubyContext)HostingHelpers.GetLanguageContext(_engine); } } @@ -339,7 +340,7 @@ int status = 0; if (_runTokenizerDriver) { - TokenizerTestDriver driver = new TokenizerTestDriver(Ruby.GetExecutionContext(Ruby.CreateRuntime())); + TokenizerTestDriver driver = new TokenizerTestDriver((RubyContext)HostingHelpers.GetLanguageContext(Ruby.CreateEngine())); if (!driver.ParseArgs(args)) { return -3; } =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C1605253 File: RubyTests.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C1605253 (server) 2/26/2010 5:31 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;RbHAPI @@ -415,6 +415,7 @@ RubyHosting2, RubyHosting3, RubyHosting4, + RubyHosting5, RubyHosting_Scopes1, CrossRuntime1, CrossRuntime2, =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ConstantTests.cs;C1426166 File: ConstantTests.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ConstantTests.cs;C1426166 (server) 2/26/2010 5:27 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ConstantTests.cs;RbHAPI @@ -16,6 +16,8 @@ using IronRuby.Builtins; using System; using System.IO; +using Microsoft.Scripting.Hosting.Providers; +using IronRuby.Runtime; namespace IronRuby.Tests { public partial class Tests { @@ -628,7 +630,7 @@ end C "); - Ruby.GetExecutionContext(engine2).DefineGlobalVariable("C", c); + ((RubyContext)HostingHelpers.GetLanguageContext(engine2)).DefineGlobalVariable("C", c); var m = engine2.Execute(@" module M =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/HostingTests.cs;C1597865 File: HostingTests.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/HostingTests.cs;C1597865 (server) 2/26/2010 5:26 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/HostingTests.cs;RbHAPI @@ -283,7 +283,7 @@ var searchPaths = Engine.GetSearchPaths(); Assert(new List(searchPaths)[searchPaths.Count - 1] == "."); - bool result = Engine.RequireRubyFile("fcntl"); + bool result = Engine.RequireFile("fcntl"); Assert(result == true); // built-in class: @@ -323,6 +323,29 @@ #endif } + [Options(NoRuntime = true)] + public void RubyHosting5() { + // app-domain creation: + if (_driver.PartialTrust) return; + + AppDomain domain = AppDomain.CreateDomain("foo"); + + var rs = ScriptRuntimeSetup.ReadConfiguration(); + LanguageSetup ls = rs.GetRubySetup(); + Debug.Assert(ls.Names.IndexOf("IronRuby") != -1); + + var newSetup = new ScriptRuntimeSetup(); + newSetup.AddRubySetup((s) => { + s.Options["Compatibility"] = RubyCompatibility.Ruby19; + s.Options["LibraryPaths"] = ls.Options["LibraryPaths"]; + }); + + ScriptRuntime runtime = ScriptRuntime.CreateRemote(domain, newSetup); + ScriptEngine engine = runtime.GetRubyEngine(); + Assert(engine.RequireFile("fcntl") == true); + Assert(engine.Execute("Object.constants.include?(:Fcntl)") == true); + } + public void RubyHosting_Scopes1() { TestOutput(@" engine = IronRuby.create_engine =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs;C1090806 File: ArrayOps.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs;C1090806 (server) 2/22/2010 5:18 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs;RbHAPI @@ -50,7 +50,6 @@ // Reinitialization. Not called when a factory/non-default ctor is called. [RubyMethod("initialize", RubyMethodAttributes.PrivateInstance)] public static RubyArray/*!*/ Reinitialize(RubyContext/*!*/ context, RubyArray/*!*/ self) { - RubyUtils.RequiresNotFrozen(context, self); self.Clear(); return self; } @@ -79,7 +78,6 @@ BlockParam block, RubyArray/*!*/ self, [NotNull]object/*!*/ arrayOrSize) { var context = toAryToInt.Context; - RubyUtils.RequiresNotFrozen(context, self); var site = toAryToInt.GetSite(CompositeConversionAction.Make(context, CompositeConversion.ToAryToInt)); var union = site.Target(site, arrayOrSize); @@ -148,7 +146,6 @@ // Reinitialization. Not called when a factory/non-default ctor is called. [RubyMethod("initialize", RubyMethodAttributes.PrivateInstance)] public static RubyArray/*!*/ ReinitializeByRepeatedValue(RubyContext/*!*/ context, RubyArray/*!*/ self, [DefaultProtocol]int size, object value) { - RubyUtils.RequiresNotFrozen(context, self); if (size < 0) { throw RubyExceptions.CreateArgumentError("negative array size"); } @@ -251,7 +248,6 @@ breakResult = null; var context = comparisonStorage.Context; - RubyUtils.RequiresNotFrozen(context, self); // TODO: this does more comparisons (and in a different order) than // Ruby's sort. Also, control flow won't work because List.Sort wraps @@ -298,7 +294,6 @@ [RubyMethod("reverse!")] public static RubyArray/*!*/ InPlaceReverse(RubyContext/*!*/ context, RubyArray/*!*/ self) { - RubyUtils.RequiresNotFrozen(context, self); self.Reverse(); return self; } =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/HashOps.cs;C1561136 File: HashOps.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/HashOps.cs;C1561136 (server) 2/22/2010 5:22 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/HashOps.cs;RbHAPI @@ -108,8 +108,7 @@ [RubyMethod("initialize_copy", RubyMethodAttributes.PrivateInstance)] public static Hash/*!*/ InitializeCopy(RubyContext/*!*/ context, Hash/*!*/ self, [NotNull]Hash/*!*/ source) { - RubyUtils.RequiresNotFrozen(context, self); - + self.Mutate(); self.DefaultProc = source.DefaultProc; self.DefaultValue = source.DefaultValue; IDictionaryOps.ReplaceData(self, source); @@ -146,7 +145,7 @@ [RubyMethod("default=")] public static object SetDefaultValue(RubyContext/*!*/ context, Hash/*!*/ self, object value) { - RubyUtils.RequiresNotFrozen(context, self); + self.Mutate(); self.DefaultProc = null; return self.DefaultValue = value; } @@ -188,8 +187,8 @@ return self; } - RubyUtils.RequiresNotFrozen(context, self); - + self.Mutate(); + Hash otherHash = other as Hash; if (otherHash != null) { self.DefaultValue = otherHash.DefaultValue; @@ -200,8 +199,8 @@ [RubyMethod("shift")] public static object Shift(CallSiteStorage>/*!*/ storage, Hash/*!*/ self) { - RubyUtils.RequiresNotFrozen(storage.Context, self); - + self.Mutate(); + if (self.Count == 0) { var site = storage.GetCallSite("default", 1); return site.Target(site, self, null); =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C1561136 File: IDictionaryOps.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C1561136 (server) 2/22/2010 5:23 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;RbHAPI @@ -455,7 +455,7 @@ [RubyMethod("replace")] public static Hash/*!*/ Replace(RubyContext/*!*/ context, Hash/*!*/ self, [DefaultProtocol, NotNull]IDictionary/*!*/ other) { - RubyUtils.RequiresNotFrozen(context, self); + self.Mutate(); return IDictionaryOps.ReplaceData(self, other); } =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.Build.csproj;C1597865 File: Ruby.Build.csproj =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.Build.csproj;C1597865 (server) 2/26/2010 6:01 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.Build.csproj;RbHAPI @@ -283,6 +283,7 @@ + =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.cs;C1221149 File: Ruby.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.cs;C1221149 (server) 2/26/2010 4:06 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.cs;RbHAPI @@ -23,6 +23,7 @@ using Microsoft.Scripting.Runtime; using IronRuby.Runtime; using IronRuby.Builtins; +using IronRuby.Hosting; using System.ComponentModel; using System; using System.Collections; @@ -35,35 +36,53 @@ #endif namespace IronRuby { - + /// + /// Implements IronRuby hosting APIs that enable embedding IronRuby in .NET application. + /// + /// + /// This class provides convenience APIs for applications that host Ruby language in a specific way. + /// Use Dynamic Language Runtime (DLR) Hosting API from namespace to implement language agnostic host, i.e. + /// a host that works with any present and future DLR based language. + /// public static class Ruby { /// /// Creates a new script runtime configured using .NET configuration files. - /// If the .NET configuration doesn't include IronRuby a default IronRuby configuration is added. + /// If the .NET configuration doesn't include IronRuby record a default IronRuby configuration is added. /// + /// A runtime that is capable of running IronRuby scripts and scripts of any other language specified in the .NET configuration files. public static ScriptRuntime/*!*/ CreateRuntime() { var setup = ScriptRuntimeSetup.ReadConfiguration(); setup.AddRubySetup(); return new ScriptRuntime(setup); } + /// + /// Creates a runtime given a runtime setup. + /// + /// The setup to use to configure the runtime. This contains all information that's needed for the runtime initialization. + /// A runtime that is capable of running scripts of languages listed in . public static ScriptRuntime/*!*/ CreateRuntime(ScriptRuntimeSetup/*!*/ setup) { return new ScriptRuntime(setup); } /// - /// Creates a new script runtime and returns its IronRuby engine. + /// Creates a new script runtime and returns its IronRuby engine configured using .NET configuration files. /// + /// A new IronRuby engine. + /// Creates a runtime using method. public static ScriptEngine/*!*/ CreateEngine() { return GetEngine(CreateRuntime()); } /// - /// Creates a new script runtime and returns its IronRuby engine configured using . + /// Creates a new script runtime and returns its IronRuby engine configured configured using .NET configuration files. /// - /// - /// If the configuration loaded from .config files already contains - /// + /// + /// A delegate that receives an instance of IronRuby's loaded from the .NET configuration + /// and can set its properties before it is used for runtime configuration. + /// If no IronRuby setup information is found in the .NET configuration a default one is created and passed to the initializer. + /// + /// A new IronRuby engine. public static ScriptEngine/*!*/ CreateEngine(Action/*!*/ setupInitializer) { ContractUtils.RequiresNotNull(setupInitializer, "setupInitializer"); @@ -81,6 +100,10 @@ /// /// Creates IronRuby setup with default language names and file extensions. /// + /// The IronRuby setup object. + /// + /// The setup options can be modified before used for a script runtime creation. + /// public static LanguageSetup/*!*/ CreateRubySetup() { return new LanguageSetup( typeof(RubyContext).AssemblyQualifiedName, @@ -90,6 +113,14 @@ ); } + /// + /// Creates a default IronRuby setup and passes it to the given delegate for initialization. + /// + /// + /// A delegate that receives a fresh instance of IronRuby's + /// and can set its properties before it is used for runtime configuration. + /// + /// The IronRuby setup object initialized by . public static LanguageSetup/*!*/ CreateRubySetup(Action/*!*/ initializer) { ContractUtils.RequiresNotNull(initializer, "initializer"); @@ -98,49 +129,20 @@ return setup; } + /// + /// Retrieves an IronRuby engine from a given script runtime. + /// + /// The runtime to get the engine from. + /// An IronRuby engine from the specified runtime. + /// + /// The is not set up to run IronRuby. + /// The doesn't contain IronRuby's . + /// public static ScriptEngine/*!*/ GetEngine(ScriptRuntime/*!*/ runtime) { ContractUtils.RequiresNotNull(runtime, "runtime"); return runtime.GetEngineByTypeName(typeof(RubyContext).AssemblyQualifiedName); } - public static bool RequireFile(ScriptEngine/*!*/ engine, string/*!*/ path) { - ContractUtils.RequiresNotNull(engine, "engine"); - ContractUtils.RequiresNotNull(path, "path"); - - return HostingHelpers.CallEngine, bool>(engine, RequireFile, - new KeyValuePair(path, null)); - } - - public static bool RequireFile(ScriptEngine/*!*/ engine, string/*!*/ path, ScriptScope/*!*/ scope) { - ContractUtils.RequiresNotNull(engine, "engine"); - ContractUtils.RequiresNotNull(path, "path"); - ContractUtils.RequiresNotNull(scope, "scope"); - - return HostingHelpers.CallEngine, bool>(engine, RequireFile, - new KeyValuePair(path, HostingHelpers.GetScope(scope))); - } - - internal static bool RequireFile(LanguageContext/*!*/ context, KeyValuePair pathAndScope) { - var rc = (RubyContext)context; - return rc.Loader.LoadFile(pathAndScope.Value, null, MutableString.Create(pathAndScope.Key, RubyEncoding.UTF8), LoadFlags.Require); - } - - // TODO: - public static RubyContext/*!*/ GetExecutionContext(ScriptEngine/*!*/ engine) { - ContractUtils.RequiresNotNull(engine, "engine"); - var context = HostingHelpers.GetLanguageContext(engine) as RubyContext; - if (context == null) { - throw new InvalidOperationException("Given engine is not a Ruby engine"); - } - return context; - } - - // TODO: - public static RubyContext/*!*/ GetExecutionContext(ScriptRuntime/*!*/ runtime) { - ContractUtils.RequiresNotNull(runtime, "runtime"); - return GetExecutionContext(GetEngine(runtime)); - } - internal static int IndexOfRubySetup(ScriptRuntimeSetup/*!*/ runtimeSetup) { for (int i = 0; i < runtimeSetup.LanguageSetups.Count; i++) { var langSetup = runtimeSetup.LanguageSetups[i]; @@ -154,23 +156,78 @@ [EditorBrowsable(EditorBrowsableState.Never)] public static class RubyHostingExtensions { - public static bool RequireRubyFile(this ScriptEngine/*!*/ engine, string/*!*/ path) { - return Ruby.RequireFile(engine, path); + /// + /// Loads a given script file using the semantics of Kernel#require method. + /// + /// The Ruby engine. + /// The path to the file to load. + /// Whether the file has already been required. + /// + /// If a relative path is given the current search paths are used to locate the script file. + /// The current search paths could be read and modified via and , + /// respectively. + /// + public static bool RequireFile(this ScriptEngine/*!*/ engine, string/*!*/ path) { + return engine.GetService(engine).RequireFile(path); + } + + /// + /// Loads a given script file using the semantics of Kernel#require method. + /// The script is executed within the context of a given . + /// + /// The Ruby engine. + /// The path to the file to load. + /// The scope to use for the script execution. + /// Whether the file has already been required. + /// + /// If a relative path is given the current search paths are used to locate the script file. + /// The current search paths could be read and modified via and , + /// respectively. + /// + public static bool RequireFile(this ScriptEngine/*!*/ engine, string/*!*/ path, ScriptScope/*!*/ scope) { + return engine.GetService(engine).RequireFile(path, scope); } + /// + /// Retrieves an IronRuby engine from a given script runtime. + /// + /// The runtime to get the engine from. + /// An IronRuby engine from the specified runtime. + /// + /// The is not set up to run IronRuby. + /// The doesn't contain IronRuby's . + /// public static ScriptEngine/*!*/ GetRubyEngine(this ScriptRuntime/*!*/ runtime) { return Ruby.GetEngine(runtime); } + /// + /// Retrieves IronRuby setup from the runtime setup. + /// + /// Runtime setup. + /// IronRuby setup or null if the runtime setup doesn't contain one. + public static LanguageSetup GetRubySetup(this ScriptRuntimeSetup/*!*/ runtimeSetup) { + int index = Ruby.IndexOfRubySetup(runtimeSetup); + return (index != -1) ? runtimeSetup.LanguageSetups[index] : null; + } + + /// + /// Adds a new IronRuby setup into the runtime setup unless already included. + /// + /// The to update. + /// The new setup or the existing setup object. public static LanguageSetup/*!*/ AddRubySetup(this ScriptRuntimeSetup/*!*/ runtimeSetup) { return AddRubySetup(runtimeSetup, null); } /// - /// Adds a new Ruby setup into the given runtime setup unless Ruby setup is already there. - /// Returns the newly created setup or the existing one. - /// If non-null is given and a new setup is created runs the initializer on the new setup instance. + /// Adds a new IronRuby setup into the given runtime setup unless already included. /// + /// The to update. + /// + /// If not null, is used to initialize the new IronRuby . + /// + /// The new setup initialized by or the existing setup object. public static LanguageSetup/*!*/ AddRubySetup(this ScriptRuntimeSetup/*!*/ runtimeSetup, Action newSetupInitializer) { ContractUtils.RequiresNotNull(runtimeSetup, "runtimeSetup"); =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C1597865 File: Ruby.csproj =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C1597865 (server) 2/26/2010 4:52 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;RbHAPI @@ -255,6 +255,7 @@ + @@ -469,4 +470,4 @@ - + \ No newline at end of file =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/Hash.cs;C966724 File: Hash.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/Hash.cs;C966724 (server) 2/22/2010 5:20 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/Hash.cs;RbHAPI @@ -24,13 +24,17 @@ /// Dictionary inherits from Object, mixes in Enumerable. /// Ruby hash is a Dictionary{object, object}, but it adds default value/proc /// - public partial class Hash : Dictionary, IDuplicable { + public partial class Hash : Dictionary, IRubyObjectState, IDuplicable { // The default value can be a Proc that we should *return*, and that is different // from the default value being a Proc that we should *call*, hence two variables private Proc _defaultProc; private object _defaultValue; + private uint _flags; + private const uint IsFrozenFlag = 1; + private const uint IsTaintedFlag = 2; + public Proc DefaultProc { get { return _defaultProc; } set { _defaultProc = value; } } public object DefaultValue { get { return _defaultValue; } set { _defaultValue = value; } } @@ -91,5 +95,40 @@ } #endregion + + #region Flags + + public void Mutate() { + if ((_flags & IsFrozenFlag) != 0) { + throw RubyExceptions.CreateObjectFrozenError(); + } + } + + public bool IsTainted { + get { + return (_flags & IsTaintedFlag) != 0; + } + set { + Mutate(); + _flags = (_flags & ~IsTaintedFlag) | (value ? IsTaintedFlag : 0); + } + } + + public bool IsFrozen { + get { + return (_flags & IsFrozenFlag) != 0; + } + } + + void IRubyObjectState.Freeze() { + Freeze(); + } + + public Hash/*!*/ Freeze() { + _flags |= IsFrozenFlag; + return this; + } + + #endregion } } =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyArray.cs;C1602122 File: RubyArray.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyArray.cs;C1602122 (server) 2/22/2010 5:17 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyArray.cs;RbHAPI @@ -136,7 +136,7 @@ #endregion - #region Versioning, Flags + #region Flags private void Mutate() { if ((_flags & IsFrozenFlag) != 0) { =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/Subclasses.Generated.cs;C1597865 File: Subclasses.Generated.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/Subclasses.Generated.cs;C1597865 (server) 2/22/2010 5:24 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/Subclasses.Generated.cs;RbHAPI @@ -20,7 +20,7 @@ namespace IronRuby.Builtins { #if GENERATOR - Stateless = ['Proc', 'Range', 'RubyRegex', 'RubyIO'] + Stateless = ['Range', 'RubyRegex', 'RubyIO'] def generate Stateless.each do |cls| @@ -33,10 +33,10 @@ @class end #else - public partial class /*$Class{*/Hash/*}*/ { + public partial class /*$Class{*/Proc/*}*/ { [DebuggerTypeProxy(typeof(RubyObjectDebugView))] [DebuggerDisplay(RubyObject.DebuggerDisplayValue, Type = RubyObject.DebuggerDisplayType)] - public sealed partial class Subclass : /*$Class{*/Hash/*}*/, IRubyObject { + public sealed partial class Subclass : /*$Class{*/Proc/*}*/, IRubyObject { private RubyInstanceData _instanceData; private RubyClass/*!*/ _immediateClass; @@ -89,10 +89,10 @@ #endif #region Generated by Subclasses.Generator.rb - public partial class Proc { + public partial class Range { [DebuggerTypeProxy(typeof(RubyObjectDebugView))] [DebuggerDisplay(RubyObject.DebuggerDisplayValue, Type = RubyObject.DebuggerDisplayType)] - public sealed partial class Subclass : Proc, IRubyObject { + public sealed partial class Subclass : Range, IRubyObject { private RubyInstanceData _instanceData; private RubyClass/*!*/ _immediateClass; @@ -142,10 +142,10 @@ } } } - public partial class Range { + public partial class RubyRegex { [DebuggerTypeProxy(typeof(RubyObjectDebugView))] [DebuggerDisplay(RubyObject.DebuggerDisplayValue, Type = RubyObject.DebuggerDisplayType)] - public sealed partial class Subclass : Range, IRubyObject { + public sealed partial class Subclass : RubyRegex, IRubyObject { private RubyInstanceData _instanceData; private RubyClass/*!*/ _immediateClass; @@ -195,10 +195,10 @@ } } } - public partial class RubyRegex { + public partial class RubyIO { [DebuggerTypeProxy(typeof(RubyObjectDebugView))] [DebuggerDisplay(RubyObject.DebuggerDisplayValue, Type = RubyObject.DebuggerDisplayType)] - public sealed partial class Subclass : RubyRegex, IRubyObject { + public sealed partial class Subclass : RubyIO, IRubyObject { private RubyInstanceData _instanceData; private RubyClass/*!*/ _immediateClass; @@ -248,10 +248,27 @@ } } } - public partial class RubyIO { + +#endregion + +#if GENERATOR + Stateful = ['RubyArray', 'Hash', 'MatchData'] + + def generate + Stateful.each do |cls| + @class = cls + super + end + end + + def Class *a + @class + end +#else + public partial class /*$Class{*/MutableString/*}*/ { [DebuggerTypeProxy(typeof(RubyObjectDebugView))] [DebuggerDisplay(RubyObject.DebuggerDisplayValue, Type = RubyObject.DebuggerDisplayType)] - public sealed partial class Subclass : RubyIO, IRubyObject { + public sealed partial class Subclass : /*$Class{*/MutableString/*}*/, IRubyObject { private RubyInstanceData _instanceData; private RubyClass/*!*/ _immediateClass; @@ -275,19 +292,6 @@ return _instanceData; } - public bool IsFrozen { - get { return _instanceData != null && _instanceData.Frozen; } - } - - public bool IsTainted { - get { return _instanceData != null && _instanceData.Tainted; } - set { GetInstanceData().Tainted = value; } - } - - public void Freeze() { - GetInstanceData().Freeze(); - } - public int BaseGetHashCode() { return base.GetHashCode(); } @@ -301,27 +305,13 @@ } } } +#endif +#region Generated by Subclasses.Generator.rb -#endregion - -#if GENERATOR - Stateful = ['RubyArray', 'MatchData'] - - def generate - Stateful.each do |cls| - @class = cls - super - end - end - - def Class *a - @class - end -#else - public partial class /*$Class{*/MutableString/*}*/ { + public partial class RubyArray { [DebuggerTypeProxy(typeof(RubyObjectDebugView))] [DebuggerDisplay(RubyObject.DebuggerDisplayValue, Type = RubyObject.DebuggerDisplayType)] - public sealed partial class Subclass : /*$Class{*/MutableString/*}*/, IRubyObject { + public sealed partial class Subclass : RubyArray, IRubyObject { private RubyInstanceData _instanceData; private RubyClass/*!*/ _immediateClass; @@ -358,13 +348,10 @@ } } } -#endif -#region Generated by Subclasses.Generator.rb - - public partial class RubyArray { + public partial class Hash { [DebuggerTypeProxy(typeof(RubyObjectDebugView))] [DebuggerDisplay(RubyObject.DebuggerDisplayValue, Type = RubyObject.DebuggerDisplayType)] - public sealed partial class Subclass : RubyArray, IRubyObject { + public sealed partial class Subclass : Hash, IRubyObject { private RubyInstanceData _instanceData; private RubyClass/*!*/ _immediateClass; =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyCommandLine.cs;C1496258 File: RubyCommandLine.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyCommandLine.cs;C1496258 (server) 2/26/2010 5:17 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyCommandLine.cs;RbHAPI @@ -121,7 +121,7 @@ protected override void UnhandledException(Exception e) { // Kernel#at_exit can access $!. So we need to publish the uncaught exception - Ruby.GetExecutionContext(Engine).CurrentException = e; + ((RubyContext)Language).CurrentException = e; base.UnhandledException(e); } =================================================================== add: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyService.cs File: RubyService.cs =================================================================== --- [no source file] +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyService.cs;RbHAPI @@ -1,0 +1,86 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. + * + * This source code is subject to terms and conditions of the Microsoft Public License. A + * copy of the license can be found in the License.html file at the root of this distribution. If + * you cannot locate the Microsoft Public License, please send an email to + * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound + * by the terms of the Microsoft Public License. + * + * You must not remove this notice, or any other, from this software. + * + * + * ***************************************************************************/ + +using System; +using System.Security.Permissions; +using IronRuby.Runtime; +using Microsoft.Scripting.Hosting; +using Microsoft.Scripting.Hosting.Providers; +using Microsoft.Scripting.Runtime; +using Microsoft.Scripting.Utils; + +namespace IronRuby.Hosting { + public sealed class RubyService +#if !SILVERLIGHT + : MarshalByRefObject +#endif + { + private readonly ScriptEngine/*!*/ _engine; + private readonly RubyContext/*!*/ _context; + + internal RubyService(RubyContext/*!*/ context, ScriptEngine/*!*/ engine) { + Assert.NotNull(context, engine); + _context = context; + _engine = engine; + } + + /// + /// Loads a given script file using the semantics of Kernel#require method. + /// + /// The Ruby engine. + /// The path to the file to load. + /// Whether the file has already been required. + /// + /// If a relative path is given the current search paths are used to locate the script file. + /// The current search paths could be read and modified via and , + /// respectively. + /// + public bool RequireFile(string/*!*/ path) { + ContractUtils.RequiresNotNull(path, "path"); + return RequireFile(path, (Scope)null); + } + + /// + /// Loads a given script file using the semantics of Kernel#require method. + /// The script is executed within the context of a given . + /// + /// The Ruby engine. + /// The path to the file to load. + /// The scope to use for the script execution. + /// Whether the file has already been required. + /// + /// If a relative path is given the current search paths are used to locate the script file. + /// The current search paths could be read and modified via and , + /// respectively. + /// + public bool RequireFile(string/*!*/ path, ScriptScope/*!*/ scope) { + ContractUtils.RequiresNotNull(path, "path"); + ContractUtils.RequiresNotNull(scope, "scope"); + return RequireFile(path, HostingHelpers.GetScope(scope)); + } + + private bool RequireFile(string/*!*/ path, Scope scope) { + return _context.Loader.LoadFile(scope, null, _context.EncodePath(path), LoadFlags.Require); + } + +#if !SILVERLIGHT + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] + public override object InitializeLifetimeService() { + // track the engines lifetime + return _engine.InitializeLifetimeService(); + } +#endif + } +} =================================================================== edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C1599184 File: RubyContext.cs =================================================================== --- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C1599184 (server) 2/26/2010 5:18 PM +++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;RbHAPI @@ -33,6 +33,7 @@ using IronRuby.Compiler; using IronRuby.Compiler.Ast; using IronRuby.Compiler.Generation; +using IronRuby.Hosting; using IronRuby.Runtime.Calls; using IronRuby.Runtime.Conversions; using Microsoft.Scripting; @@ -41,9 +42,6 @@ using Microsoft.Scripting.Utils; namespace IronRuby.Runtime { - /// - /// An isolation context: could be per thread/request or shared accross certain threads. - /// [ReflectionCached] public sealed class RubyContext : LanguageContext { internal static readonly Guid RubyLanguageGuid = new Guid("F03C4640-DABA-473f-96F1-391400714DAB"); @@ -107,6 +105,7 @@ private readonly RubyMetaBinderFactory/*!*/ _metaBinderFactory; private readonly RubyBinder _binder; private DynamicDelegateCreator _delegateCreator; + private RubyService _rubyService; #region Global Variables (thread-safe access) @@ -2678,6 +2677,10 @@ #region Language Context Overrides public override TService GetService(params object[] args) { + if (typeof(TService) == typeof(RubyService)) { + return (TService)(object)(_rubyService ?? (_rubyService = new RubyService(this, (Microsoft.Scripting.Hosting.ScriptEngine)args[0]))); + } + if (typeof(TService) == typeof(TokenizerService)) { return (TService)(object)new Tokenizer(); } ===================================================================