getObject() private method

private getObject ( IntPtr luaState, int index ) : object
luaState IntPtr
index int
return object
示例#1
0
        /// <summary>
        /// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
        /// </summary>
        /// <exception cref="LuaScriptException">Thrown if the script caused an exception</exception>
        void ThrowExceptionFromError(int oldTop)
        {
            object err = translator.getObject(luaState, -1);

            LuaDLL.lua_settop(luaState, oldTop);

            // A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved)
            LuaScriptException luaEx = err as LuaScriptException;

            if (luaEx != null)
            {
                throw luaEx;
            }

            // A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it
            if (err == null)
            {
                err = "Unknown Lua Error";
            }
            throw new LuaScriptException(err.ToString(), "");
        }
示例#2
0
        /// <summary>
        /// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
        /// </summary>
        void ThrowExceptionFromError(int oldTop)
        {
            object err = translator.getObject(luaState, -1);

            LuaDLL.lua_settop(luaState, oldTop);

            // If the 'error' on the stack is an actual C# exception, just rethrow it.  Otherwise the value must have started
            // as a true Lua error and is best interpreted as a string - wrap it in a LuaException and rethrow.
            Exception thrown = err as Exception;

            if (thrown == null)
            {
                if (err == null)
                {
                    err = "Unknown Lua Error";
                }

                thrown = new LuaException(err.ToString());
            }

            throw thrown;
        }
示例#3
0
        public object getAsObject(IntPtr luaState, int stackPos)
        {
            if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE)
            {
                if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index"))
                {
                    if (LuaDLL.luaL_checkmetatable(luaState, -1))
                    {
                        LuaDLL.lua_insert(luaState, stackPos);
                        LuaDLL.lua_remove(luaState, stackPos + 1);
                    }
                    else
                    {
                        LuaDLL.lua_settop(luaState, -2);
                    }
                }
            }
            object obj = translator.getObject(luaState, stackPos);

            return(obj);
        }
示例#4
0
        public object this[string fullPath]
        {
            get
            {
                object   returnValue = null;
                int      oldTop      = LuaAPI.lua_gettop(L);
                string[] path        = fullPath.Split(new char[] { '.' });
                LuaAPI.lua_getglobal(L, path[0]);
                returnValue = translator.getObject(L, -1);
                if (path.Length > 1)
                {
                    string[] remainingPath = new string[path.Length - 1];
                    Array.Copy(path, 1, remainingPath, 0, path.Length - 1);
                    returnValue = getObject(remainingPath);
                }
                LuaAPI.lua_settop(L, oldTop);
                return(returnValue);
            }
            set
            {
                int      oldTop = LuaAPI.lua_gettop(L);
                string[] path   = fullPath.Split(new char[] { '.' });
                if (path.Length == 1)
                {
                    translator.push(L, value);
                    LuaAPI.lua_setglobal(L, fullPath);
                }
                else
                {
                    LuaAPI.lua_getglobal(L, path[0]);
                    LuaTypes type = LuaAPI.lua_type(L, -1);
                    if (type == LuaTypes.LUA_TNIL)
                    {
                        Debugger.LogError("Table {0} not exists", path[0]);
                        LuaAPI.lua_settop(L, oldTop);
                        return;
                    }

                    string[] remainingPath = new string[path.Length - 1];
                    Array.Copy(path, 1, remainingPath, 0, path.Length - 1);
                    setObject(remainingPath, value);
                }
                LuaAPI.lua_settop(L, oldTop);
            }
        }
示例#5
0
        public object asObject(lua.State L, int index)
        {
            Debug.Assert(translator.interpreter.IsSameLua(L));
            if (lua.type(L, index) == LUA.T.TABLE)         // todo: find what purpose this branch serves and document it
            {
                luaL.checkstack(L, 1, "CheckType.asObject");
                if (luaL.getmetafield(L, index, "__index"))
                {
                    if (luaclr.isref(L, -1))
                    {
                        lua.insert(L, index);
                        lua.remove(L, index + 1);
                    }
                    else
                    {
                        lua.pop(L, 1);
                    }
                }
            }
            object obj = translator.getObject(L, index);

            return(obj);
        }
