Пример #1
0
        public static R_VAL DoFile(IntPtr mrb, string path)
        {
            if (!File.Exists(path))
            {
                return(R_VAL.NIL);
            }

#if MRUBY
            string filename     = Path.GetFileName(path);
            int    arena        = RubyDLL.mrb_gc_arena_save(mrb);
            IntPtr mrbc_context = RubyDLL.mrbc_context_new(mrb);
            RubyDLL.mrbc_filename(mrb, mrbc_context, filename);
            var ret = RubyDLL.mrb_load_string_cxt(mrb, RubyDLL.ToCBytes(File.ReadAllText(path)), mrbc_context);
            RubyDLL.mrbc_context_free(mrb, mrbc_context);
            if (RubyDLL.mrb_has_exc(mrb))
            {
                Console.WriteLine(GetExceptionBackTrace(mrb));
                RubyDLL.mrb_exc_clear(mrb);
            }
            RubyDLL.mrb_gc_arena_restore(mrb, arena);
            return(ret);
#else
            int status;
            RubyDLL.rb_load_protect(R_VAL.Create(path), 0, out status);
            return(status == 0 ? R_VAL.TRUE : R_VAL.FALSE);
#endif
        }
Пример #2
0
        public void DefineMethod(string name, RubyDLL.RubyCSFunction receiver, rb_args aspec)
        {
            // 防止被C#端GC
            state.MethodDelegates.Add(receiver);

            RubyDLL.r_define_module_function(state.rb_state, module_ptr, name, receiver, aspec);
        }
Пример #3
0
        public void DefineStaticMethod(string name, RubyDLL.RubyCSFunction receiver, rb_args aspec)
        {
            // 防止被C#端GC
            state.MethodDelegates.Add(receiver);

            RubyDLL.r_define_class_method(state, class_ptr, name, receiver, aspec);
        }
        /// <summary>
        /// Builds the return value of a call
        /// </summary>
        /// <param name="outParams">The out parameters indices, or null. See <see cref="BuildArgumentList" />.</param>
        /// <param name="pars">The parameters passed to the function.</param>
        /// <param name="retv">The return value from the function. Use DynValue.Void if the function returned no value.</param>
        /// <returns>A DynValue to be returned to scripts</returns>
        protected static R_VAL BuildReturnValue(RubyState state, List <int> outParams, object[] pars, object retv)
        {
            if (outParams == null)
            {
                return(RubyState.ObjectToValue(state, retv));
            }
            else
            {
                R_VAL[] rets = new R_VAL[outParams.Count + 1];

                if (retv is R_VAL && R_VAL.IsNil(( R_VAL )retv))
                {
                    rets[0] = R_VAL.NIL;
                }
                else
                {
                    rets[0] = RubyState.ObjectToValue(state, retv);
                }

                for (int i = 0; i < outParams.Count; i++)
                {
                    rets[i + 1] = RubyState.ObjectToValue(state, pars[outParams[i]]);
                }

                R_VAL ary = RubyDLL.r_ary_new();

                foreach (var p in rets)
                {
                    RubyDLL.r_ary_push(state, ary, p);
                }

                return(ary);
            }
        }
Пример #5
0
        public string GetCurrentBackTrace()
        {
#if MRUBY
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            R_VAL backtrace = RubyDLL.r_get_backtrace(rb_state);

            builder.AppendLine("trace:");
            for (var i = 0; i < RubyDLL.r_funcall(rb_state, backtrace, "size", 0); ++i)
            {
                R_VAL v = RubyDLL.r_ary_ref(rb_state, backtrace, i);
                builder.AppendLine($"  [{i}] {v.ToString ( rb_state )}");
            }

            return(builder.ToString());
#else
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            R_VAL exc       = DoString("Exception.new('*interactive*')");
            R_VAL backtrace = RubyDLL.r_get_backtrace(exc);

            builder.AppendLine("trace:");
            for (var i = 0; i < RubyDLL.r_funcall(backtrace, R_VAL.Create("size"), 0); ++i)
            {
                R_VAL v = RubyDLL.r_ary_ref(backtrace, R_VAL.Create(i));
                builder.AppendLine($"  [{i}] {v.ToString ()}");
            }

            return(builder.ToString());
#endif
            // return RubyDLL.mrb_inspect ( mrb_state, RubyDLL.mrb_get_backtrace ( mrb_state ) ).ToString ( mrb_state );
            // return RubyDLL.mrb_funcall ( mrb_state, RubyDLL.mrb_exc_backtrace ( mrb_state, RubyDLL.mrb_get_exc_value ( mrb_state ) ), "to_s", 0 ).ToString ( mrb_state );
            // return RubyDLL.mrb_inspect ( mrb_state, RubyDLL.mrb_get_exc_value ( mrb_state ) ).ToString ( mrb_state );
            // return RubyDLL.mrb_inspect ( mrb_state, RubyDLL.mrb_exc_backtrace ( mrb_state, RubyDLL.mrb_get_exc_value ( mrb_state ) ) ).ToString ( mrb_state );
        }
