示例#1
0
        public override object Call(Class last_class, object recv, Frame caller, Proc block, Array rest)
        {
            Hash hash;

            if ((rest.Count == 1) && (rest[0] is Hash))
            {
                hash = new Hash((Class)recv);
                hash.value = ((Hash)rest[0]).value;
                return hash;
            }

            if (rest.Count % 2 != 0)
                throw new ArgumentError("odd number of arguments for Hash").raise(caller);

            hash = new Hash((Class)recv);
            for (int i = 0; i < rest.Count; i += 2)
                rb_hash_aset.singleton.Call2(last_class, hash, caller, null, rest[i], rest[i + 1]);

            return hash;
        }
示例#2
0
 public override object Call0(Class klass, object recv, Frame caller, Proc block)
 {
     Hash hash = new Hash();
     foreach (System.Collections.DictionaryEntry pair in System.Environment.GetEnvironmentVariables())
     {
         hash.Add(Env.env_str_new(caller, (string)pair.Key), Env.env_str_new2(caller, (string)pair.Value));
     }
     return hash;
 }
示例#3
0
        internal static object r_object0(Frame caller, load_arg arg, object proc, ref int ivp, object extmod)
        {
            object v = null;
            int type = r_byte(caller, arg);
            int id;

            switch (type)
            {
                case TYPE_LINK: //TEST:

                    id = r_long(caller, arg);
                    v = Ruby.Methods.rb_hash_aref.singleton.Call1(null, arg.data, caller, null, id);
                    if (v == null)
                    {
                        throw new ArgumentError("dump format error (unlinked)").raise(caller);
                    }
                    return v;

                case TYPE_IVAR: //TEST:
                    {
                        int ivar = 1;
                        v = r_object0(caller, arg, null, ref ivar, extmod);
                        if (ivar > 0) r_ivar(caller, v, arg);                        
                    }
                break;

                case TYPE_EXTENDED: //TEST:
                    {
                        object m = path2module(r_unique(caller, arg), caller);
                        if (extmod == null)
                        {
                            extmod = new Array();
                            ((Array)extmod).value.Add(m);
                        }

                        int temp = 0;
                        v = r_object0(caller, arg, null, ref temp, extmod);
                        while (((Array)extmod).value.Count > 0)
                        {
                            m = ((Array)extmod).value[((Array)extmod).value.Count - 1];
                            ((Array)extmod).value.RemoveAt(((Array)extmod).value.Count - 1);
                            Class.rb_extend_object(caller, v, (Class)m);
                        }
                    }
                break;

                case TYPE_UCLASS:
                    {
                        object c = path2class(caller, r_unique(caller, arg));

                        if (((Class)c)._type == Class.Type.Singleton)
                        {
                            throw new TypeError("singleton can't be loaded").raise(caller);
                        }
                        int temp = 0;
                        v = r_object0(caller, arg, null, ref temp, extmod);
                        if (rb_special_const_p(v) || v is Object || (v is Class && ((Class)v)._type == Class.Type.Class))
                        {
                            throw new ArgumentError("dump format error (user class)").raise(caller);
                        }
                        if ((v is Class && ((Class)v)._type == Class.Type.Module) || !RTEST(Ruby.Methods.rb_class_inherited_p.singleton.Call1(null, c, caller, null, ((Basic)v).my_class)))
                        {
                            object tmp = new Object((Class)c);

                            //TODO: Write this comparison
                            //if (TYPE(v) != TYPE(tmp))
                            //{
                            //    throw new ArgumentError("dump format error (user class)").raise(caller);
                            //}
                        }
                        ((Basic)v).my_class = (Class)c;
                    }
                    break;

                case TYPE_NIL:
                    v = null;
                    break;

                case TYPE_TRUE:
                    v = true;
                    break;

                case TYPE_FALSE:
                    v = false;
                    break;

                case TYPE_FIXNUM:
                    {
                        v = r_long(caller, arg);
                    }
                    break;

                case TYPE_FLOAT:
                    {
                        double d;
                        object str = r_bytes(caller, arg);
                        string ptr = ((String)str).value;

                        if (ptr.Equals("nan"))
                        {
                            d = double.NaN;
                        }
                        else if (ptr.Equals("inf"))
                        {
                            d = double.PositiveInfinity;
                        }
                        else if (ptr.Equals("-inf"))
                        {
                            d = double.NegativeInfinity;
                        }
                        else if (ptr.Equals("-0"))
                        {
                            d = -0.0;
                        }
                        else
                        {
                            int e = 0;
                            d = String.strtod(ptr, 0, out e);
                            d = load_mantissa(d, ptr.Substring(e), ((String)str).value.Length - e);
                        }

                        v = new Float(d);
                        r_entry(caller, v, arg);
                    }
                    break;

                case TYPE_BIGNUM:
                    {
                        int len;
                        uint[] digits;
                        object data;

                        int sign = ((char)r_byte(caller, arg) == '+') ? 1 : -1;

                        len = r_long(caller, arg);
                        data = r_bytes0(caller, len * 2, arg);

                        int bigLen = (len + 1) * 2 / SIZEOF_BDIGITS;                      

                        //extract data to bytes
                        digits = new uint[bigLen];
                        byte[] digitData = new byte[bigLen * SIZEOF_BDIGITS];
                        char[] charDigitData = ((String)data).value.ToCharArray();
                        for (int i = 0; i < ((String)data).value.Length; i++)
                        {
                            digitData[i] = (byte)charDigitData[i];
                        }
                        //save data to digits
                        for (int uintCount = 0; uintCount < digits.Length; uintCount++)
                        {
                            digits[uintCount] = System.BitConverter.ToUInt32(digitData, (uintCount * 4));
                        }
                        v = new Bignum(new IronMath.integer(sign, digits));
                        r_entry(caller, v, arg);
                    }
                    break;
                case TYPE_STRING:
                    v = r_entry(caller, r_string(caller, arg), arg);
                    break;

                case TYPE_REGEXP:
                    {
                        object str = r_bytes(caller, arg);
                        int options = r_byte(caller, arg);
                        v = r_entry(caller, new Regexp(((String)str).value, options), arg);
                    }
                    break;

                case TYPE_ARRAY:
                    {
                        int len = r_long(caller, arg);

                        v = new Array();
                        r_entry(caller, v, arg);
                        while (len-- > 0)
                        {
                            ((Array)v).value.Add(r_object(caller, arg));
                        }
                    }
                    break;

                case TYPE_HASH:
                case TYPE_HASH_DEF:
                    {
                        int len = r_long(caller, arg);

                        v = new Hash();
                        r_entry(caller, v, arg);
                        while (len-- > 0)
                        {
                            object key = r_object(caller, arg);
                            object value = r_object(caller, arg);
                            ((Hash)v).Add(key, value);
                        }
                        if (type == TYPE_HASH_DEF)
                        {
                            ((Hash)v).defaultValue = r_object(caller, arg);
                        }
                    }
                    break;

                case TYPE_STRUCT:
                    {
                        Class klass;
                        object mem;
                        object[] values;
                        int len;
                        int slot;

                        string klassPath = r_unique(caller, arg);
                        klass = (Class)path2class(caller, klassPath);
                        mem = Ruby.Methods.rb_struct_s_members.singleton.Call0(klass, klass, caller, null);
                        if (mem == null)
                        {
                            throw new TypeError("uninitialized struct").raise(caller);
                        }
                        len = r_long(caller, arg);
                        values = new object[len];
                        for (int i = 0; i < len; i++)
                        {
                            slot = r_symbol(caller, arg);

                            if ((string)((Array)mem).value[i] != Symbol.rb_id2name((uint)slot))
                            {
                                string errorString = string.Format(CultureInfo.InvariantCulture, "struct {0} not compatible (:{1} for :{2})",
                                    rb_class2name(klass, caller),
                                    Symbol.rb_id2name((uint)slot),
                                    ((Array)mem).value[i]);

                                throw new TypeError(errorString).raise(caller);
                            }
                            values[i] = r_object(caller, arg);
                        }

                        v = Ruby.Methods.rb_class_new_instance.singleton.Call(klass, klass, caller, null, new Array(values));
                        r_entry(caller, v, arg);
                    }
                    break;
                case TYPE_USERDEF:
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        object data;

                        if (!Eval.RespondTo(klass, s_load))
                        {
                            throw new TypeError(string.Format(CultureInfo.InvariantCulture, "class {0} needs to have method `_load'", rb_class2name(klass, caller))).raise(caller);
                        }

                        data = r_string(caller, arg);
                        if (ivp > 0)
                        {
                            r_ivar(caller, data, arg);
                            ivp = 0;
                        }
                        v = Eval.CallPrivate1(klass, caller, s_load, null, data);
                        r_entry(caller, v, arg);                        
                    }
                    break;
                case TYPE_USRMARSHAL: 
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        object data;

                        v = Ruby.Methods.rb_obj_alloc.singleton.Call0(null, klass, caller, null);
                        if (extmod != null)
                        {
                            while (((Array)extmod).value.Count > 0)
                            {
                                object m = ((Array)extmod).value[((Array)extmod).value.Count - 1];
                                ((Array)extmod).value.RemoveAt(((Array)extmod).value.Count - 1);
                                Class.rb_extend_object(caller, v, (Class)m);
                            }
                        }
                        if (!Eval.RespondTo(v, s_mload))
                        {
                            throw new TypeError(string.Format(CultureInfo.InvariantCulture, "instance of {0} needs to have method `marshal_load'", rb_class2name(klass, caller))).raise(caller);
                        }
                        r_entry(caller, v, arg);
                        data = r_object(caller, arg);
                        Eval.CallPrivate1(v, caller, s_mload, null, data);
                    }
                    break;

                case TYPE_OBJECT:
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        v = Ruby.Methods.rb_obj_alloc.singleton.Call0(null, klass, caller, null);
                        if (!(v is Object))
                        {
                            throw new ArgumentError("dump format error").raise(caller);
                        }
                        r_entry(caller, v, arg);
                        r_ivar(caller, v, arg);
                    }
                    break;

                case TYPE_DATA://TEST
                    {
                        object klass = path2class(caller, r_unique(caller, arg));
                        if (Eval.RespondTo(klass, s_alloc))
                        {
                            type_data_warn = true; //TEST: static int warn = Qtrue; - test that this is equivalent note the 'STATIC' keyword
                            if (type_data_warn)
                            {
                                Errors.rb_warn("define `allocate' instead of `_alloc'");
                                type_data_warn = false;
                            }
                            v = Eval.CallPrivate0(klass, caller, s_alloc, null);
                        }
                        else
                        {
                            v = Ruby.Methods.rb_obj_alloc.singleton.Call0(null, klass, caller, null);
                        }
                        if (!(v is Data))
                        {
                            throw new ArgumentError("dump format error").raise(caller);
                        }
                        r_entry(caller, v, arg);
                        if (!Eval.RespondTo(v, s_load_data))
                        {
                            throw new TypeError(string.Format(CultureInfo.InvariantCulture, "class {0} needs to have instance method `_load_data'", rb_class2name(klass, caller))).raise(caller);
                        }
                        int temp = 0;
                        Eval.CallPrivate1(v, caller, s_load_data, null, r_object0(caller, arg, null, ref temp, extmod));
                    }
                break;

                case TYPE_MODULE_OLD: //TEST:
                    {                     
                        object str = r_bytes(caller, arg);
                        v = rb_path2class(caller, ((String)str).value);
                        r_entry(caller, v, arg);
                    }
                break;

                case TYPE_CLASS:
                    {
                        object str = r_bytes(caller, arg);
                        v = path2class(caller, ((String)str).value);
                        r_entry(caller, v, arg);
                    }
                    break;
                case TYPE_MODULE: //TEST:
                    {                        
                        object str = r_bytes(caller, arg);

                        v = path2module(((String)str).value, caller);
                        r_entry(caller, v, arg);
                    }
                    break;

                case TYPE_SYMBOL: //TEST:
                    v = new Symbol((uint)r_symreal(caller, arg));
                    break;

                case TYPE_SYMLINK: //TEST:
                    return new Symbol((uint)r_symlink(caller, arg));

                default:
                    throw new ArgumentError(string.Format(CultureInfo.InvariantCulture, "dump format error(0x{0})", type)).raise(caller);
            }

            if (proc != null) //TEST:
            {
                Eval.CallPrivate1(proc, caller, "call", null, v);
            }
            return v;

        }
示例#4
0
        public override object Call0(Class last_class, object recv, Frame caller, Proc block)
        {
            Hash h = new Hash();

            foreach (string key in Signal.siglist.Keys)
                h.Add(new String(key), Signal.siglist[key]);

            return h;
        }