示例#6
0
        /*
         * Called by the __index metafunction of CLR objects in case the
         * method is not cached or it is a field/property/event.
         * Receives the object and the member name as arguments and returns
         * either the value of the member or a delegate to call it.
         * If the member does not exist returns nil.
         */
        private int getMethod(KopiLua.Lua.lua_State luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj == null)
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }

            object index     = translator.getObject(luaState, 2);
            Type   indexType = index.GetType();

            string methodName = index as string;        // will be null if not a string arg
            Type   objType    = obj.GetType();

            // Handle the most common case, looking up the method by name
            if (methodName != null && isMemberPresent(objType, methodName))
            {
                return(getMember(luaState, objType, obj, methodName, BindingFlags.Instance));
            }

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (objType.IsArray && index is double)
            {
                object[] arr = (object[])obj;

                translator.push(luaState, arr[(int)((double)index)]);
            }
            else
            {
                // Try to use get_Item to index into this .net object
                MethodInfo      getter      = objType.GetMethod("get_Item");
                ParameterInfo[] actualParms = (getter != null) ? getter.GetParameters() : null;

                if (actualParms == null || actualParms.Length != 1)
                {
                    translator.throwError(luaState, "method not found (or no indexer): " + index);

                    LuaDLL.lua_pushnil(luaState);
                }
                else
                {
                    // Get the index in a form acceptable to the getter
                    index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);

                    object[] args = new object[1];

                    // Just call the indexer - if out of bounds an exception will happen
                    args[0] = index;
                    try
                    {
                        object result = getter.Invoke(obj, args);
                        translator.push(luaState, result);
                    }
                    catch (TargetInvocationException e)
                    {
                        // Provide a more readable description for the common case of key not found
                        if (e.InnerException is KeyNotFoundException)
                        {
                            translator.throwError(luaState, "key '" + index + "' not found ");
                        }
                        else
                        {
                            translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message);
                        }

                        LuaDLL.lua_pushnil(luaState);
                    }
                }
            }

            LuaDLL.lua_pushboolean(luaState, false);
            return(2);
        }
示例#7
0
        /*
         * Called by the __index metafunction of CLR objects in case the
         * method is not cached or it is a field/property/event.
         * Receives the object and the member name as arguments and returns
         * either the value of the member or a delegate to call it.
         * If the member does not exist returns nil.
         */
        private int getMethod(IntPtr luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj == null)
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }

            object index     = translator.getObject(luaState, 2);
            Type   indexType = index.GetType();

            string methodName = index as string;        // will be null if not a string arg
            Type   objType    = obj.GetType();

            // Handle the most common case, looking up the method by name.

            // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
            // ie: xmlelement['item'] <- item is a property of xmlelement
            try
            {
                if (methodName != null && isMemberPresent(objType, methodName))
                {
                    return(getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase));
                }
            }
            catch { }

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (objType.IsArray && index is double)
            {
                int intIndex = (int)((double)index);

                if (objType.UnderlyingSystemType == typeof(float[]))
                {
                    float[] arr = ((float[])obj);
                    translator.push(luaState, arr[intIndex]);
                }
                else if (objType.UnderlyingSystemType == typeof(double[]))
                {
                    double[] arr = ((double[])obj);
                    translator.push(luaState, arr[intIndex]);
                }
                else if (objType.UnderlyingSystemType == typeof(int[]))
                {
                    int[] arr = ((int[])obj);
                    translator.push(luaState, arr[intIndex]);
                }
                else
                {
                    object[] arr = (object[])obj;
                    translator.push(luaState, arr[intIndex]);
                }
            }
            else
            {
                // Try to use get_Item to index into this .net object
                //MethodInfo getter = objType.GetMethod("get_Item");
                MethodInfo[] methods = objType.GetMethods();

                foreach (MethodInfo mInfo in methods)
                {
                    if (mInfo.Name == "get_Item")
                    {
                        //check if the signature matches the input
                        if (mInfo.GetParameters().Length == 1)
                        {
                            MethodInfo      getter      = mInfo;
                            ParameterInfo[] actualParms = (getter != null) ? getter.GetParameters() : null;

                            if (actualParms == null || actualParms.Length != 1)
                            {
                                translator.throwError(luaState, "method not found (or no indexer): " + index);

                                LuaDLL.lua_pushnil(luaState);
                            }
                            else
                            {
                                // Get the index in a form acceptable to the getter
                                index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);

                                object[] args = new object[1];

                                // Just call the indexer - if out of bounds an exception will happen
                                args[0] = index;
                                try
                                {
                                    object result = getter.Invoke(obj, args);
                                    translator.push(luaState, result);
                                }
                                catch (TargetInvocationException e)
                                {
                                    // Provide a more readable description for the common case of key not found
                                    if (e.InnerException is KeyNotFoundException)
                                    {
                                        translator.throwError(luaState, "key '" + index + "' not found ");
                                    }
                                    else
                                    {
                                        translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message);
                                    }

                                    LuaDLL.lua_pushnil(luaState);
                                }
                            }
                        }
                    }
                }
            }

            LuaDLL.lua_pushboolean(luaState, false);
            return(2);
        }