Пример #6
0
 public mRubyModule(RubyState state, string name)
 {
     this.name         = name;
     this.state        = state;
     this.module_ptr   = RubyDLL.r_define_module(state.rb_state, name);
     this.module_value = R_VAL.CreateOBJ(module_ptr);
 }
Пример #7
0
        public R_VAL Call(string funcName, R_VAL arg)
        {
#if MRUBY
            return(RubyDLL.r_funcall_1(rb_state, RubyDLL.mrb_top_self(rb_state), funcName, 1, arg));
#else
            return(RubyDLL.r_funcall_1(RubyDLL.rb_vm_top_self(), R_VAL.Create(funcName), 1, arg));
#endif
        }
Пример #8
0
        /// <summary>
        /// 定义一个新Class,默认继承自mruby的Object
        /// </summary>
        public mRubyClass(RubyState state, string name)
        {
            mRubyClass.RegisteredClass.Add(name, this);

            this.name = name;

            this.state       = state;
            this.class_ptr   = RubyDLL.r_define_class(state, name, state.rb_object_class);
            this.class_value = R_VAL.CreateOBJ(class_ptr);
        }
Пример #9
0
        static R_VAL WriteLine(IntPtr state, R_VAL context)
        {
            R_VAL[] args = RubyDLL.GetFunctionArgs(state);

            string str = args[0].ToString(state);

            Console.WriteLine(str);

            return(context);
        }
Пример #10
0
        public static void RegisterEnum <T> (RubyState state)
        {
            Type type = typeof(T);

            IntPtr module = UserDataUtility.DefineCSharpEnum(state, type);

            foreach (int i in System.Enum.GetValues(type))
            {
                RubyDLL.r_define_const(state, module, System.Enum.GetName(type, i), RubyDLL.mrb_fixnum_value(state, i));
            }
        }
Пример #11
0
        /// <summary>
        /// 在mruby全局中定义方法
        /// </summary>
        /// <param name="name"></param>
        /// <param name="receiver"></param>
        /// <param name="aspec"></param>
        public void DefineMethod(string name, RubyDLL.RubyCSFunction receiver, rb_args aspec)
        {
            // 防止被C#端GC
            MethodDelegates.Add(receiver);

#if MRUBY
            RubyDLL.r_define_module_function(rb_state, rb_kernel_module, name, receiver, aspec);
#else
            // RubyDLL.RubyCSFunction receiverDelegate = receiver;
            // GCHandle gch = GCHandle.Alloc(receiverDelegate);
            // IntPtr intptr_delegate = Marshal.GetFunctionPointerForDelegate(receiverDelegate);
            RubyDLL.r_define_module_function(rb_kernel_module, name, receiver, aspec.value);
#endif
        }
Пример #12
0
        /// <summary>
        /// DefineCSharpClass in ruby and set data type
        /// </summary>
        /// <param name="state"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IntPtr DefineCSharpClass(RubyState state, Type type)
        {
            // 模块和类的开头必须是大写字母
            IntPtr @class = IntPtr.Zero;

            string[] namespacePath = type.FullName.Split('.');

            if (namespacePath.Length == 1)
            {
                @class = RubyDLL.r_define_class(state, type.Name, state.SystemObjectRClass);
            }
            else
            {
                foreach (var name in namespacePath)
                {
                    string validName = name;

                    // 检查命名开头字母大小写
                    if (!char.IsUpper(name[0]))
                    {
                        char   head    = char.ToUpper(name[0]);
                        string newName = name;
                        newName = name.Remove(0, 1);
                        newName = newName.Insert(0, head.ToString());

                        Console.WriteLine($"{name} -> {newName}");

                        validName = newName;
                    }

                    if (name.Equals(namespacePath[0]))
                    {
                        @class = RubyDLL.r_define_module(state, validName);
                        RubyDLL.mrb_set_instance_tt(@class, rb_vtype.RUBY_T_DATA);
                    }
                    else if (name.Equals(namespacePath[namespacePath.Length - 1]))
                    {
                        @class = RubyDLL.r_define_class_under(state, @class, validName, state.SystemObjectRClass);
                        RubyDLL.mrb_set_instance_tt(@class, rb_vtype.RUBY_T_DATA);
                    }
                    else
                    {
                        @class = RubyDLL.r_define_module_under(state, @class, validName, IntPtr.Zero);
                        RubyDLL.mrb_set_instance_tt(@class, rb_vtype.RUBY_T_DATA);
                    }
                }
            }

            return(@class);
        }
