edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Console/Program.cs;C402163
File: Program.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Console/Program.cs;C402163  (server)    5/21/2008 1:50 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Console/Program.cs;Caller1
@@ -26,6 +26,7 @@
 using Microsoft.Scripting.Generation;
 using Microsoft.Scripting.Hosting.Shell;
 using Ruby.Runtime;
+using Ruby;
 
 internal sealed class RubyConsoleHost : ConsoleHost {
 
@@ -42,6 +43,7 @@
     }
 
     [STAThread]
+    [RubyStackTraceHidden]
     static int Main(string[] args) {
         return new RubyConsoleHost().Run(args);
     }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C445173
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C445173  (server)    5/21/2008 11:02 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;Caller1
@@ -49,9 +49,9 @@
             #endif
             // Skipped primitive: Object
             ExtendModule(typeof(System.Collections.Generic.IDictionary<System.Object, System.Object>), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
-            ExtendModule(typeof(System.Collections.IEnumerable), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
+            Ruby.Builtins.RubyModule def29 = ExtendModule(typeof(System.Collections.IEnumerable), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
             ExtendModule(typeof(System.Collections.IList), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
-            Ruby.Builtins.RubyModule def29 = ExtendModule(typeof(System.IComparable), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def25, });
+            ExtendModule(typeof(System.IComparable), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def25, });
             DefineGlobalClass("Time", typeof(System.DateTime), classRef0, new System.Action<Ruby.Builtins.RubyModule>(LoadTime_Instance), new System.Action<Ruby.Builtins.RubyModule>(LoadTime_Class), new Ruby.Builtins.RubyModule[] {def25, }, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Function<System.DateTime>(Ruby.Builtins.TimeOps.Create),
             });
@@ -2202,6 +2202,10 @@
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, System.Boolean>(Ruby.Builtins.Kernel.HasBlock),
             });
             
+            module.DefineLibraryMethod("caller", 0x2a, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Function<System.Object, System.Int32, Ruby.Builtins.RubyArray>(Ruby.Builtins.Kernel.GetStackTrace),
+            });
+            
             module.DefineLibraryMethod("class", 0x29, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.RubyClass>(Ruby.Builtins.Kernel.GetClass),
             });
@@ -2466,6 +2470,10 @@
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Runtime.BlockParam, Ruby.Builtins.Proc>(Ruby.Builtins.Kernel.AtExit),
             });
             