示例#8
0
        /// <summary>[-0, +2, e]
        /// Called by the __index metafunction of CLR objects in case the method is not cached or it is a field/property/event.
        /// Receives the object and the member name as arguments and returns either the value of the member or a delegate to call it.
        /// If the member does not exist returns nil.
        /// </summary>
        int getMethod(lua.State L)
        {
            Debug.Assert(interpreter.IsSameLua(L) && luanet.infunction(L));
            object obj = luaclr.checkref(L, 1);

            object index = translator.getObject(L, 2);
            //Type indexType = index.GetType();

            string methodName = index as string;                    // will be null if not a string arg
            Type   objType    = obj.GetType();

            // Handle the most common case, looking up the method by name.

            // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
            // ie: xmlelement['item'] <- item is a property of xmlelement
            if (methodName != null && isMemberPresent(objType, methodName))
            {
                return(getMember(L, objType, obj, methodName, BindingFlags.Instance));
            }
            bool failed = true;

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (objType.IsArray && index is double)
            {
                object val;
                try { val = ((Array)obj).GetValue((int)(double)index); }
                catch (Exception ex) { return(translator.throwError(L, ex)); }
                translator.push(L, val);
                failed = false;
            }
            else
            {
                try
                {
                    // Try to use get_Item to index into this .net object
                    //MethodInfo getter = objType.GetMethod("get_Item");
                    // issue here is that there may be multiple indexers..
                    foreach (MethodInfo mInfo in objType.GetMethods())
                    {
                        if (mInfo.Name == "get_Item")
                        {
                            ParameterInfo[] actualParms = mInfo.GetParameters();
                            if (actualParms.Length != 1)                     //check if the signature matches the input
                            {
                                continue;
                            }
                            if (!translator.memberIsAllowed(mInfo))
                            {
                                continue;
                            }
                            // Get the index in a form acceptable to the getter
                            index = translator.getAsType(L, 2, actualParms[0].ParameterType);
                            // Just call the indexer - if out of bounds an exception will happen
                            object o = mInfo.Invoke(obj, new[] { index });
                            failed = false;
                            translator.push(L, o);
                            break;
                        }
                    }
                }
                catch (TargetInvocationException ex) {
                    return(translator.throwError(L, luaclr.verifyex(ex.InnerException)));
                }
                catch (LuaInternalException) { throw; }
                catch (Exception ex) {
                    return(luaL.error(L, "unable to index {0}: {1}", objType, ex.Message));
                }
            }
            if (failed)
            {
                return(luaL.error(L, "cannot find " + index));
            }
            lua.pushboolean(L, false);
            return(2);
        }