Пример #13
0
        /// <summary>
        /// 在mruby全局中定义方法
        /// </summary>
        /// <param name="name"></param>
        /// <param name="delegate">实例方法/静态方法</param>
        /// <param name="aspec"></param>
        public void DefineMethod(string name, Delegate @delegate, rb_args aspec)
        {
            var function = CallbackFunction.FromDelegate(@delegate, RubyState.ObjectDataTypePtr);
            var method   = new RubyDLL.RubyCSFunction((state, self) => function.Invoke(this, self));

            // 防止被C#端GC
            MethodDelegates.Add(method);

#if MRUBY
            RubyDLL.r_define_module_function(rb_state, rb_kernel_module, name, method, aspec);
#else
            RubyDLL.r_define_module_function(rb_kernel_module, name, method, aspec);
#endif
        }
Пример #14
0
        /// <summary>
        /// Invokes the callback function
        /// </summary>
        /// <param name="executionContext">The execution context.</param>
        /// <param name="args">The arguments.</param>
        /// <param name="isMethodCall">if set to <c>true</c> this is a method call.</param>
        /// <returns></returns>
        public R_VAL Invoke(RubyState state, R_VAL self)
        {
#if DEBUG
            try {
#endif
            return(ClrCallback(state, Target, new CallbackArguments(RubyDLL.GetFunctionArgs(state))));

#if DEBUG
        }

        catch (Exception e) {
            Console.WriteLine($"Exception on CallbackFunction::Invoke() {Name}\n{e.Message}");
            throw;
        }
#endif
        }
Пример #15
0
 public static object[] RubyFunctionParamsToObjects(IntPtr mrb, IntPtr data_type_ptr)
 {
     R_VAL[]  value = RubyDLL.GetFunctionArgs(mrb);
     object[] ret   = new object[value.Length];
     for (int i = 0; i < ret.Length; i++)
     {
         ref R_VAL val = ref value[i];
         if (!R_VAL.IsData(val))
         {
             ret[i] = ValueToObject(mrb, val);
         }
         else
         {
             IntPtr ptr = RubyDLL.mrb_data_get_ptr(mrb, val, data_type_ptr);
             ret[i] = (( GCHandle )ptr).Target;
         }
     }
Пример #16
0
        // static public implicit operator bool ( R_VAL value ) {
        //  switch ( RubyDLL.r_type ( value ) ) {
        //      case rb_vtype.RUBY_T_FALSE:
        //      // case rb_vtype.RUBY_T_EXCEPTION:
        //      case rb_vtype.RUBY_T_UNDEF:
        //          return false;
        //  }
        //
        //  return true;
        // }


        public string ToString()
        {
            var    str    = RubyDLL.rb_obj_as_string(this);
            int    length = 0;
            IntPtr ptr    = RubyDLL.r_string_value_cstr(ref str);

            unsafe {
                byte *p = ( byte * )ptr;
                while (*p != 0)
                {
                    length++;
                    p++;
                }
            }

            byte[] bytes = new byte[length];
            Marshal.Copy(ptr, bytes, 0, length);
            return(RubyDLL.Encoding.GetString(bytes));
        }
Пример #17
0
        public R_VAL Invoke(RubyState state, int argc, R_VAL[] argv, R_VAL self)
        {
#if DEBUG
            try {
#endif
#if MRUBY
            return(ClrCallback(state, Target, new CallbackArguments(RubyDLL.GetFunctionArgs(state))));
#else
            return(ClrCallback(state, Target, new CallbackArguments(argv)));
#endif
#if DEBUG
        }

        catch (Exception e) {
            Console.WriteLine($"Exception on CallbackFunction::Invoke() {Name}");
            throw;
        }
#endif
        }
Пример #18
0
        public RubyState()
        {
            #if MRUBY
            rb_state = RubyDLL.mrb_open();
            #else
            string[] argv = System.Environment.GetCommandLineArgs();
            int      argc = argv.Length;
            RubyDLL.ruby_sysinit(ref argc, argv);
            RubyDLL.ruby_init();
            RubyDLL.ruby_init_loadpath();
            #endif

            rb_object_class  = DoString("Object");
            rb_kernel_module = DoString("Kernel");

            InitBaseTypeBinding();

#if MRUBY
            // load file
            DefineMethod("dofile", _doFile, rb_args.REQ(1));
#endif
        }
Пример #19
0
        public R_VAL DoString(string str)
        {
#if MRUBY
            int    arena        = RubyDLL.mrb_gc_arena_save(rb_state);
            IntPtr mrbc_context = RubyDLL.mrbc_context_new(rb_state);
            RubyDLL.mrbc_filename(this, mrbc_context, "*interactive*");
            var ret = RubyDLL.mrb_load_string_cxt(rb_state, RubyDLL.ToCBytes(str), mrbc_context);
            RubyDLL.mrbc_context_free(rb_state, mrbc_context);

            if (RubyDLL.mrb_has_exc(rb_state))
            {
                Console.WriteLine(GetExceptionBackTrace());
                RubyDLL.mrb_exc_clear(rb_state);
            }
            RubyDLL.mrb_gc_arena_restore(rb_state, arena);
            return(ret);
#else
            int status;

            // return RubyDLL.rb_eval_string ( str );
            return(RubyDLL.rb_eval_string_protect(str, out status));
#endif
        }
Пример #20
0
        /// <summary>
        /// 获取当前异常调用堆栈信息
        /// https://qiita.com/seanchas_t/items/ca293f9dd4454cd6cb6d
        /// </summary>
        public string GetExceptionBackTrace()
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();


            R_VAL exc = RubyDLL.mrb_get_exc_value(rb_state);

            if (!RubyDLL.mrb_exception_p(exc))
            {
                return(string.Empty);
            }
            R_VAL backtrace = RubyDLL.r_exc_backtrace(rb_state, exc);

            builder.AppendLine(RubyDLL.r_funcall(rb_state, exc, "inspect", 0).ToString(rb_state));

            builder.AppendLine("trace:");
            for (var i = 0; i < RubyDLL.r_funcall(rb_state, backtrace, "size", 0); ++i)
            {
                R_VAL v = RubyDLL.r_ary_ref(rb_state, backtrace, i);
                builder.AppendLine($"  [{i}] {v.ToString ( rb_state )}");
            }

            return(builder.ToString());

            // R_VAL exc = RubyDLL.rb_errinfo ();
            // R_VAL backtrace = RubyDLL.r_exc_backtrace ( exc );
            //
            // builder.AppendLine ( RubyDLL.r_inspect ( exc ).ToString () );
            //
            // builder.AppendLine ( "trace:" );
            // for ( var i = 0; i < RubyDLL.r_funcall ( backtrace, R_VAL.Create ( "size" ), 0 ); ++i ) {
            //  R_VAL v = RubyDLL.r_ary_ref ( backtrace, R_VAL.Create ( i ) );
            //  builder.AppendLine ( $"  [{i}] {v.ToString ()}" );
            // }
            //
            // return builder.ToString ();
        }
