edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/ClassInitGenerator/Program.cs;C404624 File: Program.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/ClassInitGenerator/Program.cs;C404624 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/ClassInitGenerator/Program.cs;Super17 @@ -76,6 +76,11 @@ Class } + private enum HiddenMethod { + ClrInvisible, + Undefined + } + private class ModuleDef { public string/*!*/ QualifiedName; public string/*!*/ SimpleName; @@ -87,8 +92,8 @@ public IDictionary/*!*/ ClassMethods = new SortedDictionary(); public IDictionary/*!*/ Constants = new SortedDictionary(); - public IDictionary/*!*/ HiddenInstanceMethods = new SortedDictionary(); - public IDictionary/*!*/ HiddenClassMethods = new SortedDictionary(); + public IDictionary/*!*/ HiddenInstanceMethods = new SortedDictionary(); + public IDictionary/*!*/ HiddenClassMethods = new SortedDictionary(); public List/*!*/ Factories = new List(); @@ -315,16 +320,26 @@ ReflectConstants(def); ReflectAliases(def); - // removed CLR methods: + // hidden CLR methods: foreach (HideMethodAttribute method in trait.GetCustomAttributes(typeof(HideMethodAttribute), false)) { // TODO: warning, method already removed, method not found ... if (method.IsStatic) { - def.HiddenClassMethods[method.Name] = true; + def.HiddenClassMethods[method.Name] = HiddenMethod.ClrInvisible; } else { - def.HiddenInstanceMethods[method.Name] = true; + def.HiddenInstanceMethods[method.Name] = HiddenMethod.ClrInvisible; } } + // undefined methods: + foreach (UndefineMethodAttribute method in trait.GetCustomAttributes(typeof(UndefineMethodAttribute), false)) { + // TODO: warning, method already removed, method not found ... + if (method.IsStatic) { + def.HiddenClassMethods[method.Name] = HiddenMethod.Undefined; + } else { + def.HiddenInstanceMethods[method.Name] = HiddenMethod.Undefined; + } + } + if (def.Extends == typeof(Object)) { _hasPrimitives = true; } @@ -813,9 +828,13 @@ } } - private void GenerateHiddenMethods(IDictionary/*!*/ methods) { - foreach (string name in methods.Keys) { - _output.WriteLine("module.HideMethod(\"{0}\");", name); + private void GenerateHiddenMethods(IDictionary/*!*/ methods) { + foreach (KeyValuePair entry in methods) { + if (entry.Value == HiddenMethod.Undefined) { + _output.WriteLine("module.UndefineMethod(\"{0}\");", entry.Key); + } else { + _output.WriteLine("module.HideMethod(\"{0}\");", entry.Key); + } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Helpers.cs;C417101 File: Helpers.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Helpers.cs;C417101 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Helpers.cs;Super17 @@ -26,6 +26,7 @@ using Microsoft.Scripting.Runtime; using Microsoft.Scripting.Generation; using Ruby.Compiler; +using System.Diagnostics; namespace Ruby.Tests { @@ -76,16 +77,29 @@ public RubyExecutionContext ExecutionContext { get { return _driver.TestRuntime.ExecutionContext; } } public RubyContext Context { get { return _driver.TestRuntime.Context; } } + public string/*!*/ Eval(bool eval, string/*!*/ code) { + if (eval) { + return code.Replace("#<","eval %q{").Replace("#>", "}"); + } else { + return code.Replace("#<", "").Replace("#>", ""); + } + } + public void CompilerTest(string/*!*/ code) { - CompilerTest(code, null); + CompilerTest(code, 0, 0); } - public void CompilerTest(string/*!*/ code, ErrorSink sink) { - ScriptSource source; + public void CompilerTest(string/*!*/ code, int expectedCompilerWarningCount, int expectedRuntimeWarningCount) { + LoggingErrorSink log = new LoggingErrorSink(true); + CompilerTest(code, log); + Assert(log.ErrorCount == 0 && log.FatalErrorCount == 0, "Compile time error"); + Assert(log.WarningCount == expectedCompilerWarningCount, "Wrong number of compile time errors/warnings"); + Assert(ExecutionContext.RuntimeErrorSink.WarningCount == expectedRuntimeWarningCount, "Wrong number of runtime warnings"); + } - if (sink == null) { - sink = ErrorSink.Default; - } + public void CompilerTest(string/*!*/ code, ErrorSink/*!*/ sink) { + Debug.Assert(code != null && sink != null); + SourceUnit source; string name = _driver.TestRuntime.TestName; @@ -93,15 +107,18 @@ string path = Path.Combine(Snippets.Shared.SnippetsDirectory, name + ".rb"); Directory.CreateDirectory(Snippets.Shared.SnippetsDirectory); File.WriteAllText(path, code); - source = Engine.CreateScriptSourceFromFile(path); + source = _driver.TestRuntime.Context.CreateFileUnit(path); } else { - source = Engine.CreateScriptSourceFromString(code, name + ".rb", SourceCodeKind.File); + source = _driver.TestRuntime.Context.CreateSnippet(code, name + ".rb", SourceCodeKind.File); } if (_driver.OptimizedScopes) { source.Execute(); } else { - source.Execute(Engine.CreateScope()); + ScriptCode compiledCode = source.Compile(new RubyCompilerOptions(), sink); + if (compiledCode != null) { + compiledCode.Run(new Scope()); + } } } @@ -180,7 +197,7 @@ StringBuilder builder = new StringBuilder(); using (StringWriter output = new StringWriter(builder)) { - RedirectOutput(output, TextWriter.Null, f); + RedirectOutput(output, Console.Error, f); } string actualOutput = builder.ToString(); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/IronRuby.Tests.csproj;C420856 File: IronRuby.Tests.csproj =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/IronRuby.Tests.csproj;C420856 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/IronRuby.Tests.csproj;Super17 @@ -63,6 +63,7 @@ + =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C427406 File: RubyTests.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C427406 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;Super17 @@ -50,6 +50,7 @@ Scenario_RubyScopes3, Scenario_RubyScopes4, Scenario_RubyScopes5, + Scenario_RubyScopes6, Scenario_RubyNumericLiterals1, Scenario_RubyStrings1, @@ -80,6 +81,7 @@ Scenario_MethodAliases1, Scenario_MethodUndef1, Scenario_MethodUndef2, + MethodUndefExpression, Scenario_Assignment1, Scenario_ParallelAssignment1, @@ -92,6 +94,7 @@ Scenario_ParallelAssignment9, Scenario_ParallelAssignment10, + BlockEmpty, Scenario_RubyBlocks0, ProcYieldCaching1, ProcCallCaching1, @@ -118,6 +121,10 @@ Scenario_RubyBlockArgs4, Scenario_RubyProcs1, + RubyProcArgConversion1, + RubyProcArgConversion2, + RubyProcArgConversion3, + RubyProcArgConversion4, Scenario_DefineMethod1, Scenario_RubyInitializers0, @@ -162,12 +169,14 @@ Scenario_RubyBoolExpressions3, Scenario_RubyBoolExpressions4, Scenario_RubyBoolExpressionsWithReturn1, + Scenario_RubyBoolExpressionsWithReturn2, Scenario_RubyBoolAssignment, Scenario_RubyIfExpression1, Scenario_RubyIfExpression2, Scenario_RubyUnlessExpression1, Scenario_RubyConditionalExpression1, - Scenario_RubyConditionalStatement1, + ConditionalStatement1, + ConditionalStatement2, Scenario_UninitializedVars1, Scenario_UninitializedVars2, @@ -226,10 +235,14 @@ Scenario_RubyExceptions_Globals, Scenario_RubyRescueStatement1, Scenario_RubyRescueExpression1, + Scenario_RubyRescueExpression2, ClassVariables1, UnqualifiedConstants2, + AliasMethodLookup, + UndefMethodLookup, + Scenario_Singletons1, Scenario_Singletons2, Scenario_Singletons3, @@ -237,7 +250,11 @@ Scenario_Singletons5, Scenario_ClassVariables_Singletons, - Scenario_RubySuper1, + Super1, + SuperParameterless1, + Super2, + SuperInDefineMethod1, + SuperInDefineMethod2, Scenario_RubyDefinedOperator_Globals1, Scenario_RubyDefinedOperator_Globals2, @@ -255,7 +272,8 @@ Scenario_RubyThreads1, Scenario_YieldCodeGen, - Methods, + Methods, + MethodAliasExpression, // eval, binding: Eval1, @@ -269,6 +287,10 @@ ModuleEvalProc3, ModuleEvalString1, ModuleEvalString2, + + SuperEval1, + // TODO: SuperParameterlessEval1, + SuperInDefineMethodEval1, }; } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/BlockTests.cs;C427406 File: BlockTests.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/BlockTests.cs;C427406 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/BlockTests.cs;Super17 @@ -31,6 +31,10 @@ namespace Ruby.Tests { public partial class Tests { + public void BlockEmpty() { + CompilerTest("1.times { }"); + } + public void Scenario_RubyBlocks0() { AssertOutput(delegate() { CompilerTest(@" @@ -455,7 +459,7 @@ e { |x| puts x.inspect } f { |x| puts x.inspect } g { |(x,)| puts x.inspect } -"); +", 0, 2); // 2 runtime warnings }, @" nil 1 @@ -465,7 +469,6 @@ [1, 2] nil "); - Debug.Assert(ExecutionContext.RuntimeErrorSink.WarningCount == 2); } public void Scenario_RubyBlockArgs2() { @@ -550,18 +553,121 @@ "); } + public void RubyProcArgConversion1() { + AssertOutput(delegate() { + CompilerTest(@" +class C + def to_proc + lambda { |x| puts x } + end +end + +class D + def to_proc + lambda { |x| puts x + 1 } + end +end + +class E +end + +1.times(&C.new) +1.times(&D.new) +1.times(&E.new) rescue puts 'error' +"); + }, @" +0 +1 +error +"); + } + + public void RubyProcArgConversion2() { + AssertOutput(delegate() { + CompilerTest(@" +class C + def to_proc; 1; end +end + +class D + def to_proc; lambda { puts 'ok2' }; end +end + +1.times(&lambda { puts 'ok1' }) +1.times(&C.new) rescue puts 'error' # TODO: puts $! -> # +1.times(&D.new) +"); + }, @" +ok1 +error +ok2 +"); + } + + public void RubyProcArgConversion3() { + AssertOutput(delegate() { + CompilerTest(@" +def foo &b + p b +end + +foo(&nil) +"); + }, @"nil"); + } + + public void RubyProcArgConversion4() { + AssertOutput(delegate() { + CompilerTest(@" +class C + def respond_to? name + puts name + $has_to_proc + end + + def to_proc + lambda { puts 'ok' } + end +end + +$has_to_proc = false +1.times(&C.new) rescue puts 'error' + +$has_to_proc = true +1.times(&C.new) +"); + }, @" +to_proc +error +to_proc +ok +"); + } + public void Scenario_DefineMethod1() { AssertOutput(delegate() { CompilerTest(@" class C - define_method(:foo) { - self.class - } + def foo + $x = lambda { + puts self.class + } + + $x.call + end end -puts C.new.foo +C.new.foo + +class D + define_method :goo, &$x +end + +D.new.goo "); - }, @"C"); + }, @" +C +D"); } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/BoolAndConditionalTests.cs;C417101 File: BoolAndConditionalTests.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/BoolAndConditionalTests.cs;C417101 (server) 5/4/2008 10:39 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/BoolAndConditionalTests.cs;Super17 @@ -179,6 +179,18 @@ "); } + public void Scenario_RubyBoolExpressionsWithReturn2() { + AssertOutput(delegate() { + CompilerTest(@" +def foo + false || return + puts 'unreachable' +end +foo +"); + }, @""); + } + public void Scenario_RubyBoolAssignment() { AssertOutput(delegate() { CompilerTest(@" @@ -278,7 +290,7 @@ "); } - public void Scenario_RubyConditionalStatement1() { + public void ConditionalStatement1() { AssertOutput(delegate() { CompilerTest(@" def t; puts 1; true; end @@ -309,5 +321,17 @@ 2 "); } + + public void ConditionalStatement2() { + AssertOutput(delegate() { + CompilerTest(@" +p x = (1 if true) +p x = (1 if false) +"); + }, @" +1 +nil +"); + } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ExceptionTests.cs;C417101 File: ExceptionTests.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ExceptionTests.cs;C417101 (server) 5/4/2008 10:39 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ExceptionTests.cs;Super17 @@ -549,5 +549,22 @@ "); }, @"2"); } + + public void Scenario_RubyRescueExpression2() { + AssertOutput(delegate() { + CompilerTest(@" +def foo + raise +end + +def bar + x = foo rescue return + puts 'unreachable' +end + +bar +"); + }, @""); + } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MiscTests.cs;C420856 File: MiscTests.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MiscTests.cs;C420856 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MiscTests.cs;Super17 @@ -386,6 +386,24 @@ "); } + /// + /// Nested module scopes - they don't have DLR tuples and therefore need to be skipped when looking up a storage from closure. + /// + public void Scenario_RubyScopes6() { + CompilerTest(@" +1.times { + module M + module N + z = 1 + 1.times { + x = z + } + end + end +} +"); + } + public void Scenario_RubyNumericLiterals1() { AssertOutput(delegate() { CompilerTest(@" @@ -659,7 +677,31 @@ "); } + /// + /// Alias (unlike undef) looks up the method in Object. + /// + public void AliasMethodLookup() { + AssertOutput(delegate() { + CompilerTest(@" +module Kernel; def m_kernel; end; end +class Object; def m_object; end; end +module N + def m_n + end + + module M + alias x m_object rescue puts '!alias m_object' + alias x m_kernel rescue puts '!alias m_kernel' + alias x m_n rescue puts '!alias m_n' + end +end +"); + }, @" +!alias m_n +"); + } + public void Scenario_RubyReturnValues1() { AssertOutput(delegate() { CompilerTest(@" @@ -896,29 +938,6 @@ "); } - /// - /// Calls to super with block and no arguments (was bug in parser/AST). - /// - public void Scenario_RubySuper1() { - AssertOutput(delegate() { - CompilerTest(@" -class C - def foo - yield - end -end - -class D < C - def foo - super { puts 'foo' } - end -end - -D.new.foo -"); - }, @"foo"); - } - public void Scenario_MainSingleton() { AssertOutput(delegate() { CompilerTest(@" @@ -1003,5 +1022,14 @@ 3 "); } + + public void MethodAliasExpression() { + AssertOutput(delegate() { + CompilerTest(@" +def b; end +p ((alias a b)) +", 1, 0); + }, "nil"); + } } } =================================================================== add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/SuperTests.cs File: SuperTests.cs =================================================================== --- [no source file] +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/SuperTests.cs;Super17 @@ -1,0 +1,206 @@ +?/* **************************************************************************** + * + * 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 + * ironruby@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.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; + +using Microsoft.Scripting; +using Microsoft.Scripting.Hosting; +using Microsoft.Scripting.Math; + +using Ruby.Compiler; +using Ruby.Compiler.Ast; +using Ruby.Runtime; + +namespace Ruby.Tests { + public partial class Tests { + private void Super1_Test(bool eval) { + AssertOutput(delegate() { + CompilerTest(Eval(eval, @" +class C + def foo a + puts 'C.foo' + puts a + end +end + +class D < C + def foo + puts 'D.foo' + # + end +end + +D.new.foo +")); + }, @" +D.foo +C.foo +arg"); + } + + public void Super1() { + Super1_Test(false); + } + + public void SuperEval1() { + Super1_Test(true); + } + + public void SuperParameterless1() { + SuperParameterless1_Test(false); + } + + public void SuperParameterlessEval1() { + SuperParameterless1_Test(true); + } + + public void SuperParameterless1_Test(bool eval) { + AssertOutput(delegate() { + CompilerTest(Eval(eval, @" +class C + def foo a + puts 'C.foo' + puts a + end +end + +class D < C + def foo a + puts 'D.foo' + # + end +end + +D.new.foo 'arg' +")); + }, @" +D.foo +C.foo +arg"); + } + + /// + /// Calls to super with block and no arguments (was bug in parser/AST). + /// + public void Super2() { + AssertOutput(delegate() { + CompilerTest(@" +class C + def foo + yield + end +end + +class D < C + def foo + super { puts 'foo' } + end +end + +D.new.foo +"); + }, @"foo"); + } + + // TODO: parameters + + public void SuperInDefineMethod1() { + SuperInDefineMethod1_Test(false); + } + + public void SuperInDefineMethodEval1() { + SuperInDefineMethod1_Test(true); + } + + /// + /// Super in proc invoked via a call to a method defined by define_method uses the method's name and declaring module for super-method lookup. + /// + public void SuperInDefineMethod1_Test(bool eval) { + AssertOutput(delegate() { + CompilerTest(Eval(eval, @" +def def_lambda + 1.times { + $p = lambda { + 1.times { + p self.class + # + } + } + } +end + +class C + def foo + puts 'C.foo' + end +end + +def_lambda + +class D < C + define_method :foo, &$p +end + +D.new.foo +")); + }, @" +D +C.foo +"); + } + + /// + /// Super in proc invoked via "call" uses the self and parameters captured in closure by the block. + /// + public void SuperInDefineMethod2() { + AssertOutput(delegate() { + CompilerTest(@" +class A + def def_lambda a + puts 'A.def_lambda' + puts a + end +end + +class B < A + def def_lambda a + 1.times { + $p = lambda { + 1.times { + p self.class + super + } + } + } + end +end + +B.new.def_lambda 'arg' +$p.call 'foo' +"); + }, @" +B +A.def_lambda +arg +"); + } + } + +} =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/UndefTests.cs;C417101 File: UndefTests.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/UndefTests.cs;C417101 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/UndefTests.cs;Super17 @@ -31,7 +31,6 @@ namespace Ruby.Tests { public partial class Tests { - public void Scenario_MethodUndef1() { AssertOutput(delegate() { CompilerTest(@" @@ -147,5 +146,41 @@ "); AssertEquals(ExecutionContext.GetGlobalVariable("o"), 10); } + + public void MethodUndefExpression() { + AssertOutput(delegate() { + CompilerTest(@" +def u; end +p ((undef u)) +", 1, 0); + }, "nil"); + } + + /// + /// Undef (unlike alias) doesn't look up the method in Object. + /// + public void UndefMethodLookup() { + AssertOutput(delegate() { + CompilerTest(@" +module Kernel; def m_kernel; end; end +class Object; def m_object; end; end + +module N + def m_n + end + + module M + undef m_object rescue puts '!undef m_object' + undef m_kernel rescue puts '!undef m_kernel' + undef m_n rescue puts '!undef m_n' + end +end +"); + }, @" +!undef m_object +!undef m_kernel +!undef m_n +"); + } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;C428766 File: Initializer.Generated.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;C428766 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;Super17 @@ -44,9 +44,9 @@ #endif // Skipped primitive: Object Ruby.Builtins.RubyModule def34 = DefineModule("System::Collections::Generic::IDictionary", typeof(System.Collections.Generic.IDictionary), new System.Action(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); - DefineModule("System::Collections::IEnumerable", typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); + Ruby.Builtins.RubyModule def47 = DefineModule("System::Collections::IEnumerable", typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); Ruby.Builtins.RubyModule def42 = DefineModule("System::Collections::IList", typeof(System.Collections.IList), new System.Action(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); - Ruby.Builtins.RubyModule def47 = DefineModule("System::IComparable", typeof(System.IComparable), new System.Action(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def40, }); + DefineModule("System::IComparable", typeof(System.IComparable), new System.Action(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def40, }); DefineGlobalClass("Time", typeof(System.DateTime), typeof(Ruby.Builtins.TimeOps), new System.Action(LoadTime_Instance), new System.Action(LoadTime_Class), classRef1, new Ruby.Builtins.RubyModule[] {def40, }, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.TimeOps.Create), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.TimeOps.Create), @@ -318,11 +318,11 @@ }); module.DefineMethod("private", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MainSingletonOps.SetPrivateVisibility), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MainSingletonOps.SetPrivateVisibility), }); module.DefineMethod("public", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MainSingletonOps.SetPublicVisibility), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MainSingletonOps.SetPublicVisibility), }); module.DefineMethod("to_s", 0x9, new System.Delegate[] { @@ -566,6 +566,9 @@ private void LoadClass_Instance(Ruby.Builtins.RubyModule/*!*/ module) { + module.UndefineMethod("append_features"); + module.UndefineMethod("extend_object"); + module.UndefineMethod("module_function"); module.DefineMethod("[]", 0x9, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ClassOps.Of), }); @@ -1770,6 +1773,10 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetLocalScope), }); + module.DefineMethod("block_given?", 0xa, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.HasBlock), + }); + module.DefineMethod("class", 0x9, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.GetClass), }); @@ -1882,6 +1889,10 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.IsKindOf), }); + module.DefineMethod("iterator?", 0xa, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.HasBlock), + }); + module.DefineMethod("kind_of?", 0x9, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.Kernel.IsKindOf), }); @@ -2362,6 +2373,7 @@ }); module.DefineMethod("class_eval", 0x9, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.Evaluate), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.Evaluate), }); @@ -2444,11 +2456,15 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.MethodDefined), }); - module.DefineMethod("module_eval", 0xa, new System.Delegate[] { + module.DefineMethod("module_eval", 0x9, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.Evaluate), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.Evaluate), }); + module.DefineMethod("module_function", 0xa, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.CopyMethodsToModuleSingleton), + }); + module.DefineMethod("name", 0x9, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.GetName), }); @@ -2537,10 +2553,6 @@ private void LoadModule_Class(Ruby.Builtins.RubyModule/*!*/ module) { - module.DefineMethod("class_eval", 0x11, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.Evaluate), - }); - module.DefineMethod("constants", 0x11, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ModuleOps.GetGlobalConstants), }); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Protocols.cs;C417565 File: Protocols.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Protocols.cs;C417565 (server) 5/3/2008 1:33 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Protocols.cs;Super17 @@ -99,7 +99,7 @@ return str; } - throw RubyExceptions.MethodShouldReturnType(obj, "to_str", "String"); + throw RubyExceptions.MethodShouldReturnType(context, obj, "to_str", "String"); } return null; @@ -151,7 +151,7 @@ if (RubySites.RespondTo(context, value, "to_f")) { object obj = _ToF.Invoke(context, value); if (!(obj is double)) { - throw RubyExceptions.MethodShouldReturnType(value, "to_f", "Float"); + throw RubyExceptions.MethodShouldReturnType(context, value, "to_f", "Float"); } return (double)obj; } @@ -198,7 +198,7 @@ return result; } - throw RubyExceptions.MethodShouldReturnType(obj, "to_int", "Integer"); + throw RubyExceptions.MethodShouldReturnType(context, obj, "to_int", "Integer"); } if (RubySites.RespondTo(context, obj, "to_i")) { @@ -207,7 +207,7 @@ return result; } - throw RubyExceptions.MethodShouldReturnType(obj, "to_i", "Integer"); + throw RubyExceptions.MethodShouldReturnType(context, obj, "to_i", "Integer"); } return null; @@ -375,7 +375,7 @@ return ary; } - throw RubyExceptions.MethodShouldReturnType(obj, "to_a", "Array"); + throw RubyExceptions.MethodShouldReturnType(context, obj, "to_a", "Array"); } return null; @@ -413,7 +413,7 @@ return ary; } - throw RubyExceptions.MethodShouldReturnType(obj, "to_ary", "Array"); + throw RubyExceptions.MethodShouldReturnType(context, obj, "to_ary", "Array"); } return null; =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;C420856 File: ClassOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;C420856 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;Super17 @@ -38,6 +38,9 @@ using Ruby.Compiler.Ast; [RubyClass("Class", Extends = typeof(RubyClass), Inherits = typeof(RubyModule))] + [UndefineMethod("extend_object")] + [UndefineMethod("append_features")] + [UndefineMethod("module_function")] public sealed class ClassOps { #region Private Instance Methods // TODO =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C428766 File: Kernel.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C428766 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;Super17 @@ -107,12 +107,11 @@ return new Binding(RubyUtils.GetScope(context)); } - // TODO: - //[RubyMethod("block_given?", RubyMethodAttributes.PrivateInstance)] - //[RubyMethod("iterator?", RubyMethodAttributes.PrivateInstance)] - //public static bool HasBlock(CodeContext/*!*/ context, object self) { - // return GetLocalScope(context).Block != null; - //} + [RubyMethod("block_given?", RubyMethodAttributes.PrivateInstance)] + [RubyMethod("iterator?", RubyMethodAttributes.PrivateInstance)] + public static bool HasBlock(CodeContext/*!*/ context, object self) { + return RubyUtils.GetScope(context).GetInnerMostMethodScope().BlockParameter != null; + } //callcc //caller @@ -126,34 +125,16 @@ [RubyMethod("eval", RubyMethodAttributes.PublicSingleton)] public static object Evaluate(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ code, [Optional]Binding binding, [Optional, NotNull]MutableString file, [Optional, DefaultValue(1)]int line) { - return Evaluate(context, self, code, (binding != null) ? binding.LocalScope : RubyUtils.GetScope(context), file, line); + return RubyUtils.Evaluate(self, code, (binding != null) ? binding.LocalScope : RubyUtils.GetScope(context), file, line); } [RubyMethod("eval", RubyMethodAttributes.PrivateInstance)] [RubyMethod("eval", RubyMethodAttributes.PublicSingleton)] public static object Evaluate(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ code, [NotNull]Proc/*!*/ procBinding, [Optional, NotNull]MutableString file, [Optional, DefaultValue(1)]int line) { - return Evaluate(context, self, code, procBinding.LocalScope, file, line); + return RubyUtils.Evaluate(self, code, procBinding.LocalScope, file, line); } - internal static object Evaluate(CodeContext/*!*/ context, object self, MutableString/*!*/ code, RubyScope/*!*/ targetScope, MutableString file, int line) { - Assert.NotNull(context, code, targetScope); - - RubyContext language = (RubyContext)context.LanguageContext; - Scope globalScope = targetScope.GlobalScope; - - SourceUnit source = language.CreateSnippet(code.ToString()); - - RubyCompilerOptions options = new RubyCompilerOptions(); - options.IsEval = true; - options.LocalNames = targetScope.GetVisibleLocalNames(); - - ScriptCode compiledCode = source.Compile(options, language.ExecutionContext.RuntimeErrorSink); - Debug.Assert(compiledCode != null); - - return compiledCode.Run(targetScope, false); - } - //exec [RubyMethod("exit", RubyMethodAttributes.PrivateInstance)] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/LibrarySites.cs;C415805 File: LibrarySites.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/LibrarySites.cs;C415805 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/LibrarySites.cs;Super17 @@ -215,8 +215,7 @@ for (int i = 0; i < args.Length; ++i) { argInfos[i + 1] = new ArgumentInfo(args[i]); } - return InvokeMemberAction.Make(RubyContext.RubyBinder, name, InvokeMemberActionFlags.IsCallWithThis | InvokeMemberActionFlags.ReturnNonCallable, - new CallSignature(argInfos)); + return InvokeMemberAction.Make(RubyContext.RubyBinder, name, new CallSignature(argInfos)); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C428766 File: ModuleOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C428766 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;Super17 @@ -165,85 +165,68 @@ // initialize // initialize_copy - #region private, protected, public + #region private, protected, public, module_function - private static SymbolId[]/*!*/ CastToSymbols(CodeContext/*!*/ context, object[]/*!*/ objects) { - SymbolId[] result = new SymbolId[objects.Length]; - for (int i = 0; i < objects.Length; i++) - result[i] = Protocols.CastToSymbol(context, objects[i]); - return result; - } - - internal static void SetVisibility(CodeContext/*!*/ context, SymbolId[]/*!*/ methodNames, RubyMethodVisibility visibility) { - ContractUtils.RequiresNotNull(context, "context"); - ContractUtils.RequiresNotNull(methodNames, "methodNames"); - - if (methodNames.Length > 0) { - // TODO: - //foreach (SymbolId methodName in methodNames) { - // self.ResolveMethod(methodName, true).Visibility = visibility; - // self.ResolveMethod(methodName, false).Visibility = visibility; - //} - } else { - RubyUtils.GetScope(context).Visibility = visibility; - } - } - - //--------------------------------------------------------- Module#private - // private => self - // private(symbol, ...) => self - //------------------------------------------------------------------------ - // With no arguments, sets the default visibility for subsequently - // defined methods to private. With arguments, sets the named methods - // to have private visibility. - - // module Mod - // def a() end - // def b() end - // private - // def c() end - // private :a - // end - // Mod.private_instance_methods #=> ["a", "c"] - [RubyMethod("private", RubyMethodAttributes.PrivateInstance)] public static RubyModule/*!*/ SetPrivateVisibility(CodeContext/*!*/ context, RubyModule/*!*/ self, [NotNull]params object[]/*!*/ methodNames) { - SetVisibility(context, CastToSymbols(context, methodNames), RubyMethodVisibility.Private); + // overwrites methods to instance: + SetMethodAttributes(context, self, methodNames, RubyMethodAttributes.PrivateInstance); return self; } - //------------------------------------------------------- Module#protected - // protected => self - // protected(symbol, ...) => self - //------------------------------------------------------------------------ - // With no arguments, sets the default visibility for subsequently - // defined methods to protected. With arguments, sets the named - // methods to have protected visibility. - [RubyMethod("protected", RubyMethodAttributes.PrivateInstance)] public static RubyModule/*!*/ SetProtectedVisibility(CodeContext/*!*/ context, RubyModule/*!*/ self, [NotNull]params object[]/*!*/ methodNames) { - SetVisibility(context, CastToSymbols(context, methodNames), RubyMethodVisibility.Protected); + // overwrites methods to instance: + SetMethodAttributes(context, self, methodNames, RubyMethodAttributes.ProtectedInstance); return self; } - //---------------------------------------------------------- Module#public - // public => self - // public(symbol, ...) => self - //------------------------------------------------------------------------ - // With no arguments, sets the default visibility for subsequently - // defined methods to public. With arguments, sets the named methods - // to have public visibility. - [RubyMethod("public", RubyMethodAttributes.PrivateInstance)] public static RubyModule/*!*/ SetPublicVisibility(CodeContext/*!*/ context, RubyModule/*!*/ self, [NotNull]params object[]/*!*/ methodNames) { - SetVisibility(context, CastToSymbols(context, methodNames), RubyMethodVisibility.Public); + // overwrites methods to instance: + SetMethodAttributes(context, self, methodNames, RubyMethodAttributes.PublicInstance); return self; } + [RubyMethod("module_function", RubyMethodAttributes.PrivateInstance)] + public static RubyModule/*!*/ CopyMethodsToModuleSingleton(CodeContext/*!*/ context, RubyModule/*!*/ self, [NotNull]params object[]/*!*/ methodNames) { + // overwrites visibility to public: + SetMethodAttributes(context, self, methodNames, RubyMethodAttributes.PublicSingleton); + return self; + } + + internal static void SetMethodAttributes(CodeContext/*!*/ context, RubyModule/*!*/ module, object[]/*!*/ methodNames, RubyMethodAttributes attributes) { + ContractUtils.RequiresNotNull(context, "context"); + ContractUtils.RequiresNotNull(methodNames, "methodNames"); + + if (methodNames.Length == 0) { + RubyUtils.GetScope(context).MethodAttributes = attributes; + } else { + foreach (SymbolId methodName in CastToSymbols(context, methodNames)) { + RubyMemberInfo method = module.ResolveMethod(methodName); + if (method == null) { + throw RubyExceptions.CreateMethodMissing(context, module, methodName); + } + + if ((attributes & RubyMethodAttributes.Singleton) != 0) { + Debug.Assert(!module.SingletonClass.IsDummySingletonClass); + module.SingletonClass.SetMethod(methodName, method); + } + + method.Visibility = (RubyMethodVisibility)(attributes & RubyMethodAttributes.VisibilityMask); + } + } + } + + private static SymbolId[]/*!*/ CastToSymbols(CodeContext/*!*/ context, object[]/*!*/ objects) { + SymbolId[] result = new SymbolId[objects.Length]; + for (int i = 0; i < objects.Length; i++) + result[i] = Protocols.CastToSymbol(context, objects[i]); + return result; + } + #endregion - // module_function - [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)] public static Proc/*!*/ DefineMethod(CodeContext/*!*/ context, RubyModule/*!*/ self, BlockParam/*!*/ block, SymbolId methodName) { // TODO: [NotNull] attribute should work for BlockParams but doesn't @@ -254,7 +237,7 @@ RubyScope scope = RubyUtils.GetScope(context); Proc lambda = block.Proc.ToLambda(); - self.SetMethod(methodName, Proc.ToLambdaMethodInfo(lambda, scope.Visibility, self)); + self.SetMethod(methodName, Proc.ToLambdaMethodInfo(lambda, methodName, scope.Visibility, self)); return lambda; } @@ -524,8 +507,8 @@ #region module_eval, class_eval - [RubyMethod("module_eval", RubyMethodAttributes.PrivateInstance)] - [RubyMethod("class_eval", RubyMethodAttributes.PublicSingleton)] + [RubyMethod("module_eval")] + [RubyMethod("class_eval")] public static object Evaluate(CodeContext/*!*/ context, RubyModule/*!*/ self, BlockParam block, [NotNull]MutableString/*!*/ code, [Optional, NotNull]MutableString file, [Optional, DefaultValue(1)]int line) { @@ -534,30 +517,14 @@ throw RubyExceptions.CreateArgumentError("wrong number of arguments"); } - Assert.NotNull(context, self, code); - - RubyContext language = (RubyContext)context.LanguageContext; - SourceUnit source = language.CreateSnippet(code.ToString()); - - RubyCompilerOptions options = new RubyCompilerOptions(); - - // we want to create a new top-level local scope: - options.IsIncluded = true; - - ScriptCode compiledCode = source.Compile(options, language.ExecutionContext.RuntimeErrorSink); - Debug.Assert(compiledCode != null); - - // TODO: this is hack - we need arbitrary signature of the Initialize method: - ModuleEvalScope moduleEvalScope = new ModuleEvalScope((RubyScope)context, self); - - return compiledCode.Run(moduleEvalScope, false); + return RubyUtils.EvaluateInModule(context, self, code, file, line); } private static DynamicSite _ClassEvalSite = DynamicSite.Create(YieldAction.Make(RubyContext.RubyBinder, 2)); + [RubyMethod("module_eval")] [RubyMethod("class_eval")] - [RubyMethod("module_eval")] public static object Evaluate(CodeContext/*!*/ context, RubyModule/*!*/ self, BlockParam/*!*/ block) { if (block == null) { throw RubyExceptions.CreateArgumentError("block not supplied"); @@ -739,6 +706,8 @@ stop = true; } + } else if (method.IsUndefined) { + visited.Add(name, true); } else if (method.Visibility == visibility && !visited.ContainsKey(name)) { result.Add(new MutableString(name)); visited.Add(name, true); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;C413883 File: SingletonOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;C413883 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;Super17 @@ -47,19 +47,20 @@ } [RubyMethod("public", RubyMethodAttributes.PublicInstance)] - public static RubyModule/*!*/ SetPublicVisibility(CodeContext/*!*/ context, object/*!*/ self, [NotNull]params SymbolId[]/*!*/ methodNames) { - return SetVisibility(context, self, methodNames, RubyMethodVisibility.Public); + public static RubyModule/*!*/ SetPublicVisibility(CodeContext/*!*/ context, object/*!*/ self, [NotNull]params object[]/*!*/ methodNames) { + return SetVisibility(context, self, methodNames, RubyMethodAttributes.PublicInstance); } [RubyMethod("private", RubyMethodAttributes.PublicInstance)] - public static RubyModule/*!*/ SetPrivateVisibility(CodeContext/*!*/ context, object/*!*/ self, [NotNull]params SymbolId[]/*!*/ methodNames) { - return SetVisibility(context, self, methodNames, RubyMethodVisibility.Private); + public static RubyModule/*!*/ SetPrivateVisibility(CodeContext/*!*/ context, object/*!*/ self, [NotNull]params object[]/*!*/ methodNames) { + return SetVisibility(context, self, methodNames, RubyMethodAttributes.PrivateInstance); } - private static RubyModule/*!*/ SetVisibility(CodeContext/*!*/ context, object/*!*/ self, SymbolId[]/*!*/ methodNames, RubyMethodVisibility visibility) { + private static RubyModule/*!*/ SetVisibility(CodeContext/*!*/ context, object/*!*/ self, object[]/*!*/ methodNames, RubyMethodAttributes attributes) { Assert.NotNull(context, self, methodNames); - ModuleOps.SetVisibility(context, methodNames, visibility); - return RubyUtils.GetExecutionContext(context).GetClassOf(self); + RubyClass cls = RubyUtils.GetExecutionContext(context).GetClassOf(self); + ModuleOps.SetMethodAttributes(context, cls, methodNames, attributes); + return cls; } [RubyMethod("include", RubyMethodAttributes.PublicInstance)] @@ -113,7 +114,9 @@ public static RubyClass/*!*/ GetSuperClass(RubyClass/*!*/ self) { RubyClass result = self.SingletonClass; Debug.Assert(result != null && result.IsSingletonClass); - return result; + + // do not return dummy singletons, also do not create a new singleton (MRI does): + return result.IsDummySingletonClass ? self : result; } [RubyMethod("new", RubyMethodAttributes.PublicInstance)] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Attributes.cs;C413883 File: Attributes.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Attributes.cs;C413883 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Attributes.cs;Super17 @@ -262,5 +262,19 @@ _name = name; } } + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)] + public sealed class UndefineMethodAttribute : Attribute { + private readonly string/*!*/ _name; + private bool _isStatic; + + public string/*!*/ Name { get { return _name; } } + public bool IsStatic { get { return _isStatic; } set { _isStatic = value; } } + + public UndefineMethodAttribute(string/*!*/ name) { + ContractUtils.RequiresNotNull(name, "name"); + _name = name; + } + } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C427406 File: Ruby.csproj =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C427406 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;Super17 @@ -110,6 +110,8 @@ + + @@ -222,7 +224,7 @@ - + =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Proc.cs;C428685 File: Proc.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Proc.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Proc.cs;Super17 @@ -118,6 +118,7 @@ SetProcCallRule(rule, binder, callerContext, procExpression, // proc object Ast.ReadProperty(procExpression, Proc.SelfProperty), // self captured by the block closure + Ast.Null(typeof(RubyLambdaMethodInfo)), // do not pass calling method yieldArgs // user args ); } @@ -128,6 +129,7 @@ internal void SetProcCallRule(RuleBuilder/*!*/ rule, ActionBinder/*!*/ binder, CodeContext/*!*/ callerContext, Expression/*!*/ procExpression, // proc object Expression/*!*/ selfExpression, // self passed to the proc + Expression/*!*/ callingMethodExpression, // RubyLambdaMethodInfo passed to the proc via BlockParam CallArguments/*!*/ yieldArgs // user arguments passed to the proc ) { @@ -145,7 +147,10 @@ return Ast.Comma( Ast.Assign(bfcVariable, - Ast.Call(BlockParam.GetMethod("CreateForProcCall"), Ast.ConvertHelper(procExpression, typeof(Proc))) + Ast.Call(BlockParam.GetMethod("CreateForProcCall"), + Ast.ConvertHelper(procExpression, typeof(Proc)), + callingMethodExpression + ) ), Ast.Try( Ast.Assign(resultVariable, expression) @@ -210,8 +215,9 @@ return result; } - public static RubyMemberInfo/*!*/ ToLambdaMethodInfo(Proc/*!*/ lambda, RubyMethodVisibility visibility, RubyModule/*!*/ owner) { - return new RubyLambdaMethodInfo(lambda, visibility, owner); + public static RubyMemberInfo/*!*/ ToLambdaMethodInfo(Proc/*!*/ lambda, SymbolId definitionName, RubyMethodVisibility visibility, + RubyModule/*!*/ owner) { + return new RubyLambdaMethodInfo(lambda, definitionName, visibility, owner); } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C428685 File: RubyClass.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;Super17 @@ -352,7 +352,7 @@ targetExpr = Ast.Comma( Ast.Assign(newInstanceVariable, targetExpr), - AstFactory.MakeUserMethodBody(args.Expressions[blockArg], rfcVariable, null, null, null, methodUnwinder, SymbolTable.StringToId("ctor"), + AstFactory.MakeUserMethodBody(args.Expressions[blockArg], rfcVariable, null, null, null, methodUnwinder, null, Ast.Assign(resultVariable, MakeInitializerCall(binder, rule, args, newInstanceVariable)) ), Ast.Condition( @@ -380,7 +380,7 @@ Expression[] ps = ArrayUtils.Insert(Ast.CodeContext(), args.Expressions); ps[1] = newInstanceExpr; - return Ast.Action.InvokeMember(binder, Symbols.Initialize, typeof(object), InvokeMemberActionFlags.IsCallWithThis, args.Signature, ps); + return Ast.Action.InvokeMember(binder, Symbols.Initialize, typeof(object), args.Signature, ps); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C428403 File: RubyModule.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C428403 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;Super17 @@ -453,6 +453,10 @@ Updated(); } + public void UndefineMethod(string/*!*/ name) { + UndefineMethod(SymbolTable.StringToId(name)); + } + public void HideMethod(SymbolId name) { EnsureInitialized(); _methods[name] = RubyMethodInfo.HiddenMethod; @@ -675,15 +679,8 @@ #region IDynamicObject Members public virtual RuleBuilder GetRule(DynamicAction/*!*/ action, CodeContext/*!*/ callerContext, object[]/*!*/ args) where T : class { - switch (action.Kind) { - case DynamicActionKind.InvokeMember: - RuleBuilder result = new RuleBuilder(); - RubyBinder.MakeRuleForInvokeMember(result, (InvokeMemberAction)action, callerContext, args); - return result; - - default: - return null; - } + RuleBuilder rule = new RuleBuilder(); + return RubyBinder.SetRule(rule, action, callerContext, args) ? rule : null; } public LanguageContext/*!*/ LanguageContext { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubySites.cs;C415805 File: RubySites.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubySites.cs;C415805 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubySites.cs;Super17 @@ -224,7 +224,6 @@ return InvokeMemberAction.Make( RubyContext.RubyBinder, name, - InvokeMemberActionFlags.IsCallWithThis | InvokeMemberActionFlags.ReturnNonCallable, new CallSignature(ArrayUtils.InsertAt(argKinds, 0, ArgumentKind.Instance)) ); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/AstGenerator.cs;C428685 File: AstGenerator.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/AstGenerator.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/AstGenerator.cs;Super17 @@ -18,6 +18,7 @@ using System.Diagnostics; using System.Collections.Generic; using System.Reflection; +using System.Threading; using Microsoft.Scripting; using Microsoft.Scripting.Hosting; @@ -32,16 +33,20 @@ using AstUtils = Microsoft.Scripting.Ast.Utils; internal sealed class AstGenerator { + private static int _UniqueId; private readonly ActionBinder/*!*/ _binder; private readonly RubyCompilerOptions/*!*/ _compilerOptions; + private readonly bool _debugCompiler; public RubyCompilerOptions/*!*/ CompilerOptions { get { return _compilerOptions; } } + public bool DebugCompiler { get { return _debugCompiler; } } - internal AstGenerator(CompilerContext/*!*/ compilerContext) { + internal AstGenerator(CompilerContext/*!*/ compilerContext, bool debugCompiler) { Assert.NotNull(compilerContext); _binder = compilerContext.SourceUnit.LanguageContext.Binder; _compilerOptions = (RubyCompilerOptions)compilerContext.Options; + _debugCompiler = debugCompiler; } internal ActionBinder Binder { @@ -57,16 +62,16 @@ } public sealed class LoopScope : LexicalScope { - private readonly MSA.VariableExpression/*!*/ _redoVariable; - private readonly MSA.VariableExpression/*!*/ _resultVariable; + private readonly MSA.Expression/*!*/ _redoVariable; + private readonly MSA.Expression/*!*/ _resultVariable; private readonly MSA.LabelTarget/*!*/ _label; public LoopScope _parentLoop; - public MSA.VariableExpression/*!*/ RedoVariable { + public MSA.Expression/*!*/ RedoVariable { get { return _redoVariable; } } - public MSA.VariableExpression/*!*/ ResultVariable { + public MSA.Expression/*!*/ ResultVariable { get { return _resultVariable; } } @@ -79,7 +84,7 @@ set { _parentLoop = value; } } - public LoopScope(MSA.VariableExpression/*!*/ redoVariable, MSA.VariableExpression/*!*/ resultVariable, MSA.LabelTarget/*!*/ label) { + public LoopScope(MSA.Expression/*!*/ redoVariable, MSA.Expression/*!*/ resultVariable, MSA.LabelTarget/*!*/ label) { Assert.NotNull(redoVariable, resultVariable, label); _redoVariable = redoVariable; _resultVariable = resultVariable; @@ -88,12 +93,12 @@ } public sealed class RescueScope : LexicalScope { - private readonly MSA.VariableExpression/*!*/ _retryingVariable; + private readonly MSA.Expression/*!*/ _retryingVariable; private readonly MSA.LabelTarget/*!*/ _label; public RescueScope _parentRescue; - public MSA.VariableExpression/*!*/ RetryingVariable { + public MSA.Expression/*!*/ RetryingVariable { get { return _retryingVariable; } } @@ -106,7 +111,7 @@ get { return _label; } } - public RescueScope(MSA.VariableExpression/*!*/ retryingVariable, MSA.LabelTarget/*!*/ label) { + public RescueScope(MSA.Expression/*!*/ retryingVariable, MSA.LabelTarget/*!*/ label) { Assert.NotNull(retryingVariable, label); _retryingVariable = retryingVariable; _label = label; @@ -133,8 +138,11 @@ } public abstract class FrameScope : SelfScope { + // A unique id of the scope per app-domain. Used for caching calls in dynamic sites. + private readonly int _uniqueId; + private readonly MSA.LambdaBuilder/*!*/ _codeBlock; - private readonly MSA.VariableExpression/*!*/ _runtimeScopeVariable; + private readonly MSA.Expression/*!*/ _runtimeScopeVariable; private BlockScope _parentBlock; private RescueScope _parentRescue; private LoopScope _parentLoop; @@ -143,28 +151,33 @@ get { return _codeBlock; } } - public MSA.VariableExpression/*!*/ RuntimeScopeVariable { + public MSA.Expression/*!*/ RuntimeScopeVariable { get { return _runtimeScopeVariable; } } + public int UniqueId { + get { return _uniqueId; } + } + public BlockScope ParentBlock { get { return _parentBlock; } set { _parentBlock = value; } } public RescueScope ParentRescue { get { return _parentRescue; } set { _parentRescue = value; } } public LoopScope ParentLoop { get { return _parentLoop; } set { _parentLoop = value; } } - public FrameScope(MSA.LambdaBuilder/*!*/ codeBlock, MSA.Expression/*!*/ selfVariable, MSA.VariableExpression/*!*/ runtimeScopeVariable) + public FrameScope(MSA.LambdaBuilder/*!*/ codeBlock, MSA.Expression/*!*/ selfVariable, MSA.Expression/*!*/ runtimeScopeVariable) : base(selfVariable) { Assert.NotNull(codeBlock, runtimeScopeVariable); _codeBlock = codeBlock; _runtimeScopeVariable = runtimeScopeVariable; + _uniqueId = Interlocked.Increment(ref _UniqueId); } } public sealed class BlockScope : FrameScope { - private readonly MSA.ParameterExpression/*!*/ _bfcVariable; + private readonly MSA.Expression/*!*/ _bfcVariable; private readonly MSA.LabelTarget/*!*/ _redoLabel; - public MSA.ParameterExpression/*!*/ BfcVariable { + public MSA.Expression/*!*/ BfcVariable { get { return _bfcVariable; } } @@ -172,8 +185,8 @@ get { return _redoLabel; } } - public BlockScope(MSA.LambdaBuilder/*!*/ codeBlock, MSA.VariableExpression/*!*/ selfVariable, MSA.VariableExpression/*!*/ runtimeScopeVariable, - MSA.ParameterExpression/*!*/ bfcVariable, MSA.LabelTarget/*!*/ redoLabel) + public BlockScope(MSA.LambdaBuilder/*!*/ codeBlock, MSA.Expression/*!*/ selfVariable, MSA.Expression/*!*/ runtimeScopeVariable, + MSA.Expression/*!*/ bfcVariable, MSA.LabelTarget/*!*/ redoLabel) : base(codeBlock, selfVariable, runtimeScopeVariable) { Assert.NotNull(bfcVariable, redoLabel); _bfcVariable = bfcVariable; @@ -182,18 +195,18 @@ } public sealed class MethodScope : FrameScope { - private readonly MSA.ParameterExpression _blockVariable; - private readonly MSA.VariableExpression/*!*/ _rfcVariable; - private readonly MSA.VariableExpression _methodOwner; + private readonly MSA.Expression _blockVariable; + private readonly MSA.Expression/*!*/ _rfcVariable; + private readonly MSA.Expression _currentMethodVariable; private readonly SymbolId _methodName; private readonly Parameters _parameters; private MethodScope _parentMethod; - public MSA.ParameterExpression BlockVariable { + public MSA.Expression BlockVariable { get { return _blockVariable; } } - public MSA.VariableExpression/*!*/ RfcVariable { + public MSA.Expression/*!*/ RfcVariable { get { return _rfcVariable; } } @@ -202,39 +215,48 @@ set { _parentMethod = value; } } + // TODO: super call // non-empty if !IsTopLevelCode public SymbolId MethodName { get { return _methodName; } } + // TODO: super call // non-null if !IsTopLevelCode public Parameters Parameters { get { return _parameters; } } // non-null if !IsTopLevelCode - public MSA.VariableExpression MethodOwner { - get { return _methodOwner; } + public MSA.Expression CurrentMethodVariable { + get { return _currentMethodVariable; } } public bool IsTopLevelCode { get { return _parentMethod == null; } } - public MethodScope(MSA.LambdaBuilder/*!*/ codeBlock, MSA.Expression/*!*/ selfVariable, MSA.VariableExpression/*!*/ runtimeScopeVariable, - MSA.ParameterExpression blockVariable, MSA.VariableExpression/*!*/ rfcVariable, MSA.VariableExpression methodOwner, SymbolId methodName, Parameters parameters) + public MethodScope( + MSA.LambdaBuilder/*!*/ codeBlock, + MSA.Expression/*!*/ selfVariable, + MSA.Expression/*!*/ runtimeScopeVariable, + MSA.Expression blockVariable, + MSA.Expression/*!*/ rfcVariable, + MSA.Expression currentMethodVariable, + SymbolId methodName, + Parameters parameters) : base(codeBlock, selfVariable, runtimeScopeVariable) { Assert.NotNull(rfcVariable); _blockVariable = blockVariable; _rfcVariable = rfcVariable; _methodName = methodName; _parameters = parameters; - _methodOwner = methodOwner; + _currentMethodVariable = currentMethodVariable; } } public sealed class ModuleScope : SelfScope { - private readonly MSA.VariableExpression/*!*/ _runtimeScopeVariable; + private readonly MSA.Expression/*!*/ _runtimeScopeVariable; private readonly bool _isSingleton; private ModuleScope _parentModule; @@ -247,11 +269,11 @@ get { return _isSingleton; } } - public MSA.VariableExpression/*!*/ RuntimeScopeVariable { + public MSA.Expression/*!*/ RuntimeScopeVariable { get { return _runtimeScopeVariable; } } - public ModuleScope(MSA.VariableExpression/*!*/ selfVariable, MSA.VariableExpression/*!*/ runtimeScopeVariable, bool isSingleton) + public ModuleScope(MSA.Expression/*!*/ selfVariable, MSA.Expression/*!*/ runtimeScopeVariable, bool isSingleton) : base(selfVariable) { Assert.NotNull(runtimeScopeVariable); _runtimeScopeVariable = runtimeScopeVariable; @@ -294,7 +316,7 @@ get { return _currentRescue; } } - public MSA.VariableExpression/*!*/ CurrentRfcVariable { + public MSA.Expression/*!*/ CurrentRfcVariable { get { return CurrentMethod.RfcVariable; } } @@ -302,7 +324,7 @@ get { return _currentSelfScope.SelfVariable; } } - public MSA.VariableExpression/*!*/ CurrentScopeVariable { + public MSA.Expression/*!*/ CurrentScopeVariable { get { return (CurrentModule != null) ? CurrentModule.RuntimeScopeVariable : CurrentFrame.RuntimeScopeVariable; } } @@ -322,7 +344,7 @@ #region Entering and Leaving Lexical Scopes - public void EnterLoop(MSA.VariableExpression/*!*/ redoVariable, MSA.VariableExpression/*!*/ resultVariable, MSA.LabelTarget/*!*/ label) { + public void EnterLoop(MSA.Expression/*!*/ redoVariable, MSA.Expression/*!*/ resultVariable, MSA.LabelTarget/*!*/ label) { Assert.NotNull(redoVariable, resultVariable, label); LoopScope loop = new LoopScope(redoVariable, resultVariable, label); @@ -339,7 +361,7 @@ _currentLoop = _currentLoop.ParentLoop; } - public void EnterRescueClause(MSA.VariableExpression/*!*/ retryingVariable, MSA.LabelTarget/*!*/ label) { + public void EnterRescueClause(MSA.Expression/*!*/ retryingVariable, MSA.LabelTarget/*!*/ label) { Assert.NotNull(retryingVariable, label); RescueScope body = new RescueScope(retryingVariable, label); @@ -356,8 +378,8 @@ _currentRescue = _currentRescue.ParentRescue; } - public void EnterBlockDefinition(MSA.LambdaBuilder/*!*/ codeBlock, MSA.ParameterExpression/*!*/ bfcVariable, - MSA.VariableExpression/*!*/ selfVariable, MSA.VariableExpression/*!*/ runtimeScopeVariable, MSA.LabelTarget/*!*/ redoLabel) { + public void EnterBlockDefinition(MSA.LambdaBuilder/*!*/ codeBlock, MSA.Expression/*!*/ bfcVariable, + MSA.Expression/*!*/ selfVariable, MSA.Expression/*!*/ runtimeScopeVariable, MSA.LabelTarget/*!*/ redoLabel) { Assert.NotNull(codeBlock, bfcVariable, selfVariable, redoLabel); BlockScope block = new BlockScope(codeBlock, selfVariable, runtimeScopeVariable, bfcVariable, redoLabel); @@ -388,15 +410,25 @@ public void EnterMethodDefinition( MSA.LambdaBuilder/*!*/ codeBlock, MSA.Expression/*!*/ selfParameter, - MSA.VariableExpression/*!*/ runtimeScopeVariable, - MSA.ParameterExpression blockParameter, - MSA.VariableExpression/*!*/ rfcVariable, - MSA.VariableExpression methodOwnerVariable, + MSA.Expression/*!*/ runtimeScopeVariable, + MSA.Expression blockParameter, + MSA.Expression/*!*/ rfcVariable, + MSA.Expression currentMethodVariable, SymbolId methodName, Parameters parameters) { - Assert.NotNull(codeBlock, selfParameter, rfcVariable); + Assert.NotNull(codeBlock, selfParameter, runtimeScopeVariable, rfcVariable); - MethodScope method = new MethodScope(codeBlock, selfParameter, runtimeScopeVariable, blockParameter, rfcVariable, methodOwnerVariable, methodName, parameters); + MethodScope method = new MethodScope( + codeBlock, + selfParameter, + runtimeScopeVariable, + blockParameter, + rfcVariable, + currentMethodVariable, + methodName, + parameters + ); + method.Parent = _currentElement; method.ParentRescue = _currentRescue; method.ParentLoop = _currentLoop; @@ -424,7 +456,7 @@ _currentMethod = oldMethod.ParentMethod; } - public void EnterModuleDefinition(MSA.VariableExpression/*!*/ selfVariable, MSA.VariableExpression/*!*/ runtimeScopeVariable, bool isSingleton) { + public void EnterModuleDefinition(MSA.Expression/*!*/ selfVariable, MSA.Expression/*!*/ runtimeScopeVariable, bool isSingleton) { Assert.NotNull(selfVariable); ModuleScope module = new ModuleScope(selfVariable, runtimeScopeVariable, isSingleton); @@ -446,14 +478,29 @@ _currentModule = oldModule.ParentModule; } - public void EnterSourceUnit(MSA.LambdaBuilder/*!*/ codeBlock, MSA.VariableExpression/*!*/ rfcVariable, MSA.VariableExpression/*!*/ selfVariable, - MSA.VariableExpression/*!*/ runtimeScopeVariable) { - Assert.NotNull(codeBlock, rfcVariable, selfVariable, runtimeScopeVariable); + public void EnterSourceUnit( + MSA.LambdaBuilder/*!*/ codeBlock, + MSA.Expression/*!*/ selfParameter, + MSA.Expression/*!*/ runtimeScopeVariable, + MSA.Expression blockParameter, + MSA.Expression/*!*/ rfcVariable, + MSA.Expression currentMethodVariable, + SymbolId methodName, + Parameters parameters) { + Assert.NotNull(codeBlock, selfParameter, runtimeScopeVariable, rfcVariable); Debug.Assert(_currentElement == null && _currentLoop == null && _currentRescue == null && _currentSelfScope == null && _currentModule == null && _currentBlock == null && _currentMethod == null); - EnterMethodDefinition(codeBlock, selfVariable, runtimeScopeVariable, null, rfcVariable, null, SymbolId.Empty, null); + EnterMethodDefinition( + codeBlock, + selfParameter, + runtimeScopeVariable, + blockParameter, + rfcVariable, + currentMethodVariable, + methodName, + parameters); } public void LeaveSourceUnit() { @@ -491,7 +538,7 @@ return Ast.SimpleCallHelper(CurrentRfcVariable, RuntimeFlowControl.GetMethod(methodName), args); } - internal MSA.MethodCallExpression/*!*/ RfcCall(string/*!*/ methodName, MSA.VariableExpression/*!*/ arg) { + internal MSA.MethodCallExpression/*!*/ RfcCall(string/*!*/ methodName, MSA.Expression/*!*/ arg) { Assert.NotNull(methodName, arg); Debug.Assert(_currentMethod != null); @@ -542,93 +589,53 @@ return result; } - internal MSA.Block/*!*/ TransformStatements(List/*!*/ statements, ResultOperation resultOperation) { + internal MSA.Expression/*!*/ TransformStatements(List/*!*/ statements, ResultOperation resultOperation) { Assert.NotNullItems(statements); - if (resultOperation.IsIgnore) { - return TransformStatements(statements); - } - - ExpressionStatement exprStmt; - - // if the last statement is an expression-statement, the result is , otherwise it's Null: if (statements.Count > 0) { - exprStmt = statements[statements.Count - 1] as ExpressionStatement; - } else { - exprStmt = null; - } + MSA.Expression[] result = new MSA.Expression[statements.Count]; - MSA.Expression[] result = new MSA.Expression[statements.Count + (exprStmt == null ? 1 : 0)]; + // transform all but the last statement if it is an expression stmt: + for (int i = 0; i < statements.Count - 1; i++) { + result[i] = statements[i].Transform(this); + } - // transform all but the last statement if it is an expression stmt: - for (int i = 0; i < statements.Count - (exprStmt != null ? 1 : 0); i++) { - result[i] = statements[i].Transform(this); - } + if (resultOperation.IsIgnore) { + result[result.Length - 1] = statements[statements.Count - 1].Transform(this); + } else { + result[result.Length - 1] = statements[statements.Count - 1].TransformResult(this, resultOperation); + } - MSA.Expression resultExpr; - SourceSpan location; - - if (exprStmt != null) { - resultExpr = exprStmt.Expression.TransformRead(this); - location = exprStmt.Location; + return Ast.Block(result); } else { - resultExpr = Ast.Null(); - location = SourceSpan.None; + if (resultOperation.IsIgnore) { + return Ast.Empty(); + } else if (resultOperation.Variable != null) { + return Ast.Assign(resultOperation.Variable, Ast.Null(resultOperation.Variable.Type)); + } else { + return AstUtils.Return(Ast.Null(), SourceSpan.None); + } } + } - if (resultOperation.Variable != null) { - result[result.Length - 1] = Ast.Assign(resultOperation.Variable, Ast.Convert(resultExpr, resultOperation.Variable.Type)); - } else { - result[result.Length - 1] = AstUtils.Return(resultExpr, location); + internal MSA.Expression/*!*/ TransformStatementsToExpression(List statements) { + if (statements == null || statements.Count == 0) { + return Ast.Null(); } - return Ast.Block(result); - } + if (statements.Count == 1) { + return statements[0].TransformRead(this); + } - internal MSA.Block/*!*/ TransformStatements(List/*!*/ statements) { - Assert.NotNull(statements); - MSA.Expression[] result = new MSA.Expression[statements.Count]; - for (int i = 0; i < result.Length; i++) { + for (int i = 0; i < result.Length - 1; i++) { result[i] = statements[i].Transform(this); } + result[result.Length - 1] = statements[statements.Count - 1].TransformRead(this); - return Ast.Block(result); + return Ast.Comma(result); } - internal MSA.Expression/*!*/ TransformStatementsToExpression(List statements) { - if (statements != null && statements.Count > 0) { - MSA.Expression[] result; - - ExpressionStatement lastExprStmt = statements[statements.Count - 1] as ExpressionStatement; - if (lastExprStmt != null) { - - if (statements.Count == 1) { - return lastExprStmt.Expression.TransformRead(this); - } - - result = new MSA.Expression[statements.Count]; - - for (int i = 0; i < result.Length - 1; i++) { - result[i] = statements[i].Transform(this); - } - result[result.Length - 1] = lastExprStmt.Expression.TransformRead(this); - - } else { - result = new MSA.Expression[statements.Count + 1]; - - for (int i = 0; i < result.Length - 1; i++) { - result[i] = statements[i].Transform(this); - } - result[result.Length - 1] = Ast.Null(); - } - return Ast.Comma(result); - - } else { - return Ast.Null(); - } - } - internal List/*!*/ TransformMapletsToExpressions(IList/*!*/ maplets) { Assert.NotNullItems(maplets); return TransformMapletsToExpressions(maplets, new List(maplets.Count * 2)); @@ -659,26 +666,12 @@ ); } + internal MSA.Expression/*!*/ DebugMarker(string/*!*/ marker) { + return _debugCompiler ? AstFactory.OpCall("X", Ast.Constant(marker)) : (MSA.Expression)Ast.Empty(); + } - public MSA.Expression Condition(MSA.Expression test, MSA.Expression ifTrue, MSA.Expression ifFalse) { - Debug.Assert(test != null); - - if (test.Type != typeof(bool)) { - test = Ast.Action.ConvertTo(_binder, typeof(bool), Ast.CodeContext(), test); - } - - if (ifTrue.Type != ifFalse.Type) { - if (ifTrue.Type.IsAssignableFrom(ifFalse.Type)) { - ifFalse = Ast.Convert(ifFalse, ifTrue.Type); - } else if (ifFalse.Type.IsAssignableFrom(ifTrue.Type)) { - ifTrue = Ast.Convert(ifTrue, ifFalse.Type); - } else { - ifTrue = Ast.Convert(ifTrue, typeof(object)); - ifFalse = Ast.Convert(ifFalse, typeof(object)); - } - } - - return Ast.Condition(test, ifTrue, ifFalse); + internal MSA.Expression/*!*/ DebugMark(MSA.Expression/*!*/ expression, string/*!*/ marker) { + return _debugCompiler ? Ast.Comma(AstFactory.OpCall("X", Ast.Constant(marker)), expression) : expression; } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/ResultOperation.cs;C402444 File: ResultOperation.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/ResultOperation.cs;C402444 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/ResultOperation.cs;Super17 @@ -27,19 +27,19 @@ public static readonly ResultOperation Return = new ResultOperation(null, true); public static readonly ResultOperation Ignore = new ResultOperation(null, false); - private MSA.VariableExpression _variable; + private MSA.Expression _variable; private bool _doReturn; - public MSA.VariableExpression Variable { get { return _variable; } } + public MSA.Expression Variable { get { return _variable; } } public bool DoReturn { get { return _doReturn; } } public bool IsIgnore { get { return _variable == null && !_doReturn; } } - public ResultOperation(MSA.VariableExpression variable, bool doReturn) { + public ResultOperation(MSA.Expression variable, bool doReturn) { _variable = variable; _doReturn = doReturn; } - public static ResultOperation Store(MSA.VariableExpression/*!*/ variable) { + public static ResultOperation Store(MSA.Expression/*!*/ variable) { Assert.NotNull(variable); return new ResultOperation(variable, false); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/RubyCompilerOptions.cs;C420856 File: RubyCompilerOptions.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/RubyCompilerOptions.cs;C420856 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/RubyCompilerOptions.cs;Super17 @@ -24,24 +24,33 @@ private bool _isEval; private bool _isIncluded; private bool _isWrapped; + private SymbolId _topLevelMethodName; private List _localNames; - public bool IsEval { + internal bool IsEval { get { return _isEval; } set { _isEval = value; } } - public bool IsIncluded { + internal bool IsIncluded { get { return _isIncluded; } set { _isIncluded = value; } } - public bool IsWrapped { + internal bool IsWrapped { get { return _isWrapped; } set { _isWrapped = value; } } - public List LocalNames { + /// + /// Method name used by super in eval. + /// + internal SymbolId TopLevelMethodName { + get { return _topLevelMethodName; } + set { _topLevelMethodName = value; } + } + + internal List LocalNames { get { return _localNames; } set { _localNames = value; } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/AstFactory.cs;C428685 File: AstFactory.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/AstFactory.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/AstFactory.cs;Super17 @@ -28,6 +28,7 @@ namespace Ruby.Compiler.Ast { using Ast = Microsoft.Scripting.Ast.Expression; + using AstUtils = Microsoft.Scripting.Ast.Utils; using MSA = Microsoft.Scripting.Ast; internal static class AstFactory { @@ -37,7 +38,7 @@ #region Assignments - public static MSA.Expression/*!*/ AssignValueWithCast(MSA.VariableExpression/*!*/ variable, Type/*!*/ variableType, FieldInfo/*!*/ field, object value) { + public static MSA.Expression/*!*/ AssignValueWithCast(MSA.Expression/*!*/ variable, Type/*!*/ variableType, FieldInfo/*!*/ field, object value) { Assert.NotNull(variable, variableType, field); return Ast.AssignField( Ast.Convert(variable, variableType), field, Ast.Constant(value) @@ -48,30 +49,31 @@ #region Control Flow - public static MSA.Expression/*!*/ MakeUserMethodBody(MSA.Expression/*!*/ blockParameter, MSA.VariableExpression/*!*/ rfcVariable, - MSA.VariableExpression parentScopeVariable, - MSA.VariableExpression scopeVariable, + public static MSA.Expression/*!*/ MakeUserMethodBody(MSA.Expression/*!*/ blockParameter, MSA.Expression/*!*/ rfcVariable, + MSA.Expression parentScopeVariable, + MSA.Expression scopeVariable, MSA.Expression selfVariable, MSA.VariableExpression/*!*/ methodUnwinder, - SymbolId name, + MSA.Expression methodDefinition, MSA.Expression/*!*/ bodyStatement) { Assert.NotNull(blockParameter, rfcVariable, bodyStatement, methodUnwinder); - Debug.Assert(((parentScopeVariable == null) == (scopeVariable == null))); - Debug.Assert(((parentScopeVariable == null) == (selfVariable == null))); + bool isGenerated = parentScopeVariable == null; + + Debug.Assert(isGenerated == (scopeVariable == null)); + Debug.Assert(isGenerated == (selfVariable == null)); + Debug.Assert(isGenerated == (methodDefinition == null)); + return Ast.Try( // initialize frame (RFC): Ast.Assign(rfcVariable, Ast.Call(RuntimeFlowControl.GetMethod("CreateForMethod"), blockParameter)), + + (isGenerated) ? Ast.Empty() : + (MSA.Expression)Ast.Assign(scopeVariable, + AstFactory.OpCall("InitializeMethodScope", methodDefinition, Ast.CodeContext(), rfcVariable, selfVariable, blockParameter) + ), - (scopeVariable == null) ? Ast.Empty() : - (MSA.Expression)Ast.Assign(scopeVariable, AstFactory.OpCall("InitializeMethodScope", -#if DEBUG - Ast.Constant(name), -#endif - Ast.CodeContext(), rfcVariable, selfVariable - )), - bodyStatement ).Filter(typeof(MethodUnwinder), methodUnwinder, AstFactory.Equal(methodUnwinder, MethodUnwinder.TargetFrameField, rfcVariable, null), @@ -85,13 +87,17 @@ #endregion - public static MSA.Expression/*!*/ Result(MSA.VariableExpression/*!*/ resultVariable, MSA.Expression/*!*/ statement) { + public static MSA.Expression/*!*/ Result(MSA.Expression/*!*/ resultVariable, MSA.Expression/*!*/ statement) { return Ast.Comma( statement, resultVariable ); } + public static MSA.Expression/*!*/ Infinite(MSA.LabelTarget/*!*/ label, params MSA.Expression[]/*!*/ body) { + return AstUtils.Infinite(Ast.Block(body), label); + } + public static MSA.MethodCallExpression/*!*/ OptimizedOpCall(string/*!*/ methodName, params MSA.Expression[]/*!*/ args) { Assert.NotNull(methodName, args); @@ -112,13 +118,31 @@ return Ast.SimpleCallHelper(typeof(RubyOps).GetMethod(methodName, BindingFlags.Public | BindingFlags.Static), args); } + public static MSA.Expression/*!*/ Condition(MSA.Expression/*!*/ test, MSA.Expression/*!*/ ifTrue, MSA.Expression/*!*/ ifFalse) { + Assert.NotNull(test, ifTrue, ifFalse); + Debug.Assert(test.Type == typeof(bool)); + + if (ifTrue.Type != ifFalse.Type) { + if (ifTrue.Type.IsAssignableFrom(ifFalse.Type)) { + ifFalse = Ast.Convert(ifFalse, ifTrue.Type); + } else if (ifFalse.Type.IsAssignableFrom(ifTrue.Type)) { + ifTrue = Ast.Convert(ifTrue, ifFalse.Type); + } else { + ifTrue = Ast.Convert(ifTrue, typeof(object)); + ifFalse = Ast.Convert(ifFalse, typeof(object)); + } + } + + return Ast.Condition(test, ifTrue, ifFalse); + } + #region Equal - public static MSA.Expression/*!*/ Equal(MSA.VariableExpression leftVariable, FieldInfo leftField, object value) { + public static MSA.Expression/*!*/ Equal(MSA.Expression leftVariable, FieldInfo leftField, object value) { return Equal(leftVariable, leftField, Ast.Constant(value)); } - public static MSA.Expression/*!*/ Equal(MSA.VariableExpression leftVariable, FieldInfo leftField, MSA.Expression/*!*/ expression) { + public static MSA.Expression/*!*/ Equal(MSA.Expression leftVariable, FieldInfo leftField, MSA.Expression/*!*/ expression) { Debug.Assert(expression != null); Debug.Assert(leftVariable != null || leftField != null); @@ -127,7 +151,7 @@ return Ast.Equal(lhs, expression); } - public static MSA.Expression/*!*/ Equal(MSA.VariableExpression leftVariable, FieldInfo leftField, MSA.VariableExpression rightVariable, FieldInfo rightField) { + public static MSA.Expression/*!*/ Equal(MSA.Expression leftVariable, FieldInfo leftField, MSA.Expression rightVariable, FieldInfo rightField) { Debug.Assert(rightVariable != null || rightField != null); MSA.Expression rhs = (rightField == null) ? rightVariable : =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/BlockDefinition.cs;C428685 File: BlockDefinition.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/BlockDefinition.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/BlockDefinition.cs;Super17 @@ -60,8 +60,8 @@ } private MSA.ParameterExpression[]/*!*/ DefineParameters(MSA.LambdaBuilder/*!*/ block, - out MSA.ParameterExpression/*!*/ selfVariable, - out MSA.ParameterExpression/*!*/ blockParamVariable) { + out MSA.Expression/*!*/ selfVariable, + out MSA.Expression/*!*/ blockParamVariable) { MSA.ParameterExpression[] parameters = new MSA.ParameterExpression[ HiddenParameterCount + @@ -72,12 +72,13 @@ // hidden parameters: // #proc must be the first one - it is used as instance target for method invocation: blockParamVariable = parameters[0] = Ast.Parameter(typeof(BlockParam), "#proc"); - selfVariable = parameters[1] = Ast.Parameter(typeof(object), "#self-param"); // TODO + selfVariable = parameters[1] = Ast.Parameter(typeof(object), "#self"); for (int i = HiddenParameterCount; i < parameters.Length; i++) { parameters[i] = Ast.Parameter(typeof(object), "#" + (i - HiddenParameterCount)); } + block.Parameters.AddRange(parameters); return parameters; } @@ -92,18 +93,16 @@ string id = System.Threading.Interlocked.Increment(ref _id).ToString(); // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment): - MSA.ParameterExpression blockParamVariable, selfParameter; - // TODO: remove - MSA.VariableExpression selfVariable = codeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#self-temp"), typeof(object)); - MSA.ParameterExpression[] parameters = DefineParameters(codeBlock, out selfParameter, out blockParamVariable); - // TODO: - MSA.VariableExpression scopeVariable = gen.CurrentScopeVariable; //codeBlock.CreateLocalVariable(SymbolTable.StringToId("#scope" + id), typeof(RubyScope)); + MSA.Expression blockParameter, selfParameter; + MSA.Expression[] parameters = DefineParameters(codeBlock, out selfParameter, out blockParameter); + + MSA.Expression scopeVariable = codeBlock.CreateLocalVariable(SymbolTable.StringToId("#scope" + id), typeof(RubyScope)); MSA.LabelTarget loopLabel = Ast.Label(); gen.EnterBlockDefinition( codeBlock, - blockParamVariable, - selfVariable, + blockParameter, + selfParameter, scopeVariable, loopLabel ); @@ -113,15 +112,13 @@ } MSA.Expression paramInit = Ast.Block(MakeParametersInitialization(gen, parameters)); - MSA.VariableExpression blockUnwinder = codeBlock.CreateLocalVariable(SymbolTable.StringToId("#unwinder"), typeof(BlockUnwinder)); + MSA.Expression blockUnwinder = codeBlock.CreateLocalVariable(SymbolTable.StringToId("#unwinder"), typeof(BlockUnwinder)); codeBlock.Body = Ast.Block( - // TODO: remove: - Ast.Assign(selfVariable, selfParameter), - + Ast.Assign(scopeVariable, AstFactory.OpCall("InitializeBlockScope", Ast.CodeContext(), blockParameter, selfParameter)), paramInit, - AstUtils.Infinite( + AstFactory.Infinite(loopLabel, Ast.Try( gen.TransformStatements(_body, ResultOperation.Return) ).Catch(typeof(BlockUnwinder), blockUnwinder, @@ -130,8 +127,7 @@ // next: Ast.Return(Ast.ReadField(blockUnwinder, BlockUnwinder.ReturnValueField)) - ), - loopLabel + ) ) ); @@ -148,7 +144,7 @@ }); } - private List/*!*/ MakeParametersInitialization(AstGenerator/*!*/ gen, MSA.ParameterExpression[]/*!*/ parameters) { + private List/*!*/ MakeParametersInitialization(AstGenerator/*!*/ gen, MSA.Expression[]/*!*/ parameters) { Assert.NotNull(gen); Assert.NotNullItems(parameters); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/BlockReference.cs;C402444 File: BlockReference.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/BlockReference.cs;C402444 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/BlockReference.cs;Super17 @@ -16,10 +16,13 @@ using Microsoft.Scripting; using Microsoft.Scripting.Utils; +using Ruby.Runtime.Calls; +using Ruby.Builtins; + namespace Ruby.Compiler.Ast { using MSA = Microsoft.Scripting.Ast; using Ast = Microsoft.Scripting.Ast.Expression; - + public partial class BlockReference : Block { private readonly Expression/*!*/ _expression; @@ -38,8 +41,12 @@ internal override MSA.Expression/*!*/ Transform(AstGenerator/*!*/ gen) { Assert.NotNull(gen); - return _expression.TransformRead(gen); + return Ast.Action.ActionExpression( + Annotations.Empty, + ConvertToProcAction.Instance, + new MSA.Expression[] { Ast.CodeContext(), _expression.TransformRead(gen) }, + typeof(Proc) + ); } - } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Body.cs;C428685 File: Body.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Body.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Body.cs;Super17 @@ -69,7 +69,7 @@ Assert.NotNull(gen); if (HasExceptionHandling) { - MSA.VariableExpression resultVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#block-result"), typeof(object)); + MSA.Expression resultVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#block-result"), typeof(object)); return Ast.Comma( TransformExceptionHandling(gen, ResultOperation.Store(resultVariable)), @@ -94,12 +94,12 @@ private MSA.Expression/*!*/ TransformExceptionHandling(AstGenerator/*!*/ gen, ResultOperation resultOperation) { Assert.NotNull(gen); - MSA.VariableExpression/*!*/ exceptionThrownVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#exception-thrown"), typeof(bool)); + MSA.Expression/*!*/ exceptionThrownVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#exception-thrown"), typeof(bool)); MSA.VariableExpression/*!*/ exceptionVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#exception"), typeof(Exception)); - MSA.VariableExpression/*!*/ exceptionRethrowVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#exception-rethrow"), typeof(bool)); - MSA.VariableExpression/*!*/ retryingVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#retrying"), typeof(bool)); + MSA.Expression/*!*/ exceptionRethrowVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#exception-rethrow"), typeof(bool)); + MSA.Expression/*!*/ retryingVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#retrying"), typeof(bool)); MSA.VariableExpression/*!*/ evalUnwinder = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#unwinder"), typeof(EvalUnwinder)); - MSA.VariableExpression/*!*/ oldExceptionVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#old-exception"), typeof(Exception)); + MSA.Expression/*!*/ oldExceptionVariable = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#old-exception"), typeof(Exception)); MSA.Expression/*!*/ transformedBody; MSA.Expression/*!*/ transformedEnsure; @@ -187,7 +187,7 @@ )); } - MSA.Expression result = AstUtils.Infinite(Ast.Block( + MSA.Expression result = AstFactory.Infinite(label, Ast.Assign(exceptionThrownVariable, Ast.False()), Ast.Assign(exceptionRethrowVariable, Ast.False()), Ast.Assign(retryingVariable, Ast.False()), @@ -224,9 +224,9 @@ transformedEnsure )) ), - // break + Ast.Break(label) - ), label); + ); return result; } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/CallBuilder.cs;C427097 File: CallBuilder.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/CallBuilder.cs;C427097 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/CallBuilder.cs;Super17 @@ -20,6 +20,10 @@ namespace Ruby.Compiler.Ast { using MSA = Microsoft.Scripting.Ast; using Ast = Microsoft.Scripting.Ast.Expression; + using Ruby.Runtime.Calls; + using Microsoft.Scripting.Ast; + using Microsoft.Scripting.Utils; + using System; /// /// Simple helper for building up method invoke/call actions @@ -53,13 +57,17 @@ _args.Insert(index, new KeyValuePair(expression, kind)); } - public MSA.Expression/*!*/ MakeInvokeAction(SymbolId name, bool hasExplicitTarget) { - InvokeMemberActionFlags flags = InvokeMemberActionFlags.ReturnNonCallable; - if (hasExplicitTarget) flags |= InvokeMemberActionFlags.IsCallWithThis; + public MSA.Expression/*!*/ MakeInvokeAction(SymbolId name) { + return Ast.Action.InvokeMember(_gen.Binder, name, typeof(object), new CallSignature(ArgumentKinds), GetExpressions()); + } - return Ast.Action.InvokeMember( - _gen.Binder, - name, typeof(object), flags, new CallSignature(ArgumentKinds), GetExpressions()); + public MSA.Expression/*!*/ MakeSuperCallAction(int lexicalScopeId) { + return Ast.Action.ActionExpression( + Annotations.Empty, + SuperCallAction.Make(_gen.Binder, new CallSignature(ArgumentKinds), lexicalScopeId), + GetExpressions(), + typeof(object) + ); } public MSA.Expression/*!*/ MakeCallAction() { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Parameters.cs;C428685 File: Parameters.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Parameters.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Parameters.cs;Super17 @@ -74,7 +74,7 @@ if (_optional == null) return Ast.Empty(); - MSA.VariableExpression singleton = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#default"), typeof(object)); + MSA.Expression singleton = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#default"), typeof(object)); MSA.Expression result = Ast.Empty(); for (int i = 0; i < _optional.Count; i++) { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/SourceUnitTree.cs;C428685 File: SourceUnitTree.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/SourceUnitTree.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/SourceUnitTree.cs;Super17 @@ -17,17 +17,18 @@ using System.Text; using System.Diagnostics; using Microsoft.Scripting; +using Microsoft.Scripting.Utils; +using Microsoft.Scripting.Actions; + using Ruby.Runtime; -using Microsoft.Scripting.Utils; +using Ruby.Builtins; +using Ruby.Runtime.Calls; namespace Ruby.Compiler.Ast { - using MSA = Microsoft.Scripting.Ast; using Ast = Microsoft.Scripting.Ast.Expression; using AstUtils = Microsoft.Scripting.Ast.Utils; - using Microsoft.Scripting.Hosting; - using Microsoft.Scripting.Actions; - using Ruby.Builtins; - + using MSA = Microsoft.Scripting.Ast; + public partial class SourceUnitTree : Node { private readonly LexicalScope/*!*/ _definedScope; @@ -57,52 +58,65 @@ MSA.LambdaBuilder method = AstUtils.Lambda(typeof(object), "main", Location); method.Dictionary = true; - MSA.VariableExpression rfcVariable, selfVariable, runtimeScopeVariable, resultVariable; - MSA.Expression scopeInit, print; + MSA.Expression rfcVariable, selfVariable, runtimeScopeVariable; + MSA.Expression blockParameter = null, currentMethodVariable = null; + List body = new List(); rfcVariable = method.CreateLocalVariable(SymbolTable.StringToId("#rfc"), typeof(RuntimeFlowControl)); selfVariable = method.CreateLocalVariable(SymbolTable.StringToId("#self"), typeof(object)); runtimeScopeVariable = method.CreateLocalVariable(SymbolTable.StringToId("#scope"), typeof(RubyScope)); - gen.EnterSourceUnit(method, rfcVariable, selfVariable, runtimeScopeVariable); - if (gen.CompilerOptions.IsEval) { method.ScopeFactory = typeof(RubyOps).GetMethod("CreateEvalScope"); - scopeInit = Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeEvalScope", Ast.CodeContext())); + body.Add(Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeEvalScope", Ast.CodeContext()))); + + blockParameter = method.CreateLocalVariable(SymbolTable.StringToId("#block"), typeof(Proc)); + currentMethodVariable = method.CreateLocalVariable(SymbolTable.StringToId("#method"), typeof(RubyMethodInfo)); + body.Add(Ast.Assign(blockParameter, AstFactory.OpCall("GetCurrentMethodBlockParameter", runtimeScopeVariable))); + body.Add(Ast.Assign(currentMethodVariable, AstFactory.OpCall("GetCurrentMethodDefinition", runtimeScopeVariable))); + } else if (!gen.CompilerOptions.IsIncluded) { method.ScopeFactory = typeof(RubyOps).GetMethod("CreateMainTopLevelScope"); - scopeInit = Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeTopLevelScope", Ast.CodeContext())); + body.Add(Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeTopLevelScope", Ast.CodeContext()))); } else if (gen.CompilerOptions.IsWrapped) { method.ScopeFactory = typeof(RubyOps).GetMethod("CreateTopLevelScope"); - scopeInit = Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeWrappedTopLevelScope", Ast.CodeContext())); + body.Add(Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeWrappedTopLevelScope", Ast.CodeContext()))); } else { method.ScopeFactory = typeof(RubyOps).GetMethod("CreateTopLevelScope"); - scopeInit = Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeTopLevelScope", Ast.CodeContext())); + body.Add(Ast.Assign(runtimeScopeVariable, AstFactory.OpCall("InitializeTopLevelScope", Ast.CodeContext()))); } - if (kind == SourceCodeKind.InteractiveCode) { - resultVariable = method.CreateTemporaryVariable(SymbolTable.StringToId("#result"), typeof(object)); - print = AstFactory.OpCall("PrintInteractiveResult", runtimeScopeVariable, - Ast.Action.InvokeMember(RubySites.InstanceCallAction("inspect"), typeof(object), Ast.CodeContext(), resultVariable) - ); - } else { - resultVariable = null; - print = Ast.Empty(); - } + body.Add(Ast.Assign(rfcVariable, AstFactory.OpCall("GetRfc", runtimeScopeVariable))); + body.Add(Ast.Assign(selfVariable, AstFactory.OpCall("GetSelf", runtimeScopeVariable))); + + gen.EnterSourceUnit( + method, + selfVariable, + runtimeScopeVariable, + blockParameter, + rfcVariable, + currentMethodVariable, + gen.CompilerOptions.TopLevelMethodName, // method name + null // parameters + ); _definedScope.TransformLocals(method, gen); - method.Body = Ast.Block( - scopeInit, - Ast.Assign(rfcVariable, AstFactory.OpCall("GetRfc", runtimeScopeVariable)), - Ast.Assign(selfVariable, AstFactory.OpCall("GetSelf", runtimeScopeVariable)), + if (kind == SourceCodeKind.InteractiveCode) { + MSA.Expression resultVariable = method.CreateTemporaryVariable(SymbolTable.StringToId("#result"), typeof(object)); + + body.Add(gen.TransformStatements(_statements, ResultOperation.Store(resultVariable))); - gen.TransformStatements(_statements, (kind != SourceCodeKind.InteractiveCode) ? - ResultOperation.Return : ResultOperation.Store(resultVariable)), + body.Add(AstFactory.OpCall("PrintInteractiveResult", runtimeScopeVariable, + Ast.Action.InvokeMember(RubySites.InstanceCallAction("inspect"), typeof(object), Ast.CodeContext(), resultVariable) + )); - print - ); + } else { + body.Add(gen.TransformStatements(_statements, ResultOperation.Return)); + } + method.Body = Ast.Block(body); + gen.LeaveSourceUnit(); return method.MakeLambda(); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Clauses/RescueClause.cs;C428685 File: RescueClause.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Clauses/RescueClause.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Clauses/RescueClause.cs;Super17 @@ -77,7 +77,7 @@ MSA.Expression[] temps = new MSA.Expression[_types.Count]; MSA.Expression[] exprs = new MSA.Expression[_types.Count + 1]; for (int i = 0; i < temps.Length; i++) { - MSA.VariableExpression tmp = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#type_" + i), typeof(object)); + MSA.Expression tmp = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#type_" + i), typeof(object)); temps[i] = tmp; exprs[i] = Ast.Assign(tmp, _types[i].TransformRead(gen)); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/MethodDeclaration.cs;C428685 File: MethodDeclaration.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/MethodDeclaration.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/MethodDeclaration.cs;Super17 @@ -14,14 +14,16 @@ * ***************************************************************************/ using Microsoft.Scripting; +using Microsoft.Scripting.Utils; + using Ruby.Builtins; using Ruby.Runtime; +using Ruby.Runtime.Calls; namespace Ruby.Compiler.Ast { using Ast = Microsoft.Scripting.Ast.Expression; using AstUtils = Microsoft.Scripting.Ast.Utils; using MSA = Microsoft.Scripting.Ast; - using Microsoft.Scripting.Utils; public partial class MethodDeclaration : DeclarationExpression { @@ -57,7 +59,7 @@ _parameters = parameters ?? Parameters.Empty; } - private MSA.ParameterExpression[]/*!*/ DefineParameters(AstGenerator/*!*/ gen, MSA.LambdaBuilder/*!*/ block) { + private MSA.Expression[]/*!*/ DefineParameters(AstGenerator/*!*/ gen, MSA.LambdaBuilder/*!*/ block) { // user defined locals/args: MSA.ParameterExpression[] parameters = DefinedScope.TransformParameters(_parameters, HiddenParameterCount); @@ -76,23 +78,21 @@ return parameters; } - internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) { - MSA.VariableExpression methodOwnerVar = gen.CurrentCodeBlock.CreateLocalVariable(SymbolTable.StringToId("#method-owner"), typeof(RubyModule)); - MSA.Expression transformedTarget = (_target != null) ? _target.TransformRead(gen) : Ast.Null(); + private MSA.Expression/*!*/ TransformBody(AstGenerator/*!*/ gen, MSA.Expression/*!*/ methodDefinitionVariable) { + MSA.LambdaBuilder methodBlock = AstUtils.Lambda(typeof(object), SymbolTable.IdToString(_name), Location); - MSA.LambdaBuilder methodBlock = AstUtils.Lambda(typeof(object), SymbolTable.IdToString(_name), Location); - methodBlock.ScopeFactory = typeof(RubyOps).GetMethod("CreateMethodScope"); methodBlock.Dictionary = true; // enable closure: - MSA.VariableExpression parentScopeVariable = gen.CurrentScopeVariable; + MSA.Expression parentScopeVariable = gen.CurrentScopeVariable; - MSA.ParameterExpression[] parameters = DefineParameters(gen, methodBlock); - MSA.VariableExpression rfcVariable = methodBlock.CreateLocalVariable(SymbolTable.StringToId("#rfc"), typeof(RuntimeFlowControl)); - MSA.VariableExpression scopeVariable = methodBlock.CreateLocalVariable(SymbolTable.StringToId("#scope"), typeof(RubyScope)); - MSA.ParameterExpression selfParameter = parameters[0]; - MSA.ParameterExpression blockParameter = parameters[1]; + MSA.Expression[] parameters = DefineParameters(gen, methodBlock); + MSA.Expression currentMethodVariable = methodBlock.CreateLocalVariable(SymbolTable.StringToId("#method"), typeof(RubyMethodInfo)); + MSA.Expression rfcVariable = methodBlock.CreateLocalVariable(SymbolTable.StringToId("#rfc"), typeof(RuntimeFlowControl)); + MSA.Expression scopeVariable = methodBlock.CreateLocalVariable(SymbolTable.StringToId("#scope"), typeof(RubyScope)); + MSA.Expression selfParameter = parameters[0]; + MSA.Expression blockParameter = parameters[1]; gen.EnterMethodDefinition( methodBlock, @@ -100,7 +100,7 @@ scopeVariable, blockParameter, rfcVariable, - methodOwnerVar, + currentMethodVariable, _name, _parameters ); @@ -110,14 +110,15 @@ MSA.VariableExpression unwinder = gen.CurrentCodeBlock.CreateTemporaryVariable(SymbolTable.StringToId("#unwinder"), typeof(MethodUnwinder)); methodBlock.Body = AstFactory.MakeUserMethodBody( - blockParameter, - rfcVariable, - parentScopeVariable, - scopeVariable, + blockParameter, + rfcVariable, + parentScopeVariable, + scopeVariable, selfParameter, unwinder, - _name, + methodDefinitionVariable, Ast.Block( + Ast.Assign(currentMethodVariable, methodDefinitionVariable), _parameters.TransformOptionalsInitialization(gen), Body.TransformToStatement(gen, ResultOperation.Return) ) @@ -125,24 +126,28 @@ gen.LeaveMethodDefinition(); + return AstFactory.LambdaExpression(methodBlock); + } + + internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) { + MSA.Expression methodDefinitionVariable = gen.CurrentCodeBlock.CreateLocalVariable( + SymbolTable.StringToId("#method_" + SymbolTable.IdToString(_name)), typeof(RubyMethodInfo) + ); + return Ast.Comma( - Ast.Assign( - methodOwnerVar, - Ast.Call(RubyOps.GetMethod("GetMethodOwner"), + Ast.Assign(methodDefinitionVariable, + AstFactory.OpCall("DefineMethod", + (_target != null) ? _target.TransformRead(gen) : gen.CurrentSelfVariable, // target Ast.CodeContext(), - transformedTarget, - Ast.Constant(_target != null) + Ast.Constant(_target != null), // isSingleton? + Ast.Constant(_name), + TransformBody(gen, methodDefinitionVariable), + Ast.Constant(_parameters.MandatoryCount), + Ast.Constant(_parameters.OptionalCount), + Ast.Constant(_parameters.Array != null) // hasParamsArray ) ), - AstFactory.OpCall("DefineMethod", - Ast.CodeContext(), - methodOwnerVar, - Ast.Constant(_name), - AstFactory.LambdaExpression(methodBlock), - Ast.Constant(_parameters.MandatoryCount), - Ast.Constant(_parameters.OptionalCount), - Ast.Constant(_parameters.Array != null) - ) + Ast.Null() ); } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/ModuleDeclaration.cs;C428685 File: ModuleDeclaration.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/ModuleDeclaration.cs;C428685 (server) 5/3/2008 11:37 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/ModuleDeclaration.cs;Super17 @@ -78,14 +78,14 @@ // definition needs to take place outside the defined lexical scope: MSA.Expression definition = MakeDefinitionExpression(gen); - MSA.VariableExpression rfcVariable = gen.CurrentRfcVari