示例#9
0
        public static int getMethod(IntPtr luaState)
        {
            ObjectTranslator translator = ObjectTranslator.FromState(luaState);
            object           obj        = translator.getRawNetObject(luaState, 1);

            if (obj == null)
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }

            object index = translator.getObject(luaState, 2);
            //Type indexType = index.GetType(); //* not used

            string methodName = index as string;                    // will be null if not a string arg
            Type   objType    = obj.GetType();

            // Handle the most common case, looking up the method by name.

            // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
            // ie: xmlelement['item'] <- item is a property of xmlelement
            try
            {
                if (methodName != null && translator.metaFunctions.isMemberPresent(objType, methodName))
                {
                    return(translator.metaFunctions.getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase));
                }
            }
            catch { }
            bool failed = true;

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (objType.IsArray && index is double)
            {
                int   intIndex = (int)((double)index);
                Array aa       = obj as Array;
                if (intIndex >= aa.Length)
                {
                    return(translator.pushError(luaState, "array index out of bounds: " + intIndex + " " + aa.Length));
                }
                object val = aa.GetValue(intIndex);
                translator.push(luaState, val);
                failed = false;
            }
            else
            {
                // Try to use get_Item to index into this .net object
                //MethodInfo getter = objType.GetMethod("get_Item");
                // issue here is that there may be multiple indexers..
                MethodInfo[] methods = objType.GetMethods();

                foreach (MethodInfo mInfo in methods)
                {
                    if (mInfo.Name == "get_Item")
                    {
                        //check if the signature matches the input
                        if (mInfo.GetParameters().Length == 1)
                        {
                            MethodInfo      getter      = mInfo;
                            ParameterInfo[] actualParms = (getter != null) ? getter.GetParameters() : null;
                            if (actualParms == null || actualParms.Length != 1)
                            {
                                return(translator.pushError(luaState, "method not found (or no indexer): " + index));
                            }
                            else
                            {
                                // Get the index in a form acceptable to the getter
                                index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);
                                // Just call the indexer - if out of bounds an exception will happen
                                try
                                {
                                    object result = getter.Invoke(obj, new object[] { index });
                                    translator.push(luaState, result);
                                    failed = false;
                                }
                                catch (TargetInvocationException e)
                                {
                                    // Provide a more readable description for the common case of key not found
                                    if (e.InnerException is KeyNotFoundException)
                                    {
                                        return(translator.pushError(luaState, "key '" + index + "' not found "));
                                    }
                                    else
                                    {
                                        return(translator.pushError(luaState, "exception indexing '" + index + "' " + e.Message));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (failed)
            {
                return(translator.pushError(luaState, "cannot find " + index));
            }
            LuaDLL.lua_pushboolean(luaState, false);
            return(2);
        }
示例#10
0
        /*
         * Indexer for global variables from the LuaInterpreter
         * Supports navigation of tables by using . operator
         */
        public object this[string fullPath]
        {
            get
            {
                object   returnValue = null;
                int      oldTop      = LuaDLL.lua_gettop(L);
                string[] path        = fullPath.Split(new char[] { '.' });
                LuaDLL.lua_getglobal(L, path[0]);
                returnValue = translator.getObject(L, -1);
                if (path.Length > 1)
                {
                    string[] remainingPath = new string[path.Length - 1];
                    Array.Copy(path, 1, remainingPath, 0, path.Length - 1);
                    returnValue = getObject(remainingPath);
                }
                LuaDLL.lua_settop(L, oldTop);
                return(returnValue);
            }
            set
            {
                int      oldTop = LuaDLL.lua_gettop(L);
                string[] path   = fullPath.Split(new char[] { '.' });

                if (path.Length == 1)
                {
                    translator.push(L, value);
                    LuaDLL.lua_setglobal(L, fullPath);
                }
                else
                {
                    //LuaDLL.lua_getglobal(L, path[0]);
                    LuaDLL.lua_rawglobal(L, path[0]);
                    LuaTypes type = LuaDLL.lua_type(L, -1);

                    if (type == LuaTypes.LUA_TNIL)
                    {
                        Debugger.LogError("Table {0} not exists", path[0]);
                        LuaDLL.lua_settop(L, oldTop);
                        return;
                    }

                    string[] remainingPath = new string[path.Length - 1];
                    Array.Copy(path, 1, remainingPath, 0, path.Length - 1);
                    setObject(remainingPath, value);
                }

                LuaDLL.lua_settop(L, oldTop);

                // Globals auto-complete
                // comment by topameng, too many time cost, you shound register you type in other position

                /*if (value == null)
                 * {
                 *  // Remove now obsolete entries
                 *  globals.Remove(fullPath);
                 * }
                 * else
                 * {
                 *  // Add new entries
                 *  if (!globals.Contains(fullPath))
                 *      registerGlobal(fullPath, value.GetType(), 0);
                 * }*/
            }
        }
示例#11
0
        /*
         * Called by the __index metafunction of CLR objects in case the
         * method is not cached or it is a field/property/event.
         * Receives the object and the member name as arguments and returns
         * either the value of the member or a delegate to call it.
         * If the member does not exist returns nil.
         */
        private int getMethod(IntPtr luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj == null)
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }

            object index     = translator.getObject(luaState, 2);
            Type   indexType = index.GetType();

            string methodName = index as string;        // will be null if not a string arg
            Type   objType    = obj.GetType();

            // Handle the most common case, looking up the method by name
            if (methodName != null && isMemberPresent(objType, methodName))
            {
                return(getMember(luaState, objType, obj, methodName, BindingFlags.Instance));
            }

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (obj is Array && index is double)
            {
                object[] arr = (object[])obj;

                translator.push(luaState, arr[(int)((double)index)]);
            }
            else
            {
                // Try to use get_Item to index into this .net object
                Type[] argTypes = new Type[1];
                argTypes[0] = indexType;
                MethodInfo getter = objType.GetMethod("get_Item", argTypes);

                if (index is double)
                {
                    // For numbers we always prefer to pass ints into our accessor if possible (if the accessor
                    // is really built for doubles it should cast back correctly
                    double d = (double)index;

                    if (d == Math.Round(d))
                    {
                        bool convertToInt = true;

                        // If we already found a getter, it might be a version expecting an 'object' parameter
                        // in that case we'll want to convert to an int
                        if (getter != null)
                        {
                            ParameterInfo[] actualParms = getter.GetParameters();

                            convertToInt = actualParms[0].ParameterType != typeof(double);
                        }

                        if (convertToInt)
                        {
                            index = (int)d;     // convert the index to a true (but boxed) int
                        }
                    }

                    // If we can't find a double based indexer, fall back to an int based index
                    if (getter == null && index is int)
                    {
                        argTypes[0] = typeof(int);
                        getter      = objType.GetMethod("get_Item", argTypes);
                    }
                }

                if (getter == null)
                {
                    translator.throwError(luaState, "method not found (or no indexer): " + index);

                    LuaDLL.lua_pushnil(luaState);
                }

                object[] args = new object[1];

                // Just call the indexer - if out of bounds an exception will happen
                args[0] = index;
                try
                {
                    object result = getter.Invoke(obj, args);
                    translator.push(luaState, result);
                }
                catch (Exception e)
                {
                    translator.throwError(luaState, "exception while indexing: " + e);

                    LuaDLL.lua_pushnil(luaState);
                }
            }

            LuaDLL.lua_pushboolean(luaState, false);
            return(2);
        }
示例#12
0
        public static int getMethod(IntPtr luaState)
        {
            ObjectTranslator objectTranslator = ObjectTranslator.FromState(luaState);
            object           rawNetObject     = objectTranslator.getRawNetObject(luaState, 1);

            if (rawNetObject == null)
            {
                objectTranslator.throwError(luaState, "trying to index an invalid object reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }
            object obj  = objectTranslator.getObject(luaState, 2);
            string text = obj as string;
            Type   type = rawNetObject.GetType();

            try
            {
                if (text != null && objectTranslator.metaFunctions.isMemberPresent(type, text))
                {
                    int result = objectTranslator.metaFunctions.getMember(luaState, type, rawNetObject, text, BindingFlags.IgnoreCase | BindingFlags.Instance);
                    return(result);
                }
            }
            catch
            {
            }
            bool flag = true;

            if (type.IsArray && obj is double)
            {
                int   num   = (int)((double)obj);
                Array array = rawNetObject as Array;
                if (num >= array.Length)
                {
                    return(objectTranslator.pushError(luaState, string.Concat(new object[]
                    {
                        "array index out of bounds: ",
                        num,
                        " ",
                        array.Length
                    })));
                }
                object value = array.GetValue(num);
                objectTranslator.push(luaState, value);
                flag = false;
            }
            else
            {
                MethodInfo[] methods = type.GetMethods();
                MethodInfo[] array2  = methods;
                for (int i = 0; i < array2.Length; i++)
                {
                    MethodInfo methodInfo = array2[i];
                    if (methodInfo.Name == "get_Item" && methodInfo.GetParameters().Length == 1)
                    {
                        MethodInfo      methodInfo2 = methodInfo;
                        ParameterInfo[] array3      = (methodInfo2 == null) ? null : methodInfo2.GetParameters();
                        if (array3 == null || array3.Length != 1)
                        {
                            return(objectTranslator.pushError(luaState, "method not found (or no indexer): " + obj));
                        }
                        obj = objectTranslator.getAsType(luaState, 2, array3[0].ParameterType);
                        try
                        {
                            object o = methodInfo2.Invoke(rawNetObject, new object[]
                            {
                                obj
                            });
                            objectTranslator.push(luaState, o);
                            flag = false;
                        }
                        catch (TargetInvocationException ex)
                        {
                            int result;
                            if (ex.InnerException is KeyNotFoundException)
                            {
                                result = objectTranslator.pushError(luaState, "key '" + obj + "' not found ");
                                return(result);
                            }
                            result = objectTranslator.pushError(luaState, string.Concat(new object[]
                            {
                                "exception indexing '",
                                obj,
                                "' ",
                                ex.Message
                            }));
                            return(result);
                        }
                    }
                }
            }
            if (flag)
            {
                return(objectTranslator.pushError(luaState, "cannot find " + obj));
            }
            LuaDLL.lua_pushboolean(luaState, false);
            return(2);
        }
示例#13
0
        /// <summary>
        /// Implementation of get_object_member. Called by the __index metafunction of CLR objects in case the method is not cached or it is a field/property/event.
        /// Receives the object and the member name as arguments and returns either the value of the member or a delegate to call it.
        /// If the member does not exist returns nil.
        /// </summary>
        int getMethod(lua.State L)
        {
            Debug.Assert(translator.interpreter.IsSameLua(L) && luanet.infunction(L));
            object obj = luaclr.checkref(L, 1);

            object index = translator.getObject(L, 2);
            //Type indexType = index.GetType();

            string methodName = index as string;                    // will be null if not a string arg
            Type   objType    = obj.GetType();

            // Handle the most common case, looking up the method by name.

            // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
            // ie: xmlelement['item'] <- item is a property of xmlelement
            try
            {
                // todo: investigate: getMember throws lua errors. all other call sites are also CFunctions and do not use try{}.
                // possible reasons: (1) the author didn't know that Lua errors pass through catch{}
                //                   (2) it is passing unusual input that might generate exceptions not seen in the other use cases
                //                   (3) it is a hasty fix for a bug
                if (methodName != null && isMemberPresent(objType, methodName))
                {
                    return(getMember(L, objType, obj, methodName, BindingFlags.Instance));
                }
            }
            catch { }
            bool failed = true;

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (objType.IsArray && index is double)
            {
                int intIndex = (int)((double)index);
                var aa       = (Array)obj;
                if (intIndex >= aa.Length)
                {
                    return(pushError(L, "array index out of bounds: " + intIndex + " " + aa.Length));
                }
                object val = aa.GetValue(intIndex);
                translator.push(L, val);
                failed = false;
            }
            else
            {
                // Try to use get_Item to index into this .net object
                //MethodInfo getter = objType.GetMethod("get_Item");
                // issue here is that there may be multiple indexers..
                foreach (MethodInfo mInfo in objType.GetMethods())
                {
                    if (mInfo.Name == "get_Item")
                    {
                        ParameterInfo[] actualParms = mInfo.GetParameters();
                        if (actualParms.Length != 1)                 //check if the signature matches the input
                        {
                            continue;
                        }
                        // Get the index in a form acceptable to the getter
                        index = translator.getAsType(L, 2, actualParms[0].ParameterType);
                        // Just call the indexer - if out of bounds an exception will happen
                        try
                        {
                            translator.push(L, mInfo.Invoke(obj, new[] { index }));
                            failed = false;
                        }
                        catch (TargetInvocationException e)
                        {
                            // Provide a more readable description for the common case of key not found
                            if (e.InnerException is KeyNotFoundException)
                            {
                                return(pushError(L, "key '" + index + "' not found "));
                            }
                            else
                            {
                                return(pushError(L, "exception indexing '" + index + "' " + e.InnerException.Message));
                            }
                        }
                    }
                }
            }
            if (failed)
            {
                return(pushError(L, "cannot find " + index));
            }
            lua.pushboolean(L, false);
            return(2);
        }