コード例 #1
0
        private int ExecIndex(Instruction i, int instructionPtr)
        {
            int nestedMetaOps = 100;             // sanity check, to avoid potential infinite loop here

            // stack: base - index
            DynValue idx = i.Value ?? m_ValueStack.Pop().ToScalar();
            DynValue obj = m_ValueStack.Pop().ToScalar();

            DynValue h = null;

            while (nestedMetaOps > 0)
            {
                --nestedMetaOps;

                if (obj.Type == DataType.Table)
                {
                    var v = obj.Table.Get(idx);

                    if (!v.IsNil())
                    {
                        m_ValueStack.Push(v.AsReadOnly());
                        return(instructionPtr);
                    }

                    h = GetMetamethod(obj, "__index");

                    if (h == null || h.IsNil())
                    {
                        m_ValueStack.Push(DynValue.Nil);
                        return(instructionPtr);
                    }
                }
                else if (obj.Type == DataType.UserData)
                {
                    UserData ud = obj.UserData;

                    var v = ud.Descriptor.Index(this.GetScript(), ud.Object, idx);

                    if (v == null)
                    {
                        throw ScriptRuntimeException.UserDataMissingField(ud.Descriptor.Name, idx.String);
                    }

                    m_ValueStack.Push(v.AsReadOnly());
                    return(instructionPtr);
                }
                else
                {
                    h = GetMetamethod(obj, "__index");

                    if (h == null || h.IsNil())
                    {
                        throw ScriptRuntimeException.IndexType(obj);
                    }
                }

                if (h.Type == DataType.Function || h.Type == DataType.ClrFunction)
                {
                    m_ValueStack.Push(h);
                    m_ValueStack.Push(obj);
                    m_ValueStack.Push(idx);
                    return(Internal_ExecCall(2, instructionPtr));
                }
                else
                {
                    obj = h;
                    h   = null;
                }
            }

            throw ScriptRuntimeException.LoopInIndex();
        }