+            module.DefineLibraryMethod("caller", 0x31, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Function<System.Object, System.Int32, Ruby.Builtins.RubyArray>(Ruby.Builtins.Kernel.GetStackTrace),
+            });
+            
             module.DefineLibraryMethod("eval", 0x31, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.MutableString, Ruby.Builtins.Binding, Ruby.Builtins.MutableString, System.Int32, System.Object>(Ruby.Builtins.Kernel.Evaluate),
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.MutableString, Ruby.Builtins.Proc, Ruby.Builtins.MutableString, System.Int32, System.Object>(Ruby.Builtins.Kernel.Evaluate),
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C445173
File: Kernel.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C445173  (server)    5/21/2008 10:40 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;Caller1
@@ -25,6 +25,7 @@
 using Microsoft.Scripting.Utils;
 using Ruby.Runtime;
 using Ruby.Runtime.Calls;
+using System.Diagnostics;
 
 namespace Ruby.Builtins {
 
@@ -33,15 +34,12 @@
 
         #region Private Instance Methods
 
-        //active_gem_with_options
-        //gem_original_require
         //initialize_copy
-        //location_of_caller
         //remove_instance_variable
+        
         //singleton_method_added
         //singleton_method_removed
         //singleton_method_undefined
-        //y
 
         #endregion
 
@@ -111,7 +109,23 @@
         }
 
         //callcc
-        //caller
+
+        [RubyMethod("caller", RubyMethodAttributes.PrivateInstance)]
+        [RubyMethod("caller", RubyMethodAttributes.PublicSingleton)]
+        [RubyStackTraceHidden]
+        public static RubyArray/*!*/ GetStackTrace(object self, [DefaultParameterValue(1)]int skipFrames) {
+            if (skipFrames < 0) {
+                return new RubyArray();
+            }
+
+#if SILVERLIGHT
+            StackTrace trace = new StackTrace();
+#else
+            StackTrace trace = new StackTrace(true);
+#endif
+            return RubyExceptionData.CreateBacktrace(trace.GetFrames(), skipFrames);
+        }
+
         //catch
         //chomp
         //chomp!
@@ -295,6 +309,7 @@
 
         [RubyMethod("method_missing", RubyMethodAttributes.PrivateInstance)]
         [RubyMethod("method_missing", RubyMethodAttributes.PublicSingleton)]
+        [RubyStackTraceHidden]
         public static object MethodMissing(CodeContext/*!*/ context, object/*!*/ self, BlockParam block, SymbolId name, [NotNull]params object[]/*!*/ args) {
             throw RubyExceptions.CreateMethodMissing(context, self, name);            
         }
@@ -399,6 +414,7 @@
         [RubyMethod("raise", RubyMethodAttributes.PublicSingleton)]
         [RubyMethod("fail", RubyMethodAttributes.PrivateInstance)]
         [RubyMethod("fail", RubyMethodAttributes.PublicSingleton)]
+        [RubyStackTraceHidden]
         public static void RaiseException(CodeContext/*!*/ context, object self) {
             RubyExecutionContext ec = RubyUtils.GetExecutionContext(context);
 
@@ -415,6 +431,7 @@
         [RubyMethod("raise", RubyMethodAttributes.PublicSingleton)]
         [RubyMethod("fail", RubyMethodAttributes.PrivateInstance)]
         [RubyMethod("fail", RubyMethodAttributes.PublicSingleton)]
+        [RubyStackTraceHidden]
         public static void RaiseException(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ message) {
             ContractUtils.RequiresNotNull(message, "message");
             RubyExecutionContext ec = RubyUtils.GetExecutionContext(context);
@@ -425,6 +442,7 @@
         [RubyMethod("raise", RubyMethodAttributes.PublicSingleton)]
         [RubyMethod("fail", RubyMethodAttributes.PrivateInstance)]
         [RubyMethod("fail", RubyMethodAttributes.PublicSingleton)]
+        [RubyStackTraceHidden]
         public static void RaiseException(CodeContext/*!*/ context, object self, [NotNull]RubyClass/*!*/ exceptionClass, [Optional]MutableString message, [Optional]RubyArray stackTrace) {
             RubyExecutionContext ec = RubyUtils.GetExecutionContext(context);
             Exception e = ExceptionOps.MakeException(context, exceptionClass, message, stackTrace);
@@ -436,6 +454,7 @@
         [RubyMethod("raise", RubyMethodAttributes.PublicSingleton)]
         [RubyMethod("fail", RubyMethodAttributes.PrivateInstance)]
         [RubyMethod("fail", RubyMethodAttributes.PublicSingleton)]
+        [RubyStackTraceHidden]
         public static void RaiseException(CodeContext/*!*/ context, object self, object/*!*/ exceptionObject, [Optional]MutableString message, [Optional]List<object> stackTrace) {
             // exceptionObject <# { exception: void -> Exception }
 
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Attributes.cs;C444795
File: Attributes.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Attributes.cs;C444795  (server)    5/21/2008 1:39 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Attributes.cs;Caller1
@@ -292,5 +292,9 @@
             _name = name;
         }
     }
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+    public sealed class RubyStackTraceHiddenAttribute : Attribute {
+    }
 }
 
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/SourceUnitTree.cs;C438696
File: SourceUnitTree.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/SourceUnitTree.cs;C438696  (server)    5/21/2008 2:00 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/SourceUnitTree.cs;Caller1
@@ -55,7 +55,7 @@
         internal MSA.LambdaExpression/*!*/ Transform(AstGenerator/*!*/ gen, SourceCodeKind kind) {
             Debug.Assert(gen != null);
 
-            MSA.LambdaBuilder method = AstUtils.Lambda(typeof(object), "main", Location);
+            MSA.LambdaBuilder method = AstUtils.Lambda(typeof(object), RubyExceptionData.TopLevelMethodName, Location);
             method.Dictionary = true;
 
             MSA.Expression rfcVariable, selfVariable, runtimeScopeVariable;
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/MethodDeclaration.cs;C444795
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;C435539
File: RubyExceptionData.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;C435539  (server)    5/21/2008 10:52 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;Caller1
@@ -20,6 +20,8 @@
 using Microsoft.Scripting.Runtime;
 using Microsoft.Scripting.Utils;
 using Ruby.Builtins;
+using System.Diagnostics;
+using System.Collections.Generic;
 
 namespace Ruby.Runtime {
     /// <summary>
@@ -28,6 +30,7 @@
     [Serializable]
     public class RubyExceptionData {
         private static readonly object/*!*/ _DataKey = new object();
+        internal const string TopLevelMethodName = "#top-level-method#";
 
         private Exception/*!*/ _exception; // owner exception, needed for lazy initialization of message, backtrace
         private MutableString _message; // if this is set to null we need to initialze it
@@ -38,34 +41,127 @@
             _exception = exception;
         }
 
-        // TODO: better filtering
-        private RubyArray/*!*/ CreateBacktrace() {
+        public static RubyArray/*!*/ CreateBacktrace(Exception/*!*/ exception) {
+#if SILVERLIGHT // TODO: StackTrace.ctor(exception) security critical
             RubyArray result = new RubyArray();
-            foreach (DynamicStackFrame frame in ExceptionHelpers.GetStackFrames(_exception)) {
-                MethodBase method = frame.GetMethod();
-                Type type = method.DeclaringType;
-                // skip frames in IronRuby.dll
-                if (type != null && type.Assembly == GetType().Assembly) {
+            foreach (string line in exception.StackTrace.Split('\n')) {
+                string frame = line.Trim();
+                if (frame.StartsWith("at ")) {
+                    frame = frame.Substring("at ".Length);
+                }
+
+                if (frame.StartsWith("_stub_") ||
+                    frame.StartsWith("Microsoft.Scripting") ||
+                    frame.StartsWith("System.Runtime") ||
+                    frame.StartsWith("Ruby.Builtins.Kernel.RaiseException") ||
+                    frame.StartsWith("Ruby.Builtins.Kernel.MethodMissing")) {
                     continue;
                 }
-                
-                // skip Kernel#raise and Kernel#method_missing
-                if (type != null && type.FullName == "Ruby.Builtins.Kernel" && (method.Name == "RaiseException" || method.Name == "MethodMissing")
-                    || method.Name.StartsWith("Ruby.Builtins.Kernel.RaiseException")
-                    || method.Name.StartsWith("Ruby.Builtins.Kernel.MethodMissing")) {
-                    continue;
+
+                int dollar = frame.IndexOf('$');
+                if (dollar != -1) {
+                    frame = frame.Substring(0, dollar);
                 }
 
-                result.Add(MutableString.Create(string.Format(
-                    "{0}:{1}:in `{2}'",
-                    frame.GetFileName(),
-                    frame.GetFileLineNumber(),
-                    frame.GetMethodName())));
+                result.Add(FormatFrame("", 0, frame));
             }
+            
+            return result;
+#else
+            return CreateBacktrace(new StackTrace(exception, true).GetFrames(), 0);
+#endif
+        }
 
+        public static RubyArray/*!*/ CreateBacktrace(StackFrame[]/*!*/ stackTrace, int skipFrames) {
+            RubyArray result = new RubyArray();
+            foreach (StackFrame frame in stackTrace) {
+                if (IsVisibleFrame(frame.GetMethod())) {
+                    if (skipFrames == 0) {
+                        string methodName, file;
+                        int line;
+                        GetStackFrameInfo(frame, out methodName, out file, out line);
+                        result.Add(MutableString.Create(FormatFrame(file, line, methodName)));
+                    } else {
+                        skipFrames--;
+                    }
+                }
+            }
+
             return result;
         }
 
+        private static string/*!*/ FormatFrame(string/*!*/ file, int line, string methodName) {
+            if (String.IsNullOrEmpty(methodName)) {
+                return String.Format("{0}:{1}", file, line);
+            } else {
+                return String.Format("{0}:{1}:in `{2}'", file, line, methodName);
+            }
+        }
+
+        private static void GetStackFrameInfo(StackFrame/*!*/ frame, out string/*!*/ methodName, out string/*!*/ fileName, out int line) {
+            MethodBase method = frame.GetMethod();
+            methodName = method.Name;
+            fileName = frame.GetFileName();
+            line = frame.GetFileLineNumber();
+
+            // TODO: no support in DLR
+            int dollar = method.Name.IndexOf('$');
+            if (dollar != -1) {
+                methodName = methodName.Substring(0, dollar);
+            } else {
+                object[] attrs = method.GetCustomAttributes(typeof(RubyMethodAttribute), false);
+                if (attrs.Length > 0) {
+                    // TODO: aliases
+                    methodName = ((RubyMethodAttribute)attrs[0]).Name;
+                }
+            }
+
+            if (methodName == TopLevelMethodName) {
+                methodName = null;
+            }
+
+            if (String.IsNullOrEmpty(fileName)) {
+                if (method.DeclaringType != null) {
+                    fileName = method.DeclaringType.Assembly.GetName().Name;
+                    line = 0;
+                }
+            }
+        }
+
+        // TODO: better filtering in DLR
+        private static bool IsVisibleFrame(MethodBase/*!*/ method) {
+            // filter out the _stub_ methods
+            if (method.Name.StartsWith("_stub_")) {
+                return false;
+            }
+                
+            Type type = method.DeclaringType;
+
+            if (type != null) {
+                string typeName = type.FullName;
+                if (typeName.StartsWith("System.Reflection.") ||
+                    typeName.StartsWith("System.Runtime") ||
+                    typeName.StartsWith("Microsoft.Scripting")) {
+                    return false;
+                }
+
+                // TODO: check loaded assemblies
+                if (type.Assembly == typeof(RubyOps).Assembly) {
+                    return false;
+                }
+
+                if (method.IsDefined(typeof(RubyStackTraceHiddenAttribute), false)) {
+                    return false;
+                }
+                 
+                if (type.Assembly.IsDefined(typeof(RubyLibraryAttribute), false)) {
+                    return method.IsDefined(typeof(RubyMethodAttribute), false);
+                }
+            }
+                
+            return true;
+        }
+
         /// <summary>
         /// Gets the instance data associated with the exception
         /// </summary>
@@ -94,7 +190,7 @@
         public RubyArray Backtrace {
             get {
                 if (!_backtraceInitialized) {
-                    _backtrace = CreateBacktrace();
+                    _backtrace = CreateBacktrace(_exception);
                     _backtraceInitialized = true;
                 }
                 return _backtrace;
===================================================================