Пример #21
0
        public static string GetExceptionBackTrace()
        {
#endif

            System.Text.StringBuilder builder = new System.Text.StringBuilder();

#if MRUBY
            R_VAL exc       = RubyDLL.mrb_get_exc_value(mrb);
            R_VAL backtrace = RubyDLL.r_exc_backtrace(mrb, exc);

            builder.AppendLine(RubyDLL.r_funcall(mrb, exc, "inspect", 0).ToString(mrb));

            builder.AppendLine("trace:");
            for (var i = 0; i < RubyDLL.r_funcall(mrb, backtrace, "size", 0); ++i)
            {
                R_VAL v = RubyDLL.r_ary_ref(mrb, backtrace, i);
                builder.AppendLine($"  [{i}] {v.ToString ( mrb )}");
            }

            return(builder.ToString());
#else
            R_VAL exc       = RubyDLL.rb_errinfo();
            R_VAL backtrace = RubyDLL.r_exc_backtrace(exc);

            builder.AppendLine(RubyDLL.rb_obj_inspect(exc).ToString());

            builder.AppendLine("trace:");
            for (var i = 0; i < RubyDLL.r_funcall(backtrace, R_VAL.Create("size"), 0); ++i)
            {
                R_VAL v = RubyDLL.r_ary_ref(backtrace, R_VAL.Create(i));
                builder.AppendLine($"  [{i}] {v.ToString ()}");
            }

            return(builder.ToString());
#endif
        }
Пример #22
0
 static public bool IsArray(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_ARRAY);
 }
Пример #23
0
 static public bool IsString(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_STRING);
 }
Пример #24
0
 static public bool IsBool(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_TRUE ||
            RubyDLL.r_type(value) == rb_vtype.RUBY_T_FALSE);
 }
Пример #25
0
 static public bool IsHash(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_HASH);
 }
Пример #26
0
 static public bool IsIStruct(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_STRUCT);
 }
Пример #27
0
 static public bool IsData(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_DATA);
 }
Пример #28
0
 static public bool IsIClass(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_ICLASS);
 }
Пример #29
0
 static public bool IsModule(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_MODULE);
 }
Пример #30
0
 static public bool IsObject(R_VAL value)
 {
     return(RubyDLL.r_type(value) == rb_vtype.RUBY_T_OBJECT);
 }