Repository: yanghuan/CSharpLuaForUnity Branch: master Commit: b2945e3c7950 Files: 842 Total size: 3.1 MB Directory structure: gitextract_wjxhfzse/ ├── .gitignore ├── Assets/ │ ├── CSharpLua/ │ │ ├── Base/ │ │ │ ├── BaseScripts.asmdef │ │ │ ├── BaseScripts.asmdef.meta │ │ │ ├── CSharpLua/ │ │ │ │ ├── BaseUtility.cs │ │ │ │ ├── BaseUtility.cs.meta │ │ │ │ ├── LuaAutoWrapAttribute.cs │ │ │ │ ├── LuaAutoWrapAttribute.cs.meta │ │ │ │ ├── Settings.cs │ │ │ │ └── Settings.cs.meta │ │ │ └── CSharpLua.meta │ │ ├── Base.meta │ │ ├── Bridge/ │ │ │ ├── BridgeScripts.asmdef │ │ │ ├── BridgeScripts.asmdef.meta │ │ │ ├── TestUtils.cs │ │ │ └── TestUtils.cs.meta │ │ ├── Bridge.meta │ │ ├── CSharpLuaClient.cs │ │ ├── CSharpLuaClient.cs.meta │ │ ├── Compiled/ │ │ │ ├── CompiledScripts.asmdef │ │ │ ├── CompiledScripts.asmdef.meta │ │ │ ├── Protocol/ │ │ │ │ ├── AutoGen/ │ │ │ │ │ ├── CommonPrototype.cs │ │ │ │ │ └── CommonPrototype.cs.meta │ │ │ │ ├── AutoGen.meta │ │ │ │ ├── CommonPrototype.proto │ │ │ │ ├── CommonPrototype.proto.meta │ │ │ │ ├── IProtocol.cs │ │ │ │ └── IProtocol.cs.meta │ │ │ ├── Protocol.meta │ │ │ ├── Sample/ │ │ │ │ ├── TestCoroutine.cs │ │ │ │ ├── TestCoroutine.cs.meta │ │ │ │ ├── TestHangingScript.cs │ │ │ │ ├── TestHangingScript.cs.meta │ │ │ │ ├── TestHelloWord.cs │ │ │ │ ├── TestHelloWord.cs.meta │ │ │ │ ├── TestProtobuf.cs │ │ │ │ └── TestProtobuf.cs.meta │ │ │ └── Sample.meta │ │ ├── Compiled.meta │ │ ├── Editor/ │ │ │ ├── Compiler.cs │ │ │ └── Compiler.cs.meta │ │ ├── Editor.meta │ │ ├── Examples/ │ │ │ ├── 01_HelloWorld/ │ │ │ │ ├── HelloWorld.unity │ │ │ │ ├── HelloWorld.unity.meta │ │ │ │ ├── TestLoader.prefab │ │ │ │ ├── TestLoader.prefab.meta │ │ │ │ ├── testText.txt │ │ │ │ └── testText.txt.meta │ │ │ └── 01_HelloWorld.meta │ │ ├── Examples.meta │ │ ├── UserMonoBehaviourConverter.cs │ │ └── UserMonoBehaviourConverter.cs.meta │ ├── CSharpLua.meta │ ├── Editor/ │ │ ├── Custom/ │ │ │ ├── CustomSettings.cs │ │ │ └── CustomSettings.cs.meta │ │ └── Custom.meta │ ├── Editor.meta │ ├── Lua/ │ │ ├── 3rd/ │ │ │ ├── pbc/ │ │ │ │ ├── Protocol/ │ │ │ │ │ ├── CommonPrototype.pb │ │ │ │ │ └── CommonPrototype.pb.meta │ │ │ │ ├── Protocol.meta │ │ │ │ ├── protobuf.lua │ │ │ │ └── protobuf.lua.meta │ │ │ └── pbc.meta │ │ ├── 3rd.meta │ │ ├── Classloader.lua │ │ ├── Classloader.lua.meta │ │ ├── Compiled/ │ │ │ ├── Protocol/ │ │ │ │ ├── AutoGen/ │ │ │ │ │ ├── CommonPrototype.lua │ │ │ │ │ └── CommonPrototype.lua.meta │ │ │ │ ├── AutoGen.meta │ │ │ │ ├── IProtocol.lua │ │ │ │ └── IProtocol.lua.meta │ │ │ ├── Protocol.meta │ │ │ ├── Sample/ │ │ │ │ ├── TestCoroutine.lua │ │ │ │ ├── TestCoroutine.lua.meta │ │ │ │ ├── TestHangingScript.lua │ │ │ │ ├── TestHangingScript.lua.meta │ │ │ │ ├── TestHelloWord.lua │ │ │ │ ├── TestHelloWord.lua.meta │ │ │ │ ├── TestProtobuf.lua │ │ │ │ └── TestProtobuf.lua.meta │ │ │ ├── Sample.meta │ │ │ ├── manifest.lua │ │ │ └── manifest.lua.meta │ │ ├── Compiled.meta │ │ ├── CoreSystemLua/ │ │ │ ├── All.lua │ │ │ ├── All.lua.meta │ │ │ ├── CoreSystem/ │ │ │ │ ├── Array.lua │ │ │ │ ├── Array.lua.meta │ │ │ │ ├── Boolean.lua │ │ │ │ ├── Boolean.lua.meta │ │ │ │ ├── Char.lua │ │ │ │ ├── Char.lua.meta │ │ │ │ ├── Collections/ │ │ │ │ │ ├── Dictionary.lua │ │ │ │ │ ├── Dictionary.lua.meta │ │ │ │ │ ├── EqualityComparer.lua │ │ │ │ │ ├── EqualityComparer.lua.meta │ │ │ │ │ ├── HashSet.lua │ │ │ │ │ ├── HashSet.lua.meta │ │ │ │ │ ├── LinkedList.lua │ │ │ │ │ ├── LinkedList.lua.meta │ │ │ │ │ ├── Linq.lua │ │ │ │ │ ├── Linq.lua.meta │ │ │ │ │ ├── List.lua │ │ │ │ │ ├── List.lua.meta │ │ │ │ │ ├── Queue.lua │ │ │ │ │ ├── Queue.lua.meta │ │ │ │ │ ├── SortedSet.lua │ │ │ │ │ ├── SortedSet.lua.meta │ │ │ │ │ ├── Stack.lua │ │ │ │ │ └── Stack.lua.meta │ │ │ │ ├── Collections.meta │ │ │ │ ├── Console.lua │ │ │ │ ├── Console.lua.meta │ │ │ │ ├── Convert.lua │ │ │ │ ├── Convert.lua.meta │ │ │ │ ├── Core.lua │ │ │ │ ├── Core.lua.meta │ │ │ │ ├── DateTime.lua │ │ │ │ ├── DateTime.lua.meta │ │ │ │ ├── Delegate.lua │ │ │ │ ├── Delegate.lua.meta │ │ │ │ ├── Enum.lua │ │ │ │ ├── Enum.lua.meta │ │ │ │ ├── Exception.lua │ │ │ │ ├── Exception.lua.meta │ │ │ │ ├── IO/ │ │ │ │ │ ├── File.lua │ │ │ │ │ └── File.lua.meta │ │ │ │ ├── IO.meta │ │ │ │ ├── Interfaces.lua │ │ │ │ ├── Interfaces.lua.meta │ │ │ │ ├── Math.lua │ │ │ │ ├── Math.lua.meta │ │ │ │ ├── Number.lua │ │ │ │ ├── Number.lua.meta │ │ │ │ ├── Random.lua │ │ │ │ ├── Random.lua.meta │ │ │ │ ├── Reflection/ │ │ │ │ │ ├── Assembly.lua │ │ │ │ │ └── Assembly.lua.meta │ │ │ │ ├── Reflection.meta │ │ │ │ ├── String.lua │ │ │ │ ├── String.lua.meta │ │ │ │ ├── Text/ │ │ │ │ │ ├── StringBuilder.lua │ │ │ │ │ └── StringBuilder.lua.meta │ │ │ │ ├── Text.meta │ │ │ │ ├── Threading/ │ │ │ │ │ ├── Task.lua │ │ │ │ │ ├── Task.lua.meta │ │ │ │ │ ├── Thread.lua │ │ │ │ │ ├── Thread.lua.meta │ │ │ │ │ ├── Timer.lua │ │ │ │ │ └── Timer.lua.meta │ │ │ │ ├── Threading.meta │ │ │ │ ├── Threads.meta │ │ │ │ ├── TimeSpan.lua │ │ │ │ ├── TimeSpan.lua.meta │ │ │ │ ├── Type.lua │ │ │ │ ├── Type.lua.meta │ │ │ │ ├── Utilities.lua │ │ │ │ └── Utilities.lua.meta │ │ │ ├── CoreSystem.meta │ │ │ ├── Sample/ │ │ │ │ ├── test.lua │ │ │ │ └── test.lua.meta │ │ │ └── Sample.meta │ │ ├── CoreSystemLua.meta │ │ ├── Main.lua │ │ ├── Main.lua.meta │ │ ├── ProtobufAdapter.lua │ │ ├── ProtobufAdapter.lua.meta │ │ ├── UnityAdapter.Lua │ │ └── UnityAdapter.Lua.meta │ ├── Lua.meta │ ├── Plugins/ │ │ ├── 3rd/ │ │ │ └── protobuf-net.dll.meta │ │ ├── 3rd.meta │ │ ├── Android/ │ │ │ ├── libs/ │ │ │ │ ├── arm64-v8a/ │ │ │ │ │ └── libtolua.so.meta │ │ │ │ ├── arm64-v8a.meta │ │ │ │ ├── armeabi-v7a/ │ │ │ │ │ └── libtolua.so.meta │ │ │ │ ├── armeabi-v7a.meta │ │ │ │ ├── x86/ │ │ │ │ │ └── libtolua.so.meta │ │ │ │ └── x86.meta │ │ │ └── libs.meta │ │ ├── Android.meta │ │ ├── CString.dll.meta │ │ ├── Debugger.dll.meta │ │ ├── iOS/ │ │ │ ├── libtolua.a │ │ │ └── libtolua.a.meta │ │ ├── iOS.meta │ │ ├── tolua.bundle/ │ │ │ ├── Contents/ │ │ │ │ ├── Info.plist │ │ │ │ ├── Info.plist.meta │ │ │ │ ├── MacOS/ │ │ │ │ │ ├── tolua │ │ │ │ │ └── tolua.meta │ │ │ │ ├── MacOS.meta │ │ │ │ ├── Resources/ │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── LICENSE.meta │ │ │ │ │ ├── README.md │ │ │ │ │ ├── README.md.meta │ │ │ │ │ ├── print_r.lua │ │ │ │ │ ├── print_r.lua.meta │ │ │ │ │ ├── sproto.lua │ │ │ │ │ ├── sproto.lua.meta │ │ │ │ │ ├── sproto.new/ │ │ │ │ │ │ ├── LICENSE │ │ │ │ │ │ ├── LICENSE.meta │ │ │ │ │ │ ├── Makefile │ │ │ │ │ │ ├── Makefile.meta │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── README.md.meta │ │ │ │ │ │ ├── lsproto.c │ │ │ │ │ │ ├── lsproto.c.meta │ │ │ │ │ │ ├── msvcint.h │ │ │ │ │ │ ├── msvcint.h.meta │ │ │ │ │ │ ├── print_r.lua │ │ │ │ │ │ ├── print_r.lua.meta │ │ │ │ │ │ ├── sproto.c │ │ │ │ │ │ ├── sproto.c.meta │ │ │ │ │ │ ├── sproto.h │ │ │ │ │ │ ├── sproto.h.meta │ │ │ │ │ │ ├── sproto.lua │ │ │ │ │ │ ├── sproto.lua.meta │ │ │ │ │ │ ├── sproto.new.xcodeproj/ │ │ │ │ │ │ │ ├── project.pbxproj │ │ │ │ │ │ │ └── project.pbxproj.meta │ │ │ │ │ │ ├── sproto.new.xcodeproj.meta │ │ │ │ │ │ ├── sprotoparser.lua │ │ │ │ │ │ ├── sprotoparser.lua.meta │ │ │ │ │ │ ├── test.lua │ │ │ │ │ │ ├── test.lua.meta │ │ │ │ │ │ ├── testall.lua │ │ │ │ │ │ ├── testall.lua.meta │ │ │ │ │ │ ├── testrpc.lua │ │ │ │ │ │ └── testrpc.lua.meta │ │ │ │ │ ├── sproto.new.meta │ │ │ │ │ ├── sprotoparser.lua │ │ │ │ │ ├── sprotoparser.lua.meta │ │ │ │ │ ├── test.lua │ │ │ │ │ ├── test.lua.meta │ │ │ │ │ ├── testall.lua │ │ │ │ │ ├── testall.lua.meta │ │ │ │ │ ├── testrpc.lua │ │ │ │ │ └── testrpc.lua.meta │ │ │ │ └── Resources.meta │ │ │ └── Contents.meta │ │ ├── tolua.bundle.meta │ │ ├── x86/ │ │ │ └── tolua.dll.meta │ │ ├── x86.meta │ │ ├── x86_64/ │ │ │ └── tolua.dll.meta │ │ └── x86_64.meta │ ├── Plugins.meta │ ├── Source/ │ │ ├── Generate.meta │ │ ├── LuaConst.cs │ │ └── LuaConst.cs.meta │ ├── Source.meta │ ├── ToLua/ │ │ ├── BaseType/ │ │ │ ├── LuaInterface_EventObjectWrap.cs │ │ │ ├── LuaInterface_EventObjectWrap.cs.meta │ │ │ ├── LuaInterface_LuaConstructorWrap.cs │ │ │ ├── LuaInterface_LuaConstructorWrap.cs.meta │ │ │ ├── LuaInterface_LuaFieldWrap.cs │ │ │ ├── LuaInterface_LuaFieldWrap.cs.meta │ │ │ ├── LuaInterface_LuaMethodWrap.cs │ │ │ ├── LuaInterface_LuaMethodWrap.cs.meta │ │ │ ├── LuaInterface_LuaOutWrap.cs │ │ │ ├── LuaInterface_LuaOutWrap.cs.meta │ │ │ ├── LuaInterface_LuaPropertyWrap.cs │ │ │ ├── LuaInterface_LuaPropertyWrap.cs.meta │ │ │ ├── System_ArrayWrap.cs │ │ │ ├── System_ArrayWrap.cs.meta │ │ │ ├── System_Collections_Generic_DictionaryWrap.cs │ │ │ ├── System_Collections_Generic_DictionaryWrap.cs.meta │ │ │ ├── System_Collections_Generic_Dictionary_KeyCollectionWrap.cs │ │ │ ├── System_Collections_Generic_Dictionary_KeyCollectionWrap.cs.meta │ │ │ ├── System_Collections_Generic_Dictionary_ValueCollectionWrap.cs │ │ │ ├── System_Collections_Generic_Dictionary_ValueCollectionWrap.cs.meta │ │ │ ├── System_Collections_Generic_KeyValuePairWrap.cs │ │ │ ├── System_Collections_Generic_KeyValuePairWrap.cs.meta │ │ │ ├── System_Collections_Generic_ListWrap.cs │ │ │ ├── System_Collections_Generic_ListWrap.cs.meta │ │ │ ├── System_Collections_IEnumeratorWrap.cs │ │ │ ├── System_Collections_IEnumeratorWrap.cs.meta │ │ │ ├── System_Collections_ObjectModel_ReadOnlyCollectionWrap.cs │ │ │ ├── System_Collections_ObjectModel_ReadOnlyCollectionWrap.cs.meta │ │ │ ├── System_DelegateWrap.cs │ │ │ ├── System_DelegateWrap.cs.meta │ │ │ ├── System_EnumWrap.cs │ │ │ ├── System_EnumWrap.cs.meta │ │ │ ├── System_NullObjectWrap.cs │ │ │ ├── System_NullObjectWrap.cs.meta │ │ │ ├── System_ObjectWrap.cs │ │ │ ├── System_ObjectWrap.cs.meta │ │ │ ├── System_StringWrap.cs │ │ │ ├── System_StringWrap.cs.meta │ │ │ ├── System_TypeWrap.cs │ │ │ ├── System_TypeWrap.cs.meta │ │ │ ├── UnityEngine_CoroutineWrap.cs │ │ │ ├── UnityEngine_CoroutineWrap.cs.meta │ │ │ ├── UnityEngine_ObjectWrap.cs │ │ │ └── UnityEngine_ObjectWrap.cs.meta │ │ ├── BaseType.meta │ │ ├── Core/ │ │ │ ├── LuaAttributes.cs │ │ │ ├── LuaAttributes.cs.meta │ │ │ ├── LuaBaseRef.cs │ │ │ ├── LuaBaseRef.cs.meta │ │ │ ├── LuaBeatEvent.cs │ │ │ ├── LuaBeatEvent.cs.meta │ │ │ ├── LuaDLL.cs │ │ │ ├── LuaDLL.cs.meta │ │ │ ├── LuaEvent.cs │ │ │ ├── LuaEvent.cs.meta │ │ │ ├── LuaException.cs │ │ │ ├── LuaException.cs.meta │ │ │ ├── LuaFileUtils.cs │ │ │ ├── LuaFileUtils.cs.meta │ │ │ ├── LuaFunction.cs │ │ │ ├── LuaFunction.cs.meta │ │ │ ├── LuaMatchType.cs │ │ │ ├── LuaMatchType.cs.meta │ │ │ ├── LuaMethodCache.cs │ │ │ ├── LuaMethodCache.cs.meta │ │ │ ├── LuaMisc.cs │ │ │ ├── LuaMisc.cs.meta │ │ │ ├── LuaStackOp.cs │ │ │ ├── LuaStackOp.cs.meta │ │ │ ├── LuaState.cs │ │ │ ├── LuaState.cs.meta │ │ │ ├── LuaStatePtr.cs │ │ │ ├── LuaStatePtr.cs.meta │ │ │ ├── LuaStatic.cs │ │ │ ├── LuaStatic.cs.meta │ │ │ ├── LuaTable.cs │ │ │ ├── LuaTable.cs.meta │ │ │ ├── LuaThread.cs │ │ │ ├── LuaThread.cs.meta │ │ │ ├── LuaUnityLibs.cs │ │ │ ├── LuaUnityLibs.cs.meta │ │ │ ├── LuaValueType.cs │ │ │ ├── LuaValueType.cs.meta │ │ │ ├── ObjectPool.cs │ │ │ ├── ObjectPool.cs.meta │ │ │ ├── ObjectTranslator.cs │ │ │ ├── ObjectTranslator.cs.meta │ │ │ ├── ToLua.cs │ │ │ ├── ToLua.cs.meta │ │ │ ├── TypeChecker.cs │ │ │ ├── TypeChecker.cs.meta │ │ │ ├── TypeTraits.cs │ │ │ └── TypeTraits.cs.meta │ │ ├── Core.meta │ │ ├── Editor/ │ │ │ ├── Extend/ │ │ │ │ ├── ToLua_LuaInterface_EventObject.cs │ │ │ │ ├── ToLua_LuaInterface_EventObject.cs.meta │ │ │ │ ├── ToLua_LuaInterface_LuaConstructor.cs │ │ │ │ ├── ToLua_LuaInterface_LuaConstructor.cs.meta │ │ │ │ ├── ToLua_LuaInterface_LuaField.cs │ │ │ │ ├── ToLua_LuaInterface_LuaField.cs.meta │ │ │ │ ├── ToLua_LuaInterface_LuaMethod.cs │ │ │ │ ├── ToLua_LuaInterface_LuaMethod.cs.meta │ │ │ │ ├── ToLua_LuaInterface_LuaProperty.cs │ │ │ │ ├── ToLua_LuaInterface_LuaProperty.cs.meta │ │ │ │ ├── ToLua_System_Delegate.cs │ │ │ │ ├── ToLua_System_Delegate.cs.meta │ │ │ │ ├── ToLua_System_Enum.cs │ │ │ │ ├── ToLua_System_Enum.cs.meta │ │ │ │ ├── ToLua_System_Object.cs │ │ │ │ ├── ToLua_System_Object.cs.meta │ │ │ │ ├── ToLua_System_String.cs │ │ │ │ ├── ToLua_System_String.cs.meta │ │ │ │ ├── ToLua_System_Type.cs │ │ │ │ ├── ToLua_System_Type.cs.meta │ │ │ │ ├── ToLua_UnityEngine_GameObject.cs │ │ │ │ ├── ToLua_UnityEngine_GameObject.cs.meta │ │ │ │ ├── ToLua_UnityEngine_Input.cs │ │ │ │ ├── ToLua_UnityEngine_Input.cs.meta │ │ │ │ ├── ToLua_UnityEngine_Object.cs │ │ │ │ ├── ToLua_UnityEngine_Object.cs.meta │ │ │ │ ├── ToLua_UnityEngine_RectTransform.cs │ │ │ │ └── ToLua_UnityEngine_RectTransform.cs.meta │ │ │ ├── Extend.meta │ │ │ ├── ToLuaExport.cs │ │ │ ├── ToLuaExport.cs.meta │ │ │ ├── ToLuaMenu.cs │ │ │ ├── ToLuaMenu.cs.meta │ │ │ ├── ToLuaTree.cs │ │ │ └── ToLuaTree.cs.meta │ │ ├── Editor.meta │ │ ├── Examples/ │ │ │ ├── 01_HelloWorld/ │ │ │ │ ├── HelloWorld.cs │ │ │ │ ├── HelloWorld.cs.meta │ │ │ │ ├── HelloWorld.unity │ │ │ │ └── HelloWorld.unity.meta │ │ │ ├── 01_HelloWorld.meta │ │ │ ├── 02_ScriptsFromFile/ │ │ │ │ ├── ScriptsFromFile.cs │ │ │ │ ├── ScriptsFromFile.cs.meta │ │ │ │ ├── ScriptsFromFile.lua │ │ │ │ ├── ScriptsFromFile.lua.meta │ │ │ │ ├── ScriptsFromFile.unity │ │ │ │ └── ScriptsFromFile.unity.meta │ │ │ ├── 02_ScriptsFromFile.meta │ │ │ ├── 03_CallLuaFunction/ │ │ │ │ ├── CallLuaFunction.cs │ │ │ │ ├── CallLuaFunction.cs.meta │ │ │ │ ├── CallLuaFunction.unity │ │ │ │ └── CallLuaFunction.unity.meta │ │ │ ├── 03_CallLuaFunction.meta │ │ │ ├── 04_AccessingLuaVariables/ │ │ │ │ ├── AccessingLuaVariables.cs │ │ │ │ ├── AccessingLuaVariables.cs.meta │ │ │ │ ├── AccessingLuaVariables.unity │ │ │ │ └── AccessingLuaVariables.unity.meta │ │ │ ├── 04_AccessingLuaVariables.meta │ │ │ ├── 05_LuaCoroutine/ │ │ │ │ ├── LuaCoroutine.unity │ │ │ │ ├── LuaCoroutine.unity.meta │ │ │ │ ├── TestCoroutine.cs │ │ │ │ └── TestCoroutine.cs.meta │ │ │ ├── 05_LuaCoroutine.meta │ │ │ ├── 06_LuaCoroutine2/ │ │ │ │ ├── Coroutine.unity │ │ │ │ ├── Coroutine.unity.meta │ │ │ │ ├── TestCoroutine2.cs │ │ │ │ └── TestCoroutine2.cs.meta │ │ │ ├── 06_LuaCoroutine2.meta │ │ │ ├── 07_LuaThread/ │ │ │ │ ├── TestLuaThread.cs │ │ │ │ ├── TestLuaThread.cs.meta │ │ │ │ ├── TestThread.unity │ │ │ │ └── TestThread.unity.meta │ │ │ ├── 07_LuaThread.meta │ │ │ ├── 08_AccessingArray/ │ │ │ │ ├── AccessingArray.cs │ │ │ │ ├── AccessingArray.cs.meta │ │ │ │ ├── AccessingArray.unity │ │ │ │ └── AccessingArray.unity.meta │ │ │ ├── 08_AccessingArray.meta │ │ │ ├── 09_Dictionary/ │ │ │ │ ├── System_Collections_Generic_Dictionary_int_TestAccountWrap.cs │ │ │ │ ├── System_Collections_Generic_Dictionary_int_TestAccountWrap.cs.meta │ │ │ │ ├── System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap.cs │ │ │ │ ├── System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap.cs.meta │ │ │ │ ├── System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap.cs │ │ │ │ ├── System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap.cs.meta │ │ │ │ ├── System_Collections_Generic_KeyValuePair_int_TestAccountWrap.cs │ │ │ │ ├── System_Collections_Generic_KeyValuePair_int_TestAccountWrap.cs.meta │ │ │ │ ├── TestAccountWrap.cs │ │ │ │ ├── TestAccountWrap.cs.meta │ │ │ │ ├── UseDictionary.cs │ │ │ │ ├── UseDictionary.cs.meta │ │ │ │ ├── UseDictionary.unity │ │ │ │ └── UseDictionary.unity.meta │ │ │ ├── 09_Dictionary.meta │ │ │ ├── 10_Enum/ │ │ │ │ ├── AccessingEnum.cs │ │ │ │ ├── AccessingEnum.cs.meta │ │ │ │ ├── AccessingEnum.unity │ │ │ │ └── AccessingEnum.unity.meta │ │ │ ├── 10_Enum.meta │ │ │ ├── 11_Delegate/ │ │ │ │ ├── TestDelegate.cs │ │ │ │ ├── TestDelegate.cs.meta │ │ │ │ ├── TestEventListener.cs │ │ │ │ ├── TestEventListener.cs.meta │ │ │ │ ├── TestEventListenerWrap.cs │ │ │ │ ├── TestEventListenerWrap.cs.meta │ │ │ │ ├── UseDelegate.unity │ │ │ │ └── UseDelegate.unity.meta │ │ │ ├── 11_Delegate.meta │ │ │ ├── 12_GameObject/ │ │ │ │ ├── TestGameObject.cs │ │ │ │ ├── TestGameObject.cs.meta │ │ │ │ ├── TestGameObject.unity │ │ │ │ └── TestGameObject.unity.meta │ │ │ ├── 12_GameObject.meta │ │ │ ├── 13_CustomLoader/ │ │ │ │ ├── CustomLoader.unity │ │ │ │ ├── CustomLoader.unity.meta │ │ │ │ ├── TestCustomLoader.cs │ │ │ │ └── TestCustomLoader.cs.meta │ │ │ ├── 13_CustomLoader.meta │ │ │ ├── 14_Out/ │ │ │ │ ├── TestOut.unity │ │ │ │ ├── TestOut.unity.meta │ │ │ │ ├── TestOutArg.cs │ │ │ │ └── TestOutArg.cs.meta │ │ │ ├── 14_Out.meta │ │ │ ├── 15_ProtoBuffer/ │ │ │ │ ├── ProtoBuffer.unity │ │ │ │ ├── ProtoBuffer.unity.meta │ │ │ │ ├── TestProtoBuffer.cs │ │ │ │ ├── TestProtoBuffer.cs.meta │ │ │ │ ├── TestProtol.cs │ │ │ │ ├── TestProtol.cs.meta │ │ │ │ ├── TestProtolWrap.cs │ │ │ │ ├── TestProtolWrap.cs.meta │ │ │ │ ├── common.proto │ │ │ │ ├── common.proto.meta │ │ │ │ ├── person.proto │ │ │ │ └── person.proto.meta │ │ │ ├── 15_ProtoBuffer.meta │ │ │ ├── 16_Int64/ │ │ │ │ ├── TestInt64.cs │ │ │ │ ├── TestInt64.cs.meta │ │ │ │ ├── TestInt64.unity │ │ │ │ └── TestInt64.unity.meta │ │ │ ├── 16_Int64.meta │ │ │ ├── 17_Inherit/ │ │ │ │ ├── Inherit.unity │ │ │ │ ├── Inherit.unity.meta │ │ │ │ ├── TestInherit.cs │ │ │ │ └── TestInherit.cs.meta │ │ │ ├── 17_Inherit.meta │ │ │ ├── 18_Bundle/ │ │ │ │ ├── TesetAssetBundle.unity │ │ │ │ ├── TesetAssetBundle.unity.meta │ │ │ │ ├── TestABLoader.cs │ │ │ │ └── TestABLoader.cs.meta │ │ │ ├── 18_Bundle.meta │ │ │ ├── 19_cjson/ │ │ │ │ ├── TestCJson.cs │ │ │ │ ├── TestCJson.cs.meta │ │ │ │ ├── testcjson.unity │ │ │ │ └── testcjson.unity.meta │ │ │ ├── 19_cjson.meta │ │ │ ├── 20_utf8/ │ │ │ │ ├── TestUTF8.cs │ │ │ │ ├── TestUTF8.cs.meta │ │ │ │ ├── utf8.unity │ │ │ │ └── utf8.unity.meta │ │ │ ├── 20_utf8.meta │ │ │ ├── 21_String/ │ │ │ │ ├── TestString.cs │ │ │ │ ├── TestString.cs.meta │ │ │ │ ├── TestString.unity │ │ │ │ └── TestString.unity.meta │ │ │ ├── 21_String.meta │ │ │ ├── 22_Reflection/ │ │ │ │ ├── TestReflection.cs │ │ │ │ ├── TestReflection.cs.meta │ │ │ │ ├── TestReflection.unity │ │ │ │ └── TestReflection.unity.meta │ │ │ ├── 22_Reflection.meta │ │ │ ├── 23_List/ │ │ │ │ ├── UseList.cs │ │ │ │ ├── UseList.cs.meta │ │ │ │ ├── UseList.unity │ │ │ │ └── UseList.unity.meta │ │ │ ├── 23_List.meta │ │ │ ├── 24_Struct/ │ │ │ │ ├── PassStruct.cs │ │ │ │ ├── PassStruct.cs.meta │ │ │ │ ├── Struct.unity │ │ │ │ └── Struct.unity.meta │ │ │ ├── 24_Struct.meta │ │ │ ├── Performance/ │ │ │ │ ├── Performance.unity │ │ │ │ ├── Performance.unity.meta │ │ │ │ ├── TestPerformance.cs │ │ │ │ └── TestPerformance.cs.meta │ │ │ ├── Performance.meta │ │ │ ├── README.md │ │ │ ├── README.md.meta │ │ │ ├── Resources/ │ │ │ │ ├── Lua/ │ │ │ │ │ ├── Protol/ │ │ │ │ │ │ ├── common_pb.lua.bytes │ │ │ │ │ │ ├── common_pb.lua.bytes.meta │ │ │ │ │ │ ├── person_pb.lua.bytes │ │ │ │ │ │ └── person_pb.lua.bytes.meta │ │ │ │ │ ├── Protol.meta │ │ │ │ │ ├── TestErrorStack.lua.bytes │ │ │ │ │ ├── TestErrorStack.lua.bytes.meta │ │ │ │ │ ├── TestLoader.lua.bytes │ │ │ │ │ ├── TestLoader.lua.bytes.meta │ │ │ │ │ ├── TestLuaCoroutine.lua.bytes │ │ │ │ │ ├── TestLuaCoroutine.lua.bytes.meta │ │ │ │ │ ├── TestPerf.lua.bytes │ │ │ │ │ ├── TestPerf.lua.bytes.meta │ │ │ │ │ ├── ToLuaInjectionTestInjector.lua.bytes │ │ │ │ │ └── ToLuaInjectionTestInjector.lua.bytes.meta │ │ │ │ ├── Lua.meta │ │ │ │ ├── jsonexample.json │ │ │ │ └── jsonexample.json.meta │ │ │ ├── Resources.meta │ │ │ ├── TestErrorStack/ │ │ │ │ ├── TestInstantiate.cs │ │ │ │ ├── TestInstantiate.cs.meta │ │ │ │ ├── TestInstantiate.prefab │ │ │ │ ├── TestInstantiate.prefab.meta │ │ │ │ ├── TestInstantiate2.cs │ │ │ │ ├── TestInstantiate2.cs.meta │ │ │ │ ├── TestInstantiate2.prefab │ │ │ │ ├── TestInstantiate2.prefab.meta │ │ │ │ ├── TestLuaStack.cs │ │ │ │ ├── TestLuaStack.cs.meta │ │ │ │ ├── TestLuaStack.unity │ │ │ │ └── TestLuaStack.unity.meta │ │ │ ├── TestErrorStack.meta │ │ │ ├── TestInjection/ │ │ │ │ ├── BaseTestWrap.cs │ │ │ │ ├── BaseTestWrap.cs.meta │ │ │ │ ├── TestInjection.cs │ │ │ │ ├── TestInjection.cs.meta │ │ │ │ ├── TestInjection.unity │ │ │ │ ├── TestInjection.unity.meta │ │ │ │ ├── ToLuaInjectionTest.cs │ │ │ │ ├── ToLuaInjectionTest.cs.meta │ │ │ │ ├── ToLuaInjectionTestWrap.cs │ │ │ │ └── ToLuaInjectionTestWrap.cs.meta │ │ │ ├── TestInjection.meta │ │ │ ├── TestOverload/ │ │ │ │ ├── TestExportWrap.cs │ │ │ │ ├── TestExportWrap.cs.meta │ │ │ │ ├── TestExport_SpaceWrap.cs │ │ │ │ ├── TestExport_SpaceWrap.cs.meta │ │ │ │ ├── TestOverload.cs │ │ │ │ ├── TestOverload.cs.meta │ │ │ │ ├── TestOverload.unity │ │ │ │ └── TestOverload.unity.meta │ │ │ └── TestOverload.meta │ │ ├── Examples.meta │ │ ├── Injection/ │ │ │ ├── Editor/ │ │ │ │ ├── CustomCecilRocks/ │ │ │ │ │ ├── MethodBodyRocks.cs │ │ │ │ │ └── MethodBodyRocks.cs.meta │ │ │ │ ├── CustomCecilRocks.meta │ │ │ │ ├── ToLuaInjection.cs │ │ │ │ ├── ToLuaInjection.cs.meta │ │ │ │ ├── ToLuaInjectionHelper.cs │ │ │ │ ├── ToLuaInjectionHelper.cs.meta │ │ │ │ ├── ToLuaText.cs │ │ │ │ ├── ToLuaText.cs.meta │ │ │ │ ├── ToluaInjectionBlackListPanel.cs │ │ │ │ └── ToluaInjectionBlackListPanel.cs.meta │ │ │ ├── Editor.meta │ │ │ ├── InjectionBlackList.txt │ │ │ ├── InjectionBlackList.txt.meta │ │ │ ├── InjectionBridgeEditorInfo.xml │ │ │ ├── InjectionBridgeEditorInfo.xml.meta │ │ │ ├── LuaInjectionSkipPaths.txt │ │ │ ├── LuaInjectionSkipPaths.txt.meta │ │ │ ├── LuaInjectionStation.cs │ │ │ └── LuaInjectionStation.cs.meta │ │ ├── Injection.meta │ │ ├── Lua/ │ │ │ ├── Build.bat │ │ │ ├── Build.bat.meta │ │ │ ├── System/ │ │ │ │ ├── Injection/ │ │ │ │ │ ├── InjectionBridgeInfo.lua │ │ │ │ │ ├── InjectionBridgeInfo.lua.meta │ │ │ │ │ ├── LuaInjectionBus.lua │ │ │ │ │ ├── LuaInjectionBus.lua.meta │ │ │ │ │ ├── LuaInjectionStation.lua │ │ │ │ │ └── LuaInjectionStation.lua.meta │ │ │ │ ├── Injection.meta │ │ │ │ ├── Reflection/ │ │ │ │ │ ├── BindingFlags.lua │ │ │ │ │ └── BindingFlags.lua.meta │ │ │ │ ├── Reflection.meta │ │ │ │ ├── Timer.lua │ │ │ │ ├── Timer.lua.meta │ │ │ │ ├── ValueType.lua │ │ │ │ ├── ValueType.lua.meta │ │ │ │ ├── coroutine.lua │ │ │ │ └── coroutine.lua.meta │ │ │ ├── System.meta │ │ │ ├── UnityEngine/ │ │ │ │ ├── Bounds.lua │ │ │ │ ├── Bounds.lua.meta │ │ │ │ ├── Color.lua │ │ │ │ ├── Color.lua.meta │ │ │ │ ├── Color32.lua │ │ │ │ ├── Color32.lua.meta │ │ │ │ ├── LayerMask.lua │ │ │ │ ├── LayerMask.lua.meta │ │ │ │ ├── Mathf.lua │ │ │ │ ├── Mathf.lua.meta │ │ │ │ ├── Plane.lua │ │ │ │ ├── Plane.lua.meta │ │ │ │ ├── Profiler.lua │ │ │ │ ├── Profiler.lua.meta │ │ │ │ ├── Quaternion.lua │ │ │ │ ├── Quaternion.lua.meta │ │ │ │ ├── Ray.lua │ │ │ │ ├── Ray.lua.meta │ │ │ │ ├── RaycastHit.lua │ │ │ │ ├── RaycastHit.lua.meta │ │ │ │ ├── Time.lua │ │ │ │ ├── Time.lua.meta │ │ │ │ ├── Touch.lua │ │ │ │ ├── Touch.lua.meta │ │ │ │ ├── Vector2.lua │ │ │ │ ├── Vector2.lua.meta │ │ │ │ ├── Vector3.lua │ │ │ │ ├── Vector3.lua.meta │ │ │ │ ├── Vector4.lua │ │ │ │ └── Vector4.lua.meta │ │ │ ├── UnityEngine.meta │ │ │ ├── cjson/ │ │ │ │ ├── util.lua │ │ │ │ └── util.lua.meta │ │ │ ├── cjson.meta │ │ │ ├── event.lua │ │ │ ├── event.lua.meta │ │ │ ├── jit/ │ │ │ │ ├── bc.lua │ │ │ │ ├── bc.lua.meta │ │ │ │ ├── bcsave.lua │ │ │ │ ├── bcsave.lua.meta │ │ │ │ ├── dis_arm.lua │ │ │ │ ├── dis_arm.lua.meta │ │ │ │ ├── dis_arm64.lua │ │ │ │ ├── dis_arm64.lua.meta │ │ │ │ ├── dis_arm64be.lua │ │ │ │ ├── dis_arm64be.lua.meta │ │ │ │ ├── dis_mips.lua │ │ │ │ ├── dis_mips.lua.meta │ │ │ │ ├── dis_mips64.lua │ │ │ │ ├── dis_mips64.lua.meta │ │ │ │ ├── dis_mips64el.lua │ │ │ │ ├── dis_mips64el.lua.meta │ │ │ │ ├── dis_mipsel.lua │ │ │ │ ├── dis_mipsel.lua.meta │ │ │ │ ├── dis_ppc.lua │ │ │ │ ├── dis_ppc.lua.meta │ │ │ │ ├── dis_x64.lua │ │ │ │ ├── dis_x64.lua.meta │ │ │ │ ├── dis_x86.lua │ │ │ │ ├── dis_x86.lua.meta │ │ │ │ ├── dump.lua │ │ │ │ ├── dump.lua.meta │ │ │ │ ├── p.lua │ │ │ │ ├── p.lua.meta │ │ │ │ ├── v.lua │ │ │ │ ├── v.lua.meta │ │ │ │ ├── zone.lua │ │ │ │ └── zone.lua.meta │ │ │ ├── jit.meta │ │ │ ├── list.lua │ │ │ ├── list.lua.meta │ │ │ ├── lpeg/ │ │ │ │ ├── re.lua │ │ │ │ └── re.lua.meta │ │ │ ├── lpeg.meta │ │ │ ├── ltn12.lua │ │ │ ├── ltn12.lua.meta │ │ │ ├── mime.lua │ │ │ ├── mime.lua.meta │ │ │ ├── misc/ │ │ │ │ ├── functions.lua │ │ │ │ ├── functions.lua.meta │ │ │ │ ├── strict.lua │ │ │ │ ├── strict.lua.meta │ │ │ │ ├── utf8.lua │ │ │ │ └── utf8.lua.meta │ │ │ ├── misc.meta │ │ │ ├── pbc.meta │ │ │ ├── protobuf/ │ │ │ │ ├── containers.lua │ │ │ │ ├── containers.lua.meta │ │ │ │ ├── decoder.lua │ │ │ │ ├── decoder.lua.meta │ │ │ │ ├── descriptor.lua │ │ │ │ ├── descriptor.lua.meta │ │ │ │ ├── encoder.lua │ │ │ │ ├── encoder.lua.meta │ │ │ │ ├── listener.lua │ │ │ │ ├── listener.lua.meta │ │ │ │ ├── protobuf.lua │ │ │ │ ├── protobuf.lua.meta │ │ │ │ ├── text_format.lua │ │ │ │ ├── text_format.lua.meta │ │ │ │ ├── type_checkers.lua │ │ │ │ ├── type_checkers.lua.meta │ │ │ │ ├── wire_format.lua │ │ │ │ └── wire_format.lua.meta │ │ │ ├── protobuf.meta │ │ │ ├── slot.lua │ │ │ ├── slot.lua.meta │ │ │ ├── socket/ │ │ │ │ ├── ftp.lua │ │ │ │ ├── ftp.lua.meta │ │ │ │ ├── headers.lua │ │ │ │ ├── headers.lua.meta │ │ │ │ ├── http.lua │ │ │ │ ├── http.lua.meta │ │ │ │ ├── mbox.lua │ │ │ │ ├── mbox.lua.meta │ │ │ │ ├── smtp.lua │ │ │ │ ├── smtp.lua.meta │ │ │ │ ├── tp.lua │ │ │ │ ├── tp.lua.meta │ │ │ │ ├── url.lua │ │ │ │ └── url.lua.meta │ │ │ ├── socket.lua │ │ │ ├── socket.lua.meta │ │ │ ├── socket.meta │ │ │ ├── tolua.lua │ │ │ ├── tolua.lua.meta │ │ │ ├── typeof.lua │ │ │ └── typeof.lua.meta │ │ ├── Lua.meta │ │ ├── Misc/ │ │ │ ├── LuaClient.cs │ │ │ ├── LuaClient.cs.meta │ │ │ ├── LuaCoroutine.cs │ │ │ ├── LuaCoroutine.cs.meta │ │ │ ├── LuaLooper.cs │ │ │ ├── LuaLooper.cs.meta │ │ │ ├── LuaProfiler.cs │ │ │ ├── LuaProfiler.cs.meta │ │ │ ├── LuaResLoader.cs │ │ │ └── LuaResLoader.cs.meta │ │ ├── Misc.meta │ │ ├── Reflection/ │ │ │ ├── LuaConstructor.cs │ │ │ ├── LuaConstructor.cs.meta │ │ │ ├── LuaField.cs │ │ │ ├── LuaField.cs.meta │ │ │ ├── LuaMethod.cs │ │ │ ├── LuaMethod.cs.meta │ │ │ ├── LuaProperty.cs │ │ │ ├── LuaProperty.cs.meta │ │ │ ├── LuaReflection.cs │ │ │ └── LuaReflection.cs.meta │ │ ├── Reflection.meta │ │ ├── readme.txt │ │ └── readme.txt.meta │ ├── ToLua.meta │ ├── link.xml │ └── link.xml.meta ├── LICENSE-tolua ├── Luajit/ │ ├── Build.bat │ └── jit/ │ ├── bc.lua │ ├── bcsave.lua │ ├── dis_arm.lua │ ├── dis_arm64.lua │ ├── dis_arm64be.lua │ ├── dis_mips.lua │ ├── dis_mips64.lua │ ├── dis_mips64el.lua │ ├── dis_mipsel.lua │ ├── dis_ppc.lua │ ├── dis_x64.lua │ ├── dis_x86.lua │ ├── dump.lua │ ├── p.lua │ ├── v.lua │ ├── vmdef.lua │ └── zone.lua ├── Luajit64/ │ ├── Build.bat │ └── jit/ │ ├── bc.lua │ ├── bcsave.lua │ ├── dis_arm.lua │ ├── dis_arm64.lua │ ├── dis_arm64be.lua │ ├── dis_mips.lua │ ├── dis_mips64.lua │ ├── dis_mips64el.lua │ ├── dis_mipsel.lua │ ├── dis_ppc.lua │ ├── dis_x64.lua │ ├── dis_x86.lua │ ├── dump.lua │ ├── p.lua │ ├── v.lua │ ├── vmdef.lua │ └── zone.lua ├── README-tolua.md ├── README.md ├── Tools/ │ ├── CSharpLua/ │ │ ├── CSharp.lua/ │ │ │ ├── CSharp.lua.Launcher.deps.json │ │ │ ├── CSharp.lua.Launcher.pdb │ │ │ ├── CSharp.lua.Launcher.runtimeconfig.json │ │ │ ├── CSharp.lua.pdb │ │ │ └── System.xml │ │ ├── UnityEngine.xml │ │ ├── codes/ │ │ │ └── All.lua │ │ ├── disable_track.bat │ │ ├── enable_track.bat │ │ └── update_csharp.lua.cmd │ └── ProtobufGen/ │ ├── protobuf-net/ │ │ ├── Licence.txt │ │ ├── common.xslt │ │ ├── csharp.xslt │ │ ├── descriptor.proto │ │ ├── protobuf-net.xml │ │ ├── protoc-license.txt │ │ ├── protogen.exe.config │ │ ├── vb.xslt │ │ └── xml.xslt │ └── protogen.bat └── Unity5.x/ └── Assets/ └── Plugins/ ├── Android/ │ └── libs/ │ ├── armeabi-v7a/ │ │ └── libtolua.so.meta │ └── x86/ │ └── libtolua.so.meta ├── iOS/ │ └── libtolua.a.meta ├── tolua.bundle.meta ├── x86/ │ └── tolua.dll.meta └── x86_64/ └── tolua.dll.meta ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ [Ll]ibrary/ [Tt]emp/ [Oo]bj/ [Bb]uild/ # Autogenerated VS/MD solution and project files *.csproj *.unityproj *.sln *.suo *.tmp *.user *.userprefs *.pidb *.booproj # Unity3D generated meta files *.pidb.meta # Unity3D Generated File On Crash Reports sysinfo.txt /Assets/UnityVS.meta /Assets/UnityVS /UnityVS.tolua.v11.suo /UnityVS.tolua.CSharp.csproj /UnityVS.tolua.CSharp.Editor.csproj /UnityVS.tolua.sln .vs/ Packages ProjectSettings /Assets/Source/Generate /Assets/CSharpLuaTemp /Assets/CSharpLuaTemp.meta /Assets/Lua/.idea/ /Assets/.lpproj /Assets/ThirdParty/ /Assets/ThirdParty.meta LuaDebuggee.dll ================================================ FILE: Assets/CSharpLua/Base/BaseScripts.asmdef ================================================ { "name": "Base", "references": [], "optionalUnityReferences": [], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false } ================================================ FILE: Assets/CSharpLua/Base/BaseScripts.asmdef.meta ================================================ fileFormatVersion: 2 guid: a74114e4c2e22e5439cffab27da66e88 AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Base/CSharpLua/BaseUtility.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace CSharpLua { public interface IProvider { void ConvertCustomMonoBehaviour(ref GameObject prefab); } public static class BaseUtility { public static IProvider Provider { get; set; } } } ================================================ FILE: Assets/CSharpLua/Base/CSharpLua/BaseUtility.cs.meta ================================================ fileFormatVersion: 2 guid: 926b10807f8340942925508454855bca MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Base/CSharpLua/LuaAutoWrapAttribute.cs ================================================ using System; /// /// 加入此标记,可以自动添加到导出列表 /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct)] public class LuaAutoWrapAttribute : Attribute { public LuaAutoWrapAttribute() { } } ================================================ FILE: Assets/CSharpLua/Base/CSharpLua/LuaAutoWrapAttribute.cs.meta ================================================ fileFormatVersion: 2 guid: dafb7d14d4c87b74da4e18fb257c904d timeCreated: 1526898161 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Base/CSharpLua/Settings.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using UnityEngine; namespace CSharpLua { public static class Settings { #if UNITY_EDITOR public static class Paths { public static readonly string CompiledScriptDir = Application.dataPath + "/CSharpLua/Compiled"; public static readonly string CompiledOutDir = Application.dataPath + "/Lua/Compiled"; public static readonly string ToolsDir = Application.dataPath + "/../Tools"; public const string kTempDir = "Assets/CSharpLuaTemp"; public const string kCompiledScripts = "Compiled"; public static readonly string SettingFilePath = Application.dataPath + "/CSharpLua/Base/CSharpLua/Settings.cs"; } public static class Menus { public const string kCompile = "CharpLua/Compile"; public const string kRunFromCSharp = "CharpLua/Switch to RunFromCSharp"; public const string kRunFromLua = "CharpLua/Swicth to RunFromLua"; public const string kGenProtobuf = "CharpLua/Gen protobuf"; } #endif public const bool kIsRunFromLua = true; } } ================================================ FILE: Assets/CSharpLua/Base/CSharpLua/Settings.cs.meta ================================================ fileFormatVersion: 2 guid: 3496baf3649572f44b1d70ef854e729f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Base/CSharpLua.meta ================================================ fileFormatVersion: 2 guid: 344556a0bba10b744aceb8f65773392e folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Base.meta ================================================ fileFormatVersion: 2 guid: 58354dbb9d958af4399ff1a50246b611 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Bridge/BridgeScripts.asmdef ================================================ { "name": "Bridge", "references": [ "Base" ], "optionalUnityReferences": [], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false } ================================================ FILE: Assets/CSharpLua/Bridge/BridgeScripts.asmdef.meta ================================================ fileFormatVersion: 2 guid: 4c78da7caad00b44ea75ddb210bf7528 AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Bridge/TestUtils.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using UnityEditor; [LuaAutoWrap] public sealed class TestUtils { public static GameObject Load(string path) { GameObject prefab = (GameObject)AssetDatabase.LoadMainAssetAtPath(path); CSharpLua.BaseUtility.Provider.ConvertCustomMonoBehaviour(ref prefab); return prefab; } } ================================================ FILE: Assets/CSharpLua/Bridge/TestUtils.cs.meta ================================================ fileFormatVersion: 2 guid: 0f7832487e5e88a47b620e14661a1e00 timeCreated: 1528447325 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Bridge.meta ================================================ fileFormatVersion: 2 guid: d5c23c299d89e9f47a02659740280a56 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/CSharpLuaClient.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using LuaInterface; namespace CSharpLua { [LuaAutoWrap] public sealed class BridgeMonoBehaviour : MonoBehaviour { private static readonly YieldInstruction[] updateYieldInstructions_ = new YieldInstruction[] { null, new WaitForFixedUpdate(), new WaitForEndOfFrame() }; public LuaTable Table { get; private set; } public string LuaClass; public string SerializeData; public UnityEngine.Object[] SerializeObjects; public void Bind(LuaTable table, string luaClass) { Table = table; LuaClass = luaClass; } public void Bind(LuaTable table) { Table = table; } internal void Bind(string luaClass, string serializeData, UnityEngine.Object[] serializeObjects) { LuaClass = luaClass; SerializeData = serializeData; SerializeObjects = serializeObjects; } public void RegisterUpdate(int instructionIndex, LuaFunction updateFn) { StartCoroutine(StartUpdate(updateFn, updateYieldInstructions_[instructionIndex])); } private IEnumerator StartUpdate(LuaFunction updateFn, YieldInstruction yieldInstruction) { while (true) { yield return yieldInstruction; updateFn.Call(Table); } } private void Awake() { if (!string.IsNullOrEmpty(LuaClass)) { if (Table == null) { Table = CSharpLuaClient.Instance.BindLua(this); } else { using (var fn = Table.GetLuaFunction("Awake")) { fn.Call(Table); } } } } private void Start() { using (var fn = Table.GetLuaFunction("Start")) { fn.Call(Table); } } } internal sealed class LuaIEnumerator : IEnumerator, IDisposable { private LuaTable table_; private LuaFunction current_; private LuaFunction moveNext_; private LuaIEnumerator(LuaTable table) { table_ = table; current_ = table.GetLuaFunction("getCurrent"); if (current_ == null) { throw new ArgumentNullException(); } moveNext_ = table.GetLuaFunction("MoveNext"); if (moveNext_ == null) { throw new ArgumentNullException(); } } public static LuaIEnumerator Create(LuaTable table) { var ret = table.GetTable("ref"); if (ret == null) { ret = new LuaIEnumerator(table); table.SetTable("ref", ret); } return ret; } public void Push(IntPtr L) { table_.Push(); } public object Current { get { object obj = current_.Invoke(table_); var t = obj as LuaTable; if (t != null && CSharpLuaClient.Instance.IsLuaIEnumerator(t)) { return Create(t); } return obj; } } public void Dispose() { if (current_ != null) { current_.Dispose(); current_ = null; } if (moveNext_ != null) { moveNext_.Dispose(); moveNext_ = null; } if (table_ != null) { table_.Dispose(); table_ = null; } } public bool MoveNext() { bool hasNext = moveNext_.Invoke(table_); if (!hasNext) { Dispose(); } return hasNext; } public void Reset() { throw new NotSupportedException(); } } public class CSharpLuaClient : LuaClient, IProvider { public string[] Components; private LuaFunction bindFn_; private LuaFunction isIEnumeratorFn_; public static new CSharpLuaClient Instance { get { return (CSharpLuaClient)LuaClient.Instance; } } protected override void OpenLibs() { base.OpenLibs(); OpenCJson(); OpenPBC(); } private void OpenPBC() { luaState.OpenLibs(LuaDLL.luaopen_protobuf_c); } public override void Destroy() { if (bindFn_ != null) { bindFn_.Dispose(); bindFn_ = null; } if (isIEnumeratorFn_ != null) { isIEnumeratorFn_.Dispose(); isIEnumeratorFn_ = null; } base.Destroy(); BaseUtility.Provider = null; } protected override void StartMain() { BaseUtility.Provider = this; if (Settings.kIsRunFromLua) { base.StartMain(); bindFn_ = luaState.GetFunction("UnityEngine.bind"); if (bindFn_ == null) { throw new InvalidProgramException(); } if (Components != null && Components.Length > 0) { using (var fn = luaState.GetFunction("UnityEngine.addComponent")) { foreach (string type in Components) { fn.Call(gameObject, type); } } } } else { #pragma warning disable 0162 if (Components != null) { foreach (string type in Components) { Type componentType = Type.GetType(type, true, false); gameObject.AddComponent(componentType); } } #pragma warning restore 0162 } } internal LuaTable BindLua(BridgeMonoBehaviour bridgeMonoBehaviour) { return bindFn_.Invoke( bridgeMonoBehaviour, bridgeMonoBehaviour.LuaClass, bridgeMonoBehaviour.SerializeData, bridgeMonoBehaviour.SerializeObjects); } internal bool IsLuaIEnumerator(LuaTable t) { if (isIEnumeratorFn_ == null) { isIEnumeratorFn_ = luaState.GetFunction("System.IsIEnumerator"); if (isIEnumeratorFn_ == null) { throw new InvalidProgramException(); } } return isIEnumeratorFn_.Invoke(t); } public void ConvertCustomMonoBehaviour(ref GameObject prefab) { #if UNITY_EDITOR if (Settings.kIsRunFromLua) { UserMonoBehaviourConverter.Default.Do(ref prefab); } #endif } } } ================================================ FILE: Assets/CSharpLua/CSharpLuaClient.cs.meta ================================================ fileFormatVersion: 2 guid: 1c379516c224fca4198f4de0962735e4 timeCreated: 1528271831 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/CompiledScripts.asmdef ================================================ { "name": "Compiled", "references": [ "Bridge" ], "optionalUnityReferences": [], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false } ================================================ FILE: Assets/CSharpLua/Compiled/CompiledScripts.asmdef.meta ================================================ fileFormatVersion: 2 guid: 55be9d1390aba8646b0237dae609af2e AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Protocol/AutoGen/CommonPrototype.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ // Generated from: CommonPrototype.proto using System; using System.Collections.Generic; using ProtoBuf; namespace CSharpLua.Project.Protocol { [ProtoContract] public partial class SettingProto : IProtocol { [ProtoMember(1, DataFormat = DataFormat.Default)] public List Values { get; set; } = new List(); [ProtoMember(2, IsRequired = true, DataFormat = DataFormat.TwosComplement)] public int SettingsMark { get; set; } [ProtoContract] public partial class ValuePairProto : IProtocol { [ProtoMember(1, IsRequired = true, DataFormat = DataFormat.Default)] public string Key { get; set; } [ProtoMember(2, IsRequired = true, DataFormat = DataFormat.Default)] public string Value { get; set; } } } } ================================================ FILE: Assets/CSharpLua/Compiled/Protocol/AutoGen/CommonPrototype.cs.meta ================================================ fileFormatVersion: 2 guid: 78debcec0b8758e4b9dbde7b10c1128a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Protocol/AutoGen.meta ================================================ fileFormatVersion: 2 guid: b7e6a6d4681331a47b4a8f5228a03018 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Protocol/CommonPrototype.proto ================================================ package CSharpLua.Project.Protocol; message SettingProto { message ValuePairProto { required string Key = 1; required string Value = 2; } repeated ValuePairProto Values = 1; required int32 SettingsMark = 2; } ================================================ FILE: Assets/CSharpLua/Compiled/Protocol/CommonPrototype.proto.meta ================================================ fileFormatVersion: 2 guid: 07f5e97e19969f74dbd315423dbc49fb DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Protocol/IProtocol.cs ================================================ namespace ProtoBuf { public interface IProtocol { } } ================================================ FILE: Assets/CSharpLua/Compiled/Protocol/IProtocol.cs.meta ================================================ fileFormatVersion: 2 guid: 3e84cedf7f75dd1488cd80392079610f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Protocol.meta ================================================ fileFormatVersion: 2 guid: e27d3b48940561d4b86687784d596098 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestCoroutine.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Sample { public class TestCoroutine : MonoBehaviour { private List list = new List(); public void Awake() { Debug.Log("TestCoroutine"); StartCoroutine(OnTick()); print(gameObject.name); print(list.Count); StartCoroutine(T1()); } private IEnumerator OnTick() { while (true) { yield return new WaitForSeconds(1); print("TestCoroutine.OnTick"); } } public void Test() { print("TestCoroutine.Test"); } private IEnumerator T1() { print("a0"); yield return null; print("a1"); yield return T2(); print("a2"); } private IEnumerator T2() { print("b0"); yield return null; print("b1"); yield return null; print("b2"); } } } ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestCoroutine.cs.meta ================================================ fileFormatVersion: 2 guid: 729f6a41b84190a4ea3b9a09e6fa57a7 timeCreated: 1528274108 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestHangingScript.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Sample { public class TestHangingScript : MonoBehaviour { public string DataOfString; public int DataOfInt; public string DataOfString2 = "ddddd"; public int a = 10; public GameObject DataOfGameObject; public UnityEngine.Object DateOfObject; public TestCoroutine HangingMonoBehaviour; public List l = new List(); public Vector2 vector2; public Vector3 vector3; public void Awake() { print("Awake"); print(DataOfString); print(DataOfInt); print(DataOfString2); print(a); print(HangingMonoBehaviour.name); print(string.Join(",", l)); print($"{vector2}, {vector3}"); } public void Start() { print("Start"); } } } ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestHangingScript.cs.meta ================================================ fileFormatVersion: 2 guid: aa1fc193057764b49b4ef3ad042007cd timeCreated: 1528274108 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestHelloWord.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Sample { public sealed class TestHelloWord : MonoBehaviour { public void Awake() { Debug.Log("TestHelloWord"); gameObject.AddComponent(); var c = GetComponent(); print(c.name); var obj1 = FindObjectOfType(); Destroy(obj1); GameObject i = TestUtils.Load("Assets/CSharpLua/Examples/01_HelloWorld/TestLoader.prefab"); var obj = Instantiate(i); obj.transform.parent = transform; TestProtobuf.Run(); } private void Start() { print("TestHelloWord.Start"); } private void Update() { print("TestHelloWord.Update"); } } } ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestHelloWord.cs.meta ================================================ fileFormatVersion: 2 guid: d01266a3cb9c65446aff41f37bc14f67 timeCreated: 1528274108 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestProtobuf.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ProtoBuf; using CSharpLua.Project.Protocol; using System.IO; using ProtoBuf.Meta; namespace Sample { public static class TestProtobuf { public static void Run() { #if __CSharpLua__ /* [[ protobuf.register_file("Assets/Lua/3rd/pbc/Protocol/CommonPrototype.pb") ]] */ #endif SettingProto proto = new SettingProto() { SettingsMark = 101 }; proto.Values.Add(new SettingProto.ValuePairProto() { Key = "a", Value = "b" }); var bytes = Encode(proto); var t = Decode(bytes); UnityEngine.Debug.LogFormat("ProtobufDecode {0}", t.SettingsMark); } private static byte[] Encode(IProtocol proto) { #if !__CSharpLua__ using (MemoryStream s = new MemoryStream()) { RuntimeTypeModel.Default.Serialize(s, proto); return s.ToArray(); } #else byte[] bytes = null; /* [[ bytes = encodeProtobuf(proto) ]] */ return bytes; #endif } private static T Decode(byte[] bytes) where T : class { #if !__CSharpLua__ using (MemoryStream s = new MemoryStream(bytes)) { var t = (T)RuntimeTypeModel.Default.Deserialize(s, null, typeof(T)); return t; } #else T t = null; /* [[ t = decodeProtobuf(bytes, T) ]] */ return t; #endif } } } ================================================ FILE: Assets/CSharpLua/Compiled/Sample/TestProtobuf.cs.meta ================================================ fileFormatVersion: 2 guid: 702d00be8d6fcda448f17c8a3eecd43f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled/Sample.meta ================================================ fileFormatVersion: 2 guid: c756251f944f45b4f91b0d682a8e5811 folderAsset: yes timeCreated: 1528272569 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Compiled.meta ================================================ fileFormatVersion: 2 guid: 30775760c22aaf9428e8d40b0574a998 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Editor/Compiler.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Linq; using System.Text; using UnityEditor; using UnityEngine; namespace CSharpLua { public static class Compiler { private sealed class CompiledFail : Exception { public CompiledFail(string message) : base(message) { } } #if UNITY_EDITOR_WIN private const string kDotnet = "dotnet"; #else private const string kDotnet = "/usr/local/share/dotnet/dotnet"; #endif private static readonly string compiledScriptDir_ = Settings.Paths.CompiledScriptDir; private static readonly string outDir_ = Settings.Paths.CompiledOutDir; private static readonly string csharpToolsDir_ = $"{Settings.Paths.ToolsDir}/CSharpLua"; private static readonly string csharpLua_ = $"{csharpToolsDir_}/CSharp.lua/CSharp.lua.Launcher.dll"; private static readonly string genProtobuf = $"{Settings.Paths.ToolsDir}/ProtobufGen/protogen.bat"; private static readonly string settingFilePath_ = Settings.Paths.SettingFilePath; [MenuItem(Settings.Menus.kCompile)] public static void Compile() { if (!CheckDotnetInstall()) { return; } if (!File.Exists(csharpLua_)) { throw new InvalidProgramException($"{csharpLua_} not found"); } var outDirectoryInfo = new DirectoryInfo(outDir_); if (outDirectoryInfo.Exists) { foreach (var luaFile in outDirectoryInfo.EnumerateFiles("*.lua", SearchOption.AllDirectories)) { luaFile.Delete(); } } HashSet libs = new HashSet(); FillUnityLibraries(libs); AssemblyName assemblyName = new AssemblyName(Settings.Paths.kCompiledScripts); Assembly assembly = Assembly.Load(assemblyName); foreach (var referenced in assembly.GetReferencedAssemblies()) { if (referenced.Name != "mscorlib" && !referenced.Name.StartsWith("System")) { string libPath = Assembly.Load(referenced).Location; libs.Add(libPath); } } string[] metas = new string[] { $"{csharpToolsDir_}/UnityEngine.xml" }; string lib = string.Join(";", libs.ToArray()); string meta = string.Join(";", metas); string args = $"{csharpLua_} -s \"{compiledScriptDir_}\" -d \"{outDir_}\" -l \"{lib}\" -m {meta} -c"; string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup); if (!string.IsNullOrEmpty(definesString)) { args += $" -csc -define:{definesString}"; } var info = new ProcessStartInfo() { FileName = kDotnet, Arguments = args, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8, }; using (var p = Process.Start(info)) { var output = new StringBuilder(); var error = new StringBuilder(); p.OutputDataReceived += (sender, eventArgs) => output.AppendLine(eventArgs.Data); p.ErrorDataReceived += (sender, eventArgs) => error.AppendLine(eventArgs.Data); p.BeginOutputReadLine(); p.BeginErrorReadLine(); p.WaitForExit(); if (p.ExitCode == 0) { UnityEngine.Debug.Log(output); } else { throw new CompiledFail($"Compile fail, {error}\n{output}\n{kDotnet} {args}"); } } } private static void FillUnityLibraries(HashSet libs) { string unityObjectPath = typeof(UnityEngine.Object).Assembly.Location; string baseDir = Path.GetDirectoryName(unityObjectPath); foreach (string path in Directory.EnumerateFiles(baseDir, "*.dll")) { libs.Add(path); } } private static bool CheckDotnetInstall() { bool has = InternalCheckDotnetInstall(); if (!has) { UnityEngine.Debug.LogWarning("not found dotnet"); if (EditorUtility.DisplayDialog(".NET未安装", "未安装.NET 5.0运行环境,点击确定前往安装", "确定", "取消")) { Application.OpenURL("https://dotnet.microsoft.com/download/dotnet/5.0"); } } return has; } private static bool InternalCheckDotnetInstall() { var info = new ProcessStartInfo() { FileName = kDotnet, Arguments = "--version", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8, }; try { using (var p = Process.Start(info)) { p.WaitForExit(); if (p.ExitCode == 0) { string version = p.StandardOutput.ReadToEnd(); UnityEngine.Debug.LogFormat("found dotnet {0}", version); int major = version[0] - '0'; if (major >= 5) { return true; } else { UnityEngine.Debug.LogErrorFormat("dotnet verson {0} must >= 5.0", version); } } return false; } } catch (Exception e) { UnityEngine.Debug.LogException(e); return false; } } [MenuItem(Settings.kIsRunFromLua ? Settings.Menus.kRunFromCSharp : Settings.Menus.kRunFromLua)] public static void Switch() { #if UNITY_2018_1_OR_NEWER const string kFieldName = nameof(Settings.kIsRunFromLua); #else const string kFieldName = "kIsRunFromLua"; #endif string text = File.ReadAllText(settingFilePath_); int begin = text.IndexOf(kFieldName); if (begin != -1) { int end = text.IndexOf(';', begin + kFieldName.Length); if (end != -1) { string s = text.Substring(begin, end - begin); string[] array = s.Split('='); bool v = bool.Parse(array[1]); string replace = kFieldName + " = " + (v ? "false" : "true"); text = text.Replace(s, replace); File.WriteAllText(settingFilePath_, text); AssetDatabase.Refresh(); } else { throw new InvalidProgramException($"field {kFieldName} not found end symbol in {settingFilePath_}"); } } else { throw new InvalidProgramException($"not found field {kFieldName} in {settingFilePath_}"); } } [MenuItem(Settings.Menus.kGenProtobuf)] public static void GenProtobuf() { var info = new ProcessStartInfo() { FileName = genProtobuf, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8, WorkingDirectory = $"{Settings.Paths.ToolsDir}/ProtobufGen/", }; var p = Process.Start(info); p.OutputDataReceived += (sender, eventArgs) => { if (!string.IsNullOrEmpty(eventArgs.Data)) { UnityEngine.Debug.Log(eventArgs.Data); } }; p.ErrorDataReceived += (sender, eventArgs) => { if (!string.IsNullOrEmpty(eventArgs.Data)) { UnityEngine.Debug.LogError(eventArgs.Data); } }; p.BeginOutputReadLine(); p.BeginErrorReadLine(); } } #if UNITY_2018_1_OR_NEWER [InitializeOnLoad] public class EditorQuitHandler { static void Quit() { string tempDir = Settings.Paths.kTempDir; if (Directory.Exists(tempDir)) { Directory.Delete(tempDir, true); } } static EditorQuitHandler() { EditorApplication.quitting += Quit; } } #endif } ================================================ FILE: Assets/CSharpLua/Editor/Compiler.cs.meta ================================================ fileFormatVersion: 2 guid: 59c6d8baca17a7146b763b1e4fa394d6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Editor.meta ================================================ fileFormatVersion: 2 guid: 4fe6f8ae96df5fd45bf9bbab5cb9a8e7 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Examples/01_HelloWorld/HelloWorld.unity.meta ================================================ fileFormatVersion: 2 guid: 44e8c9b1935171746b04903a251c413d timeCreated: 1526899852 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Examples/01_HelloWorld/TestLoader.prefab.meta ================================================ fileFormatVersion: 2 guid: 20c93afce42002a41a008ca942ccb69d NativeFormatImporter: externalObjects: {} mainObjectFileID: 100100000 userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Examples/01_HelloWorld/testText.txt ================================================ hello,word ================================================ FILE: Assets/CSharpLua/Examples/01_HelloWorld/testText.txt.meta ================================================ fileFormatVersion: 2 guid: a0ac40db8f690ec43aeb9ee683d170f6 TextScriptImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Examples/01_HelloWorld.meta ================================================ fileFormatVersion: 2 guid: e64303adce0f8d8438e46552eb0f8b84 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/Examples.meta ================================================ fileFormatVersion: 2 guid: 19a7a8aa535d0de4ba63cd62704e83f6 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua/UserMonoBehaviourConverter.cs ================================================ #if UNITY_EDITOR using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Text; using System.IO; using System.Reflection; using UnityEngine; using UnityEditor; using LuaInterface; namespace CSharpLua { public sealed class UserMonoBehaviourConverter { private sealed class StructField { private string s_; public bool HasField { get; set; } public StructField(object v) { StringBuilder sb = new StringBuilder(); sb.Append('{'); Type t = v.GetType(); bool isFirst = true; foreach (var field in t.GetFields(BindingFlags.Instance | BindingFlags.Public)) { object x = field.GetValue(v); if (x != null) { var y = Activator.CreateInstance(x.GetType()); if (!x.EQ(y)) { if (isFirst) { isFirst = false; } else { sb.Append(','); } sb.Append(field.Name); sb.Append('='); sb.Append(SerializeFieldsInfo.NormalValueToString(x)); HasField = true; } } } sb.Append(','); sb.Append(t.FullName); sb.Append('}'); s_ = sb.ToString(); } public override string ToString() { return s_; } } private sealed class SerializeFieldsInfo { internal abstract class ObjectField { public string Name; public abstract void FillTo(StringBuilder sb); } internal sealed class PoolIndexObjectField : ObjectField { public int PoolIndex; public override void FillTo(StringBuilder sb) { sb.Append(PoolIndex); } } internal sealed class ArrayObjectField : ObjectField { public bool IsArray; public Type ElementType; public List PoolIndexs = new List(); public override void FillTo(StringBuilder sb) { string array = ToList(IsArray, ElementType, PoolIndexs, i => i.ToString()); sb.Append(array); } } internal sealed class MonoBehaviourField { public int PoolIndex; public string ClassName; } public Dictionary Normals = new Dictionary(); public List ObjectsPool = new List(); public List Objects = new List(); public List MonoBehaviourFields = new List(); private void AppendNormals(StringBuilder sb) { sb.Append('{'); bool isFirst = true; foreach (var normal in Normals) { if (isFirst) { isFirst = false; } else { sb.Append(','); } sb.Append(normal.Key); sb.Append('='); sb.Append(ValueToString(normal.Value)); } sb.Append("}"); } private void AppendObjects(StringBuilder sb) { if (Objects.Count > 0) { sb.Append('{'); bool isFirst = true; foreach (var field in Objects) { if (isFirst) { isFirst = false; } else { sb.Append(','); } sb.Append(field.Name); sb.Append('='); field.FillTo(sb); } sb.Append('}'); } } public string GetSerializeData() { bool isEmpty = Normals.Count == 0 && Objects.Count == 0; StringBuilder sb = new StringBuilder(); if (!isEmpty) { sb.Append("return{"); AppendNormals(sb); sb.Append(','); AppendObjects(sb); sb.Append('}'); } return sb.ToString(); } public UnityEngine.Object[] GetSerializeObjects() { return ObjectsPool.Count > 0 ? ObjectsPool.ToArray() : null; } private static string ToList(bool isArray, Type elementType, IList list, Func transfore) { StringBuilder sb = new StringBuilder(); sb.Append('{'); if (list.Count > 0) { bool isFirst = true; foreach (var i in list) { if (isFirst) { isFirst = false; } else { sb.Append(','); } sb.Append(transfore(i)); } sb.Append(','); } if (isArray) { sb.AppendFormat("System.Array({0})", elementType.FullName); } else { sb.AppendFormat("System.List({0})", elementType.FullName); } sb.Append('}'); return sb.ToString(); } internal static string NormalValueToString(object v) { if (v is string) { return "\"" + v + "\""; } return v.ToString(); } private static string ValueToString(object v) { if (v is IList) { var list = (IList)v; bool isArray = list is Array; var elementType = isArray ? v.GetType().GetElementType() : v.GetType().GetIListElementType(); return ToList(isArray, elementType, list, NormalValueToString); } return NormalValueToString(v); } } private sealed class MonoBehaviourFieldLazy { public string ClassName; public SerializeFieldsInfo SerializeInfo; public BridgeMonoBehaviour BridgeMonoBehaviour; public void Bind() { foreach (var field in SerializeInfo.MonoBehaviourFields) { var gameObject = (GameObject)SerializeInfo.ObjectsPool[field.PoolIndex]; var bridges = gameObject.GetComponents(); var item = bridges.Single(i => i.LuaClass == field.ClassName); SerializeInfo.ObjectsPool[field.PoolIndex] = item; } BridgeMonoBehaviour.Bind(ClassName, SerializeInfo.GetSerializeData(), SerializeInfo.GetSerializeObjects()); } } private static readonly string tempPrefabDir_ = Settings.Paths.kTempDir + "/prefabs"; private static readonly string compiledScriptsManifestPath_ = Settings.Paths.CompiledOutDir + "/manifest.lua"; private static UserMonoBehaviourConverter default_; private HashSet userDefinedNames_; private LuaState luaState_; public UserMonoBehaviourConverter() { Load(); } private void Load() { LoadClassNames(); luaState_ = LuaClient.GetMainState(); if (luaState_ == null) { throw new InvalidProgramException("not found MainState"); } } public static UserMonoBehaviourConverter Default { get { if (default_ == null) { default_ = new UserMonoBehaviourConverter(); } return default_; } } private void PauseEdit() { if (Application.isPlaying) { UnityEngine.Debug.Break(); } } private void LoadClassNames() { const string kBeginToken = "types = {"; const string kEndToken = "}"; if (!File.Exists(compiledScriptsManifestPath_)) { PauseEdit(); throw new InvalidOperationException("please compiled scripts first"); } string content = File.ReadAllText(compiledScriptsManifestPath_); int begin = content.IndexOf(kBeginToken); if (begin == -1) { throw new InvalidProgramException(); } begin += kBeginToken.Length; int end = content.IndexOf(kEndToken, begin); if (end == -1) { throw new InvalidProgramException(); } var userDefines = content.Substring(begin, end - begin).Split(',').Select(i => i.Trim().Trim('"')).ToArray(); userDefinedNames_ = new HashSet(userDefines); } private static void CopyTempPrefab(ref GameObject prefab) { string oldPath = AssetDatabase.GetAssetPath(prefab); string path = Path.Combine(tempPrefabDir_, oldPath); Directory.CreateDirectory(Path.GetDirectoryName(path)); #if UNITY_2018_3 || UNITY_2018_4 prefab = PrefabUtility.SaveAsPrefabAsset(UnityEngine.Object.Instantiate(prefab), path); #else prefab = PrefabUtility.CreatePrefab(path, prefab); #endif /* try { prefab = PrefabUtility.CreatePrefab(path, prefab); } catch (ArgumentException e) when (e.Message == "Can't save persistent object as a Prefab asset") { throw new InvalidDataException("目前2018.3拷贝预设存在BUG,暂时未发现规避的方法,请使用较低或较高版本"); }*/ } private bool IsUserMonoBehaviourExists(GameObject prefab) { var childrens = GetChildrenTransform(prefab.transform); foreach (var gameObject in childrens) { var monoBehaviours = gameObject.GetComponents(); foreach (MonoBehaviour monoBehaviour in monoBehaviours) { if (IsUserDefine(monoBehaviour.GetType())) { return true; } } } return false; } public bool Do(ref GameObject prefab) { if (IsUserMonoBehaviourExists(prefab)) { CopyTempPrefab(ref prefab); List monoBehaviourFieldLazys = new List(); var childrens = GetChildrenTransform(prefab.transform); foreach (var t in childrens) { Convert(t.gameObject, monoBehaviourFieldLazys); } foreach (var i in monoBehaviourFieldLazys) { i.Bind(); } return true; } return false; } private List GetChildrenTransform(Transform parent) { List list = new List { parent }; GetChildrenTransform(list, parent); return list; } private void GetChildrenTransform(List list, Transform parent) { int count = parent.childCount; for (int i = 0; i < count; i++) { Transform child = parent.GetChild(i); list.Add(child); GetChildrenTransform(list, child); } } private bool IsUserDefine(Type type) { return userDefinedNames_.Contains(type.FullName); } private void Convert(GameObject gameObject, List lazys) { var monoBehaviours = gameObject.GetComponents(); foreach (MonoBehaviour monoBehaviour in monoBehaviours) { if (IsUserDefine(monoBehaviour.GetType())) { Convert(monoBehaviour, lazys); } } } private bool IsSerializedField(FieldInfo field) { if (field.IsPublic) { return !field.IsDefined(typeof(HideInInspector), false); } else { return field.IsDefined(typeof(SerializeField), false); } } private void Convert(MonoBehaviour monoBehaviour, List lazys) { Type type = monoBehaviour.GetType(); string className = type.FullName; using (var luaClass = luaState_.GetTable(className)) { if (luaClass == null) { PauseEdit(); throw new InvalidOperationException($"{className} is not found in lua env"); } SerializeFieldsInfo info = new SerializeFieldsInfo(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { if (IsSerializedField(field)) { Convert(monoBehaviour, luaClass, field, info); } } GameObject gameObject = monoBehaviour.gameObject; UnityEngine.Object.DestroyImmediate(monoBehaviour, true); var bridgeMonoBehaviour = gameObject.AddComponent(); if (info.MonoBehaviourFields.Count == 0) { bridgeMonoBehaviour.Bind(className, info.GetSerializeData(), info.GetSerializeObjects()); } else { lazys.Add(new MonoBehaviourFieldLazy() { ClassName = className, SerializeInfo = info, BridgeMonoBehaviour = bridgeMonoBehaviour, }); } } } private static bool IsSameRootGameObject(GameObject x, GameObject y) { string pathX = AssetDatabase.GetAssetPath(x); string pathY = AssetDatabase.GetAssetPath(y); return pathX == pathY; } private static bool IsNormalType(Type type, out TypeCode typeCode) { typeCode = Type.GetTypeCode(type); return typeCode == TypeCode.String || (typeCode >= TypeCode.Boolean && typeCode <= TypeCode.Double); } private static bool IsNormalType(Type type) { TypeCode typeCode; return IsNormalType(type, out typeCode); } private int ConvertUnityEngineGameObject(MonoBehaviour monoBehaviour, object fieldValue, SerializeFieldsInfo info) { int poolIndex = info.ObjectsPool.Count; var obj = (UnityEngine.Object)fieldValue; if (obj is GameObject) { var gameObject = (GameObject)obj; if (!IsSameRootGameObject(monoBehaviour.gameObject, gameObject)) { bool hasChanged = Do(ref gameObject); if (hasChanged) { obj = gameObject; } } } else if (obj is MonoBehaviour) { var mb = (MonoBehaviour)obj; var gameObject = mb.gameObject; bool isSameRoot = IsSameRootGameObject(monoBehaviour.gameObject, gameObject); if (!isSameRoot) { bool hasChanged = Do(ref gameObject); if (hasChanged) { obj = gameObject; } } else { obj = gameObject; } if (IsUserDefine(mb.GetType())) { if (isSameRoot) { info.MonoBehaviourFields.Add(new SerializeFieldsInfo.MonoBehaviourField() { PoolIndex = poolIndex, ClassName = mb.GetType().FullName, }); } else { var bridges = gameObject.GetComponents(); var mbNew = bridges.Single(i => i.LuaClass == mb.GetType().FullName); Contract.Assert(mbNew != null); obj = mbNew; } } else { var mbNew = gameObject.GetComponent(mb.GetType()); obj = mbNew; } } info.ObjectsPool.Add(obj); return poolIndex; } private void Convert(MonoBehaviour monoBehaviour, LuaTable luaClass, FieldInfo field, SerializeFieldsInfo info) { Type fieldType = field.FieldType; object fieldValue = field.GetValue(monoBehaviour); TypeCode fieldTypeCode; if (IsNormalType(fieldType, out fieldTypeCode)) { object x = fieldValue; object y = luaClass.RawGet(field.Name); if (y is double) { if (fieldTypeCode == TypeCode.Char) { x = (double)(char)x; } else { x = System.Convert.ToDouble(x); } } if (!x.EQ(y)) { info.Normals.Add(field.Name, x); } return; } if (fieldType.IsEnum) { int x = (int)(ValueType)fieldValue; int y = luaClass.RawGet(field.Name); if (x != y) { info.Normals.Add(field.Name, x); } return; } if (fieldType.IsUnityEngineStruct()) { var structField = new StructField(fieldValue); if (structField.HasField) { info.Normals.Add(field.Name, structField); } return; } if (fieldValue == null) { return; } if (fieldType.IsUnityEngineObject()) { int poolIndex = ConvertUnityEngineGameObject(monoBehaviour, fieldValue, info); info.Objects.Add(new SerializeFieldsInfo.PoolIndexObjectField() { Name = field.Name, PoolIndex = poolIndex, }); return; } var elementTypeOfIList = fieldType.GetIListElementType(); if (elementTypeOfIList != null) { if (IsNormalType(elementTypeOfIList)) { info.Normals.Add(field.Name, fieldValue); return; } else if (elementTypeOfIList.IsUnityEngineObject()) { SerializeFieldsInfo.ArrayObjectField array = new SerializeFieldsInfo.ArrayObjectField() { Name = field.Name, IsArray = fieldType.IsArray, ElementType = elementTypeOfIList }; IList list = (IList)fieldValue; foreach (object v in list) { int poolIndex = ConvertUnityEngineGameObject(monoBehaviour, v, info); array.PoolIndexs.Add(poolIndex); } info.Objects.Add(array); return; } } PauseEdit(); throw new NotSupportedException($"{monoBehaviour.GetType()}'s field[{field.Name}] type[{fieldType}] not support serialized"); } } public static partial class Extensions { public static Type GetIListElementType(this Type type) { var listType = type.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)); return listType != null ? listType.GetGenericArguments().First() : null; } public static bool IsUnityEngineObject(this Type type) { return typeof(UnityEngine.Object).IsAssignableFrom(type); } public static bool EQ(this object x, object y) { return EqualityComparer.Default.Equals(x, y); } public static bool IsUnityEngineStruct(this Type type) { return type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Vector4); } } } #endif ================================================ FILE: Assets/CSharpLua/UserMonoBehaviourConverter.cs.meta ================================================ fileFormatVersion: 2 guid: b7f3e9e39306b8540a8a2420099dec1d timeCreated: 1528353588 licenseType: Free MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/CSharpLua.meta ================================================ fileFormatVersion: 2 guid: 25458f95ee0f5374894471ba2a523a15 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Editor/Custom/CustomSettings.cs ================================================ using UnityEngine; using System; using System.Collections.Generic; using System.Linq; using LuaInterface; using UnityEditor; using BindType = ToLuaMenu.BindType; using System.Reflection; public static class CustomSettings { public static string saveDir = Application.dataPath + "/Source/Generate/"; public static string toluaBaseType = Application.dataPath + "/ToLua/BaseType/"; public static string baseLuaDir = Application.dataPath + "/Tolua/Lua/"; public static string injectionFilesPath = Application.dataPath + "/ToLua/Injection/"; //导出时强制做为静态类的类型(注意customTypeList 还要添加这个类型才能导出) //unity 有些类作为sealed class, 其实完全等价于静态类 public static List staticClassTypes = new List { typeof(UnityEngine.Application), typeof(UnityEngine.Time), typeof(UnityEngine.Screen), typeof(UnityEngine.SleepTimeout), typeof(UnityEngine.Input), typeof(UnityEngine.Resources), typeof(UnityEngine.Physics), typeof(UnityEngine.RenderSettings), typeof(UnityEngine.QualitySettings), typeof(UnityEngine.GL), typeof(UnityEngine.Graphics), }; //附加导出委托类型(在导出委托时, customTypeList 中牵扯的委托类型都会导出, 无需写在这里) public static DelegateType[] customDelegateList = { _DT(typeof(Action)), _DT(typeof(UnityEngine.Events.UnityAction)), _DT(typeof(System.Predicate)), _DT(typeof(System.Action)), _DT(typeof(System.Comparison)), _DT(typeof(System.Func)), }; //在这里添加你要导出注册到lua的类型列表 public static BindType[] customTypeList_ = { //------------------------为例子导出-------------------------------- //_GT(typeof(TestEventListener)), //_GT(typeof(TestProtol)), //_GT(typeof(TestAccount)), //_GT(typeof(Dictionary)).SetLibName("AccountMap"), //_GT(typeof(KeyValuePair)), //_GT(typeof(Dictionary.KeyCollection)), //_GT(typeof(Dictionary.ValueCollection)), //_GT(typeof(TestExport)), //_GT(typeof(TestExport.Space)), //------------------------------------------------------------------- _GT(typeof(LuaInjectionStation)), _GT(typeof(InjectType)), _GT(typeof(Debugger)).SetNameSpace(null), #if USING_DOTWEENING _GT(typeof(DG.Tweening.DOTween)), _GT(typeof(DG.Tweening.Tween)).SetBaseType(typeof(System.Object)).AddExtendType(typeof(DG.Tweening.TweenExtensions)), _GT(typeof(DG.Tweening.Sequence)).AddExtendType(typeof(DG.Tweening.TweenSettingsExtensions)), _GT(typeof(DG.Tweening.Tweener)).AddExtendType(typeof(DG.Tweening.TweenSettingsExtensions)), _GT(typeof(DG.Tweening.LoopType)), _GT(typeof(DG.Tweening.PathMode)), _GT(typeof(DG.Tweening.PathType)), _GT(typeof(DG.Tweening.RotateMode)), _GT(typeof(Component)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), _GT(typeof(Transform)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), _GT(typeof(Light)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), _GT(typeof(Material)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), _GT(typeof(Rigidbody)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), _GT(typeof(Camera)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), _GT(typeof(AudioSource)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), //_GT(typeof(LineRenderer)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), //_GT(typeof(TrailRenderer)).AddExtendType(typeof(DG.Tweening.ShortcutExtensions)), #else _GT(typeof(Component)), _GT(typeof(Transform)), _GT(typeof(Material)), _GT(typeof(Light)), _GT(typeof(Rigidbody)), _GT(typeof(Camera)), _GT(typeof(AudioSource)), //_GT(typeof(LineRenderer)) //_GT(typeof(TrailRenderer)) #endif _GT(typeof(YieldInstruction)), _GT(typeof(WaitForEndOfFrame)), _GT(typeof(WaitForFixedUpdate)), _GT(typeof(WaitForSeconds)), _GT(typeof(Behaviour)), _GT(typeof(MonoBehaviour)), _GT(typeof(GameObject)), _GT(typeof(TrackedReference)), _GT(typeof(Application)), _GT(typeof(Physics)), _GT(typeof(Collider)), _GT(typeof(Time)), _GT(typeof(Texture)), _GT(typeof(Texture2D)), _GT(typeof(Shader)), _GT(typeof(Renderer)), _GT(typeof(WWW)), _GT(typeof(Screen)), _GT(typeof(CameraClearFlags)), _GT(typeof(AudioClip)), _GT(typeof(AssetBundle)), _GT(typeof(ParticleSystem)), _GT(typeof(AsyncOperation)).SetBaseType(typeof(System.Object)), _GT(typeof(LightType)), _GT(typeof(SleepTimeout)), #if UNITY_5_3_OR_NEWER && !UNITY_5_6_OR_NEWER _GT(typeof(UnityEngine.Experimental.Director.DirectorPlayer)), #endif _GT(typeof(Animator)), _GT(typeof(Input)), _GT(typeof(KeyCode)), _GT(typeof(SkinnedMeshRenderer)), _GT(typeof(Space)), _GT(typeof(MeshRenderer)), #if !UNITY_5_4_OR_NEWER _GT(typeof(ParticleEmitter)), _GT(typeof(ParticleRenderer)), _GT(typeof(ParticleAnimator)), #endif _GT(typeof(BoxCollider)), _GT(typeof(MeshCollider)), _GT(typeof(SphereCollider)), _GT(typeof(CharacterController)), _GT(typeof(CapsuleCollider)), _GT(typeof(Animation)), _GT(typeof(AnimationClip)).SetBaseType(typeof(UnityEngine.Object)), _GT(typeof(AnimationState)), _GT(typeof(AnimationBlendMode)), _GT(typeof(QueueMode)), _GT(typeof(PlayMode)), _GT(typeof(WrapMode)), _GT(typeof(QualitySettings)), _GT(typeof(RenderSettings)), _GT(typeof(BlendWeights)), _GT(typeof(RenderTexture)), _GT(typeof(Resources)), _GT(typeof(LuaProfiler)), }; public static List dynamicList = new List() { typeof(MeshRenderer), #if !UNITY_5_4_OR_NEWER typeof(ParticleEmitter), typeof(ParticleRenderer), typeof(ParticleAnimator), #endif typeof(BoxCollider), typeof(MeshCollider), typeof(SphereCollider), typeof(CharacterController), typeof(CapsuleCollider), typeof(Animation), typeof(AnimationClip), typeof(AnimationState), typeof(BlendWeights), typeof(RenderTexture), typeof(Rigidbody), }; //重载函数,相同参数个数,相同位置out参数匹配出问题时, 需要强制匹配解决 //使用方法参见例子14 public static List outList = new List() { }; //ngui优化,下面的类没有派生类,可以作为sealed class public static List sealedList = new List() { /*typeof(Transform), typeof(UIRoot), typeof(UICamera), typeof(UIViewport), typeof(UIPanel), typeof(UILabel), typeof(UIAnchor), typeof(UIAtlas), typeof(UIFont), typeof(UITexture), typeof(UISprite), typeof(UIGrid), typeof(UITable), typeof(UIWrapGrid), typeof(UIInput), typeof(UIScrollView), typeof(UIEventListener), typeof(UIScrollBar), typeof(UICenterOnChild), typeof(UIScrollView), typeof(UIButton), typeof(UITextList), typeof(UIPlayTween), typeof(UIDragScrollView), typeof(UISpriteAnimation), typeof(UIWrapContent), typeof(TweenWidth), typeof(TweenAlpha), typeof(TweenColor), typeof(TweenRotation), typeof(TweenPosition), typeof(TweenScale), typeof(TweenHeight), typeof(TypewriterEffect), typeof(UIToggle), typeof(Localization),*/ }; public static BindType _GT(Type t) { return new BindType(t); } public static DelegateType _DT(Type t) { return new DelegateType(t); } [MenuItem("Lua/Attach Profiler", false, 151)] static void AttachProfiler() { if (!Application.isPlaying) { EditorUtility.DisplayDialog("警告", "请在运行时执行此功能", "确定"); return; } LuaClient.Instance.AttachProfiler(); } [MenuItem("Lua/Detach Profiler", false, 152)] static void DetachProfiler() { if (!Application.isPlaying) { return; } LuaClient.Instance.DetachProfiler(); } private static bool IsCustomAssembly(string name) { if (name == "mscorlib" || name.StartsWith("System") || name.StartsWith("UnityEngine") || name.StartsWith("UnityEditor")) { return false; } return true; } public static BindType[] customTypeList { get { const string kBridgeAssemblyName = "Bridge"; List result = new List(customTypeList_); var names = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Select(i => i.Name).Where(IsCustomAssembly).ToList(); if (!names.Contains(kBridgeAssemblyName)) { names.Add(kBridgeAssemblyName); } foreach (string name in names) { Assembly a = Assembly.Load(name); Type[] types = a.GetExportedTypes(); foreach (Type type in types) { if (type.IsDefined(typeof(LuaAutoWrapAttribute), false)) { result.Add(_GT(type)); } } } return result.ToArray(); } } } ================================================ FILE: Assets/Editor/Custom/CustomSettings.cs.meta ================================================ fileFormatVersion: 2 guid: d68e81cfa02de7e44a2ff558bdc3ac89 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/Editor/Custom.meta ================================================ fileFormatVersion: 2 guid: 327fa85d300c38c48836bfee53f47cb0 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Editor.meta ================================================ fileFormatVersion: 2 guid: 772338ec68e701847a565d981a690787 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Lua/3rd/pbc/Protocol/CommonPrototype.pb ================================================  CommonPrototype.protoCSharpLua.Project.Protocol" SettingProtoG Values ( 27.CSharpLua.Project.Protocol.SettingProto.ValuePairProto SettingsMark (, ValuePairProto Key (  Value ( ================================================ FILE: Assets/Lua/3rd/pbc/Protocol/CommonPrototype.pb.meta ================================================ fileFormatVersion: 2 guid: 799e7c66ac22f364e9547543461301c4 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/3rd/pbc/Protocol.meta ================================================ fileFormatVersion: 2 guid: a7200e606f253ed44ad5a8801bf7eae2 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/3rd/pbc/protobuf.lua ================================================ local c = require "protobuf.c" local setmetatable = setmetatable local type = type local table = table local assert = assert local pairs = pairs local ipairs = ipairs local string = string local print = print local io = io local tinsert = table.insert local rawget = rawget module "protobuf" local _pattern_cache = {} -- skynet clear local P = c._env_new() local GC = c._gc(P) function lasterror() return c._last_error(P) end local decode_type_cache = {} local _R_meta = {} function _R_meta:__index(key) local v = decode_type_cache[self._CType][key](self, key) self[key] = v return v end local _reader = {} function _reader:int(key) return c._rmessage_integer(self._CObj , key , 0) end function _reader:real(key) return c._rmessage_real(self._CObj , key , 0) end function _reader:string(key) return c._rmessage_string(self._CObj , key , 0) end function _reader:bool(key) return c._rmessage_integer(self._CObj , key , 0) ~= 0 end function _reader:message(key, message_type) -- will return default table, we want nil, so comment this function --[[ local rmessage = c._rmessage_message(self._CObj , key , 0) if rmessage then local v = { _CObj = rmessage, _CType = message_type, _Parent = self, } return setmetatable( v , _R_meta ) end--]] end function _reader:int32(key) return c._rmessage_int32(self._CObj , key , 0) end function _reader:int64(key) return c._rmessage_int64(self._CObj , key , 0) end function _reader:int52(key) return c._rmessage_int52(self._CObj , key , 0) end function _reader:uint52(key) return c._rmessage_uint52(self._CObj , key , 0) end function _reader:int_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_integer(cobj , key , i)) end return ret end function _reader:real_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_real(cobj , key , i)) end return ret end function _reader:string_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_string(cobj , key , i)) end return ret end function _reader:bool_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_integer(cobj , key , i) ~= 0) end return ret end function _reader:message_repeated(key, message_type) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do local m = { _CObj = c._rmessage_message(cobj , key , i), _CType = message_type, _Parent = self, } tinsert(ret, setmetatable( m , _R_meta )) end return ret end function _reader:int32_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_int32(cobj , key , i)) end return ret end function _reader:int64_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_int64(cobj , key , i)) end return ret end function _reader:int52_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_int52(cobj , key , i)) end return ret end function _reader:uint52_repeated(key) local cobj = self._CObj local n = c._rmessage_size(cobj , key) local ret = {} for i=0,n-1 do tinsert(ret, c._rmessage_uint52(cobj , key , i)) end return ret end _reader[1] = function(msg) return _reader.int end _reader[2] = function(msg) return _reader.real end _reader[3] = function(msg) return _reader.bool end _reader[4] = function(msg) return _reader.string end _reader[5] = function(msg) return _reader.string end _reader[6] = function(msg) local message = _reader.message return function(self,key) return message(self, key, msg) end end _reader[7] = function(msg) return _reader.int64 end _reader[8] = function(msg) return _reader.int32 end _reader[9] = _reader[5] _reader[10] = function(msg) return _reader.int52 end _reader[11] = function(msg) return _reader.uint52 end _reader[128+1] = function(msg) return _reader.int_repeated end _reader[128+2] = function(msg) return _reader.real_repeated end _reader[128+3] = function(msg) return _reader.bool_repeated end _reader[128+4] = function(msg) return _reader.string_repeated end _reader[128+5] = function(msg) return _reader.string_repeated end _reader[128+6] = function(msg) local message = _reader.message_repeated return function(self,key) return message(self, key, msg) end end _reader[128+7] = function(msg) return _reader.int64_repeated end _reader[128+8] = function(msg) return _reader.int32_repeated end _reader[128+9] = _reader[128+5] _reader[128+10] = function(msg) return _reader.int52_repeated end _reader[128+11] = function(msg) return _reader.uint52_repeated end local _decode_type_meta = {} function _decode_type_meta:__index(key) local t, msg = c._env_type(P, self._CType, key) local func = assert(_reader[t],key)(msg) self[key] = func return func end setmetatable(decode_type_cache , { __index = function(self, key) local v = setmetatable({ _CType = key } , _decode_type_meta) self[key] = v return v end }) local function decode_message( message , buffer, length) local rmessage = c._rmessage_new(P, message, buffer, length) if rmessage then local self = { _CObj = rmessage, _CType = message, } c._add_rmessage(GC,rmessage) return setmetatable( self , _R_meta ) end end ----------- encode ---------------- local encode_type_cache = {} local function encode_message(CObj, message_type, t) local type = encode_type_cache[message_type] for k,v in pairs(t) do local func = type[k] func(CObj, k , v) end end local _writer = { int = c._wmessage_integer, real = c._wmessage_real, enum = c._wmessage_string, string = c._wmessage_string, int64 = c._wmessage_int64, int32 = c._wmessage_int32, int52 = c._wmessage_int52, uint52 = c._wmessage_uint52, } function _writer:bool(k,v) c._wmessage_integer(self, k, v and 1 or 0) end function _writer:message(k, v , message_type) local submessage = c._wmessage_message(self, k) encode_message(submessage, message_type, v) end function _writer:int_repeated(k,v) for _,v in ipairs(v) do c._wmessage_integer(self,k,v) end end function _writer:real_repeated(k,v) for _,v in ipairs(v) do c._wmessage_real(self,k,v) end end function _writer:bool_repeated(k,v) for _,v in ipairs(v) do c._wmessage_integer(self, k, v and 1 or 0) end end function _writer:string_repeated(k,v) for _,v in ipairs(v) do c._wmessage_string(self,k,v) end end function _writer:message_repeated(k,v, message_type) for _,v in ipairs(v) do local submessage = c._wmessage_message(self, k) encode_message(submessage, message_type, v) end end function _writer:int32_repeated(k,v) for _,v in ipairs(v) do c._wmessage_int32(self,k,v) end end function _writer:int64_repeated(k,v) for _,v in ipairs(v) do c._wmessage_int64(self,k,v) end end function _writer:int52_repeated(k,v) for _,v in ipairs(v) do c._wmessage_int52(self,k,v) end end function _writer:uint52_repeated(k,v) for _,v in ipairs(v) do c._wmessage_uint52(self,k,v) end end function _writer:enum(k, v) if type(v) == "number" then return c._wmessage_integer(self, k, v) end return c._wmessage_string(self, k, v) end _writer[1] = function(msg) return _writer.int end _writer[2] = function(msg) return _writer.real end _writer[3] = function(msg) return _writer.bool end _writer[4] = function(msg) return _writer.enum end _writer[5] = function(msg) return _writer.string end _writer[6] = function(msg) local message = _writer.message return function(self,key , v) return message(self, key, v, msg) end end _writer[7] = function(msg) return _writer.int64 end _writer[8] = function(msg) return _writer.int32 end _writer[9] = _writer[5] _writer[10] = function(msg) return _writer.int52 end _writer[11] = function(msg) return _writer.uint52 end _writer[128+1] = function(msg) return _writer.int_repeated end _writer[128+2] = function(msg) return _writer.real_repeated end _writer[128+3] = function(msg) return _writer.bool_repeated end _writer[128+4] = function(msg) return _writer.string_repeated end _writer[128+5] = function(msg) return _writer.string_repeated end _writer[128+6] = function(msg) local message = _writer.message_repeated return function(self,key, v) return message(self, key, v, msg) end end _writer[128+7] = function(msg) return _writer.int64_repeated end _writer[128+8] = function(msg) return _writer.int32_repeated end _writer[128+9] = _writer[128+5] _writer[128+10] = function(msg) return _writer.int52_repeated end _writer[128+11] = function(msg) return _writer.uint52_repeated end local _encode_type_meta = {} function _encode_type_meta:__index(key) local t, msg = c._env_type(P, self._CType, key) local func = assert(_writer[t],key)(msg) self[key] = func return func end setmetatable(encode_type_cache , { __index = function(self, key) local v = setmetatable({ _CType = key } , _encode_type_meta) self[key] = v return v end }) function encode( message, t , func , ...) local encoder = c._wmessage_new(P, message) assert(encoder , message) encode_message(encoder, message, t) if func then local buffer, len = c._wmessage_buffer(encoder) local ret = func(buffer, len, ...) c._wmessage_delete(encoder) return ret else local s = c._wmessage_buffer_string(encoder) c._wmessage_delete(encoder) return s end end --------- unpack ---------- local _pattern_type = { [1] = {"%d","i"}, [2] = {"%F","r"}, [3] = {"%d","b"}, [4] = {"%d","i"}, [5] = {"%s","s"}, [6] = {"%s","m"}, [7] = {"%D","x"}, [8] = {"%d","p"}, [10] = {"%D","d"}, [11] = {"%D","u"}, [128+1] = {"%a","I"}, [128+2] = {"%a","R"}, [128+3] = {"%a","B"}, [128+4] = {"%a","I"}, [128+5] = {"%a","S"}, [128+6] = {"%a","M"}, [128+7] = {"%a","X"}, [128+8] = {"%a","P"}, [128+10] = {"%a", "D" }, [128+11] = {"%a", "U" }, } _pattern_type[9] = _pattern_type[5] _pattern_type[128+9] = _pattern_type[128+5] local function _pattern_create(pattern) local iter = string.gmatch(pattern,"[^ ]+") local message = iter() local cpat = {} local lua = {} for v in iter do local tidx = c._env_type(P, message, v) local t = _pattern_type[tidx] assert(t,tidx) tinsert(cpat,v .. " " .. t[1]) tinsert(lua,t[2]) end local cobj = c._pattern_new(P, message , "@" .. table.concat(cpat," ")) if cobj == nil then return end c._add_pattern(GC, cobj) local pat = { CObj = cobj, format = table.concat(lua), size = 0 } pat.size = c._pattern_size(pat.format) return pat end setmetatable(_pattern_cache, { __index = function(t, key) local v = _pattern_create(key) t[key] = v return v end }) function unpack(pattern, buffer, length) local pat = _pattern_cache[pattern] return c._pattern_unpack(pat.CObj , pat.format, pat.size, buffer, length) end function pack(pattern, ...) local pat = _pattern_cache[pattern] return c._pattern_pack(pat.CObj, pat.format, pat.size , ...) end function check(typename , field) if field == nil then return c._env_type(P,typename) else return c._env_type(P,typename,field) ~=0 end end -------------- local default_cache = {} -- todo : clear default_cache, v._CObj local function default_table(typename) local v = default_cache[typename] if v then return v end v = { __index = assert(decode_message(typename , "")) } default_cache[typename] = v return v end local decode_message_mt = {} local function decode_message_cb(typename, buffer) return setmetatable ( { typename, buffer } , decode_message_mt) end function decode(typename, buffer, length) local ret = {} local ok = c._decode(P, decode_message_cb , ret , typename, buffer, length) if ok then return setmetatable(ret , default_table(typename)) else return false , c._last_error(P) end end local function expand(tbl) local typename = rawget(tbl , 1) local buffer = rawget(tbl , 2) tbl[1] , tbl[2] = nil , nil assert(c._decode(P, decode_message_cb , tbl , typename, buffer), typename) setmetatable(tbl , default_table(typename)) end function decode_message_mt.__index(tbl, key) expand(tbl) return tbl[key] end function decode_message_mt.__pairs(tbl) expand(tbl) return pairs(tbl) end local function set_default(typename, tbl) for k,v in pairs(tbl) do if type(v) == "table" then local t, msg = c._env_type(P, typename, k) if t == 6 then set_default(msg, v) elseif t == 128+6 then for _,v in ipairs(v) do set_default(msg, v) end end end end return setmetatable(tbl , default_table(typename)) end function register( buffer) c._env_register(P, buffer) end function register_file(filename) local f = assert(io.open(filename , "rb")) local buffer = f:read "*a" c._env_register(P, buffer) f:close() end default=set_default ================================================ FILE: Assets/Lua/3rd/pbc/protobuf.lua.meta ================================================ fileFormatVersion: 2 guid: 1ba29465c7f40ae4aa388cefab41f5e0 DefaultImporter: userData: ================================================ FILE: Assets/Lua/3rd/pbc.meta ================================================ fileFormatVersion: 2 guid: 4bf5196cb12726f4a9958b8bbffdaffe folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/3rd.meta ================================================ fileFormatVersion: 2 guid: 0921f818f1bc02e499634048e5c59679 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Classloader.lua ================================================ local typeof = typeof toluaSystem = System local isInstanceOfType = typeof(toluaSystem.Object).IsInstanceOfType local Timer = Timer.New -- tolua.Timer local function isFromCSharp(T) return T[".name"] ~= nil end local function isUserdataType(obj, T) if isFromCSharp(T) then return isInstanceOfType(typeof(T), obj) end return true end local config = { time = tolua.gettime, setTimeout = function (f, milliseconds) local t = Timer(f, milliseconds / 1000, 1, true) t:Start() return t end, clearTimeout = function (t) t:Stop() end, customTypeCheck = function (T) if isFromCSharp(T) then return isUserdataType end end } UnityEngine.isFromCSharp = isFromCSharp if jit then -- luajit table.move may causes a crash in a version, do not confirm whether the current version is fixed table.move = function(a1, f, e, t, a2) if a2 == nil then a2 = a1 end if t > f then t = e - f + t while e >= f do a2[t] = a1[e] t = t - 1 e = e - 1 end else while f <= e do a2[t] = a1[f] t = t + 1 f = f + 1 end end end end require("CoreSystemLua.All")("CoreSystemLua", config) require("UnityAdapter") require("ProtobufAdapter") require("Compiled.manifest")("Compiled") ================================================ FILE: Assets/Lua/Classloader.lua.meta ================================================ fileFormatVersion: 2 guid: 896a17f3a9cc84246858465cab87a45a DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Protocol/AutoGen/CommonPrototype.lua ================================================ -- Generated by CSharp.lua Compiler -------------------------------------------------------------------------------- -- -- This code was generated by a tool. -- -- Changes to this file may cause incorrect behavior and will be lost if -- the code is regenerated. -- -------------------------------------------------------------------------------- -- Generated from: CommonPrototype.proto local System = System local CSharpLuaSettingProto local ListValuePairProto System.import(function (out) CSharpLuaSettingProto = CSharpLua.Project.Protocol.SettingProto ListValuePairProto = System.List(CSharpLuaSettingProto.ValuePairProto) end) System.namespace("CSharpLua.Project.Protocol", function (namespace) namespace.class("SettingProto", function (namespace) local __ctor__ namespace.class("ValuePairProto", function (namespace) return { base = function (out) return { out.ProtoBuf.IProtocol } end } end) __ctor__ = function (this) this.Values = ListValuePairProto() end return { base = function (out) return { out.ProtoBuf.IProtocol } end, SettingsMark = 0, __ctor__ = __ctor__ } end) end) ================================================ FILE: Assets/Lua/Compiled/Protocol/AutoGen/CommonPrototype.lua.meta ================================================ fileFormatVersion: 2 guid: 4c15c22eddb928345a01a9ff7de17cd5 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Protocol/AutoGen.meta ================================================ fileFormatVersion: 2 guid: 1b33b39ff0a98b243be124e052b89741 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Protocol/IProtocol.lua ================================================ -- Generated by CSharp.lua Compiler local System = System System.namespace("ProtoBuf", function (namespace) namespace.interface("IProtocol", function () return {} end) end) ================================================ FILE: Assets/Lua/Compiled/Protocol/IProtocol.lua.meta ================================================ fileFormatVersion: 2 guid: 8955781becf16fc48b8ec217d536653e DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Protocol.meta ================================================ fileFormatVersion: 2 guid: 839f71ef436eef449a8aa098ab4c8008 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Sample/TestCoroutine.lua ================================================ -- Generated by CSharp.lua Compiler local System = System local UnityEngine = UnityEngine local ListInt32 = System.List(System.Int32) System.namespace("Sample", function (namespace) namespace.class("TestCoroutine", function (namespace) local Awake, OnTick, Test, T1, T2, __ctor__ __ctor__ = function (this) this.list = ListInt32() System.base(this).__ctor__(this) end Awake = function (this) UnityEngine.Debug.Log("TestCoroutine") this:StartCoroutine(OnTick(this)) UnityEngine.MonoBehaviour.print(this:getgameObject():getname()) UnityEngine.MonoBehaviour.print(#this.list) this:StartCoroutine(T1(this)) end OnTick = function (this) return System.yieldIEnumerator(function (this) while true do System.yield(UnityEngine.WaitForSeconds(1)) UnityEngine.MonoBehaviour.print("TestCoroutine.OnTick") end end, System.Object, this) end Test = function (this) UnityEngine.MonoBehaviour.print("TestCoroutine.Test") end T1 = function (this) return System.yieldIEnumerator(function (this) UnityEngine.MonoBehaviour.print("a0") System.yield(nil) UnityEngine.MonoBehaviour.print("a1") System.yield(T2(this)) UnityEngine.MonoBehaviour.print("a2") end, System.Object, this) end T2 = function (this) return System.yieldIEnumerator(function (this) UnityEngine.MonoBehaviour.print("b0") System.yield(nil) UnityEngine.MonoBehaviour.print("b1") System.yield(nil) UnityEngine.MonoBehaviour.print("b2") end, System.Object, this) end return { base = function (out) return { out.UnityEngine.MonoBehaviour } end, Awake = Awake, OnTick = OnTick, Test = Test, __ctor__ = __ctor__ } end) end) ================================================ FILE: Assets/Lua/Compiled/Sample/TestCoroutine.lua.meta ================================================ fileFormatVersion: 2 guid: da6a71c38b8b9984c833b5b4ca0e5644 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Sample/TestHangingScript.lua ================================================ -- Generated by CSharp.lua Compiler local System = System local UnityEngine = UnityEngine local ListInt32 = System.List(System.Int32) System.namespace("Sample", function (namespace) namespace.class("TestHangingScript", function (namespace) local Awake, Start, __ctor__ __ctor__ = function (this) this.l = ListInt32() this.vector2 = System.default(UnityEngine.Vector2) this.vector3 = System.default(UnityEngine.Vector3) System.base(this).__ctor__(this) end Awake = function (this) UnityEngine.MonoBehaviour.print("Awake") UnityEngine.MonoBehaviour.print(this.DataOfString) UnityEngine.MonoBehaviour.print(this.DataOfInt) UnityEngine.MonoBehaviour.print(this.DataOfString2) UnityEngine.MonoBehaviour.print(this.a) UnityEngine.MonoBehaviour.print(this.HangingMonoBehaviour:getname()) UnityEngine.MonoBehaviour.print(System.String.JoinEnumerable(",", this.l)) UnityEngine.MonoBehaviour.print(this.vector2:ToString() .. ", " .. this.vector3:ToString()) end Start = function (this) UnityEngine.MonoBehaviour.print("Start") end return { base = function (out) return { out.UnityEngine.MonoBehaviour } end, DataOfInt = 0, DataOfString2 = "ddddd", a = 10, Awake = Awake, Start = Start, __ctor__ = __ctor__ } end) end) ================================================ FILE: Assets/Lua/Compiled/Sample/TestHangingScript.lua.meta ================================================ fileFormatVersion: 2 guid: 1a47e23a7d689fb4c8b535daac4e7506 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Sample/TestHelloWord.lua ================================================ -- Generated by CSharp.lua Compiler local System = System local UnityEngine = UnityEngine local Sample System.import(function (out) Sample = out.Sample end) System.namespace("Sample", function (namespace) namespace.class("TestHelloWord", function (namespace) local Awake, Start, Update Awake = function (this) UnityEngine.Debug.Log("TestHelloWord") this:getgameObject():AddComponent(Sample.TestCoroutine) local c = this:GetComponent(UnityEngine.MonoBehaviour) UnityEngine.MonoBehaviour.print(c:getname()) local obj1 = UnityEngine.Object.FindObjectOfType(UnityEngine.MonoBehaviour) UnityEngine.Object.Destroy(obj1) local i = TestUtils.Load("Assets/CSharpLua/Examples/01_HelloWorld/TestLoader.prefab") local obj = UnityEngine.Object.Instantiate(i) obj:gettransform():setparent(this:gettransform()) Sample.TestProtobuf.Run() end Start = function (this) UnityEngine.MonoBehaviour.print("TestHelloWord.Start") end Update = function (this) UnityEngine.MonoBehaviour.print("TestHelloWord.Update") end return { base = function (out) return { out.UnityEngine.MonoBehaviour } end, Awake = Awake, Start = Start, Update = Update } end) end) ================================================ FILE: Assets/Lua/Compiled/Sample/TestHelloWord.lua.meta ================================================ fileFormatVersion: 2 guid: d650d1e86eb0ece4981a48b1b0e95878 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Sample/TestProtobuf.lua ================================================ -- Generated by CSharp.lua Compiler local System = System local UnityEngine = UnityEngine local CSharpLuaProjectProtocol local CSharpLuaSettingProto System.import(function (out) CSharpLuaProjectProtocol = CSharpLua.Project.Protocol CSharpLuaSettingProto = CSharpLua.Project.Protocol.SettingProto end) System.namespace("Sample", function (namespace) namespace.class("TestProtobuf", function (namespace) local Run, Encode, Decode Run = function () protobuf.register_file("Assets/Lua/3rd/pbc/Protocol/CommonPrototype.pb") local default = CSharpLuaProjectProtocol.SettingProto() default.SettingsMark = 101 local proto = default local extern = CSharpLuaSettingProto.ValuePairProto() extern.Key = "a" extern.Value = "b" proto.Values:Add(extern) local bytes = Encode(proto) local t = Decode(bytes, CSharpLuaProjectProtocol.SettingProto) UnityEngine.Debug.LogFormat("ProtobufDecode {0}", t.SettingsMark) end Encode = function (proto) local bytes = nil bytes = encodeProtobuf(proto) return bytes end Decode = function (bytes, T) local t = nil t = decodeProtobuf(bytes, T) return t end return { Run = Run } end) end) ================================================ FILE: Assets/Lua/Compiled/Sample/TestProtobuf.lua.meta ================================================ fileFormatVersion: 2 guid: 73822b2e531795d4d9cca42b4b834d38 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/Sample.meta ================================================ fileFormatVersion: 2 guid: f5664ef679fb2bb4c85569a055f6debd folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled/manifest.lua ================================================ -- Generated by CSharp.lua Compiler return function (path) return System.init({ path = path, files = { "Protocol.AutoGen.CommonPrototype", "Protocol.IProtocol", "Sample.TestCoroutine", "Sample.TestHangingScript", "Sample.TestHelloWord", "Sample.TestProtobuf" }, types = { "ProtoBuf.IProtocol", "CSharpLua.Project.Protocol.SettingProto", "CSharpLua.Project.Protocol.SettingProto.ValuePairProto", "Sample.TestCoroutine", "Sample.TestHangingScript", "Sample.TestHelloWord", "Sample.TestProtobuf" } }) end ================================================ FILE: Assets/Lua/Compiled/manifest.lua.meta ================================================ fileFormatVersion: 2 guid: d66a9fc55c5de2a459db4893f0db8279 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Compiled.meta ================================================ fileFormatVersion: 2 guid: e7429fd7d84e7a94691ccffa8843d572 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/All.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] return function(dir, conf) dir = (dir and #dir > 0) and (dir .. ".CoreSystem.") or "CoreSystem." local require = require local load = function(module) return require(dir .. module) end load("Core")(conf) load("Interfaces") load("Exception") load("Number") load("Char") load("String") load("Boolean") load("Delegate") load("Enum") load("TimeSpan") load("DateTime") load("Collections.EqualityComparer") load("Array") load("Type") load("Collections.List") load("Collections.Dictionary") load("Collections.Queue") load("Collections.Stack") load("Collections.HashSet") load("Collections.LinkedList") load("Collections.Linq") load("Convert") load("Math") load("Random") load("Text.StringBuilder") load("Console") load("IO.File") load("Reflection.Assembly") load("Threading.Timer") load("Threading.Thread") load("Threading.Task") load("Utilities") end ================================================ FILE: Assets/Lua/CoreSystemLua/All.lua.meta ================================================ fileFormatVersion: 2 guid: f7703f768c9abc748b02b74d42ff099c timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Array.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local div = System.div local trueFn = System.trueFn local falseFn = System.falseFn local lengthFn = System.lengthFn local InvalidOperationException = System.InvalidOperationException local NullReferenceException = System.NullReferenceException local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local IndexOutOfRangeException = System.IndexOutOfRangeException local NotSupportedException = System.NotSupportedException local EqualityComparer = System.EqualityComparer local Comparer_1 = System.Comparer_1 local IEnumerator_1 = System.IEnumerator_1 local assert = assert local select = select local getmetatable = getmetatable local setmetatable = setmetatable local type = type local table = table local tinsert = table.insert local tremove = table.remove local tmove = table.move local tsort = table.sort local pack = table.pack local unpack = table.unpack local error = error local coroutine = coroutine local ccreate = coroutine.create local cresume = coroutine.resume local cyield = coroutine.yield local null = {} local arrayEnumerator local arrayFromTable local versions = setmetatable({}, { __mode = "k" }) System.versions = versions local function throwFailedVersion() throw(InvalidOperationException("Collection was modified; enumeration operation may not execute.")) end local function checkIndex(t, index) if index < 0 or index >= #t then throw(ArgumentOutOfRangeException("index")) end end local function checkIndexAndCount(t, index, count) if t == nil then throw(ArgumentNullException("array")) end if index < 0 or count < 0 or index + count > #t then throw(ArgumentOutOfRangeException("index or count")) end end local function wrap(v) if v == nil then return null end return v end local function unWrap(v) if v == null then return nil end return v end local function ipairs(t) local version = versions[t] return function (t, i) if version ~= versions[t] then throwFailedVersion() end local v = t[i] if v ~= nil then if v == null then v = nil end return i + 1, v end end, t, 1 end local function eachFn(en) if en:MoveNext() then return true, en:getCurrent() end return nil end local function each(t) if t == nil then throw(NullReferenceException(), 1) end local getEnumerator = t.GetEnumerator if getEnumerator == arrayEnumerator then return ipairs(t) end local en = getEnumerator(t) return eachFn, en end function System.isArrayLike(t) return type(t) == "table" and t.GetEnumerator == arrayEnumerator end function System.isEnumerableLike(t) return type(t) == "table" and t.GetEnumerator ~= nil end function System.toLuaTable(array) local t = {} for i = 1, #array do local item = array[i] if item ~= null then t[i] = item end end return t end System.null = null System.Void = null System.each = each System.ipairs = ipairs System.throwFailedVersion = throwFailedVersion System.wrap = wrap System.unWrap = unWrap System.checkIndex = checkIndex System.checkIndexAndCount = checkIndexAndCount local Array local emptys = {} local function get(t, index) local v = t[index + 1] if v == nil then throw(ArgumentOutOfRangeException("index")) end if v ~= null then return v end return nil end local function set(t, index, v) index = index + 1 if t[index] == nil then throw(ArgumentOutOfRangeException("index")) end t[index] = v == nil and null or v versions[t] = (versions[t] or 0) + 1 end local function add(t, v) local n = #t t[n + 1] = v == nil and null or v versions[t] = (versions[t] or 0) + 1 return n end local function addRange(t, collection) if collection == nil then throw(ArgumentNullException("collection")) end local count = #t + 1 if collection.GetEnumerator == arrayEnumerator then tmove(collection, 1, #collection, count, t) else for _, v in each(collection) do t[count] = v == nil and null or v count = count + 1 end end versions[t] = (versions[t] or 0) + 1 end local function unset() throw(NotSupportedException("Collection is read-only.")) end local function fill(t, f, e, v) while f <= e do t[f] = v f = f + 1 end end local function buildArray(T, len, t) if t == nil then t = {} if len > 0 then local genericT = T.__genericT__ local default = genericT:default() if default == nil then fill(t, 1, len, null) elseif type(default) ~= "table" then fill(t, 1, len, default) else for i = 1, len do t[i] = genericT:default() end end end else if len > 0 then local default = T.__genericT__:default() if default == nil then for i = 1, len do if t[i] == nil then t[i] = null end end end end end return setmetatable(t, T) end local function indexOf(t, v, startIndex, count) if t == nil then throw(ArgumentNullException("array")) end local len = #t if not startIndex then startIndex, count = 0, len elseif not count then if startIndex < 0 or startIndex > len then throw(ArgumentOutOfRangeException("startIndex")) end count = len - startIndex else if startIndex < 0 or startIndex > len then throw(ArgumentOutOfRangeException("startIndex")) end if count < 0 or count > len - startIndex then throw(ArgumentOutOfRangeException("count")) end end local comparer = EqualityComparer(t.__genericT__).getDefault() local equals = comparer.EqualsOf for i = startIndex + 1, startIndex + count do local item = t[i] if item == null then item = nil end if equals(comparer, item, v) then return i - 1 end end return -1 end local function findIndex(t, startIndex, count, match) if t == nil then throw(ArgumentNullException("array")) end local len = #t if not count then startIndex, count, match = 0, len, startIndex elseif not match then if startIndex < 0 or startIndex > len then throw(ArgumentOutOfRangeException("startIndex")) end count, match = len - startIndex, count else if startIndex < 0 or startIndex > len then throw(ArgumentOutOfRangeException("startIndex")) end if count < 0 or count > len - startIndex then throw(ArgumentOutOfRangeException("count")) end end if match == nil then throw(ArgumentNullException("match")) end local endIndex = startIndex + count for i = startIndex + 1, endIndex do local item = t[i] if item == null then item = nil end if match(item) then return i - 1 end end return -1 end local function copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable) if not reliable then checkIndexAndCount(sourceArray, sourceIndex, length) checkIndexAndCount(destinationArray, destinationIndex, length) end tmove(sourceArray, sourceIndex + 1, sourceIndex + length, destinationIndex + 1, destinationArray) end local function removeRange(t, index, count) local n = #t if count < 0 or index > n - count then throw(ArgumentOutOfRangeException("index or count")) end if count > 0 then if index + count < n then tmove(t, index + count + 1, n, index + 1) end fill(t, n - count + 1, n, nil) versions[t] = (versions[t] or 0) + 1 end end local function findAll(t, match) if t == nil then throw(ArgumentNullException("array")) end if match == nil then throw(ArgumentNullException("match")) end local list = {} local count = 1 for i = 1, #t do local item = t[i] if (item == null and match(nil)) or match(item) then list[count] = item count = count + 1 end end return list end local function getComp(t, comparer) local compare if comparer then if type(comparer) == "function" then compare = comparer else local Compare = comparer.Compare if Compare then compare = function (x, y) return Compare(comparer, x, y) end else compare = comparer end end else comparer = Comparer_1(t.__genericT__).getDefault() local Compare = comparer.Compare compare = function (x, y) return Compare(comparer, x, y) end end return function(x, y) if x == null then x = nil end if y == null then y = nil end return compare(x, y) < 0 end end local function sort(t, comparer) if #t > 1 then tsort(t, getComp(t, comparer)) versions[t] = (versions[t] or 0) + 1 end end local ArrayEnumerator = define("System.ArrayEnumerator", function (T) return { base = { IEnumerator_1(T) } } end, { getCurrent = System.getCurrent, Dispose = System.emptyFn, Reset = function (this) this.index = 1 this.current = nil end, MoveNext = function (this) local t = this.list if this.version ~= versions[t] then throwFailedVersion() end local index = this.index local v = t[index] if v ~= nil then if v == null then this.current = nil else this.current = v end this.index = index + 1 return true end this.current = nil return false end }) arrayEnumerator = function (t, T) if not T then T = t.__genericT__ end return setmetatable({ list = t, index = 1, version = versions[t], currnet = T:default() }, ArrayEnumerator(T)) end local ArrayReverseEnumerator = define("System.ArrayReverseEnumerator", function (T) return { base = { IEnumerator_1(T) } } end, { getCurrent = System.getCurrent, Dispose = System.emptyFn, Reset = function (this) this.index = #this.list this.current = nil end, MoveNext = function (this) local t = this.list if this.version ~= versions[t] then throwFailedVersion() end local index = this.index local v = t[index] if v ~= nil then if v == null then this.current = nil else this.current = v end this.index = index - 1 return true end this.current = nil return false end }) local function reverseEnumerator(t) local T = t.__genericT__ return setmetatable({ list = t, index = #t, version = versions[t], currnet = T:default() }, ArrayReverseEnumerator(T)) end local function checkArrayIndex(index1, index2) if index2 then throw(ArgumentException("Indices length does not match the array rank.")) elseif type(index1) == "table" then if #index1 ~= 1 then throw(ArgumentException("Indices length does not match the array rank.")) else index1 = index1[1] end end return index1 end Array = { version = 0, new = buildArray, set = set, get = get, ctorList = function (t, ...) local len = select("#", ...) if len == 0 then return end local collection = ... if type(collection) == "number" then return end addRange(t, collection) end, add = add, addObj = function (this, item) if not System.is(item, this.__genericT__) then throw(ArgumentException()) end return add(this, item) end, addRange = addRange, AsReadOnly = function (t) return System.ReadOnlyCollection(t.__genericT__)(t) end, clear = function (t) local size = #t if size > 0 then for i = 1, size do t[i] = nil end versions[t] = (versions[t] or 0) + 1 end end, findAll = function (t, match) return setmetatable(findAll(t, match), System.List(t.__genericT__)) end, first = function (t) if #t == 0 then throw(InvalidOperationException()) end local v = t[1] if v ~= null then return v end return nil end, insert = function (t, index, v) if index < 0 or index > #t then throw(ArgumentOutOfRangeException("index")) end tinsert(t, index + 1, v == nil and null or v) versions[t] = (versions[t] or 0) + 1 end, insertRange = function (t, index, collection) if collection == nil then throw(ArgumentNullException("collection")) end local len = #t if index < 0 or index > len then throw(ArgumentOutOfRangeException("index")) end if t.GetEnumerator == arrayEnumerator then local count = #collection if count > 0 then if index < len then tmove(t, index + 1, len, index + 1 + count, t) end if t == collection then tmove(t, 1, index, index + 1, t) tmove(t, index + 1 + count, count * 2, index * 2 + 1, t) else tmove(collection, 1, count, index + 1, t) end end else for _, v in each(collection) do index = index + 1 tinsert(t, index, v == nil and null or v) end end versions[t] = (versions[t] or 0) + 1 end, last = function (t) local n = #t if n == 0 then throw(InvalidOperationException()) end local v = t[n] if v ~= null then return v end return nil end, popFirst = function (t) if #t == 0 then throw(InvalidOperationException()) end local v = t[1] tremove(t, 1) versions[t] = (versions[t] or 0) + 1 if v ~= null then return v end return nil end, popLast = function (t) local n = #t if n == 0 then throw(InvalidOperationException()) end local v = t[n] t[n] = nil if v ~= null then return v end return nil end, removeRange = removeRange, remove = function (t, v) local index = indexOf(t, v) if index >= 0 then tremove(t, index + 1) versions[t] = (versions[t] or 0) + 1 return true end return false end, removeAll = function (t, match) if match == nil then throw(ArgumentNullException("match")) end local size = #t local freeIndex = 1 while freeIndex <= size do local item = t[freeIndex] if item == null then item = nil end if match(item) then break end freeIndex = freeIndex + 1 end if freeIndex > size then return 0 end local current = freeIndex + 1 while current <= size do while current <= size do local item = t[current] if item == null then item = nil end if not match(item) then break end current = current + 1 end if current <= size then t[freeIndex] = t[current] freeIndex = freeIndex + 1 current = current + 1 end end freeIndex = freeIndex -1 local count = size - freeIndex removeRange(t, freeIndex, count) return count end, removeAt = function (t, index) local v = tremove(t, index + 1) if v == nil then throw(ArgumentOutOfRangeException("index")) end versions[t] = (versions[t] or 0) + 1 end, getRange = function (t, index, count) if count < 0 or index > #t - count then throw(ArgumentOutOfRangeException("index or count")) end local list = {} tmove(t, index + 1, index + count, 1, list) return setmetatable(list, System.List(t.__genericT__)) end, reverseEnumerator = reverseEnumerator, getCount = lengthFn, getSyncRoot = System.identityFn, getLongLength = lengthFn, getLength = lengthFn, getIsSynchronized = falseFn, getIsReadOnly = falseFn, getIsFixedSize = trueFn, getRank = System.oneFn, Add = unset, Clear = unset, Insert = unset, Remove = unset, RemoveAt = unset, BinarySearch = function (t, ...) if t == nil then throw(ArgumentNullException("array")) end local len = #t local index, count, v, comparer local n = select("#", ...) if n == 1 or n == 2 then index, count, v, comparer = 0, len, ... else index, count, v, comparer = ... end checkIndexAndCount(t, index, count) local compare if comparer == nil then comparer = Comparer_1(t.__genericT__).getDefault() compare = comparer.Compare else compare = comparer.Compare end local lo = index local hi = index + count - 1 while lo <= hi do local i = lo + div(hi - lo, 2) local item = t[i + 1] if item == null then item = nil end local order = compare(comparer, item, v); if order == 0 then return i end if order < 0 then lo = i + 1 else hi = i - 1 end end return -1 end, ClearArray = function (t, index, length) if t == nil then throw(ArgumentNullException("array")) end if index < 0 or length < 0 or index + length > #t then throw(IndexOutOfRangeException()) end local default = t.__genericT__:default() if default == nil then default = null end fill(t, index + 1, index + length, default) end, Contains = function (t, v) return indexOf(t, v) ~= -1 end, Copy = function (t, ...) local len = select("#", ...) if len == 2 then local array, length = ... copy(t, 0, array, 0, length) else copy(t, ...) end end, CreateInstance = function (elementType, length) return buildArray(Array(elementType[1]), length) end, Empty = function (T) local t = emptys[T] if t == nil then t = Array(T)() emptys[T] = t end return t end, Exists = function (t, match) return findIndex(t, match) ~= -1 end, Fill = function (t, value, startIndex, count) if t == nil then throw(ArgumentNullException("array")) end local len = #t if not startIndex then startIndex, count = 0, len else if startIndex < 0 or startIndex > len then throw(ArgumentOutOfRangeException("startIndex")) end if count < 0 or count > len - startIndex then throw(ArgumentOutOfRangeException("count")) end end fill(t, startIndex + 1, startIndex + count, value) end, Find = function (t, match) if t == nil then throw(ArgumentNullException("array")) end if match == nil then throw(ArgumentNullException("match")) end for i = 1, #t do local item = t[i] if item == null then item = nil end if match(item) then return item end end return t.__genericT__:default() end, FindAll = function (t, match) return setmetatable(findAll(t, match), Array(t.__genericT__)) end, FindIndex = findIndex, FindLast = function (t, match) if t == nil then throw(ArgumentNullException("array")) end if match == nil then throw(ArgumentNullException("match")) end for i = #t, 1, -1 do local item = t[i] if item == null then item = nil end if match(item) then return item end end return t.__genericT__:default() end, FindLastIndex = function (t, startIndex, count, match) if t == nil then throw(ArgumentNullException("array")) end local len = #t if not count then startIndex, count, match = len - 1, len, startIndex elseif not match then count, match = startIndex + 1, count end if match == nil then throw(ArgumentNullException("match")) end if count < 0 or startIndex - count + 1 < 0 then throw(ArgumentOutOfRangeException("count")) end local endIndex = startIndex - count + 1 for i = startIndex + 1, endIndex + 1, -1 do local item = t[i] if item == null then item = nil end if match(item) then return i - 1 end end return -1 end, ForEach = function (t, action) if action == nil then throw(ArgumentNullException("action")) end for i = 1, #t do local item = t[i] if item == null then item = nil end action(item) end end, IndexOf = indexOf, LastIndexOf = function (t, value, startIndex, count) if t == nil then throw(ArgumentNullException("array")) end local len = #t if not startIndex then startIndex, count = len - 1, len elseif not count then count = len == 0 and 0 or (startIndex + 1) end if len == 0 then if startIndex ~= -1 and startIndex ~= 0 then throw(ArgumentOutOfRangeException("startIndex")) end if count ~= 0 then throw(ArgumentOutOfRangeException("count")) end end if startIndex < 0 or startIndex >= len then throw(ArgumentOutOfRangeException("startIndex")) end if count < 0 or startIndex - count + 1 < 0 then throw(ArgumentOutOfRangeException("count")) end local comparer = EqualityComparer(t.__genericT__).getDefault() local equals = comparer.EqualsOf local endIndex = startIndex - count + 1 for i = startIndex + 1, endIndex + 1, -1 do local item = t[i] if item == null then item = nil end if equals(comparer, item, value) then return i - 1 end end return -1 end, Resize = function (t, newSize, T) if newSize < 0 then throw(ArgumentOutOfRangeException("newSize")) end if t == nil then return buildArray(Array(T), newSize) end local len = #t if len > newSize then fill(t, newSize + 1, len, nil) elseif len < newSize then local default = t.__genericT__:default() if default == nil then default = null end fill(t, len + 1, newSize, default) end return t end, Reverse = function (t, index, count) if not index then index = 0 count = #t else if count < 0 or index > #t - count then throw(ArgumentOutOfRangeException("index or count")) end end local i, j = index + 1, index + count while i <= j do t[i], t[j] = t[j], t[i] i = i + 1 j = j - 1 end versions[t] = (versions[t] or 0) + 1 end, Sort = function (t, ...) if t == nil then throw(ArgumentNullException("array")) end local len = select("#", ...) if len == 0 then sort(t) elseif len == 1 then local comparer = ... sort(t, comparer) else local index, count, comparer = ... if count > 1 then local comp = getComp(t, comparer) if index == 0 and count == #t then tsort(t, comp) else checkIndexAndCount(t, index, count) local arr = {} tmove(t, index + 1, index + count, 1, arr) tsort(arr, comp) tmove(arr, 1, count, index + 1, t) end versions[t] = (versions[t] or 0) + 1 end end end, toArray = function (t) local array = {} if t.GetEnumerator == arrayEnumerator then tmove(t, 1, #t, 1, array) else local count = 1 for _, v in each(t) do array[count] = v == nil and null or v count = count + 1 end end return arrayFromTable(array, t.__genericT__) end, TrueForAll = function (t, match) if t == nil then throw(ArgumentNullException("array")) end if match == nil then throw(ArgumentNullException("match")) end for i = 1, #t do local item = t[i] if item == null then item = nil end if not match(item) then return false end end return true end, Clone = function (this) local t = setmetatable({}, getmetatable(this)) tmove(this, 1, #this, 1, t) return t end, CopyTo = function (this, array, index) local n = #this checkIndexAndCount(array, index, n) local T = this.__genericT__ if T.class == "S" then local default = T:default() if type(default) == "table" then for i = 1, n do array[i + index] = this[i]:__clone__() end return end end tmove(this, 1, n, index + 1, array) end, GetEnumerator = arrayEnumerator, GetLength = function (this, dimension) if dimension ~= 0 then throw(IndexOutOfRangeException()) end return #this end, GetLowerBound = function (this, dimension) if dimension ~= 0 then throw(IndexOutOfRangeException()) end return 0 end, GetUpperBound = function (this, dimension) if dimension ~= 0 then throw(IndexOutOfRangeException()) end return #this - 1 end, GetValue = function (this, index1, index2) if index1 == nil then throw(ArgumentNullException("indices")) end return get(this, checkArrayIndex(index1, index2)) end, SetValue = function (this, value, index1, index2) if index1 == nil then throw(ArgumentNullException("indices")) end set(this, checkArrayIndex(index1, index2), System.castWithNullable(this.__genericT__, value)) end, Clone = function (this) local array = {} tmove(this, 1, #this, 1, array) return arrayFromTable(array, this.__genericT__) end } function Array.__call(T, ...) return buildArray(T, select("#", ...), { ... }) end function System.arrayFromList(t) return setmetatable(t, Array(t.__genericT__)) end arrayFromTable = function (t, T, readOnly) assert(T) local array = setmetatable(t, Array(T)) if readOnly then array.set = unset end return array end System.arrayFromTable = arrayFromTable local function getIndex(t, ...) local rank = t.__rank__ local id = 0 local len = #rank for i = 1, len do id = id * rank[i] + select(i, ...) end return id, len end local function checkMultiArrayIndex(t, index1, ...) if index1 == nil then throw(ArgumentNullException("indices")) end local rank = t.__rank__ local len = #rank if type(index1) == "table" then if #index1 ~= len then throw(ArgumentException("Indices length does not match the array rank.")) end local id = 0 for i = 1, len do id = id * rank[i] + index1[i] end return id elseif len ~= select("#", ...) + 1 then throw(ArgumentException("Indices length does not match the array rank.")) end return getIndex(t, index1, ...) end local MultiArray = { set = function (this, ...) local index, len = getIndex(this, ...) set(this, index, select(len + 1, ...)) end, get = function (this, ...) local index = getIndex(this, ...) return get(this, index) end, getRank = function (this) return #this.__rank__ end, GetLength = function (this, dimension) local rank = this.__rank__ if dimension < 0 or dimension >= #rank then throw(IndexOutOfRangeException()) end return rank[dimension + 1] end, GetLowerBound = function (this, dimension) local rank = this.__rank__ if dimension < 0 or dimension >= #rank then throw(IndexOutOfRangeException()) end return 0 end, GetUpperBound = function (this, dimension) local rank = this.__rank__ if dimension < 0 or dimension >= #rank then throw(IndexOutOfRangeException()) end return rank[dimension + 1] - 1 end, GetValue = function (this, ...) return get(this, checkMultiArrayIndex(this, ...)) end, SetValue = function (this, value, ...) set(this, checkMultiArrayIndex(this, ...), System.castWithNullable(this.__genericT__, value)) end, Clone = function (this) local array = { __rank__ = this.__rank__ } tmove(this, 1, #this, 1, array) return arrayFromTable(array, this.__genericT__) end } function MultiArray.__call(T, rank, t) local len = 1 for i = 1, #rank do len = len * rank[i] end t = buildArray(T, len, t) t.__rank__ = rank return t end System.defArray("System.Array", function(T) return { base = { System.ICloneable, System.IList_1(T), System.IReadOnlyList_1(T), System.IList }, __genericT__ = T } end, Array, MultiArray) local cpool = {} local function createCoroutine(f) local c = tremove(cpool) if c == nil then c = ccreate(function (...) f(...) while true do f = nil cpool[#cpool + 1] = c f = cyield(cpool) f(cyield()) end end) else cresume(c, f) end return c end System.ccreate = createCoroutine System.cpool = cpool System.cresume = cresume System.yield = cyield local YieldEnumerable YieldEnumerable = define("System.YieldEnumerable", function (T) return { base = { System.IEnumerable_1(T), System.IEnumerator_1(T), System.IDisposable }, __genericT__ = T } end, { getCurrent = System.getCurrent, Dispose = System.emptyFn, GetEnumerator = function (this) return setmetatable({ f = this.f, args = this.args }, YieldEnumerable(this.__genericT__)) end, MoveNext = function (this) local c = this.c if c == false then return false end local ok, v if c == nil then c = createCoroutine(this.f) this.c = c local args = this.args ok, v = cresume(c, unpack(args, 1, args.n)) this.args = nil else ok, v = cresume(c) end if ok then if v == cpool then this.c = false this.current = nil return false else this.current = v return true end else error(v) end end }) local function yieldIEnumerable(f, T, ...) return setmetatable({ f = f, args = pack(...) }, YieldEnumerable(T)) end System.yieldIEnumerable = yieldIEnumerable System.yieldIEnumerator = yieldIEnumerable local ReadOnlyCollection = { __ctor__ = function (this, list) if not list then throw(ArgumentNullException("list")) end this.list = list end, getCount = function (this) return #this.list end, get = function (this, index) return this.list:get(index) end, Contains = function (this, value) return this.list:Contains(value) end, GetEnumerator = function (this) return this.list:GetEnumerator() end, CopyTo = function (this, array, index) this.list:CopyTo(array, index) end, IndexOf = function (this, value) return this.list:IndexOf(value) end, getIsSynchronized = falseFn, getIsReadOnly = trueFn, getIsFixedSize = trueFn, } define("System.ReadOnlyCollection", function (T) return { base = { System.IList_1(T), System.IList, System.IReadOnlyList_1(T) }, __genericT__ = T } end, ReadOnlyCollection) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Array.lua.meta ================================================ fileFormatVersion: 2 guid: cfb931ea6b78c994aac377dd25e13e3f timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Boolean.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local debugsetmetatable = System.debugsetmetatable local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local FormatException = System.FormatException local type = type local setmetatable = setmetatable local function compareTo(this, v) if this == v then return 0 elseif this == false then return -1 end return 1 end local falseString = "False" local trueString = "True" local function parse(s) if s == nil then return nil, 1 end local i, j, value = s:find("^[%s%c%z]*(%a+)[%s%c%z]*$") if value then s = value:lower() if s == "true" then return true elseif s == "false" then return false end end return nil, 2 end local function toString(this) return this and trueString or falseString end local Boolean = System.defStc("System.Boolean", { default = System.falseFn, GetHashCode = System.identityFn, Equals = System.equals, CompareTo = compareTo, ToString = toString, FalseString = falseString, TrueString = trueString, CompareToObj = function (this, v) if v == nil then return 1 end if type(v) ~= "boolean" then throw(ArgumentException("Arg_MustBeBoolean")) end return compareTo(this, v) end, EqualsObj = function (this, v) if type(v) ~= "boolean" then return false end return this == v end, __concat = function (a, b) if type(a) == "boolean" then return toString(a) .. b else return a .. toString(b) end end, __tostring = toString, Parse = function (s) local v, err = parse(s) if v == nil then if err == 1 then throw(ArgumentNullException()) else throw(FormatException()) end end return v end, TryParse = function (s) local v = parse(s) if v ~= nil then return true, v end return false, false end, base = function (_, T) return { System.IComparable, System.IConvertible, System.IComparable_1(T), System.IEquatable_1(T) } end }) if debugsetmetatable then debugsetmetatable(false, Boolean) end local ValueType = System.ValueType local boolMetaTable = setmetatable({ __index = ValueType, __call = Boolean.default }, ValueType) setmetatable(Boolean, boolMetaTable) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Boolean.lua.meta ================================================ fileFormatVersion: 2 guid: 1d6746daf7f157440a3bca4ef0d89b5e timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Char.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local Int = System.Int local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local setmetatable = setmetatable local byte = string.byte local isSeparatorTable = { [32] = true, [160] = true, [0x2028] = true, [0x2029] = true, [0x0020] = true, [0x00A0] = true, [0x1680] = true, [0x180E] = true, [0x202F] = true, [0x205F] = true, [0x3000] = true, } local isSymbolTable = { [36] = true, [43] = true, [60] = true, [61] = true, [62] = true, [94] = true, [96] = true, [124] = true, [126] = true, [172] = true, [180] = true, [182] = true, [184] = true, [215] = true, [247] = true, } --https://msdn.microsoft.com/zh-cn/library/t809ektx(v=vs.110).aspx local isWhiteSpace = { [0x0020] = true, [0x00A0] = true, [0x1680] = true, [0x202F] = true, [0x205F] = true, [0x3000] = true, [0x2028] = true, [0x2029] = true, [0x0085] = true, } local function get(s, index) if s == nil then throw(ArgumentNullException("s")) end local c = byte(s, index + 1) if not c then throw(ArgumentOutOfRangeException("index")) end return c end local function isDigit(c, index) if index then c = get(c, index) end return (c >= 48 and c <= 57) end -- https://msdn.microsoft.com/zh-cn/library/yyxz6h5w(v=vs.110).aspx local function isLetter(c, index) if index then c = get(c, index) end if c < 128 then return (c >= 65 and c <= 90) or (c >= 97 and c <= 122) else return (c >= 0x0400 and c <= 0x042F) or (c >= 0x03AC and c <= 0x03CE) or (c == 0x01C5 or c == 0x1FFC) or (c >= 0x02B0 and c <= 0x02C1) or (c >= 0x1D2C and c <= 0x1D61) or (c >= 0x05D0 and c <= 0x05EA) or (c >= 0x0621 and c <= 0x063A) or (c >= 0x4E00 and c <= 0x9FC3) end end local Char = System.defStc("System.Char", { ToString = string.char, CompareTo = Int.CompareTo, CompareToObj = Int.CompareToObj, Equals = Int.Equals, EqualsObj = Int.EqualsObj, GetHashCode = Int.GetHashCode, default = Int.default, IsControl = function (c, index) if index then c = get(c, index) end return (c >=0 and c <= 31) or (c >= 127 and c <= 159) end, IsDigit = isDigit, IsLetter = isLetter, IsLetterOrDigit = function (c, index) if index then c = get(c, index) end return isDigit(c) or isLetter(c) end, IsLower = function (c, index) if index then c = get(c, index) end return (c >= 97 and c <= 122) or (c >= 945 and c <= 969) end, IsNumber = function (c, index) if index then c = get(c, index) end return (c >= 48 and c <= 57) or c == 178 or c == 179 or c == 185 or c == 188 or c == 189 or c == 190 end, IsPunctuation = function (c, index) if index then c = get(c, index) end if c < 256 then return (c >= 0x0021 and c <= 0x0023) or (c >= 0x0025 and c <= 0x002A) or (c >= 0x002C and c <= 0x002F) or (c >= 0x003A and c <= 0x003B) or (c >= 0x003F and c <= 0x0040) or (c >= 0x005B and c <= 0x005D) or c == 0x5F or c == 0x7B or c == 0x007D or c == 0x00A1 or c == 0x00AB or c == 0x00AD or c == 0x00B7 or c == 0x00BB or c == 0x00BF end return false end, IsSeparator = function (c, index) if index then c = get(c, index) end return (c >= 0x2000 and c <= 0x200A) or isSeparatorTable[c] == true end, IsSymbol = function (c, index) if index then c = get(c, index) end if c < 256 then return (c >= 162 and c <= 169) or (c >= 174 and c <= 177) or isSymbolTable(c) == true end return false end, IsUpper = function (c, index) if index then c = get(c, index) end return (c >= 65 and c <= 90) or (c >= 913 and c <= 937) end, IsWhiteSpace = function (c, index) if index then c = get(c, index) end return (c >= 0x2000 and c <= 0x200A) or (c >= 0x0009 and c <= 0x000d) or isWhiteSpace[c] == true end, Parse = function (s) if s == nil then throw(System.ArgumentNullException()) end if #s ~= 1 then throw(System.FormatException()) end return s:byte() end, TryParse = function (s) if s == nil or #s ~= 1 then return false, 0 end return true, s:byte() end, ToLower = function (c) if (c >= 65 and c <= 90) or (c >= 913 and c <= 937) then return c + 32 end return c end, ToUpper = function (c) if (c >= 97 and c <= 122) or (c >= 945 and c <= 969) then return c - 32 end return c end, IsHighSurrogate = function (c, index) if index then c = get(c, index) end return c >= 0xD800 and c <= 0xDBFF end, IsLowSurrogate = function (c, index) if index then c = get(c, index) end return c >= 0xDC00 and c <= 0xDFFF end, IsSurrogate = function (c, index) if index then c = get(c, index) end return c >= 0xD800 and c <= 0xDFFF end, base = function (_, T) return { System.IComparable, System.IComparable_1(T), System.IEquatable_1(T) } end }) local ValueType = System.ValueType local charMetaTable = setmetatable({ __index = ValueType, __call = Char.default }, ValueType) setmetatable(Char, charMetaTable) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Char.lua.meta ================================================ fileFormatVersion: 2 guid: 258f15fe832bc224ea63662b03a89289 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Dictionary.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local null = System.null local falseFn = System.falseFn local each = System.each local lengthFn = System.lengthFn local versions = System.versions local Array = System.Array local checkIndexAndCount = System.checkIndexAndCount local throwFailedVersion = System.throwFailedVersion local ArgumentNullException = System.ArgumentNullException local ArgumentException = System.ArgumentException local KeyNotFoundException = System.KeyNotFoundException local EqualityComparer = System.EqualityComparer local NotSupportedException = System.NotSupportedException local assert = assert local pairs = pairs local next = next local select = select local getmetatable = getmetatable local setmetatable = setmetatable local tconcat = table.concat local tremove = table.remove local type = type local counts = setmetatable({}, { __mode = "k" }) System.counts = counts local function getCount(this) local t = counts[this] if t then return t[1] end return 0 end local function pairsFn(t, i) local count = counts[t] if count then if count[2] ~= count[3] then throwFailedVersion() end end local k, v = next(t, i) if v == null then return k end return k, v end function System.pairs(t) local count = counts[t] if count then count[3] = count[2] end return pairsFn, t end local KeyValuePairFn local KeyValuePair = { __ctor__ = function (this, ...) if select("#", ...) == 0 then this.Key, this.Value = this.__genericTKey__:default(), this.__genericTValue__:default() else this.Key, this.Value = ... end end, Create = function (key, value, TKey, TValue) return setmetatable({ Key = key, Value = value }, KeyValuePairFn(TKey, TValue)) end, Deconstruct = function (this) return this.Key, this.Value end, ToString = function (this) local t = { "[" } local count = 2 local k, v = this.Key, this.Value if k ~= nil then t[count] = k:ToString() count = count + 1 end t[count] = ", " count = count + 1 if v ~= nil then t[count] = v:ToString() count = count + 1 end t[count] = "]" return tconcat(t) end } KeyValuePairFn = System.defStc("System.Collections.Generic.KeyValuePair", function(TKey, TValue) local cls = { __genericTKey__ = TKey, __genericTValue__ = TValue, } return cls end, KeyValuePair) System.KeyValuePair = KeyValuePairFn local function isKeyValuePair(t) return getmetatable(getmetatable(t)) == KeyValuePair end local DictionaryEnumerator = define("System.Collections.Generic.DictionaryEnumerator", { getCurrent = System.getCurrent, Dispose = System.emptyFn, MoveNext = function (this) local t, kind = this.dict, this.kind local count = counts[t] if this.version ~= (count and count[2] or 0) then throwFailedVersion() end local k, v = next(t, this.index) if k ~= nil then if kind then kind.Key = k if v == null then v = nil end kind.Value = v elseif kind == false then if v == null then v = nil end this.current = v else this.current = k end this.index = k return true else if kind then kind.Key, kind.Value = kind.__genericTKey__:default(), kind.__genericTValue__:default() elseif kind == false then this.current = t.__genericTValue__:default() else this.current = t.__genericTKey__:default() end return false end end }) local function dictionaryEnumerator(t, kind) local current if not kind then local TKey, TValue = t.__genericTKey__, t.__genericTValue__ kind = setmetatable({ Key = TKey:default(), Value = TValue:default() }, t.__genericT__) current = kind elseif kind == 1 then local TKey = t.__genericTKey__ current = TKey:default() kind = nil else local TValue = t.__genericTValue__ current = TValue:default() kind = false end local count = counts[t] local en = { dict = t, version = count and count[2] or 0, kind = kind, current = current } return setmetatable(en, DictionaryEnumerator) end local DictionaryCollection = define("System.Collections.Generic.DictionaryCollection", function (T) return { base = { System.ICollection_1(T), System.IReadOnlyCollection_1(T), System.ICollection }, __genericT__ = T } end, { __ctor__ = function (this, dict, kind) this.dict = dict this.kind = kind end, getCount = function (this) return getCount(this.dict) end, GetEnumerator = function (this) return dictionaryEnumerator(this.dict, this.kind) end }) local function add(this, key, value) if key == nil then throw(ArgumentNullException("key")) end if this[key] ~= nil then throw(ArgumentException("key already exists")) end this[key] = value == nil and null or value local t = counts[this] if t then t[1] = t[1] + 1 t[2] = t[2] + 1 else counts[this] = { 1, 1 } end end local function remove(this, key) if key == nil then throw(ArgumentNullException("key")) end if this[key] ~= nil then this[key] = nil local t = counts[this] t[1] = t[1] - 1 t[2] = t[2] + 1 return true end return false end local function buildFromDictionary(this, dictionary) if dictionary == nil then throw(ArgumentNullException("dictionary")) end local count = 0 for k, v in pairs(dictionary) do this[k] = v count = count + 1 end counts[this] = { count, 0 } end local ArrayDictionaryFn local function buildHasComparer(this, ...) local Dictionary = ArrayDictionaryFn(this.__genericTKey__, this.__genericTValue__) Dictionary.__ctor__(this, ...) return setmetatable(this, Dictionary) end local Dictionary = { getIsFixedSize = falseFn, getIsReadOnly = falseFn, __ctor__ = function (this, ...) local n = select("#", ...) if n == 0 then elseif n == 1 then local comparer = ... if comparer == nil or type(comparer) == "number" then else local equals = comparer.EqualsOf if equals == nil then buildFromDictionary(this, comparer) else buildHasComparer(this, ...) end end else local dictionary, comparer = ... if comparer ~= nil then buildHasComparer(this, ...) end if type(dictionary) ~= "number" then buildFromDictionary(this, dictionary) end end end, AddKeyValue = add, Add = function (this, ...) local k, v if select("#", ...) == 1 then local pair = ... k, v = pair.Key, pair.Value else k, v = ... end add(this, k ,v) end, Clear = function (this) for k, v in pairs(this) do this[k] = nil end counts[this] = nil end, ContainsKey = function (this, key) if key == nil then throw(ArgumentNullException("key")) end return this[key] ~= nil end, ContainsValue = function (this, value) if value == nil then for _, v in pairs(this) do if v == null then return true end end else local comparer = EqualityComparer(this.__genericTValue__).getDefault() local equals = comparer.EqualsOf for _, v in pairs(this) do if v ~= null then if equals(comparer, value, v ) then return true end end end end return false end, Contains = function (this, pair) local key = pair.Key if key == nil then throw(ArgumentNullException("key")) end local value = this[key] if value ~= nil then if value == null then value = nil end local comparer = EqualityComparer(this.__genericTValue__).getDefault() if comparer:EqualsOf(value, pair.Value) then return true end end return false end, CopyTo = function (this, array, index) local count = getCount(this) checkIndexAndCount(array, index, count) if count > 0 then local KeyValuePair = this.__genericT__ index = index + 1 for k, v in pairs(this) do if v == null then v = nil end array[index] = setmetatable({ Key = k, Value = v }, KeyValuePair) index = index + 1 end end end, RemoveKey = remove, Remove = function (this, key) if isKeyValuePair(key) then local k, v = key.Key, key.Value if k == nil then throw(ArgumentNullException("key")) end local value = this[k] if value ~= nil then if value == null then value = nil end local comparer = EqualityComparer(this.__genericTValue__).getDefault() if comparer:EqualsOf(value, v) then remove(this, k) return true end end return false end return remove(this, key) end, TryGetValue = function (this, key) if key == nil then throw(ArgumentNullException("key")) end local value = this[key] if value == nil then return false, this.__genericTValue__:default() end if value == null then return true end return true, value end, getComparer = function (this) return EqualityComparer(this.__genericTKey__).getDefault() end, getCount = getCount, get = function (this, key) if key == nil then throw(ArgumentNullException("key")) end local value = this[key] if value == nil then throw(KeyNotFoundException()) end if value ~= null then return value end return nil end, set = function (this, key, value) if key == nil then throw(ArgumentNullException("key")) end local t = counts[this] if t then if this[key] == nil then t[1] = t[1] + 1 end t[2] = t[2] + 1 else counts[this] = { 1, 1 } end this[key] = value == nil and null or value end, GetEnumerator = dictionaryEnumerator, getKeys = function (this) return DictionaryCollection(this.__genericTKey__)(this, 1) end, getValues = function (this) return DictionaryCollection(this.__genericTValue__)(this, 2) end } local ArrayDictionaryEnumerator = define("System.Collections.Generic.ArrayDictionaryEnumerator", function (T) return { base = { System.IEnumerator_1(T) } } end, { getCurrent = System.getCurrent, Dispose = System.emptyFn, MoveNext = function (this) local t = this.list if this.version ~= versions[t] then throwFailedVersion() end local index = this.index local pair = t[index] if pair ~= nil then if t.kind then this.current = pair.Value else this.current = pair.Key end this.index = index + 1 return true end this.current = nil return false end }) local arrayDictionaryEnumerator = function (t, kind, T) return setmetatable({ list = t, kind = kind, index = 1, version = versions[t], currnet = T:default() }, ArrayDictionaryEnumerator(T)) end local ArrayDictionaryCollection = define("System.Collections.Generic.ArrayDictionaryCollection", function (T) return { base = { System.ICollection_1(T), System.IReadOnlyCollection_1(T), System.ICollection }, __genericT__ = T } end, { __ctor__ = function (this, dict, kind) this.dict = dict this.kind = kind end, getCount = function (this) return getCount(this.dict) end, GetEnumerator = function (this) return arrayDictionaryEnumerator(this.dict, this.kind, this.__genericT__) end }) local ArrayDictionary = (function () local function buildFromDictionary(this, dictionary) if dictionary == nil then throw(ArgumentNullException("dictionary")) end local count = 1 local KeyValuePair = this.__genericT__ for _, pair in each(dictionary) do local k, v = pair.Key, pair.Value if type(k) == "table" and k.class == 'S' then k = k:__clone__() end this[count] = setmetatable({ Key = k, Value = v }, KeyValuePair) count = count + 1 end end local function add(this, key, value, set) if key == nil then throw(ArgumentNullException("key")) end local len = #this if len > 0 then local comparer = this.comparer local equals = comparer.EqualsOf for i = 1, len do if equals(comparer, this[i].Key, key) then if set then this[i].Value = value return else throw(ArgumentException("key already exists")) end end end end this[len + 1] = setmetatable({ Key = key, Value = value }, this.__genericT__) versions[this] = (versions[this] or 0) + 1 end local function remove(this, key) if key == nil then throw(ArgumentNullException("key")) end local len = #this if len > 0 then local comparer = this.comparer local equals = comparer.EqualsOf for i = 1, len do if equals(comparer, this[i].Key, key) then tremove(this, i) versions[this] = (versions[this] or 0) + 1 return true end end end return false end return { getIsFixedSize = falseFn, getIsReadOnly = falseFn, __ctor__ = function (this, ...) local Comparer local n = select("#", ...) if n == 0 then elseif n == 1 then local comparer = ... if comparer == nil or type(comparer) == "number" then else local equals = comparer.EqualsOf if equals == nil then buildFromDictionary(this, comparer) else Comparer = comparer end end else local dictionary, comparer = ... if type(dictionary) ~= "number" then buildFromDictionary(this, dictionary) end Comparer = comparer end this.comparer = Comparer or EqualityComparer(this.__genericTKey__).getDefault() end, AddKeyValue = add, Add = function (this, ...) local k, v if select("#", ...) == 1 then local pair = ... k, v = pair.Key, pair.Value else k, v = ... end add(this, k ,v) end, Clear = Array.clear, ContainsKey = function (this, key) if key == nil then throw(ArgumentNullException("key")) end local len = #this if len > 0 then local comparer = this.comparer local equals = comparer.EqualsOf for i = 1, len do if equals(comparer, this[i].Key, key) then return true end end end return false end, ContainsValue = function (this, value) local len = #this if len > 0 then local comparer = EqualityComparer(this.__genericTValue__).getDefault() local equals = comparer.EqualsOf for i = 1, #this do if equals(comparer, value, this[i].Value) then return true end end end return false end, Contains = function (this, pair) local key = pair.Key if key == nil then throw(ArgumentNullException("key")) end local len = #this if len > 0 then local comparer = this.comparer local equals = comparer.EqualsOf for i = 1, len do local t = this[i] if equals(comparer, t.Key, key) then local comparer = EqualityComparer(this.__genericTValue__).getDefault() if comparer:EqualsOf(t.Value, pair.Value) then return true end end end end return false end, CopyTo = function (this, array, index) local count = #this checkIndexAndCount(array, index, count) if count > 0 then local KeyValuePair = this.__genericT__ index = index + 1 for i = 1, count do local t = this[i] array[index] = setmetatable({ Key = t.Key:__clone__(), Value = t.Value }, KeyValuePair) index = index + 1 end end end, RemoveKey = remove, Remove = function (this, key) if isKeyValuePair(key) then local len = #this local k, v = key.Key, key.Value for i = 1, #this do local pair = this[i] if pair.Key:EqualsObj(k) then local comparer = EqualityComparer(this.__genericTValue__).getDefault() if comparer:EqualsOf(pair.Value, v) then tremove(this, i) return true end end end end return false end, TryGetValue = function (this, key) if key == nil then throw(ArgumentNullException("key")) end local len = #this if len > 0 then local comparer = this.comparer local equals = comparer.EqualsOf for i = 1, len do local pair = this[i] if equals(comparer, pair.Key, key) then return true, pair.Value end end end return false, this.__genericTValue__:default() end, getComparer = function (this) return this.comparer end, getCount = lengthFn, get = function (this, key) if key == nil then throw(ArgumentNullException("key")) end local len = #this if len > 0 then local comparer = this.comparer local equals = comparer.EqualsOf for i = 1, len do local pair = this[i] if equals(comparer, pair.Key, key) then return pair.Value end end end throw(KeyNotFoundException()) end, set = function (this, key, value) add(this, key, value, true) end, GetEnumerator = Array.GetEnumerator, getKeys = function (this) return ArrayDictionaryCollection(this.__genericTKey__)(this) end, getValues = function (this) return ArrayDictionaryCollection(this.__genericTValue__)(this, true) end } end)() ArrayDictionaryFn = define("System.Collections.Generic.ArrayDictionary", function(TKey, TValue) return { base = { System.IDictionary_2(TKey, TValue), System.IDictionary, System.IReadOnlyDictionary_2(TKey, TValue) }, __genericT__ = KeyValuePairFn(TKey, TValue), __genericTKey__ = TKey, __genericTValue__ = TValue, } end, ArrayDictionary) function System.dictionaryFromTable(t, TKey, TValue) return setmetatable(t, Dictionary(TKey, TValue)) end function System.isDictLike(t) return type(t) == "table" and t.GetEnumerator == dictionaryEnumerator end local DictionaryFn = define("System.Collections.Generic.Dictionary", function(TKey, TValue) local array, len if TKey.class == 'S' and type(TKey:default()) == "table" then array = ArrayDictionary else len = getCount end return { base = { System.IDictionary_2(TKey, TValue), System.IDictionary, System.IReadOnlyDictionary_2(TKey, TValue) }, __genericT__ = KeyValuePairFn(TKey, TValue), __genericTKey__ = TKey, __genericTValue__ = TValue, __len = len }, array end, Dictionary) System.Dictionary = DictionaryFn local Object = System.Object System.Hashtable = DictionaryFn(Object, Object) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Dictionary.lua.meta ================================================ fileFormatVersion: 2 guid: 625aaca11aa54a741a84ecf3084a47ad timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/EqualityComparer.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local equalsObj = System.equalsObj local compareObj = System.compareObj local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local type = type local EqualityComparer EqualityComparer = define("System.EqualityComparer", function (T) local equals local Equals = T.Equals if Equals then if T.class == 'S' then equals = Equals else equals = function (x, y) return x:Equals(y) end end else equals = equalsObj end local function getHashCode(x) if type(x) == "table" then return x:GetHashCode() end return x end local defaultComparer return { __genericT__ = T, base = { System.IEqualityComparer_1(T), System.IEqualityComparer }, getDefault = function () local comparer = defaultComparer if comparer == nil then comparer = EqualityComparer(T)() defaultComparer = comparer end return comparer end, EqualsOf = function (this, x, y) if x ~= nil then if y ~= nil then return equals(x, y) end return false end if y ~= nil then return false end return true end, GetHashCodeOf = function (this, obj) if obj == nil then return 0 end return getHashCode(obj) end, GetHashCodeObjOf = function (this, obj) if obj == nil then return 0 end if System.is(obj, T) then return getHashCode(obj) end throw(ArgumentException("Type of argument is not compatible with the generic comparer.")) return false end, EqualsObjOf = function (this, x, y) if x == y then return true end if x == nil or y == nil then return false end local is = System.is if is(x, T) and is(y, T) then return equals(x, y) end throw(ArgumentException("Type of argument is not compatible with the generic comparer.")) return false end } end) local function compare(this, a, b) return compareObj(a, b) end define("System.Comparer", (function () local Comparer Comparer = { base = { System.IComparer }, static = function (this) local default = Comparer() this.Default = default this.DefaultInvariant = default end, Compare = compare } return Comparer end)()) local Comparer, ComparisonComparer ComparisonComparer = define("System.ComparisonComparer", function (T) return { base = { Comparer(T) }, __ctor__ = function (this, comparison) this.comparison = comparison end, Compare = function (this, x, y) return this.comparison(x, y) end } end) Comparer = define("System.Comparer_1", function (T) local Compare local compareTo = T.CompareTo if compareTo then if T.class ~= 'S' then compareTo = function (x, y) return x:CompareTo(y) end end Compare = function (this, x, y) if x ~= nil then if y ~= nil then return compareTo(x, y) end return 1 end if y ~= nil then return -1 end return 0 end else Compare = compare end local defaultComparer local function getDefault() local comparer = defaultComparer if comparer == nil then comparer = Comparer(T)() defaultComparer = comparer end return comparer end local function Create(comparison) if comparison == nil then throw(ArgumentNullException("comparison")) end return ComparisonComparer(T)(comparison) end return { __genericT__ = T, base = { System.IComparer_1(T), System.IComparer }, getDefault = getDefault, getDefaultInvariant = getDefault, Compare = Compare, Create = Create } end) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/EqualityComparer.lua.meta ================================================ fileFormatVersion: 2 guid: 19a630f833902d243b0634c66042bfb3 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/HashSet.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local each = System.each local Dictionary = System.Dictionary local wrap = System.wrap local unWrap = System.unWrap local getEnumerator = Dictionary.GetEnumerator local ArgumentNullException = System.ArgumentNullException local assert = assert local pairs = pairs local select = select local counts = System.counts local function build(this, collection, comparer) if comparer ~= nil then assert(false) end if collection == nil then throw(ArgumentNullException("collection")) end this:UnionWith(collection) end local function checkUniqueAndUnfoundElements(this, other, returnIfUnfound) if #this == 0 then local numElementsInOther = 0 for _, item in each(other) do numElementsInOther = numElementsInOther + 1 break end return 0, numElementsInOther end local set, uniqueCount, unfoundCount = {}, 0, 0 for _, item in each(other) do item = wrap(item) if this[item] ~= nil then if set[item] == nil then set[item] = true uniqueCount = uniqueCount + 1 end else unfoundCount = unfoundCount + 1 if returnIfUnfound then break end end end return uniqueCount, unfoundCount end local HashSet = { __ctor__ = function (this, ...) local len = select("#", ...) if len == 0 then elseif len == 1 then local collection = ... if collection == nil then return end if collection.getEnumerator ~= nil then build(this, collection, nil) else assert(true) end else build(this, ...) end end, Clear = Dictionary.Clear, getCount = Dictionary.getCount, getIsReadOnly = System.falseFn, Contains = function (this, item) item = wrap(item) return this[item] ~= nil end, Remove = function (this, item) item = wrap(item) if this[item] then this[item] = nil local t = counts[this] t[1] = t[1] - 1 t[2] = t[2] + 1 return true end return false end, GetEnumerator = function (this) return getEnumerator(this, 1) end, Add = function (this, v) v = wrap(v) if this[v] == nil then this[v] = true local t = counts[this] if t then t[1] = t[1] + 1 t[2] = t[2] + 1 else counts[this] = { 1, 1 } end return true end return false end, UnionWith = function (this, other) if other == nil then throw(ArgumentNullException("other")) end local count = 0 for _, v in each(collection) do v = wrap(v) if this[v] == nil then this[v] = true count = count + 1 end end if count > 0 then local t = counts[this] if t then t[1] = t[1] + count t[2] = t[2] + 1 else counts[this] = { count, 1 } end end end, IntersectWith = function (this, other) if other == nil then throw(ArgumentNullException("other")) end local set = {} for _, v in each(other) do v = wrap(v) if this[v] ~= nil then set[v] = true end end local count = 0 for v, _ in pairs(this) do if set[v] == nil then this[v] = nil count = count + 1 end end if count > 0 then local t = counts[this] t[1] = t[1] - count t[2] = t[2] + 1 end end, ExceptWith = function (this, other) if other == nil then throw(ArgumentNullException("other")) end if other == this then this:Clear() return end local count = 0 for _, v in each(other) do v = wrap(v) if this[v] ~= nil then this[v] = nil count = count + 1 end end if count > 0 then local t = counts[this] t[1] = t[1] - count t[2] = t[2] + 1 end end, SymmetricExceptWith = function (this, other) if other == nil then throw(ArgumentNullException("other")) end if other == this then this:Clear() return end local set = {} local count = 0 local changed = false for _, v in each(other) do v = wrap(v) if this[v] == nil then this[v] = true count = count + 1 changed = true set[v] = true elseif set[v] == nil then this[v] = nil count = count - 1 changed = true end end if changed then local t = counts[this] if t then t[1] = t[1] + count t[2] = t[2] + 1 else counts[this] = { count, 1 } end end end, IsSubsetOf = function (this, other) if other == nil then throw(ArgumentNullException("other")) end local count = #this if count == 0 then return true end local uniqueCount, unfoundCount = checkUniqueAndUnfoundElements(this, other, false) return uniqueCount == count and unfoundCount >= 0 end, IsProperSubsetOf = function (this, other) if other == nil then throw(ArgumentNullException("other")) end local uniqueCount, unfoundCount = checkUniqueAndUnfoundElements(this, other, false) return uniqueCount == #this and unfoundCount > 0 end, IsSupersetOf = function (this, other) if other == nil then throw(ArgumentNullException("other")) end for _, element in each(other) do element = wrap(element) if this[element] == nil then return false end end return true end, IsProperSupersetOf = function (this, other) if other == nil then throw(ArgumentNullException("other")) end local count = #this if count == 0 then return false end local uniqueCount, unfoundCount = checkUniqueAndUnfoundElements(this, other, true) return uniqueCount < count and unfoundCount == 0 end, Overlaps = function (this, other) if other == nil then throw(ArgumentNullException("other")) end if #this == 0 then return false end for _, element in each(other) do element = wrap(element) if this[element] ~= nil then return true end end return false end, SetEquals = function (this, other) if other == nil then throw(ArgumentNullException("other")) end local uniqueCount, unfoundCount = checkUniqueAndUnfoundElements(this, other, true) return uniqueCount == #this and unfoundCount == 0 end, RemoveWhere = function (this, match) if match == nil then throw(ArgumentNullException("match")) end local numRemoved = 0 for v, _ in pairs(this) do if match(unWrap(v)) then this[v] = nil numRemoved = numRemoved + 1 end end if numRemoved > 0 then local t = counts[this] t[1] = t[1] - numRemoved t[2] = t[2] + 1 end return numRemoved end, TrimExcess = System.emptyFn } function System.hashSetFromTable(t, T) return setmetatable(t, HashSet(T)) end System.HashSet = System.define("System.Collections.Generic.HashSet", function(T) return { base = { System.ICollection_1(T), System.ISet_1(T) }, __genericT__ = T, __genericTKey__ = T, __len = HashSet.getCount } end, HashSet) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/HashSet.lua.meta ================================================ fileFormatVersion: 2 guid: f3fa2f69bd6bf7e498359d7ab15251af timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/LinkedList.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local each = System.each local checkIndexAndCount = System.checkIndexAndCount local ArgumentNullException = System.ArgumentNullException local InvalidOperationException = System.InvalidOperationException local EqualityComparer = System.EqualityComparer local setmetatable = setmetatable local select = select local LinkedListNode = define("System.Collections.Generic.LinkedListNode", { __ctor__ = function (this, value) this.Value = value end, getNext = function (this) local next = this.next if next == nil or next == this.List.head then return nil end return next end, getPrevious = function (this) local prev = this.prev if prev == nil or this == this.List.head then return nil end return prev end }) System.LinkedListNode = LinkedListNode local function newLinkedListNode(list, value) return setmetatable({ List = assert(list), Value = value }, LinkedListNode) end local function vaildateNewNode(this, node) if node == nil then throw(ArgumentNullException("node")) end if node.List ~= nil then throw(InvalidOperationException("ExternalLinkedListNode")) end end local function vaildateNode(this, node) if node == nil then throw(ArgumentNullException("node")) end if node.List ~= this then throw(InvalidOperationException("ExternalLinkedListNode")) end end local function insertNodeBefore(this, node, newNode) newNode.next = node newNode.prev = node.prev node.prev.next = newNode node.prev = newNode this.Count = this.Count + 1 this.version = this.version + 1 end local function insertNodeToEmptyList(this, newNode) newNode.next = newNode newNode.prev = newNode this.head = newNode this.Count = this.Count + 1 this.version = this.version + 1 end local function invalidate(this) this.List = nil this.next = nil this.prev = nil end local function remvoeNode(this, node) if node.next == node then this.head = nil else node.next.prev = node.prev node.prev.next = node.next if this.head == node then this.head = node.next end end invalidate(node) this.Count = this.Count - 1 this.version = this.version + 1 end local LinkedListEnumerator = { __index = false, getCurrent = System.getCurrent, Dispose = System.emptyFn, MoveNext = function (this) local list = this.list local node = this.node if this.version ~= list.version then System.throwFailedVersion() end if node == nil then return false end this.current = node.Value node = node.next if node == list.head then node = nil end this.node = node return true end } LinkedListEnumerator.__index = LinkedListEnumerator local LinkedList = { Count = 0, version = 0, __ctor__ = function (this, ...) local len = select("#", ...) if len == 1 then local collection = ... if collection == nil then throw(ArgumentNullException("collection")) end for _, item in each(collection) do this:AddLast(item) end end end, getCount = function (this) return this.Count end, getFirst = function(this) return this.head end, getLast = function (this) local head = this.head return head ~= nil and head.prev or nil end, AddAfterNode = function (this, node, newNode) vaildateNode(this, node) vaildateNewNode(this, newNode) insertNodeBefore(this, node.next, newNode) newNode.List = this end, AddAfter = function (this, node, value) vaildateNode(this, node) local result = newLinkedListNode(node.List, value) insertNodeBefore(this, node.next, result) return result end, AddBeforeNode = function (this, node, newNode) vaildateNode(this, node) vaildateNewNode(this, newNode) insertNodeBefore(this, node, newNode) newNode.List = this if node == this.head then this.head = newNode end end, AddBefore = function (this, node, value) vaildateNode(this, node) local result = newLinkedListNode(node.List, value) insertNodeBefore(this, node, result) if node == this.head then this.head = result end return result end, AddFirstNode = function (this, node) vaildateNewNode(this, node) if this.head == nil then insertNodeToEmptyList(this, node) else insertNodeBefore(this, this.head, node) this.head = node end node.List = this end, AddFirst = function (this, value) local result = newLinkedListNode(this, value) if this.head == nil then insertNodeToEmptyList(this, result) else insertNodeBefore(this, this.head, result) this.head = result end return result end, AddLastNode = function (this, node) vaildateNewNode(this, node) if this.head == nil then insertNodeToEmptyList(this, node) else insertNodeBefore(this, this.head, node) end node.List = this end, AddLast = function (this, value) local result = newLinkedListNode(this, value) if this.head == nil then insertNodeToEmptyList(this, result) else insertNodeBefore(this, this.head, result) end return result end, Clear = function (this) local current = this.head while current ~= nil do local temp = current current = current.next invalidate(temp) end this.head = nil this.Count = 0 this.version = this.version + 1 end, Contains = function (this, value) return this:Find(value) ~= nil end, CopyTo = function (this, array, index) checkIndexAndCount(array, index, this.Count) local head = this.head local node = head if node then index = index + 1 repeat local value = node.Value if value == nil then value = System.null end array[index] = value index = index + 1 node = node.next until node == head end end, Find = function (this, value) local head = this.head local node = head local comparer = EqualityComparer(this.__genericT__).getDefault() local equals = comparer.EqualsOf if node ~= nil then if value ~= nil then repeat if equals(comparer, node.Value, value) then return node end node = node.next until node == head else repeat if node.Value == nil then return node end node = node.next until node == head end end return nil end, FindLast = function (this, value) local head = this.head if head == nil then return nil end local last = head.prev local node = last local comparer = EqualityComparer(this.__genericT__).getDefault() local equals = comparer.EqualsOf if node ~= nil then if value ~= nil then repeat if equals(comparer, node.Value, value) then return node end node = node.prev until node == last else repeat if node.Value == nil then return node end node = node.prev until node == last end end return nil end, RemoveNode = function (this, node) vaildateNode(this, node) remvoeNode(this, node) end, Remove = function (this, node) node = this:Find(node) if node ~= nil then remvoeNode(this, node) end return false end, RemoveFirst = function (this) local head = this.head if head == nil then throw(InvalidOperationException("LinkedListEmpty")) end remvoeNode(this, head) end, RemoveLast = function (this) local head = this.head if head == nil then throw(InvalidOperationException("LinkedListEmpty")) end remvoeNode(this, head.prev) end, GetEnumerator = function (this) return setmetatable({ list = this, version = this.version, node = this.head }, LinkedListEnumerator) end } function System.linkedListFromTable(t, T) return setmetatable(t, LinkedList(T)) end System.LinkedList = define("System.Collections.Generic.LinkedList", function(T) return { base = { System.ICollection_1(T), System.ICollection }, __genericT__ = T, __len = LinkedList.getCount } end, LinkedList) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/LinkedList.lua.meta ================================================ fileFormatVersion: 2 guid: 75ca5de6d7b98f747a64607ed526171e timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Linq.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local each = System.each local identityFn = System.identityFn local wrap = System.wrap local unWrap = System.unWrap local is = System.is local cast = System.cast local Int32 = System.Int32 local isArrayLike = System.isArrayLike local isDictLike = System.isDictLike local Array = System.Array local arrayEnumerator = Array.GetEnumerator local NullReferenceException = System.NullReferenceException local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local InvalidOperationException = System.InvalidOperationException local EqualityComparer = System.EqualityComparer local Comparer_1 = System.Comparer_1 local Empty = System.Array.Empty local IEnumerable_1 = System.IEnumerable_1 local IEnumerable = System.IEnumerable local IEnumerator_1 = System.IEnumerator_1 local IEnumerator = System.IEnumerator local assert = assert local getmetatable = getmetatable local setmetatable = setmetatable local select = select local pairs = pairs local tsort = table.sort local InternalEnumerable = define("System.Linq.InternalEnumerable", function(T) return { base = { IEnumerable_1(T) } } end) local function createEnumerable(T, GetEnumerator) assert(T) return setmetatable({ __genericT__ = T, GetEnumerator = GetEnumerator }, InternalEnumerable(T)) end local InternalEnumerator = define("System.Linq.InternalEnumerator", function(T) return { base = { IEnumerator_1(T) } } end) local function createEnumerator(T, source, tryGetNext, init) assert(T) local state = 1 local current local en return setmetatable({ MoveNext = function() if state == 1 then state = 2 if source then en = source:GetEnumerator() end if init then init(en) end end if state == 2 then local ok, v = tryGetNext(en) if ok then current = v return true elseif en then local dispose = en.Dispose if dispose then dispose(en) end end end return false end, getCurrent = function() return current end }, InternalEnumerator(T)) end local Enumerable = {} define("System.Linq.Enumerable", Enumerable) function Enumerable.Where(source, predicate) if source == nil then throw(ArgumentNullException("source")) end if predicate == nil then throw(ArgumentNullException("predicate")) end local T = source.__genericT__ return createEnumerable(T, function() local index = -1 return createEnumerator(T, source, function(en) while en:MoveNext() do local current = en:getCurrent() index = index + 1 if predicate(current, index) then return true, current end end return false end) end) end function Enumerable.Select(source, selector, T) if source == nil then throw(ArgumentNullException("source")) end if selector == nil then throw(ArgumentNullException("selector")) end return createEnumerable(T, function() local index = -1 return createEnumerator(T, source, function(en) if en:MoveNext() then index = index + 1 return true, selector(en:getCurrent(), index) end return false end) end) end local function selectMany(source, collectionSelector, resultSelector, T) if source == nil then throw(ArgumentNullException("source")) end if collectionSelector == nil then throw(ArgumentNullException("collectionSelector")) end if resultSelector == nil then throw(ArgumentNullException("resultSelector")) end return createEnumerable(T, function() local element, midEn local index = -1 return createEnumerator(T, source, function(en) while true do if midEn and midEn:MoveNext() then return true, resultSelector(element, midEn:getCurrent()) else if not en:MoveNext() then return false end index = index + 1 local current = en:getCurrent() midEn = collectionSelector(current, index):GetEnumerator() if midEn == nil then throw(NullReferenceException()) end element = current end end end) end) end local function identityFnOfSelectMany(s, x) return x end function Enumerable.SelectMany(source, ...) local len = select("#", ...) if len == 2 then local collectionSelector, T = ... return selectMany(source, collectionSelector, identityFnOfSelectMany, T) else return selectMany(source, ...) end end function Enumerable.Take(source, count) if source == nil then throw(ArgumentNullException("source")) end local T = source.__genericT__ return createEnumerable(T, function() return createEnumerator(T, source, function(en) if count > 0 then if en:MoveNext() then count = count - 1 return true, en:getCurrent() end end return false end) end) end function Enumerable.TakeWhile(source, predicate) if source == nil then throw(ArgumentNullException("source")) end if predicate == nil then throw(ArgumentNullException("predicate")) end local T = source.__genericT__ return createEnumerable(T, function() local index = -1 return createEnumerator(T, source, function(en) if en:MoveNext() then local current = en:getCurrent() index = index + 1 if not predicate(current, index) then return false end return true, current end return false end) end) end function Enumerable.Skip(source, count) if source == nil then throw(ArgumentNullException("source")) end local T = source.__genericT__ return createEnumerable(T, function() return createEnumerator(T, source, function(en) while count > 0 and en:MoveNext() do count = count - 1 end if count <= 0 then if en:MoveNext() then return true, en:getCurrent() end end return false end) end) end function Enumerable.SkipWhile(source, predicate) if source == nil then throw(ArgumentNullException("source")) end if predicate == nil then throw(ArgumentNullException("predicate")) end local T = source.__genericT__ return createEnumerable(T, function() local index = -1 local isSkipEnd = false return createEnumerator(T, source, function(en) while not isSkipEnd do if en:MoveNext() then local current = en:getCurrent() index = index + 1 if not predicate(current, index) then isSkipEnd = true return true, current end else return false end end if en:MoveNext() then return true, en:getCurrent() end return false end) end) end local IGrouping = System.defInf("System.Linq.IGrouping_2", function (TKey, TElement) return { base = { IEnumerable_1(TElement) } } end) local Grouping = define("System.Linq.Grouping", function (TKey, TElement) return { __genericT__ = TElement, base = { IGrouping(TKey, TElement) }, GetEnumerator = arrayEnumerator, getKey = function (this) return this.key end, getCount = function (this) return #this end } end) local function getGrouping(this, key) local hashCode = this.comparer:GetHashCodeOf(key) local groupIndex = this.indexs[hashCode] return this.groups[groupIndex] end local Lookup = { __ctor__ = function (this, comparer) this.comparer = comparer or EqualityComparer(this.__genericTKey__).getDefault() this.groups = {} this.indexs = {} end, get = function (this, key) local grouping = getGrouping(this, key) if grouping ~= nil then return grouping end return Empty(this.__genericTElement__) end, GetCount = function (this) return #this.groups end, Contains = function (this, key) return getGrouping(this, key) ~= nil end, GetEnumerator = function (this) return arrayEnumerator(this.groups, IGrouping) end } local LookupFn = define("System.Linq.Lookup", function(TKey, TElement) local cls = { __genericTKey__ = TKey, __genericTElement__ = TElement, } return cls end, Lookup) local function addToLookup(this, key, value) local hashCode = this.comparer:GetHashCodeOf(key) local groupIndex = this.indexs[hashCode] local group if groupIndex == nil then groupIndex = #this.groups + 1 this.indexs[hashCode] = groupIndex group = setmetatable({ key = key }, Grouping(this.__genericTKey__, this.__genericTElement__)) this.groups[groupIndex] = group else group = this.groups[groupIndex] assert(group) end group[#group + 1] = wrap(value) end local function createLookup(source, keySelector, elementSelector, comparer, TKey, TElement) local lookup = LookupFn(TKey, TElement)(comparer) for _, item in each(source) do addToLookup(lookup, keySelector(item), elementSelector(item)) end return lookup end local function createLookupForJoin(source, keySelector, comparer, TKey, TElement) local lookup = LookupFn(TKey, TElement)(comparer) for _, item in each(source) do local key = keySelector(item) if key ~= nil then addToLookup(lookup, key, item) end end return lookup end function Enumerable.Join(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, TKey, TResult) if outer == nil then throw(ArgumentNullException("outer")) end if inner == nil then throw(ArgumentNullException("inner")) end if outerKeySelector == nil then throw(ArgumentNullException("outerKeySelector")) end if innerKeySelector == nil then throw(ArgumentNullException("innerKeySelector")) end if resultSelector == nil then throw(ArgumentNullException("resultSelector")) end local lookup = createLookupForJoin(inner, innerKeySelector, comparer, TKey, inner.__genericT__) return createEnumerable(TResult, function () local item, grouping, index return createEnumerator(TResult, outer, function (en) while true do if grouping ~= nil then index = index + 1 if index < #grouping then return true, resultSelector(item, unWrap(grouping[index + 1])) end end if not en:MoveNext() then return false end local current = en:getCurrent() item = current grouping = getGrouping(lookup, outerKeySelector(current)) index = -1 end end) end) end function Enumerable.GroupJoin(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer, TKey, TResult) if outer == nil then throw(ArgumentNullException("outer")) end if inner == nil then throw(ArgumentNullException("inner")) end if outerKeySelector == nil then throw(ArgumentNullException("outerKeySelector")) end if innerKeySelector == nil then throw(ArgumentNullException("innerKeySelector")) end if resultSelector == nil then throw(ArgumentNullException("resultSelector")) end local lookup = createLookupForJoin(inner, innerKeySelector, comparer, TKey, inner.__genericT__) return createEnumerable(TResult, function () return createEnumerator(TResult, outer, function (en) if en:MoveNext() then local item = en:getCurrent() return true, resultSelector(item, lookup:get(outerKeySelector(item))) end return false end) end) end local function ordered(source, compare) local T = source.__genericT__ local orderedEnumerable = createEnumerable(T, function() local t = {} local index = 0 return createEnumerator(T, source, function() index = index + 1 local v = t[index] if v ~= nil then return true, unWrap(v) end return false end, function() local count = 1 if isDictLike(source) then for k, v in pairs(source) do t[count] = setmetatable({ Key = k, Value = v }, T) count = count + 1 end else for _, v in each(source) do t[count] = wrap(v) count = count + 1 end end if count > 1 then tsort(t, function(x, y) return compare(unWrap(x), unWrap(y)) < 0 end) end end) end) orderedEnumerable.source = source orderedEnumerable.compare = compare return orderedEnumerable end local function orderBy(source, keySelector, comparer, TKey, descending) if source == nil then throw(ArgumentNullException("source")) end if keySelector == nil then throw(ArgumentNullException("keySelector")) end if comparer == nil then comparer = Comparer_1(TKey).getDefault() end local keys = {} local function getKey(t) local k = keys[t] if k == nil then k = keySelector(t) keys[t] = k end return k end local c = comparer.Compare local compare if descending then compare = function(x, y) return -c(comparer, getKey(x), getKey(y)) end else compare = function(x, y) return c(comparer, getKey(x), getKey(y)) end end return ordered(source, compare) end function Enumerable.OrderBy(source, keySelector, comparer, TKey) return orderBy(source, keySelector, comparer, TKey, false) end function Enumerable.OrderByDescending(source, keySelector, comparer, TKey) return orderBy(source, keySelector, comparer, TKey, true) end local function thenBy(source, keySelector, comparer, TKey, descending) if source == nil then throw(ArgumentNullException("source")) end if keySelector == nil then throw(ArgumentNullException("keySelector")) end if comparer == nil then comparer = Comparer_1(TKey).getDefault() end local keys = {} local function getKey(t) local k = keys[t] if k == nil then k = keySelector(t) keys[t] = k end return k end local c = comparer.Compare local compare local parentSource, parentCompare = source.source, source.compare if descending then compare = function(x, y) local v = parentCompare(x, y) if v ~= 0 then return v else return -c(comparer, getKey(x), getKey(y)) end end else compare = function(x, y) local v = parentCompare(x, y) if v ~= 0 then return v else return c(comparer, getKey(x), getKey(y)) end end end return ordered(parentSource, compare) end function Enumerable.ThenBy(source, keySelector, comparer, TKey) return thenBy(source, keySelector, comparer, TKey, false) end function Enumerable.ThenByDescending(source, keySelector, comparer, TKey) return thenBy(source, keySelector, comparer, TKey, true) end local function groupBy(source, keySelector, elementSelector, comparer, TKey, TElement) if source == nil then throw(ArgumentNullException("source")) end if keySelector == nil then throw(ArgumentNullException("keySelector")) end if elementSelector == nil then throw(ArgumentNullException("elementSelector")) end return createEnumerable(IGrouping, function() return createLookup(source, keySelector, elementSelector, comparer, TKey, TElement):GetEnumerator() end) end function Enumerable.GroupBy(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) if len == 2 then local keySelector, TKey = ... return groupBy(source, keySelector, identityFn, nil, TKey, source.__genericT__) elseif len == 3 then local keySelector, comparer, TKey = ... return groupBy(source, keySelector, identityFn, comparer, TKey, source.__genericT__) elseif len == 4 then local keySelector, elementSelector, TKey, TElement = ... return groupBy(source, keySelector, elementSelector, nil, TKey, TElement) else return groupBy(source, ...) end end local function groupBySelect(source, keySelector, elementSelector, resultSelector, comparer, TKey, TElement, TResult) if source == nil then throw(ArgumentNullException("source")) end if keySelector == nil then throw(ArgumentNullException("keySelector")) end if elementSelector == nil then throw(ArgumentNullException("elementSelector")) end if resultSelector == nil then throw(ArgumentNullException("resultSelector")) end return createEnumerable(TResult, function() local lookup = createLookup(source, keySelector, elementSelector, comparer, TKey, TElement) return createEnumerator(TResult, lookup, function(en) if en:MoveNext() then local current = en:getCurrent() return resultSelector(current.key, current) end return false end) end) end function Enumerable.GroupBySelect(source, ...) local len = select("#", ...) if len == 4 then local keySelector, resultSelector, TKey, TResult = ... return groupBySelect(source, keySelector, identityFn, resultSelector, nil, TKey, source.__genericT__, TResult) elseif len == 5 then local keySelector, resultSelector, comparer, TKey, TResult = ... return groupBySelect(source, keySelector, identityFn, resultSelector, comparer, TKey, source.__genericT__, TResult) elseif len == 6 then local keySelector, elementSelector, resultSelector, TKey, TElement, TResult = ... return groupBySelect(source, keySelector, elementSelector, resultSelector, nil, TKey, TElement, TResult) else return groupBySelect(source, ...) end end function Enumerable.Concat(first, second) if first == nil then throw(ArgumentNullException("first")) end if second == nil then throw(ArgumentNullException("second")) end local T = first.__genericT__ return createEnumerable(T, function() local secondEn return createEnumerator(T, first, function(en) if secondEn == nil then if en:MoveNext() then return true, en:getCurrent() end secondEn = second:GetEnumerator() end if secondEn:MoveNext() then return true, secondEn:getCurrent() end return false end) end) end function Enumerable.Zip(first, second, resultSelector, TResult) if first == nil then throw(ArgumentNullException("first")) end if second == nil then throw(ArgumentNullException("second")) end if resultSelector == nil then throw(ArgumentNullException("resultSelector")) end return createEnumerable(TResult, function() local e2 return createEnumerator(TResult, first, function(e1) if e1:MoveNext() and e2:MoveNext() then return true, resultSelector(e1:getCurrent(), e2:getCurrent()) end end, function() e2 = second:GetEnumerator() end) end) end local function addToSet(set, v, getHashCode, comparer) local hashCode = getHashCode(comparer, v) if set[hashCode] == nil then set[hashCode] = true return true end return false end local function removeFromSet(set, v, getHashCode, comparer) local hashCode = getHashCode(comparer, v) if set[hashCode] ~= nil then set[hashCode] = nil return true end return false end local function getComparer(source, comparer) return comparer or EqualityComparer(source.__genericT__).getDefault() end function Enumerable.Distinct(source, comparer) if source == nil then throw(ArgumentNullException("source")) end local T = source.__genericT__ return createEnumerable(T, function() local set = {} comparer = getComparer(source, comparer) local getHashCode = comparer.GetHashCodeOf return createEnumerator(T, source, function(en) while en:MoveNext() do local current = en:getCurrent() if addToSet(set, current, getHashCode, comparer) then return true, current end end return false end) end) end function Enumerable.Union(first, second, comparer) if first == nil then throw(ArgumentNullException("first")) end if second == nil then throw(ArgumentNullException("second")) end local T = first.__genericT__ return createEnumerable(T, function() local set = {} comparer = getComparer(first, comparer) local getHashCode = comparer.GetHashCodeOf local secondEn return createEnumerator(T, first, function(en) if secondEn == nil then while en:MoveNext() do local current = en:getCurrent() if addToSet(set, current, getHashCode, comparer) then return true, current end end secondEn = second:GetEnumerator() end while secondEn:MoveNext() do local current = secondEn:getCurrent() if addToSet(set, current, getHashCode, comparer) then return true, current end end return false end) end) end function Enumerable.Intersect(first, second, comparer) if first == nil then throw(ArgumentNullException("first")) end if second == nil then throw(ArgumentNullException("second")) end local T = first.__genericT__ return createEnumerable(T, function() local set = {} comparer = getComparer(first, comparer) local getHashCode = comparer.GetHashCodeOf return createEnumerator(T, first, function(en) while en:MoveNext() do local current = en:getCurrent() if removeFromSet(set, current, getHashCode, comparer) then return true, current end end return false end, function() for _, v in each(second) do addToSet(set, v, getHashCode, comparer) end end) end) end function Enumerable.Except(first, second, comparer) if first == nil then throw(ArgumentNullException("first")) end if second == nil then throw(ArgumentNullException("second")) end local T = first.__genericT__ return createEnumerable(T, function() local set = {} comparer = getComparer(first, comparer) local getHashCode = comparer.GetHashCodeOf return createEnumerator(T, first, function(en) while en:MoveNext() do local current = en:getCurrent() if addToSet(set, current, getHashCode, comparer) then return true, current end end return false end, function() for _, v in each(second) do addToSet(set, v, getHashCode, comparer) end end) end) end function Enumerable.Reverse(source) if source == nil then throw(ArgumentNullException("source")) end local T = source.__genericT__ return createEnumerable(T, function() local t = {} local index return createEnumerator(T, nil, function() if index > 1 then index = index - 1 return true, t[index] end return false end, function() local count = 1 for _, v in each(source) do t[count] = v count = count + 1 end index = count end) end) end function Enumerable.SequenceEqual(first, second, comparer) if first == nil then throw(ArgumentNullException("first")) end if second == nil then throw(ArgumentNullException("second")) end comparer = getComparer(first, comparer) local equals = comparer.EqualsOf local e1 = first:GetEnumerator() local e2 = second:GetEnumerator() while e1:MoveNext() do if not(e2:MoveNext() and equals(comparer, e1:getCurrent(), e2:getCurrent())) then return false end end if e2:MoveNext() then return false end return true end Enumerable.ToArray = Array.toArray function Enumerable.ToList(source) return System.List(source.__genericT__)(source) end local function toDictionary(source, keySelector, elementSelector, comparer, TKey, TValue) if source == nil then throw(ArgumentNullException("source")) end if keySelector == nil then throw(ArgumentNullException("keySelector")) end if elementSelector == nil then throw(ArgumentNullException("elementSelector")) end local dict = System.Dictionary(TKey, TValue)(comparer) for _, v in each(source) do dict:Add(keySelector(v), elementSelector(v)) end return dict end function Enumerable.ToDictionary(source, ...) local len = select("#", ...) if len == 2 then local keySelector, TKey = ... return toDictionary(source, keySelector, identityFn, nil, TKey, source.__genericT__) elseif len == 3 then local keySelector, comparer, TKey = ... return toDictionary(source, keySelector, identityFn, comparer, TKey, source.__genericT__) elseif len == 4 then local keySelector, elementSelector, TKey, TElement = ... return toDictionary(source, keySelector, elementSelector, nil, TKey, TElement) else return toDictionary(source, ...) end end local function toLookup(source, keySelector, elementSelector, comparer, TKey, TElement ) if source == nil then throw(ArgumentNullException("source")) end if keySelector == nil then throw(ArgumentNullException("keySelector")) end if elementSelector == nil then throw(ArgumentNullException("elementSelector")) end return createLookup(source, keySelector, elementSelector, comparer, TKey, TElement) end function Enumerable.ToLookup(source, ...) local len = select("#", ...) if len == 2 then local keySelector, TKey = ... return toLookup(source, keySelector, identityFn, nil, TKey, source.__genericT__) elseif len == 3 then local keySelector, comparer, TKey = ... return toLookup(source, keySelector, identityFn, comparer, TKey, source.__genericT__) elseif len == 4 then local keySelector, elementSelector, TKey, TElement = ... return toLookup(source, keySelector, elementSelector, nil, TKey, TElement) else return toLookup(source, ...) end end function Enumerable.DefaultIfEmpty(source) if source == nil then throw(ArgumentNullException("source")) end local T = source.__genericT__ local state return createEnumerable(T, function() return createEnumerator(T, source, function(en) if not state then if en:MoveNext() then state = 1 return true, en:getCurrent() end state = 2 return true, T:default() elseif state == 1 then if en:MoveNext() then return true, en:getCurrent() end end return false end) end) end function Enumerable.OfType(source, T) if source == nil then throw(ArgumentNullException("source")) end return createEnumerable(T, function() return createEnumerator(T, source, function(en) while en:MoveNext() do local current = en:getCurrent() if is(current, T) then return true, current end end return false end) end) end function Enumerable.Cast(source, T) if source == nil then throw(ArgumentNullException("source")) end if is(source, IEnumerable_1(T)) then return source end return createEnumerable(T, function() return createEnumerator(T, source, function(en) if en:MoveNext() then return true, cast(T, en:getCurrent()) end return false end) end) end local function first(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) if len == 0 then if isArrayLike(source) then local count = #source if count > 0 then return true, unWrap(source[1]) end else local en = source:GetEnumerator() if en:MoveNext() then return true, en:getCurrent() end end return false, 0 else local predicate = ... if predicate == nil then throw(ArgumentNullException("predicate")) end for _, v in each(source) do if predicate(v) then return true, v end end return false, 1 end end function Enumerable.First(source, ...) local ok, result = first(source, ...) if ok then return result end if result == 0 then throw(InvalidOperationException("NoElements")) end throw(InvalidOperationException("NoMatch")) end function Enumerable.FirstOrDefault(source, ...) local ok, result = first(source, ...) return ok and result or source.__genericT__:default() end local function last(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) if len == 0 then if isArrayLike(source) then local count = #source if count > 0 then return true, unWrap(source[count]) end else local en = source:GetEnumerator() if en:MoveNext() then local result repeat result = en:getCurrent() until not en:MoveNext() return true, result end end return false, 0 else local predicate = ... if predicate == nil then throw(ArgumentNullException("predicate")) end local result, found for _, v in each(source) do if predicate(v) then result = v found = true end end if found then return true, result end return false, 1 end end function Enumerable.Last(source, ...) local ok, result = last(source, ...) if ok then return result end if result == 0 then throw(InvalidOperationException("NoElements")) end throw(InvalidOperationException("NoMatch")) end function Enumerable.LastOrDefault(source, ...) local ok, result = last(source, ...) return ok and result or source.__genericT__:default() end local function single(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) if len == 0 then if isArrayLike(source) then local count = #source if count == 0 then return false, 0 elseif count == 1 then return true, unWrap(source[1]) end else local en = source:GetEnumerator() if not en:MoveNext() then return false, 0 end local result = en:getCurrent() if not en:MoveNext() then return true, result end end return false, 1 else local predicate = ... if predicate == nil then throw(ArgumentNullException("predicate")) end local result, found for _, v in each(source) do if predicate(v) then result = v if found then return false, 1 end found = true end end if foun then return true, result end return false, 0 end end function Enumerable.Single(source, ...) local ok, result = single(source, ...) if ok then return result end if result == 0 then throw(InvalidOperationException("NoElements")) end throw(InvalidOperationException("MoreThanOneMatch")) end function Enumerable.SingleOrDefault(source, ...) local ok, result = single(source, ...) return ok and result or source.__genericT__:default() end local function elementAt(source, index) if source == nil then throw(ArgumentNullException("source")) end if index >= 0 then if isArrayLike(source) then local count = #source if index < count then return true, unWrap(source[index + 1]) end else local en = source:GetEnumerator() while true do if not en:MoveNext() then break end if index == 0 then return true, en:getCurrent() end index = index - 1 end end end return false end function Enumerable.ElementAt(source, index) local ok, result = elementAt(source, index) if ok then return result end throw(ArgumentOutOfRangeException("index")) end function Enumerable.ElementAtOrDefault(source, index) local ok, result = elementAt(source, index) return ok and result or source.__genericT__:default() end function Enumerable.Range(start, count) if count < 0 then throw(ArgumentOutOfRangeException("count")) end return createEnumerable(Int32, function() local index = -1 return createEnumerator(Int32, nil, function() index = index + 1 if index < count then return true, start + index end return false end) end) end function Enumerable.Repeat(element, count, T) if count < 0 then throw(ArgumentOutOfRangeException("count")) end return createEnumerable(T, function() local index = -1 return createEnumerator(T, nil, function() index = index + 1 if index < count then return true, element end return false end) end) end function Enumerable.Any(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) if len == 0 then local en = source:GetEnumerator() return en:MoveNext() else local predicate = ... if predicate == nil then throw(ArgumentNullException("predicate")) end for _, v in each(source) do if predicate(v) then return true end end return false end end function Enumerable.All(source, predicate) if source == nil then throw(ArgumentNullException("source")) end if predicate == nil then throw(ArgumentNullException("predicate")) end for _, v in each(source) do if not predicate(v) then return false end end return true end function Enumerable.Count(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) if len == 0 then if isArrayLike(source) then return #source end local count = 0 local en = source:GetEnumerator() while en:MoveNext() do count = count + 1 end return count else local predicate = ... if predicate == nil then throw(ArgumentNullException("predicate")) end local count = 0 for _, v in each(source) do if predicate(v) then count = count + 1 end end return count end end function Enumerable.Contains(source, value, comparer) if source == nil then throw(ArgumentNullException("source")) end comparer = getComparer(source, comparer) local equals = comparer.EqualsOf for _, v in each(source) do if equals(comparer, v, value) then return true end end return false end function Enumerable.Aggregate(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...); if len == 1 then local func = ... if func == nil then throw(ArgumentNullException("func")) end local e = source:GetEnumerator() if not e:MoveNext() then throw(InvalidOperationException("NoElements")) end local result = e:getCurrent() while e:MoveNext() do result = func(result, e:getCurrent()) end return result elseif len == 2 then local seed, func = ... if func == nil then throw(ArgumentNullException("func")) end local result = seed for _, element in each(source) do result = func(result, element) end return result else local seed, func, resultSelector = ... if func == nil then throw(ArgumentNullException("func")) end if resultSelector == nil then throw(ArgumentNullException("resultSelector")) end local result = seed for _, element in each(source) do result = func(result, element) end return resultSelector(result) end end function Enumerable.Sum(source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) if len == 0 then local sum = 0 for _, v in each(source) do sum = sum + v end return sum else local selector = ... if selector == nil then throw(ArgumentNullException("selector")) end local sum = 0 for _, v in each(source) do sum = sum + selector(v) end return sum end end local function minOrMax(compareFn, source, ...) if source == nil then throw(ArgumentNullException("source")) end local len = select("#", ...) local selector, T if len == 0 then selector, T = identityFn, source.__genericT__ else selector, T = ... if selector == nil then throw(ArgumentNullException("selector")) end end local comparer = Comparer_1(T).getDefault() local compare = comparer.Compare local value = T:default() if value == nil then for _, x in each(source) do x = selector(x) if x ~= nil and (value == nil or compareFn(compare, comparer, x, value)) then value = x end end return value else local hasValue = false for _, x in each(source) do x = selector(x) if hasValue then if compareFn(compare, comparer, x, value) then value = x end else value = x hasValue = true end end if hasValue then return value end throw(InvalidOperationException("NoElements")) end end local function minFn(compare, comparer, x, y) return compare(comparer, x, y) < 0 end function Enumerable.Min(source, ...) return minOrMax(minFn, source, ...) end local function maxFn(compare, comparer, x, y) return compare(comparer, x, y) > 0 end function Enumerable.Max(source, ...) return minOrMax(maxFn, source, ...) end function Enumerable.Average(source, ...) if source == nil then throw(ArgumentNullException("source")) end local sum, count = 0, 0 local len = select("#", ...) if len == 0 then for _, v in each(source) do sum = sum + v count = count + 1 end else local selector = ... if selector == nil then throw(ArgumentNullException("selector")) end for _, v in each(source) do sum = sum + selector(v) count = count + 1 end end if count > 0 then return sum / count end throw(InvalidOperationException("NoElements")) end ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Linq.lua.meta ================================================ fileFormatVersion: 2 guid: 406172d729eefcd42b2022990679be11 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/List.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local falseFn = System.falseFn local lengthFn = System.lengthFn local Array = System.Array local List = { __ctor__ = Array.ctorList, getCapacity = lengthFn, getCount = lengthFn, getIsFixedSize = falseFn, getIsReadOnly = falseFn, get = Array.get, set = Array.set, Add = Array.add, AddObj = Array.addObj, AddRange = Array.addRange, AsReadOnly = Array.AsReadOnly, BinarySearch = Array.BinarySearch, Clear = Array.clear, Contains = Array.Contains, CopyTo = Array.CopyTo, Exists = Array.Exists, Find = Array.Find, FindAll = Array.findAll, FindIndex = Array.FindIndex, FindLast = Array.FindLast, FindLastIndex = Array.FindLastIndex, ForEach = Array.ForEach, GetEnumerator = Array.GetEnumerator, GetRange = Array.getRange, IndexOf = Array.IndexOf, Insert = Array.insert, InsertRange = Array.insertRange, LastIndexOf = Array.LastIndexOf, Remove = Array.remove, RemoveAll = Array.removeAll, RemoveAt = Array.removeAt, RemoveRange = Array.removeRange, Reverse = Array.Reverse, Sort = Array.Sort, TrimExcess = System.emptyFn, ToArray = Array.toArray, TrueForAll = Array.TrueForAll } function System.listFromTable(t, T) return setmetatable(t, List(T)) end local ListFn = System.define("System.Collections.Generic.List", function(T) return { base = { System.IList_1(T), System.IReadOnlyList_1(T), System.IList }, __genericT__ = T, } end, List) System.List = ListFn System.ArrayList = ListFn(System.Object) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/List.lua.meta ================================================ fileFormatVersion: 2 guid: 7c865abfcba1c6446b184a2b82126f67 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Queue.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local Array = System.Array local function tryDequeue(this) if #this == 0 then return false end return true, this:Dequeue() end local Queue = { __ctor__ = Array.ctorList, getCount = Array.getLength, Clear = Array.clear, Contains = Array.Contains, CopyTo = Array.CopyTo, Dequeue = Array.popFirst, Enqueue = Array.add, GetEnumerator = Array.GetEnumerator, Peek = Array.first, ToArray = Array.toArray, TrimExcess = System.emptyFn, TryDequeue = tryDequeue } function System.queueFromTable(t, T) return setmetatable(t, Queue(T)) end local QueueFn = System.define("System.Collections.Generic.Queue", function(T) return { base = { System.IEnumerable_1(T), System.ICollection }, __genericT__ = T, } end, Queue) System.Queue = QueueFn System.queue = QueueFn(System.Object) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Queue.lua.meta ================================================ fileFormatVersion: 2 guid: 50f419f82317ada4ea81ad0a9e9f5d2d timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/SortedSet.lua ================================================ --[[ Copyright YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local SortedSet = { } ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/SortedSet.lua.meta ================================================ fileFormatVersion: 2 guid: cbb8de3cd60559c4a8569173e08c7914 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Stack.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local Array = System.Array local Stack = { __ctor__ = Array.ctorList, getCount = Array.getLength, Clear = Array.clear, Contains = Array.Contains, GetEnumerator = Array.reverseEnumerator, Push = Array.add, Peek = Array.last, Pop = Array.popLast, ToArray = Array.toArray, TrimExcess = System.emptyFn } function System.stackFromTable(t, T) return setmetatable(t, Stack(T)) end local StackFn = System.define("System.Collections.Generic.Stack", function(T) return { base = { System.IEnumerable_1(T), System.ICollection }, __genericT__ = T, } end, Stack) System.Stack = StackFn System.stack = StackFn(System.Object) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections/Stack.lua.meta ================================================ fileFormatVersion: 2 guid: 440302017e524d742a46d9347f06adbe timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Collections.meta ================================================ fileFormatVersion: 2 guid: 6c593174ea67b1c49a59b342c76fe211 folderAsset: yes timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Console.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local toString = System.toString local print = print local select = select local string = string local byte = string.byte local char = string.char local Format = string.Format local function getWriteValue(v, ...) if select("#", ...) ~= 0 then return Format(v, ...) end return toString(v) end local Console = System.define("System.Console", { WriteLine = function (v, ...) print(getWriteValue(v, ...)) end, WriteLineChar = function (v) print(char(v)) end }) local io = io if io then local stdin = io.stdin local stdout = io.stdout local read = stdin.read local write = stdout.write function Console.Read() local ch = read(stdin, 1) return byte(ch) end function Console.ReadLine() return read(stdin) end function Console.Write(v, ...) write(stdout, getWriteValue(v, ...)) end function Console.WriteChar(v) write(stdout, char(v)) end end ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Console.lua.meta ================================================ fileFormatVersion: 2 guid: 4fe1932f201910c4e908b248ec1cd570 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Convert.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local cast = System.cast local as = System.as local trunc = System.trunc local define = System.define local identityFn = System.identityFn local IConvertible = System.IConvertible local systemToString = System.toString local OverflowException = System.OverflowException local FormatException = System.FormatException local ArgumentException = System.ArgumentException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local ArgumentNullException = System.ArgumentNullException local InvalidCastException = System.InvalidCastException local SByte = System.SByte local Byte = System.Byte local Int16 = System.Int16 local UInt16 = System.UInt16 local Int32 = System.Int32 local UInt32 = System.UInt32 local Int64 = System.Int64 local UInt64 = System.UInt64 local Single = System.Single local Double = System.Double local Boolean = System.Boolean local Char = System.Char local DateTime = System.DateTime local String = System.String local Object = System.Object local ParseSByte = SByte.Parse local ParseByte = Byte.Parse local ParseInt16 = Int16.Parse local ParseUInt16 = UInt16.Parse local ParseInt32 = Int32.Parse local ParseUInt32 = UInt32.Parse local ParseInt64 = Int64.Parse local ParseUInt64 = UInt64.Parse local ParseSingle = Single.Parse local ParseDouble = Double.Parse local ParseBoolean = Boolean.Parse local type = type local string = string local sbyte = string.byte local math = math local floor = math.floor local tconcat = table.concat local getmetatable = getmetatable local tonumber = tonumber local function toBoolean(value) if value == nil then return false end local typename = type(value) if typename == "number" then return value ~= 0 elseif typename == "string" then return ParseBoolean(value) elseif typename == "boolean" then return value else return cast(IConvertible, value):ToBoolean() end end local function toChar(value) if value == nil then return 0 end local typename = type(value) if typename == "number" then if value ~= floor(value) or value > 9223372036854775807 or value < -9223372036854775808 then throw(InvalidCastException("InvalidCast_FromTo_Char")) end if value < 0 or value > 65535 then throw(OverflowException("Overflow_Char")) end return value elseif typename == "string" then if #value ~= 1 then throw(FormatException("Format_NeedSingleChar")) end return sbyte(value) else return cast(IConvertible, value):ToChar() end end local function parseBits(s, p, n) local i, j, v = s:find(p) if not i then throw(FormatException()) end v = tonumber(v) for i = j + 1, #s do local ch = sbyte(s, i) local b = ch - 48 if b < 0 or b >= n then if not s:find("^%s*$", i) then throw(FormatException()) end break end v = v * n + b end return v end local function parseNumberFromBase(value, fromBase, min, max) if fromBase == 2 then value = parseBits(value, "^%s*([01])", fromBase) elseif fromBase == 8 then value = parseBits(value, "^%s*([0-7])", fromBase) elseif fromBase == 16 then local _, _, v = value:find("^%s*(%w+)%s*$") if not v then throw(ArgumentException("String cannot contain a minus sign if the base is not 10.")) end local ch = sbyte(v, 2) if ch == 120 or ch == 88 then else v = "0x" .. v end value = tonumber(v) if value == nil then throw(FormatException()) end else throw(ArgumentException("fromBase")) end if max == 127 and value <= 255 then return System.toSByte(value) end if max == 32767 and value <= 65535 then return System.toInt16(value) end if max == 2147483647 and value <= 4294967295 then return System.toInt32(value) end if value < min or value > max then throw(OverflowException()) end return value end local function toNumber(value, min, max, parse, objectTo, sign) if value == nil then return 0 end local typename = type(value) if typename == "number" then if sign == false then value = System.ToSingle(value * 1.0) elseif sign == true then value = value * 1.0 else local i = value value = trunc(value) if value ~= i then local dif = i - value if value >= 0 then if dif > 0.5 or (dif == 0.5 and value % 2 ~= 0) then value = value + 1 end else if dif < -0.5 or (dif == -0.5 and value % 2 ~= 0) then value = value - 1 end end end if value < min or value > max then throw(OverflowException()) end end return value elseif typename == "string" then if sign and sign ~= 10 and type(sign) == "number" then return parseNumberFromBase(value, sign, min, max) end return parse(value) elseif typename == "boolean" then return value and 1 or 0 else return objectTo(value) end end local function objectToSByte(value) return cast(IConvertible, value):ToSByte() end local function toSByte(value, fromBase) return toNumber(value, -128, 127, ParseSByte, objectToSByte, fromBase) end local function objectToByte(value) return cast(IConvertible, value):ToByte() end local function toByte(value, fromBase) return toNumber(value, 0, 255, ParseByte, objectToByte, fromBase) end local function objectToInt16(value) return cast(IConvertible, value):ToInt16() end local function toInt16(value, fromBase) return toNumber(value, -32768, 32767, ParseInt16, objectToInt16, fromBase) end local function objectToUInt16(value) return cast(IConvertible, value):ToUInt16() end local function toUInt16(value, fromBase) return toNumber(value, 0, 65535, ParseUInt16, objectToUInt16, fromBase) end local function objectToInt32(value) return cast(IConvertible, value):ToInt32() end local function toInt32(value, fromBase) return toNumber(value, -2147483648, 2147483647, ParseInt32, objectToInt32, fromBase) end local function objectToUInt32(value) return cast(IConvertible, value):ToUInt32() end local function toUInt32(value, fromBase) return toNumber(value, 0, 4294967295, ParseUInt32, objectToUInt32, fromBase) end local function objectToInt64(value) return cast(IConvertible, value):ToInt64() end local function toInt64(value, fromBase) return toNumber(value, -9223372036854775808, 9223372036854775807, ParseInt64, objectToInt64, fromBase) end local function objectToUInt64(value) return cast(IConvertible, value):ToUInt64() end local function toUInt64(value, fromBase) return toNumber(value, 0, 18446744073709551615.0, ParseUInt64, objectToUInt64, fromBase) end local function objectToSingle(value) return cast(IConvertible, value):ToSingle() end local function toSingle(value) return toNumber(value, nil, nil, ParseSingle, objectToSingle, false) end local function objectToDouble(value) return cast(IConvertible, value):ToDouble() end local function toDouble(value) return toNumber(value, nil, nil, ParseDouble, objectToDouble, true) end local function toDateTime(value) if value == nil then return DateTime.MinValue end if getmetatable(value) == DateTime then return value end if type(value) == "string" then return DateTime.Parse(value) end return cast(IConvertible, value):ToDateTime() end local function toBaseType(ic, targetType) local cls = targetType[1] if cls == Boolean then return ic:ToBoolean() end if cls == Char then return ic:ToChar() end if cls == SByte then return ic:ToSByte() end if cls == Byte then return ic:ToByte() end if cls == Int16 then return ic:ToInt16() end if cls == UInt16 then return ic:ToUInt16() end if cls == Int32 then return ic:ToInt32() end if cls == UInt32 then return ic:ToUInt32() end if cls == Int64 then return ic:ToInt64() end if cls == UInt64 then return ic:ToUInt64() end if cls == Single then return ic:ToSingle() end if cls == Double then return ic:ToDouble() end if cls == DateTime then return ic:ToDateTime() end if cls == String then return ic:ToString() end if cls == Object then return value end end local function defaultToType(value, targetType) if targetType == nil then throw(ArgumentNullException("targetType")) end if value:GetType() == targetType then return value end local v = toBaseType(value, targetType) if v ~= nil then return v end throw(InvalidCastException()) end local function changeType(value, conversionType) if conversionType == nil then throw(ArgumentNullException("conversionType")) end if value == nil then if conversionType:getIsValueType() then throw(InvalidCastException("InvalidCast_CannotCastNullToValueType")) end return nil end local ic = as(value, IConvertible) if ic == nil then if value:GetType() == conversionType then return value end throw(InvalidCastException("InvalidCast_IConvertible")) end local v = toBaseType(ic, conversionType) if v ~= nil then return v end return ic.ToType(conversionType) end local function toBits(num, bits) -- returns a table of bits, most significant first. bits = bits or math.max(1, select(2, math.frexp(num))) local t = {} -- will contain the bits for b = bits, 1, -1 do local i = num % 2 t[b] = i num = System.div(num - i, 2) end if bits == 64 and t[1] == 0 then return tconcat(t, nil, 2, bits) end return tconcat(t) end local function toString(value, toBaseOrProvider, cast) if value == nil then return "" end if toBaseOrProvider then if type(toBaseOrProvider) == "number" then if toBaseOrProvider ~= 10 then if cast and value < 0 then value = cast(value) end end if toBaseOrProvider == 2 then return toBits(value) elseif toBaseOrProvider == 8 then return ("%o"):format(value) elseif toBaseOrProvider == 10 then return value .. "" elseif toBaseOrProvider == 16 then return ("%x"):format(value) else throw(ArgumentException()) end end end return systemToString(value) end define("System.Convert", { ToBoolean = toBoolean, ToChar = toChar, ToSByte = toSByte, ToByte = toByte, ToInt16 = toInt16, ToUInt16 = toUInt16, ToInt32 = toInt32, ToUInt32 = toUInt32, ToInt64 = toInt64, ToUInt64 = toUInt64, ToSingle = toSingle, ToDouble = toDouble, ToDateTime = toDateTime, ChangeType = changeType, ToString = toString, ToStringFromChar = string.char }) String.ToBoolean = toBoolean String.ToChar = toChar String.ToSByte = toSByte String.ToByte = toByte String.ToInt16 = toInt16 String.ToUInt16 = toUInt16 String.ToInt32 = toInt32 String.ToUInt32 = toUInt32 String.ToInt64 = toInt64 String.ToUInt64 = toUInt64 String.ToSingle = identityFn String.ToDouble = toDouble String.ToDateTime = toDateTime String.ToType = defaultToType local function throwInvalidCastException() throw(InvalidCastException()) end local Number = System.Number Number.ToBoolean = toBoolean Number.ToChar = toChar Number.ToSByte = toSByte Number.ToByte = toByte Number.ToInt16 = toInt16 Number.ToUInt16 = toUInt16 Number.ToInt32 = toInt32 Number.ToUInt32 = toUInt32 Number.ToInt64 = toInt64 Number.ToUInt64 = toUInt64 Number.ToSingle = toSingle Number.ToDouble = toDouble Number.ToDateTime = throwInvalidCastException Number.ToType = defaultToType Boolean.ToBoolean = identityFn Boolean.ToChar = throwInvalidCastException Boolean.ToSByte = toSByte Boolean.ToByte = toByte Boolean.ToInt16 = toInt16 Boolean.ToUInt16 = toUInt16 Boolean.ToInt32 = toInt32 Boolean.ToUInt32 = toUInt32 Boolean.ToInt64 = toInt64 Boolean.ToUInt64 = toUInt64 Boolean.ToSingle = toSingle Boolean.ToDouble = toDouble Boolean.ToDateTime = throwInvalidCastException Boolean.ToType = defaultToType DateTime.ToBoolean = throwInvalidCastException DateTime.ToChar = throwInvalidCastException DateTime.ToSByte = throwInvalidCastException DateTime.ToByte = throwInvalidCastException DateTime.ToInt16 = throwInvalidCastException DateTime.ToUInt16 = throwInvalidCastException DateTime.ToInt32 = throwInvalidCastException DateTime.ToUInt32 = throwInvalidCastException DateTime.ToInt64 = throwInvalidCastException DateTime.ToUInt64 = throwInvalidCastException DateTime.ToSingle = throwInvalidCastException DateTime.ToDouble = throwInvalidCastException DateTime.ToDateTime = identityFn DateTime.ToType = defaultToType -- BitConverter local band = System.band local bor = System.bor local sl = System.sl local sr = System.sr local div = System.div local global = System.global local systemToInt16 = System.toInt16 local systemToInt32 = System.toInt32 local systemToUInt64 = System.toUInt64 local arrayFromTable = System.arrayFromTable local NotSupportedException = System.NotSupportedException local assert = assert local rawget = rawget local unpack = table.unpack local schar = string.char -- https://github.com/ToxicFrog/vstruct/blob/master/io/endianness.lua#L30 local isLittleEndian = true if rawget(global, "jit") then if require("ffi").abi("be") then isLittleEndian = false end else local dump = string.dump if dump and sbyte(dump(System.emptyFn, 7)) == 0x00 then isLittleEndian = false end end local function bytes(t) return arrayFromTable(t, Byte) end local function checkIndex(value, startIndex, count) if value == nil then throw(ArgumentNullException("value")) end local len = #value if startIndex < 0 or startIndex >= len then throw(ArgumentOutOfRangeException("startIndex")) end if startIndex > len - count then throw(ArgumentException()) end end local spack, sunpack, getBytesFromInt64, toInt64 if System.luaVersion < 5.3 then local struct = rawget(global, "struct") if struct then spack, sunpack = struct.pack, struct.upack end if not spack then spack = function () throw(NotSupportedException("not found struct"), 1) end sunpack = spack end getBytesFromInt64 = function (value) if value <= -2147483647 or value >= 2147483647 then local s = spack("i8", value) return bytes({ sbyte(s, 1), sbyte(s, 2), sbyte(s, 3), sbyte(s, 4), sbyte(s, 5), sbyte(s, 6), sbyte(s, 7), sbyte(s, 8) }) end return bytes({ band(value, 0xff), band(sr(value, 8), 0xff), band(sr(value, 16), 0xff), band(sr(value, 24), 0xff), 0, 0, 0, 0 }) end toInt64 = function (value, startIndex) checkIndex(value, startIndex, 8) if value <= -2147483647 or value >= 2147483647 then throw(System.NotSupportedException()) end if isLittleEndian then local i = value[startIndex + 1] i = bor(i, sl(value[startIndex + 2], 8)) i = bor(i, sl(value[startIndex + 3], 16)) i = bor(i, sl(value[startIndex + 4], 24)) return i else local i = value[startIndex + 8] i = bor(i, sl(value[startIndex + 7], 8)) i = bor(i, sl(value[startIndex + 6], 16)) i = bor(i, sl(value[startIndex + 5], 24)) return i end end else spack, sunpack = string.pack, string.unpack getBytesFromInt64 = function (value) return bytes({ band(value, 0xff), band(sr(value, 8), 0xff), band(sr(value, 16), 0xff), band(sr(value, 24), 0xff), band(sr(value, 32), 0xff), band(sr(value, 40), 0xff), band(sr(value, 48), 0xff), band(sr(value, 56), 0xff) }) end toInt64 = function (value, startIndex) checkIndex(value, startIndex, 8) if isLittleEndian then local i = value[startIndex + 1] i = bor(i, sl(value[startIndex + 2], 8)) i = bor(i, sl(value[startIndex + 3], 16)) i = bor(i, sl(value[startIndex + 4], 24)) i = bor(i, sl(value[startIndex + 5], 32)) i = bor(i, sl(value[startIndex + 6], 40)) i = bor(i, sl(value[startIndex + 7], 48)) i = bor(i, sl(value[startIndex + 8], 56)) return i else local i = value[startIndex + 8] i = bor(i, sl(value[startIndex + 7], 8)) i = bor(i, sl(value[startIndex + 6], 16)) i = bor(i, sl(value[startIndex + 5], 24)) i = bor(i, sl(value[startIndex + 4], 32)) i = bor(i, sl(value[startIndex + 3], 40)) i = bor(i, sl(value[startIndex + 2], 48)) i = bor(i, sl(value[startIndex + 1], 56)) return i end end end local function getBytesFromBoolean(value) return bytes({ value and 1 or 0 }) end local function getBytesFromInt16(value) return bytes({ band(value, 0xff), band(sr(value, 8), 0xff), }) end local function getBytesFromInt32(value) return bytes({ band(value, 0xff), band(sr(value, 8), 0xff), band(sr(value, 16), 0xff), band(sr(value, 24), 0xff) }) end local function getBytesFromFloat(value) local s = spack("f", value) return bytes({ sbyte(s, 1), sbyte(s, 2), sbyte(s, 3), sbyte(s, 4) }) end local function getBytesFromDouble(value) local s = spack("d", value) return bytes({ sbyte(s, 1), sbyte(s, 2), sbyte(s, 3), sbyte(s, 4), sbyte(s, 5), sbyte(s, 6), sbyte(s, 7), sbyte(s, 8) }) end local function toBoolean(value, startIndex) checkIndex(value, startIndex, 1) return value[startIndex + 1] ~= 0 and true or false end local function toUInt16(value, startIndex) checkIndex(value, startIndex, 2) if isLittleEndian then value = bor(value[startIndex + 1], sl(value[startIndex + 2], 8)) else value = bor(sl(value[startIndex + 1], 8), value[startIndex + 2]) end return value end local function toInt16(value, startIndex) value = toUInt16(value, startIndex) return systemToInt16(value) end local function toUInt32(value, startIndex) checkIndex(value, startIndex, 4) local i if isLittleEndian then i = value[startIndex + 1] i = bor(i, sl(value[startIndex + 2], 8)) i = bor(i, sl(value[startIndex + 3], 16)) i = bor(i, sl(value[startIndex + 4], 24)) else local i = value[startIndex + 4] i = bor(i, sl(value[startIndex + 3], 8)) i = bor(i, sl(value[startIndex + 2], 16)) i = bor(i, sl(value[startIndex + 1], 24)) end return i end local function toInt32(value, startIndex) value = toUInt32(value, startIndex) return systemToInt32(value) end local function toUInt64(value, startIndex) value = toInt64(value, startIndex) return systemToUInt64(value) end local function toSingle(value, startIndex) checkIndex(value, startIndex, 4) return sunpack("f", schar(unpack(value, startIndex + 1))) end local function toDouble(value, startIndex) checkIndex(value, startIndex, 8) return sunpack("d", schar(unpack(value, startIndex + 1))) end local function getHexValue(i) assert(i >= 0 and i < 16, "i is out of range.") if i < 10 then return i + 48 end return i - 10 + 65 end local function toString(value, startIndex, length) if value == nil then throw(ArgumentNullException("value")) end local len = #value if not startIndex then startIndex, length = 0, #value elseif not length then length = len - startIndex end if startIndex < 0 or (startIndex >= len and startIndex > 0) then throw(ArgumentOutOfRangeException("startIndex")) end if length < 0 then throw(ArgumentOutOfRangeException("length")) end if startIndex + length > len then throw(ArgumentException()) end if length == 0 then return "" end local t = {} local len = 1 for i = startIndex + 1, startIndex + length do local b = value[i] t[len] = getHexValue(div(b, 16)) t[len + 1] = getHexValue(b % 16) t[len + 2] = 45 len = len + 3 end return schar(unpack(t, 1, len - 2)) end local function doubleToInt64Bits(value) assert(isLittleEndian, "This method is implemented assuming little endian with an ambiguous spec.") local s = spack("d", value) return (sunpack("i8", s)) end local function int64BitsToDouble(value) assert(isLittleEndian, "This method is implemented assuming little endian with an ambiguous spec.") local s = spack("i8", value) return (sunpack("d", s)) end define("System.BitConverter", { IsLittleEndian = isLittleEndian, GetBytesFromBoolean = getBytesFromBoolean, GetBytesFromInt16 = getBytesFromInt16, GetBytesFromInt32 = getBytesFromInt32, GetBytesFromInt64 = getBytesFromInt64, GetBytesFromFloat = getBytesFromFloat, GetBytesFromDouble = getBytesFromDouble, ToBoolean = toBoolean, ToChar = toUInt16, ToInt16 = toInt16, ToUInt16 = toUInt16, ToInt32 = toInt32, ToUInt32 = toUInt32, ToInt64 = toInt64, ToUInt64 = toUInt64, ToSingle = toSingle, ToDouble = toDouble, ToString = toString, DoubleToInt64Bits = doubleToInt64Bits, Int64BitsToDouble = int64BitsToDouble }) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Convert.lua.meta ================================================ fileFormatVersion: 2 guid: 4484884b9aaf34742b746fe8ebf350be DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Core.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local setmetatable = setmetatable local getmetatable = getmetatable local type = type local pairs = pairs local assert = assert local table = table local tremove = table.remove local tconcat = table.concat local floor = math.floor local ceil = math.ceil local error = error local select = select local xpcall = xpcall local rawget = rawget local rawset = rawset local rawequal = rawequal local tostring = tostring local string = string local sfind = string.find local ssub = string.sub local debug = debug local next = next local global = _G local prevSystem = rawget(global, "System") local emptyFn = function() end local nilFn = function() return nil end local falseFn = function() return false end local trueFn = function() return true end local identityFn = function(x) return x end local lengthFn = function (t) return #t end local zeroFn = function() return 0 end local oneFn = function() return 1 end local equals = function(x, y) return x == y end local getCurrent = function(t) return t.current end local assembly, metadatas local System, Object, ValueType local function new(cls, ...) local this = setmetatable({}, cls) return this, cls.__ctor__(this, ...) end local function throw(e, lv) if e == nil then e = System.NullReferenceException() end e:traceback(lv) error(e) end local function xpcallErr(e) if e == nil then e = System.Exception("script error") e:traceback() elseif type(e) == "string" then if sfind(e, "attempt to index") then e = System.NullReferenceException(e) elseif sfind(e, "attempt to divide by zero") then e = System.DivideByZeroException(e) else e = System.Exception(e) end e:traceback() end return e end local function try(try, catch, finally) local ok, status, result = xpcall(try, xpcallErr) if not ok then if catch then if finally then ok, status, result = xpcall(catch, xpcallErr, status) else ok, status, result = true, catch(status) end if ok then if status == 1 then ok = false status = result end end end end if finally then finally() end if not ok then error(status) end return status, result end local function set(className, cls) local scope = global local starIndex = 1 while true do local pos = sfind(className, "[%.+]", starIndex) or 0 local name = ssub(className, starIndex, pos -1) if pos ~= 0 then local t = rawget(scope, name) if t == nil then if cls then t = {} rawset(scope, name, t) else return nil end end scope = t starIndex = pos + 1 else if cls then assert(rawget(scope, name) == nil, className) rawset(scope, name, cls) return cls else return rawget(scope, name) end end end end local function multiKey(t, ...) local n, i, k = select("#", ...), 1 while true do k = assert(select(i, ...)) if i == n then break end local tk = t[k] if tk == nil then tk = {} t[k] = tk end t = tk i = i + 1 end return t, k end local function genericName(name, ...) if name:byte(-2) == 95 then name = ssub(name, 1, -3) end local n = select("#", ...) local t = { name, "`", n, "[" } local count = 5 local hascomma for i = 1, n do local cls = select(i, ...) if hascomma then t[count] = "," count = count + 1 else hascomma = true end t[count] = cls.__name__ count = count + 1 end t[count] = "]" return tconcat(t) end local enumMetatable = { class = "E", default = zeroFn, __index = false, interface = false, __call = function (_, v) return v or 0 end } enumMetatable.__index = enumMetatable local interfaceMetatable = { class = "I", default = nilFn, __index = false } interfaceMetatable.__index = interfaceMetatable local ctorMetatable = { __call = function (ctor, ...) return ctor[1](...) end } local function applyExtends(cls) local extends = cls.base if extends then if type(extends) == "function" then extends = extends(global, cls) end cls.base = nil end return extends end local function applyMetadata(cls) local metadata = cls.__metadata__ if metadata then if metadatas then metadatas[#metadatas + 1] = function (global) cls.__metadata__ = metadata(global) end else cls.__metadata__ = metadata(global) end end end local function setBase(cls, kind) local ctor = cls.__ctor__ if ctor and type(ctor) == "table" then setmetatable(ctor, ctorMetatable) end local extends = applyExtends(cls) applyMetadata(cls) cls.__index = cls cls.__call = new if kind == "S" then if extends then cls.interface = extends end setmetatable(cls, ValueType) else if extends then local base = extends[1] if not base then error(cls.__name__ .. "'s base is nil") end if base.class == "I" then cls.interface = extends setmetatable(cls, Object) else setmetatable(cls, base) if #extends > 1 then tremove(extends, 1) cls.interface = extends end end else setmetatable(cls, Object) end end end local function staticCtorSetBase(cls) setmetatable(cls, nil) local t = cls[cls] for k, v in pairs(t) do cls[k] = v end cls[cls] = nil local kind = cls.class cls.class = nil setBase(cls, kind) cls:static() cls.static = nil end local staticCtorMetatable = { __index = function(cls, key) staticCtorSetBase(cls) return cls[key] end, __newindex = function(cls, key, value) staticCtorSetBase(cls) cls[key] = value end, __call = function(cls, ...) staticCtorSetBase(cls) return new(cls, ...) end } local function setHasStaticCtor(cls, kind) local name = cls.__name__ cls.__name__ = nil local t = {} for k, v in pairs(cls) do t[k] = v cls[k] = nil end cls[cls] = t cls.__name__ = name cls.class = kind cls.__call = new cls.__index = cls setmetatable(cls, staticCtorMetatable) end local function defCore(name, kind, cls, generic) cls = cls or {} cls.__name__ = name cls.__assembly__ = assembly if not generic then set(name, cls) end if kind == "C" or kind == "S" then if cls.static == nil then setBase(cls, kind) else setHasStaticCtor(cls, kind) end elseif kind == "I" then local extends = applyExtends(cls) if extends then cls.interface = extends end applyMetadata(cls) setmetatable(cls, interfaceMetatable) elseif kind == "E" then applyMetadata(cls) setmetatable(cls, enumMetatable) else assert(false, kind) end return cls end local function def(name, kind, cls, generic) if type(cls) == "function" then local mt = {} local fn = function(_, ...) local gt, gk = multiKey(mt, ...) local t = gt[gk] if t == nil then local class, super = cls(...) t = defCore(genericName(name, ...), kind, class or {}, true) if generic then setmetatable(t, super or generic) end gt[gk] = t end return t end local base = kind ~= "S" and Object or ValueType local caller = setmetatable({ __call = fn, __index = base }, base) if generic then generic.__index = generic generic.__call = new end return set(name, setmetatable(generic or {}, caller)) else return defCore(name, kind, cls, generic) end end local function defCls(name, cls, generic) return def(name, "C", cls, generic) end local function defInf(name, cls) return def(name, "I", cls) end local function defStc(name, cls, generic) return def(name, "S", cls, generic) end local function defEnum(name, cls) return def(name, "E", cls) end local function defArray(name, cls, Array, MultiArray) Array.__index = Array MultiArray.__index = MultiArray setmetatable(MultiArray, Array) local mt = {} local function create(Array, T) local ArrayT = mt[T] if ArrayT == nil then ArrayT = defCore(T.__name__ .. "[]", "C", cls(T), true) setmetatable(ArrayT, Array) mt[T] = ArrayT end return ArrayT end local mtMulti = {} local function createMulti(MultiArray, T, dimension) local gt, gk = multiKey(mtMulti, T, dimension) local ArrayT = gt[gk] if ArrayT == nil then local name = T.__name__ .. "[" .. (","):rep(dimension - 1) .. "]" ArrayT = defCore(name, "C", cls(T), true) setmetatable(ArrayT, MultiArray) gt[gk] = ArrayT end return ArrayT end return set(name, setmetatable(Array, { __index = Object, __call = function (Array, T, dimension) if not dimension then return create(Array, T) else return createMulti(MultiArray, T, dimension) end end })) end local function trunc(num) return num > 0 and floor(num) or ceil(num) end local function when(f, ...) local ok, r = pcall(f, ...) return ok and r end System = { emptyFn = emptyFn, falseFn = falseFn, trueFn = trueFn, identityFn = identityFn, lengthFn = lengthFn, zeroFn = zeroFn, oneFn = oneFn, equals = equals, getCurrent = getCurrent, try = try, when = when, throw = throw, getClass = set, multiKey = multiKey, define = defCls, defInf = defInf, defStc = defStc, defEnum = defEnum, defArray = defArray, enumMetatable = enumMetatable, trunc = trunc, global = global } if prevSystem then setmetatable(System, { __index = prevSystem }) end global.System = System local debugsetmetatable = debug and debug.setmetatable System.debugsetmetatable = debugsetmetatable local _, _, version = sfind(_VERSION, "^Lua (.*)$") version = tonumber(version) System.luaVersion = version if version < 5.3 then local bnot, band, bor, xor, sl, sr local bit = rawget(global, "bit") if not bit then local ok, b = pcall(require, "bit") if ok then bit = b end end if bit then bnot, band, bor, xor, sl, sr = bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift else local function disable() throw(System.NotSupportedException("bit operation is not enabled.")) end bnot, band, bor, xor, sl, sr = disable, disable, disable, disable, disable, disable end System.bnot = bnot System.band = band System.bor = bor System.xor = xor System.sl = sl System.sr = sr function System.div(x, y) if y == 0 then throw(System.DivideByZeroException(), 1) end return trunc(x / y) end function System.mod(x, y) if y == 0 then throw(System.DivideByZeroException(), 1) end local v = x % y if v ~= 0 and x * y < 0 then return v - y end return v end function System.modf(x, y) local v = x % y if v ~= 0 and x * y < 0 then return v - y end return v end function System.toUInt(v, max, mask, checked) if v >= 0 and v <= max then return v end if checked then throw(System.OverflowException(), 1) end return band(v, mask) end function System.ToUInt(v, max, mask, checked) v = trunc(v) if v >= 0 and v <= max then return v end if checked then throw(System.OverflowException(), 1) end if v < -2147483648 or v > 2147483647 then return 0 end return band(v, mask) end local function toInt(v, mask, umask) v = band(v, mask) local uv = band(v, umask) if uv ~= v then v = xor(uv - 1, umask) if uv ~= 0 then v = -v end end return v end function System.toInt(v, min, max, mask, umask, checked) if v >= min and v <= max then return v end if checked then throw(System.OverflowException(), 1) end return toInt(v, mask, umask) end function System.ToInt(v, min, max, mask, umask, checked) v = trunc(v) if v >= min and v <= max then return v end if checked then throw(System.OverflowException(), 1) end if v < -2147483648 or v > 2147483647 then return 0 end return toInt(v, mask, umask) end local function toUInt32(v) if v <= -2251799813685248 or v >= 2251799813685248 then -- 2 ^ 51, Lua BitOp used 51 and 52 throw(System.InvalidCastException()) end v = band(v, 0xffffffff) local uv = band(v, 0x7fffffff) if uv ~= v then return uv + 0x80000000 end return v end function System.toUInt32(v, checked) if v >= 0 and v <= 4294967295 then return v end if checked then throw(System.OverflowException(), 1) end return toUInt32(v) end function System.ToUInt32(v, checked) v = trunc(v) if v >= 0 and v <= 4294967295 then return v end if checked then throw(System.OverflowException(), 1) end return toUInt32(v) end function System.toInt32(v, checked) if v >= -2147483648 and v <= 2147483647 then return v end if checked then throw(System.OverflowException(), 1) end if v <= -2251799813685248 or v >= 2251799813685248 then -- 2 ^ 51, Lua BitOp used 51 and 52 throw(System.InvalidCastException()) end return band(v, 0xffffffff) end function System.toInt64(v, checked) if v >= -9223372036854775808 and v <= 9223372036854775807 then return v end if checked then throw(System.OverflowException(), 1) end throw(System.InvalidCastException()) -- 2 ^ 51, Lua BitOp used 51 and 52 end function System.toUInt64(v, checked) if v >= 0 then return v end if checked then throw(System.OverflowException(), 1) end if v >= -2147483648 then return band(v, 0x7fffffff) + 0xffffffff80000000 end throw(System.InvalidCastException()) end function System.ToUInt64(v, checked) v = trunc(v) if v >= 0 and v <= 18446744073709551615 then return v end if checked then throw(System.OverflowException(), 1) end if v >= -2147483648 and v <= 2147483647 then v = band(v, 0xffffffff) local uv = band(v, 0x7fffffff) if uv ~= v then return uv + 0xffffffff80000000 end return v end throw(System.InvalidCastException()) end if table.pack == nil then table.pack = function(...) return { n = select("#", ...), ... } end end if table.unpack == nil then table.unpack = assert(unpack) end if table.move == nil then table.move = function(a1, f, e, t, a2) if a2 == nil then a2 = a1 end if t > f then t = e - f + t while e >= f do a2[t] = a1[e] t = t - 1 e = e - 1 end else while f <= e do a2[t] = a1[f] t = t + 1 f = f + 1 end end end end else load[[ local System = System local throw = System.throw local trunc = System.trunc function System.bnot(x) return ~x end function System.band(x, y) return x & y end function System.bor(x, y) return x | y end function System.xor(x, y) return x ~ y end function System.sl(x, y) return x << y end function System.sr(x, y) return x >> y end function System.div(x, y) if x ~ y < 0 then return -(-x // y) end return x // y end function System.mod(x, y) local v = x % y if v ~= 0 and 1.0 * x * y < 0 then return v - y end return v end local function toUInt(v, max, mask, checked) if v >= 0 and v <= max then return v end if checked then throw(System.OverflowException(), 2) end return v & mask end System.toUInt = toUInt function System.ToUInt(v, max, mask, checked) v = trunc(v) if v >= 0 and v <= max then return v end if checked then throw(System.OverflowException(), 2) end if v < -2147483648 or v > 2147483647 then return 0 end return v & mask end local function toSingedInt(v, mask, umask) v = v & mask local uv = v & umask if uv ~= v then v = (uv - 1) ~ umask if uv ~= 0 then v = -v end end return v end local function toInt(v, min, max, mask, umask, checked) if v >= min and v <= max then return v end if checked then throw(System.OverflowException(), 2) end return toSingedInt(v, mask, umask) end System.toInt = toInt function System.ToInt(v, min, max, mask, umask, checked) v = trunc(v) if v >= min and v <= max then return v end if checked then throw(System.OverflowException(), 2) end if v < -2147483648 or v > 2147483647 then return 0 end return toSingedInt(v, mask, umask) end function System.toUInt32(v, checked) return toUInt(v, 4294967295, 0xffffffff, checked) end function System.ToUInt32(v, checked) v = trunc(v) if v >= 0 and v <= 4294967295 then return v end if checked then throw(System.OverflowException(), 1) end return v & 0xffffffff end function System.toInt32(v, checked) return toInt(v, -2147483648, 2147483647, 0xffffffff, 0x7fffffff, checked) end function System.toInt64(v, checked) return toInt(v, -9223372036854775808, 9223372036854775807, 0xffffffffffffffff, 0x7fffffffffffffff, checked) end function System.toUInt64(v, checked) if v >= 0 then return v end if checked then throw(System.OverflowException(), 1) end return (v & 0x7fffffffffffffff) + 0x8000000000000000 end function System.ToUInt64(v, checked) v = trunc(v) if v >= 0 and v <= 18446744073709551615 then return v end if checked then throw(System.OverflowException(), 1) end v = v & 0xffffffffffffffff local uv = v & 0x7fffffffffffffff if uv ~= v then return uv + 0x8000000000000000 end return v end ]]() end local toUInt = System.toUInt local toInt = System.toInt local ToUInt = System.ToUInt local ToInt = System.ToInt function System.toByte(v, checked) return toUInt(v, 255, 0xff, checked) end function System.toSByte(v, checked) return toInt(v, -128, 127, 0xff, 0x7f, checked) end function System.toInt16(v, checked) return toInt(v, -32768, 32767, 0xffff, 0x7fff, checked) end function System.toUInt16(v, checked) return toUInt(v, 65535, 0xffff, checked) end function System.ToByte(v, checked) return ToUInt(v, 255, 0xff, checked) end function System.ToSByte(v, checked) return ToInt(v, -128, 127, 0xff, 0x7f, checked) end function System.ToInt16(v, checked) return ToInt(v, -32768, 32767, 0xffff, 0x7fff, checked) end function System.ToUInt16(v, checked) return ToUInt(v, 65535, 0xffff, checked) end function System.ToInt32(v, checked) v = trunc(v) if v >= -2147483648 and v <= 2147483647 then return v end if checked then throw(System.OverflowException(), 1) end return -2147483648 end function System.ToInt64(v, checked) v = trunc(v) if v >= -9223372036854775808 and v <= 9223372036854775807 then return v end if checked then throw(System.OverflowException(), 1) end return -9223372036854775808 end function System.ToSingle(v, checked) if v >= -3.40282347E+38 and v <= 3.40282347E+38 then return v end if checked then throw(System.OverflowException(), 1) end if v > 0 then return 1 / 0 else return -1 / 0 end end function System.using(t, f) local dispose = t and t.Dispose if dispose ~= nil then local ok, status, ret = xpcall(f, xpcallErr, t) dispose(t) if not ok then error(status) end return status, ret else return f(t) end end function System.usingX(f, ...) local ok, status, ret = xpcall(f, xpcallErr, ...) for i = 1, select("#", ...) do local t = select(i, ...) if t ~= nil then local dispose = t.Dispose if dispose ~= nil then dispose(t) end end end if not ok then error(status) end return status, ret end function System.apply(t, f) f(t) return t end function System.default(T) return T:default() end function System.property(name) local function g(this) return this[name] end local function s(this, v) this[name] = v end return g, s end function System.new(cls, index, ...) local this = setmetatable({}, cls) return this, cls.__ctor__[index](this, ...) end function System.base(this) return getmetatable(getmetatable(this)) end local equalsObj, compareObj, toString if debugsetmetatable then equalsObj = function (x, y) if x == y then return true end if x == nil or y == nil then return false end local ix = x.EqualsObj if ix ~= nil then return ix(x, y) end local iy = y.EqualsObj if iy ~= nil then return iy(y, x) end return false end compareObj = function (a, b) if a == b then return 0 end if a == nil then return -1 end if b == nil then return 1 end local ia = a.CompareToObj if ia ~= nil then return ia(a, b) end local ib = b.CompareToObj if ib ~= nil then return -ib(b, a) end throw(System.ArgumentException("Argument_ImplementIComparable")) end toString = function (t) return t ~= nil and t:ToString() or "" end debugsetmetatable(nil, { __concat = function(a, b) if a == nil then if b == nil then return "" else return b end else return a end end, __add = function (a, b) if a == nil then if b == nil or type(b) == "number" then return nil end return b end return nil end, __sub = nilFn, __mul = nilFn, __div = nilFn, __mod = nilFn, __unm = nilFn, __lt = falseFn, __le = falseFn, -- lua 5.3 __idiv = nilFn, __band = nilFn, __bor = nilFn, __bxor = nilFn, __bnot = nilFn, __shl = nilFn, __shr = nilFn, }) else equalsObj = function (x, y) if x == y then return true end if x == nil or y == nil then return false end local t = type(x) if t == "table" then local ix = x.EqualsObj if ix ~= nil then return ix(x, y) end elseif t == "number" then return System.Number.EqualsObj(x, y) end t = type(y) if t == "table" then local iy = y.EqualsObj if iy ~= nil then return iy(y, x) end end return false end compareObj = function (a, b) if a == b then return 0 end if a == nil then return -1 end if b == nil then return 1 end local t = type(a) if t == "number" then return System.Number.CompareToObj(a, b) elseif t == "boolean" then return System.Boolean.CompareToObj(a, b) else local ia = a.CompareToObj if ia ~= nil then return ia(a, b) end end t = type(b) if t == "number" then return -System.Number.CompareToObj(b, a) elseif t == "boolean" then return -System.Boolean.CompareToObj(a, b) else local ib = b.CompareToObj if ib ~= nil then return -ib(b, a) end end throw(System.ArgumentException("Argument_ImplementIComparable")) end toString = function (obj) if obj == nil then return "" end local t = type(obj) if t == "table" then return obj:ToString() elseif t == "boolean" then return obj and "True" or "False" elseif t == "function" then return "System.Delegate" end return tostring(obj) end end System.equalsObj = equalsObj System.compareObj = compareObj System.toString = toString Object = defCls("System.Object", { __call = new, __ctor__ = emptyFn, default = nilFn, class = "C", EqualsObj = equals, ReferenceEquals = rawequal, GetHashCode = identityFn, EqualsStatic = equalsObj, GetType = false, ToString = function(this) return this.__name__ end }) setmetatable(Object, { __call = new }) ValueType = defCls("System.ValueType", { class = "S", default = function(T) return T() end, __clone__ = function(this) if type(this) == "table" then local cls = getmetatable(this) local t = {} for k, v in pairs(this) do if type(v) == "table" and v.class == "S" then t[k] = v:__clone__() else t[k] = v end end return setmetatable(t, cls) end return this end, __copy__ = function (this, obj) for k, v in pairs(obj) do if type(v) == "table" and v.class == "S" then this[k] = v:__clone__() else this[k] = v end end for k, v in pairs(this) do if v ~= nil and rawget(obj, k) == nil then this[k] = nil end end end, EqualsObj = function (this, obj) if getmetatable(this) ~= getmetatable(obj) then return false end for k, v in pairs(this) do if not equalsObj(v, obj[k]) then return false end end return true end, GetHashCode = function (this) throw(System.NotSupportedException(this.__name__ .. " User-defined struct not support GetHashCode"), 1) end }) local AnonymousType AnonymousType = defCls("System.AnonymousType", { EqualsObj = function (this, obj) if getmetatable(obj) ~= AnonymousType then return false end for k, v in pairs(this) do if not equalsObj(v, obj[k]) then return false end end return true end }) local function anonymousTypeCreate(T, t) return setmetatable(t, T) end local anonymousTypeMetaTable = setmetatable({ __index = Object, __call = anonymousTypeCreate }, Object) setmetatable(AnonymousType, anonymousTypeMetaTable) local pack, unpack = table.pack, table.unpack local function tupleDeconstruct(t) return unpack(t, 1, t.n) end local function tupleEquals(t, other) for i = 1, t.n do if not equalsObj(t[i], other[i]) then return false end end return true end local function tupleEqualsObj(t, obj) if getmetatable(obj) ~= getmetatable(t) or t.n ~= obj.n then return false end return tupleEquals(t, obj) end local function tupleCompareTo(t, other) for i = 1, t.n do local v = compareObj(t[i], other[i]) if v ~= 0 then return v end end return 0 end local function tupleCompareToObj(t, obj) if obj == nil then return 1 end if getmetatable(obj) ~= getmetatable(t) or t.n ~= obj.n then throw(System.ArgumentException()) end return tupleCompareTo(t, obj) end local function tupleToString(t) local a = { "(" } local count = 2 for i = 1, t.n do if i ~= 1 then a[count] = ", " count = count + 1 end local v = t[i] if v ~= nil then a[count] = v:ToString() count = count + 1 end end a[count] = ")" return tconcat(a) end local function tupleLength(t) return t.n end local function tupleGet(t, index) if index < 0 or index >= t.n then throw(System.IndexOutOfRangeException()) end return t[index + 1] end local function tupleGetRest(t) return t[8] end local function tupleCreate(T, ...) return setmetatable(pack(...), T) end local Tuple = defCls("System.Tuple", { Deconstruct = tupleDeconstruct, ToString = tupleToString, EqualsObj = tupleEqualsObj, CompareToObj = tupleCompareToObj, getLength = tupleLength, get = tupleGet, getRest = tupleGetRest }) local tupleMetaTable = setmetatable({ __index = Object, __call = tupleCreate }, Object) setmetatable(Tuple, tupleMetaTable) local ValueTuple = defStc("System.ValueTuple", { Deconstruct = tupleDeconstruct, ToString = tupleToString, __eq = tupleEquals, Equals = tupleEquals, EqualsObj = tupleEqualsObj, CompareTo = tupleCompareTo, CompareToObj = tupleCompareToObj, getLength = tupleLength, get = tupleGet, default = function () throw(System.NotSupportedException("not support default(T) when T is ValueTuple")) end }) local valueTupleMetaTable = setmetatable({ __index = ValueType, __call = tupleCreate }, ValueType) setmetatable(ValueTuple, valueTupleMetaTable) local function recordEquals(t, other) if getmetatable(t) == getmetatable(other) then for k, v in pairs(t) do if not equalsObj(v, other[k]) then return false end end return true end return false end defCls("System.RecordType", { __eq = recordEquals, __clone__ = function (this) local cls = getmetatable(this) local t = {} for k, v in pairs(this) do t[k] = v end return setmetatable(t, cls) end, Equals = recordEquals, PrintMembers = function (this, builder) local p = pack(this.__members__()) local n = p.n for i = 2, n do local k = p[i] local v = this[k] builder:Append(k) builder:Append(" = ") if v ~= nil then builder:Append(toString(v)) end if i ~= n then builder:Append(", ") end end end, ToString = function (this) local p = pack(this.__members__()) local n = p.n local t = { p[1], "{" } local count = 3 for i = 2, n do local k = p[i] local v = this[k] t[count] = k t[count + 1] = "=" if v ~= nil then if i ~= n then t[count + 2] = toString(v) .. ',' else t[count + 2] = toString(v) end else if i ~= n then t[count + 2] = ',' end end if v == nil and i == n then count = count + 2 else count = count + 3 end end t[count] = "}" return tconcat(t, ' ') end }) local Attribute = defCls("System.Attribute") defCls("System.FlagsAttribute", { base = { Attribute } }) local Nullable = { default = nilFn, Value = function (this) if this == nil then throw(System.InvalidOperationException("Nullable object must have a value.")) end return this end, EqualsObj = equalsObj, GetHashCode = function (this) if this == nil then return 0 end if type(this) == "table" then return this:GetHashCode() end return this end, clone = function (t) if type(t) == "table" then return t:__clone__() end return t end } defStc("System.Nullable", function (T) return { __genericT__ = T } end, Nullable) function System.isNullable(T) return getmetatable(T) == Nullable end local Index = defStc("System.Index", { End = -0.0, Start = 0, IsFromEnd = function (this) return 1 / this < 0 end, GetOffset = function (this, length) if 1 / this < 0 then return length + this end return this end, ToString = function (this) return ((1 / this < 0) and '^' or '') .. this end }) setmetatable(Index, { __call = function (value, fromEnd) if value < 0 then throw(System.ArgumentOutOfRangeException("Non-negative number required.")) end if fromEnd then if value == 0 then return -0.0 end return -value end return value end }) local function pointerAddress(p) local address = p[3] if address == nil then address = ssub(tostring(p), 7) p[3] = address end return address + p[2] end local Pointer local function newPointer(t, i) return setmetatable({ t, i }, Pointer) end Pointer = { __index = false, get = function(this) local t, i = this[1], this[2] return t[i] end, set = function(this, value) local t, i = this[1], this[2] t[i] = value end, __add = function(this, count) return newPointer(this[1], this[2] + count) end, __sub = function(this, count) return newPointer(this[1], this[2] - count) end, __lt = function(t1, t2) return pointerAddress(t1) < pointerAddress(t2) end, __le = function(t1, t2) return pointerAddress(t1) <= pointerAddress(t2) end } Pointer.__index = Pointer function System.stackalloc(t) return newPointer(t, 1) end local modules, imports = {}, {} function System.import(f) imports[#imports + 1] = f end local namespace local function defIn(kind, name, f) local namespaceName, isClass = namespace[1], namespace[2] if #namespaceName > 0 then name = namespaceName .. (isClass and "+" or ".") .. name end assert(modules[name] == nil, name) namespace[1], namespace[2] = name, kind == "C" or kind == "S" local t = f(assembly) namespace[1], namespace[2] = namespaceName, isClass modules[isClass and name:gsub("+", ".") or name] = function() return def(name, kind, t) end end namespace = { "", false, __index = false, class = function(name, f) defIn("C", name, f) end, struct = function(name, f) defIn("S", name, f) end, interface = function(name, f) defIn("I", name, f) end, enum = function(name, f) defIn("E", name, f) end, namespace = function(name, f) local namespaceName = namespace[1] name = namespaceName .. "." .. name namespace[1] = name f(namespace) namespace[1] = namespaceName end } namespace.__index = namespace function System.namespace(name, f) if not assembly then assembly = setmetatable({}, namespace) end namespace[1] = name f(namespace) namespace[1], namespace[2] = "", false end function System.init(t) local path, files = t.path, t.files if files then path = (path and #path > 0) and (path .. '.') or "" for i = 1, #files do require(path .. files[i]) end end metadatas = {} local types = t.types if types then local classes = {} for i = 1, #types do local name = types[i] local cls = assert(modules[name], name)() classes[i] = cls end assembly.classes = classes end for i = 1, #imports do imports[i](global) end local b, e = 1, #metadatas while true do for i = b, e do metadatas[i](global) end local len = #metadatas if len == e then break end b, e = e + 1, len end local main = t.Main if main then assembly.entryPoint = main System.entryAssembly = assembly end local attributes = t.assembly if attributes then if type(attributes) == "function" then attributes = attributes(global) end for k, v in pairs(attributes) do assembly[k] = v end end local current = assembly modules, imports, assembly, metadatas = {}, {}, nil, nil return current end System.config = rawget(global, "CSharpLuaSystemConfig") or {} local isSingleFile = rawget(global, "CSharpLuaSingleFile") if not isSingleFile then return function (config) if config then System.config = config end end end ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Core.lua.meta ================================================ fileFormatVersion: 2 guid: 87416cb6b5e986a48ba26b5391e32fa3 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/DateTime.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local div = System.div local trunc = System.trunc local TimeSpan = System.TimeSpan local compare = TimeSpan.Compare local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local FormatException = System.FormatException local assert = assert local getmetatable = getmetatable local select = select local sformat = string.format local sfind = string.find local os = os local ostime = os.time local osdifftime = os.difftime local osdate = os.date local tonumber = tonumber local math = math local floor = math.floor local log10 = math.log10 local modf = math.modf --http://referencesource.microsoft.com/#mscorlib/system/datetime.cs local DateTime local minValue local daysToMonth365 = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 } local daysToMonth366 = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } local function isLeapYear(year) if year < 1 or year > 9999 then throw(ArgumentOutOfRangeException("year", "ArgumentOutOfRange_Year")) end return year % 4 == 0 and (year % 100 ~= 0 or year % 400 == 0) end local function dateToTicks(year, month, day) if year >= 1 and year <= 9999 and month >= 1 and month <= 12 then local days = isLeapYear(year) and daysToMonth366 or daysToMonth365 if day >= 1 and day <= days[month + 1] - days[month] then local y = year - 1 local n = y * 365 + div(y, 4) - div(y, 100) + div(y, 400) + days[month] + day - 1 return n * 864000000000 end end end local function timeToTicks(hour, minute, second) if hour >= 0 and hour < 24 and minute >= 0 and minute < 60 and second >=0 and second < 60 then return (((hour * 60 + minute) * 60) + second) * 10000000 end throw(ArgumentOutOfRangeException("ArgumentOutOfRange_BadHourMinuteSecond")) end local function checkTicks(ticks) if ticks < 0 or ticks > 3155378975999999999 then throw(ArgumentOutOfRangeException("ticks", "ArgumentOutOfRange_DateTimeBadTicks")) end end local function checkKind(kind) if kind and (kind < 0 or kind > 2) then throw(ArgumentOutOfRangeException("kind")) end end local function addTicks(this, value) return DateTime(this.ticks + value, this.kind) end local function addTimeSpan(this, ts) return addTicks(this, ts.ticks) end local function add(this, value, scale) local millis = trunc(value * scale + (value >= 0 and 0.5 or -0.5)) return addTicks(this, millis * 10000) end local function subtract(this, v) if getmetatable(v) == DateTime then return TimeSpan(this.ticks - v.ticks) end return DateTime(this.ticks - v.ticks, this.kind) end local function getDataPart(ticks, part) local n = div(ticks, 864000000000) local y400 = div(n, 146097) n = n - y400 * 146097 local y100 = div(n, 36524) if y100 == 4 then y100 = 3 end n = n - y100 * 36524 local y4 = div(n, 1461) n = n - y4 * 1461; local y1 = div(n, 365) if y1 == 4 then y1 = 3 end if part == 0 then return y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1 end n = n - y1 * 365 if part == 1 then return n + 1 end local leapYear = y1 == 3 and (y4 ~= 24 or y100 == 3) local days = leapYear and daysToMonth366 or daysToMonth365 local m = div(n, 32) + 1 while n >= days[m + 1] do m = m + 1 end if part == 2 then return m end return n - days[m] + 1 end local function getDatePart(ticks) local year, month, day local n = div(ticks, 864000000000) local y400 = div(n, 146097) n = n - y400 * 146097 local y100 = div(n, 36524) if y100 == 4 then y100 = 3 end n = n - y100 * 36524 local y4 = div(n, 1461) n = n - y4 * 1461 local y1 = div(n, 365) if y1 == 4 then y1 = 3 end year = y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1 n = n - y1 * 365 local leapYear = y1 == 3 and (y4 ~= 24 or y100 == 3) local days = leapYear and daysToMonth366 or daysToMonth365 local m = div(n, 32) + 1 while n >= days[m + 1] do m = m + 1 end month = m day = n - days[m] + 1 return year, month, day end local function daysInMonth(year, month) if month < 1 or month > 12 then throw(ArgumentOutOfRangeException("month")) end local days = isLeapYear(year) and daysToMonth366 or daysToMonth365 return days[month + 1] - days[month] end local function addMonths(this, months) if months < -120000 or months > 12000 then throw(ArgumentOutOfRangeException("months")) end local ticks = this.ticks local y, m, d = getDatePart(ticks) local i = m - 1 + months if i >= 0 then m = i % 12 + 1 y = y + div(i, 12) else m = 12 + (i + 1) % -12 y = y + div(i - 11, 12) end if y < 1 or y > 9999 then throw(ArgumentOutOfRangeException("months")) end local days = daysInMonth(y, m) if d > days then d = days end return DateTime(dateToTicks(y, m, d) + ticks % 864000000000, this.kind) end local function getTimeZone() local date = osdate("*t") local dst = date.isdst local now = ostime(date) return osdifftime(now, ostime(osdate("!*t", now))) * 10000000, dst and 3600 * 10000000 or 0 end local timeZoneTicks, dstTicks = getTimeZone() local time = System.config.time or ostime System.time = time System.currentTimeMillis = function () return trunc(time() * 1000) end local function now() local seconds = time() local ticks = seconds * 10000000 + timeZoneTicks + dstTicks + 621355968000000000 return DateTime(ticks, 2) end local function parse(s) if s == nil then return nil, 1 end local i, j, year, month, day, hour, minute, second, milliseconds i, j, year, month, day = sfind(s, "^%s*(%d+)%s*/%s*(%d+)%s*/%s*(%d+)%s*") if i == nil then return nil, 2 else year, month, day = tonumber(year), tonumber(month), tonumber(day) end if j < #s then i, j, hour, minute = sfind(s, "^(%d+)%s*:%s*(%d+)", j + 1) if i == nil then return nil, 2 else hour, minute = tonumber(hour), tonumber(minute) end local next = j + 1 i, j, second = sfind(s, "^:%s*(%d+)", next) if i == nil then if sfind(s, "^%s*$", next) == nil then return nil, 2 else second = 0 milliseconds = 0 end else second = tonumber(second) next = j + 1 i, j, milliseconds = sfind(s, "^%.(%d+)%s*$", next) if i == nil then if sfind(s, "^%s*$", next) == nil then return nil, 2 else milliseconds = 0 end else milliseconds = tonumber(milliseconds) local n = floor(log10(milliseconds) + 1) if n > 3 then if n <= 7 then milliseconds = milliseconds / (10 ^ (n - 3)) else local ticks = milliseconds / (10 ^ (n - 7)) local _, decimal = modf(ticks) if decimal > 0.5 then ticks = ticks + 1 end milliseconds = floor(ticks) / 10000 end end end end end if hour == nil then return DateTime(year, month, day) end return DateTime(year, month, day, hour, minute, second, milliseconds) end DateTime = System.defStc("System.DateTime", { ticks = 0, kind = 0, Compare = compare, CompareTo = compare, CompareToObj = function (this, t) if t == nil then return 1 end if getmetatable(t) ~= DateTime then throw(ArgumentException("Arg_MustBeDateTime")) end return compare(this, t) end, Equals = function (t1, t2) return t1.ticks == t2.ticks end, EqualsObj = function (this, t) if getmetatable(t) == DateTime then return this.ticks == t.ticks end return false end, GetHashCode = function (this) return this.ticks end, IsLeapYear = isLeapYear, __ctor__ = function (this, ...) local len = select("#", ...) if len == 0 then elseif len == 1 then local ticks = ... checkTicks(ticks) this.ticks = ticks elseif len == 2 then local ticks, kind = ... checkTicks(ticks) checkKind(kind) this.ticks = ticks this.kind = kind elseif len == 3 then this.ticks = dateToTicks(...) elseif len == 6 then local year, month, day, hour, minute, second = ... this.ticks = dateToTicks(year, month, day) + timeToTicks(hour, minute, second) elseif len == 7 then local year, month, day, hour, minute, second, millisecond = ... this.ticks = dateToTicks(year, month, day) + timeToTicks(hour, minute, second) + millisecond * 10000 elseif len == 8 then local year, month, day, hour, minute, second, millisecond, kind = ... checkKind(kind) this.ticks = dateToTicks(year, month, day) + timeToTicks(hour, minute, second) + millisecond * 10000 this.kind = kind else assert(false) end end, AddTicks = addTicks, Add = addTimeSpan, AddDays = function (this, days) return add(this, days, 86400000) end, AddHours = function (this, hours) return add(this, hours, 3600000) end, AddMinutes = function (this, minutes) return add(this, minutes, 60000); end, AddSeconds = function (this, seconds) return add(this, seconds, 1000) end, AddMilliseconds = function (this, milliseconds) return add(this, milliseconds, 1) end, DaysInMonth = daysInMonth, AddMonths = addMonths, AddYears = function (this, years) if years < - 10000 or years > 10000 then throw(ArgumentOutOfRangeException("years")) end return addMonths(this, years * 12) end, SpecifyKind = function (this, kind) return DateTime(this.ticks, kind) end, Subtract = subtract, getDay = function (this) return getDataPart(this.ticks, 3) end, getDate = function (this) local ticks = this.ticks return DateTime(ticks - ticks % 864000000000, this.kind) end, getDayOfWeek = function (this) return (div(this.ticks, 864000000000) + 1) % 7 end, getDayOfYear = function (this) return getDataPart(this.ticks, 1) end, getKind = function (this) return this.kind end, getHour = TimeSpan.getHours, getMinute = TimeSpan.getMinutes, getSecond = TimeSpan.getSeconds, getMillisecond = TimeSpan.getMilliseconds, getMonth = function (this) return getDataPart(this.ticks, 2) end, getYear = function (this) return getDataPart(this.ticks, 0) end, getTimeOfDay = function (this) return TimeSpan(this.ticks % 864000000000) end, getTicks = function (this) return this.ticks end, BaseUtcOffset = TimeSpan(timeZoneTicks), getUtcNow = function () local seconds = time() local ticks = seconds * 10000000 + 621355968000000000 return DateTime(ticks, 1) end, getNow = now, getToday = function () return now():getDate() end, ToLocalTime = function (this) if this.kind == 2 then return this end local ticks = this.ticks + timeZoneTicks + dstTicks return DateTime(ticks, 2) end, ToUniversalTime = function (this) if this.kind == 1 then return this end local ticks = this.ticks - timeZoneTicks - dstTicks return DateTime(ticks, 1) end, IsDaylightSavingTime = function(this) return this.kind == 2 and dstTicks > 0 end, ToString = function (this) local year, month, day = getDatePart(this.ticks) return sformat("%d/%d/%d %02d:%02d:%02d", year, month, day, this:getHour(), this:getMinute(), this:getSecond()) end, Parse = function (s) local v, err = parse(s) if v then return v end if err == 1 then throw(ArgumentNullException()) else throw(FormatException()) end end, TryParse = function(s) local v = parse(s) if v then return true, v end return false, minValue end, __add = addTimeSpan, __sub = subtract, __eq = TimeSpan.__eq, __lt = TimeSpan.__lt, __le = TimeSpan.__le, base = function(_, T) return { System.IComparable, System.IComparable_1(T), System.IConvertible, System.IEquatable_1(T), System.IFormattable } end, default = function () return minValue end, MinValue = false, MaxValue = false }) minValue = DateTime(0) DateTime.MinValue = minValue DateTime.MaxValue = DateTime(3155378975999999999) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/DateTime.lua.meta ================================================ fileFormatVersion: 2 guid: 5d0c7552cbae5324c9a33be5db8e6125 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Delegate.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local Object = System.Object local debugsetmetatable = System.debugsetmetatable local ArgumentNullException = System.ArgumentNullException local setmetatable = setmetatable local assert = assert local select = select local type = type local unpack = table.unpack local tmove = table.move local Delegate local multicast local function appendFn(t, count, f) if type(f) == "table" then for i = 1, #f do t[count] = f[i] count = count + 1 end else t[count] = f count = count + 1 end return count end local function combineImpl(fn1, fn2) local t = setmetatable({}, multicast) local count = 1 count = appendFn(t, count, fn1) appendFn(t, count, fn2) return t end local function combine(fn1, fn2) if fn1 ~= nil then if fn2 ~= nil then return combineImpl(fn1, fn2) end return fn1 end if fn2 ~= nil then return fn2 end return nil end local function equalsMulticast(fn1, fn2, start, count) for i = 1, count do if fn1[start + i] ~= fn2[i] then return false end end return true end local function delete(fn, count, deleteIndex, deleteCount) local t = setmetatable({}, multicast) local len = 1 for i = 1, deleteIndex - 1 do t[len] = fn[i] len = len + 1 end for i = deleteIndex + deleteCount, count do t[len] = fn[i] len = len + 1 end return t end local function removeImpl(fn1, fn2) if type(fn2) ~= "table" then if type(fn1) ~= "table" then if fn1 == fn2 then return nil end else local count = #fn1 for i = count, 1, -1 do if fn1[i] == fn2 then if count == 2 then return fn1[3 - i] else return delete(fn1, count, i, 1) end end end end elseif type(fn1) == "table" then local count1, count2 = #fn1, # fn2 local diff = count1 - count2 for i = diff + 1, 1, -1 do if equalsMulticast(fn1, fn2, i - 1, count2) then if diff == 0 then return nil elseif diff == 1 then return fn1[i ~= 1 and 1 or count1] else return delete(fn1, count1, i, count2) end end end end return fn1 end local function remove(fn1, fn2) if fn1 ~= nil then if fn2 ~= nil then return removeImpl(fn1, fn2) end return fn1 end return nil end local multiKey = System.multiKey local mt = {} local function makeGenericTypes(...) local gt, gk = multiKey(mt, ...) local t = gt[gk] if t == nil then t = setmetatable({ ... }, Delegate) gt[gk] = t end return t end Delegate = System.define("System.Delegate", { __add = combine, __sub = remove, EqualsObj = System.equals, Combine = combine, Remove = remove, RemoveAll = function (source, value) local newDelegate repeat newDelegate = source source = remove(source, value) until newDelegate == source return newDelegate end, DynamicInvoke = function (this, ...) return this(...) end, GetType = function (this) return System.typeof(Delegate) end, GetInvocationList = function (this) local t if type(this) == "table" then t = {} tmove(this, 1, #this, 1, t) else t = { this } end return System.arrayFromTable(t, Delegate) end }) local delegateMetaTable = setmetatable({ __index = Object, __call = makeGenericTypes }, Object) setmetatable(Delegate, delegateMetaTable) if debugsetmetatable then debugsetmetatable(System.emptyFn, Delegate) function System.event(name) local function a(this, v) this[name] = this[name] + v end local function r(this, v) this[name] = this[name] - v end return a, r end else System.DelegateCombine = combine System.DelegateRemove = remove function System.event(name) local function a(this, v) this[name] = combine(this[name], v) end local function r(this, v) this[name] = remove(this[name], v) end return a, r end end multicast = setmetatable({ __index = Delegate, __add = combine, __sub = remove, __call = function (t, ...) local result for i = 1, #t do result = t[i](...) end return result end, __eq = function (fn1, fn2) local len1, len2 = #fn1, #fn2 if len1 ~= len2 then return false end for i = 1, len1 do if fn1[i] ~= fn2[i] then return false end end return true end }, Delegate) function System.fn(target, method) assert(method) if target == nil then throw(ArgumentNullException()) end local f = target[method] if f == nil then f = function (...) return method(target, ...) end target[method] = f end return f end local binds = setmetatable({}, { __mode = "k" }) function System.bind(f, n, ...) assert(f) local gt, gk = multiKey(binds, f, ...) local fn = gt[gk] if fn == nil then local args = { ... } fn = function (...) local len = select("#", ...) if len == n then return f(..., unpack(args)) else assert(len > n) local t = { ... } for i = 1, #args do local j = args[i] if type(j) == "number" then j = select(n + j, ...) assert(j) end t[n + i] = j end return f(unpack(t, 1, n + #args)) end end gt[gk] = fn end return fn end local function bind(f, create, ...) assert(f) local gt, gk = multiKey(binds, f, create) local fn = gt[gk] if fn == nil then fn = create(f, ...) gt[gk] = fn end return fn end local function create1(f, a) return function (...) return f(..., a) end end function System.bind1(f, a) return bind(f, create1, a) end local function create2(f, a, b) return function (...) return f(..., a, b) end end function System.bind2(f, a, b) return bind(f, create2, a, b) end local function create3(f, a, b, c) return function (...) return f(..., a, b, c) end end function System.bind3(f, a, b, c) return bind(f, create3, a, b, c) end local function create2_1(f) return function(x1, x2, T1, T2) return f(x1, x2, T2, T1) end end function System.bind2_1(f) return bind(f, create2_1) end local function create0_2(f) return function(x1, x2, T1, T2) return f(x1, x2, T2) end end function System.bind0_2(f) return bind(f, create0_2) end local EventArgs = System.define("System.EventArgs") EventArgs.Empty = setmetatable({}, EventArgs) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Delegate.lua.meta ================================================ fileFormatVersion: 2 guid: dd8640b062a392b408bb4b676a336bec timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Enum.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local Int = System.Int local Number = System.Number local band = System.band local bor = System.bor local ArgumentNullException = System.ArgumentNullException local ArgumentException = System.ArgumentException local assert = assert local pairs = pairs local tostring = tostring local type = type local function toString(this, cls) if this == nil then return "" end if cls then for k, v in pairs(cls) do if v == this then return k end end end return tostring(this) end local function hasFlag(this, flag) if this == flag then return true end return band(this, flag) ~= 0 end Number.EnumToString = toString Number.HasFlag = hasFlag System.EnumToString = toString System.EnumHasFlag = hasFlag local function tryParseEnum(enumType, value, ignoreCase) if enumType == nil then throw(ArgumentNullException("enumType")) end local cls = enumType[1] or enumType if cls.class ~= "E" then throw(ArgumentException("Arg_MustBeEnum")) end if value == nil then return end if ignoreCase then value = value:lower() end local i, j, s, r = 1 while true do i, j, s = value:find("%s*(%a+)%s*", i) if not i then return end for k, v in pairs(cls) do if ignoreCase then k = k:lower() end if k == s then if not r then r = v else r = bor(r, v) end break end end i = value:find(',', j + 1) if not i then break end i = i + 1 end return r end System.define("System.Enum", { CompareToObj = Int.CompareToObj, EqualsObj = Int.EqualsObj, default = Int.default, ToString = toString, HasFlag = hasFlag, GetName = function (enumType, value) if enumType == nil then throw(ArgumentNullException("enumType")) end if value == nil then throw(ArgumentNullException("value")) end if not enumType:getIsEnum() then throw(ArgumentException("Arg_MustBeEnum")) end for k, v in pairs(enumType[1]) do if v == value then return k end end end, GetNames = function (enumType) if enumType == nil then throw(ArgumentNullException("enumType")) end if not enumType:getIsEnum() then throw(ArgumentException("Arg_MustBeEnum")) end local t = {} local count = 1 for k, v in pairs(enumType[1]) do if type(v) == "number" then t[count] = k count = count + 1 end end return System.arrayFromTable(t, System.String) end, GetValues = function (enumType) if enumType == nil then throw(ArgumentNullException("enumType")) end if not enumType:getIsEnum() then throw(ArgumentException("Arg_MustBeEnum")) end local t = {} local count = 1 for k, v in pairs(enumType[1]) do if type(v) == "number" then t[count] = v count = count + 1 end end return System.arrayFromTable(t, System.Int32) end, IsDefined = function (enumType, value) if enumType == nil then throw(ArgumentNullException("enumType")) end if value == nil then throw(ArgumentNullException("value")) end if not enumType:getIsEnum() then throw(ArgumentException("Arg_MustBeEnum")) end local cls = enumType[1] local t = type(value) if t == "string" then return cls[value] ~= nil elseif t == "number" then for k, v in pairs(cls) do if v == value then return true end end return false end throw(System.InvalidOperationException()) end, Parse = function (enumType, value, ignoreCase) local result = tryParseEnum(enumType, value, ignoreCase) if result == nil then throw(ArgumentException("Requested value '" .. value .. "' was not found.")) end return result end, TryParse = function (type, value, ignoreCase) local result = tryParseEnum(type, value, ignoreCase) if result == nil then return false, 0 end return true, result end }) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Enum.lua.meta ================================================ fileFormatVersion: 2 guid: 81553c3618b10a14a853d14ccff36ef0 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Exception.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local Object = System.Object local tconcat = table.concat local type = type local debug = debug local function getMessage(this) return this.message or ("Exception of type '%s' was thrown."):format(this.__name__) end local traceback = (debug and debug.traceback) or System.config.traceback or function () return "" end System.traceback = traceback local function toString(this) local t = { this.__name__ } local count = 2 local message, innerException, stackTrace = getMessage(this), this.innerException, this.errorStack t[count] = ": " t[count + 1] = message count = count + 2 if innerException then t[count] = "---> " t[count + 1] = innerException:ToString() count = count + 2 end if stackTrace then t[count] = stackTrace end return tconcat(t) end local function ctorOfException(this, message, innerException) this.message = message this.innerException = innerException end local Exception = define("System.Exception", { __tostring = toString, __ctor__ = ctorOfException, ToString = toString, getMessage = getMessage, getInnerException = function(this) return this.innerException end, getStackTrace = function(this) return this.errorStack end, getData = function (this) local data = this.data if not data then data = System.Dictionary(Object, Object)() this.data = data end return data end, traceback = function(this, lv) this.errorStack = traceback("", lv and lv + 3 or 3) end }) local SystemException = define("System.SystemException", { __tostring = toString, base = { Exception }, __ctor__ = function (this, message, innerException) ctorOfException(this, message or "System error.", innerException) end }) local ArgumentException = define("System.ArgumentException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, paramName, innerException) if type(paramName) == "table" then paramName, innerException = nil, paramName end ctorOfException(this, message or "Value does not fall within the expected range.", innerException) this.paramName = paramName if paramName and #paramName > 0 then this.message = this.message .. "\nParameter name: " .. paramName end end, getParamName = function(this) return this.paramName end }) define("System.ArgumentNullException", { __tostring = toString, base = { ArgumentException }, __ctor__ = function(this, paramName, message, innerException) ArgumentException.__ctor__(this, message or "Value cannot be null.", paramName, innerException) end }) define("System.ArgumentOutOfRangeException", { __tostring = toString, base = { ArgumentException }, __ctor__ = function(this, paramName, message, innerException, actualValue) ArgumentException.__ctor__(this, message or "Specified argument was out of the range of valid values.", paramName, innerException) this.actualValue = actualValue end, getActualValue = function(this) return this.actualValue end }) define("System.IndexOutOfRangeException", { __tostring = toString, base = { SystemException }, __ctor__ = function (this, message, innerException) ctorOfException(this, message or "Index was outside the bounds of the array.", innerException) end }) define("System.CultureNotFoundException", { __tostring = toString, base = { ArgumentException }, __ctor__ = function(this, paramName, invalidCultureName, message, innerException, invalidCultureId) if not message then message = "Culture is not supported." if paramName then message = message .. "\nParameter name = " .. paramName end if invalidCultureName then message = message .. "\n" .. invalidCultureName .. " is an invalid culture identifier." end end ArgumentException.__ctor__(this, message, paramName, innerException) this.invalidCultureName = invalidCultureName this.invalidCultureId = invalidCultureId end, getInvalidCultureName = function(this) return this.invalidCultureName end, getInvalidCultureId = function(this) return this.invalidCultureId end }) local KeyNotFoundException = define("System.Collections.Generic.KeyNotFoundException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "The given key was not present in the dictionary.", innerException) end }) System.KeyNotFoundException = KeyNotFoundException local ArithmeticException = define("System.ArithmeticException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Overflow or underflow in the arithmetic operation.", innerException) end }) define("System.DivideByZeroException", { __tostring = toString, base = { ArithmeticException }, __ctor__ = function(this, message, innerException) ArithmeticException.__ctor__(this, message or "Attempted to divide by zero.", innerException) end }) define("System.OverflowException", { __tostring = toString, base = { ArithmeticException }, __ctor__ = function(this, message, innerException) ArithmeticException.__ctor__(this, message or "Arithmetic operation resulted in an overflow.", innerException) end }) define("System.FormatException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Invalid format.", innerException) end }) define("System.InvalidCastException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Specified cast is not valid.", innerException) end }) local InvalidOperationException = define("System.InvalidOperationException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Operation is not valid due to the current state of the object.", innerException) end }) define("System.NotImplementedException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "The method or operation is not implemented.", innerException) end }) define("System.NotSupportedException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Specified method is not supported.", innerException) end }) define("System.NullReferenceException", { __tostring = toString, base = { SystemException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Object reference not set to an instance of an object.", innerException) end }) define("System.RankException", { __tostring = toString, base = { Exception }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Attempted to operate on an array with the incorrect number of dimensions.", innerException) end }) define("System.TypeLoadException", { __tostring = toString, base = { Exception }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Failed when load type.", innerException) end }) define("System.ObjectDisposedException", { __tostring = toString, base = { InvalidOperationException }, __ctor__ = function(this, objectName, message, innerException) ctorOfException(this, message or "Cannot access a disposed object.", innerException) this.objectName = objectName if objectName and #objectName > 0 then this.message = this.message .. "\nObject name: '" .. objectName .. "'." end end }) local function toStringOfAggregateException(this) local t = { toString(this) } local count = 2 for i = 0, this.innerExceptions:getCount() - 1 do t[count] = "\n---> (Inner Exception #" t[count + 1] = i t[count + 2] = ") " t[count + 3] = this.innerExceptions:get(i):ToString() t[count + 4] = "<---\n" count = count + 5 end return tconcat(t) end define("System.AggregateException", { ToString = toStringOfAggregateException, __tostring = toStringOfAggregateException, base = { Exception }, __ctor__ = function (this, message, innerExceptions) if type(message) == "table" then message, innerExceptions = nil, message end Exception.__ctor__(this, message or "One or more errors occurred.") local ReadOnlyCollection = System.ReadOnlyCollection(Exception) if innerExceptions then if System.is(innerExceptions, Exception) then local list = System.List(Exception)() list:Add(innerExceptions) this.innerExceptions = ReadOnlyCollection(list) else if not System.isArrayLike(innerExceptions) then innerExceptions = System.Array.toArray(innerExceptions) end this.innerExceptions = ReadOnlyCollection(innerExceptions) end else this.innerExceptions = ReadOnlyCollection(System.Array.Empty(Exception)) end end, getInnerExceptions = function (this) return this.innerExceptions end }) System.SwitchExpressionException = define("System.Runtime.CompilerServices", { __tostring = toString, base = { InvalidOperationException }, __ctor__ = function(this, message, innerException) ctorOfException(this, message or "Non-exhaustive switch expression failed to match its input.", innerException) end }) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Exception.lua.meta ================================================ fileFormatVersion: 2 guid: 06bacb731a81a8442b212c8972952f18 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/IO/File.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local io = io if io then local System = System local define = System.define local throw = System.throw local each = System.each local open = io.open local remove = os.remove local IOException = define("System.IO.IOException", { __tostring = System.Exception.ToString, base = { System.Exception }, __ctor__ = function(this, message, innerException) System.Exception.__ctor__(this, message or "I/O error occurred.", innerException) end, }) local function openFile(path, mode) local f, err = open(path, mode) if f == nil then throw(IOException(err)) end return f end local function readAll(path, mode) local f = openFile(path, mode) local bytes = f:read("*all") f:close() return bytes end local function writeAll(path, contents, mode) local f = openFile(path, mode) f:write(contents) f:close() end define("System.IO.File", { ReadAllBytes = function (path) return readAll(path, "rb") end, ReadAllText = function (path) return readAll(path, "r") end, ReadAllLines = function (path) local t = {} local count = 1 for line in io.lines(path) do t[count] = line count = count + 1 end return System.arrayFromTable(t, System.String) end, WriteAllBytes = function (path, contents) writeAll(path, contents, "wb") end, WriteAllText = function (path, contents) writeAll(path, contents, "w") end, WriteAllLines = function (path, contents) local f = openFile(path, "w") for _, line in each(contents) do if line == nil then f:write("\n") else f:write(line, "\n") end end f:close() end, Exists = function (path) local file = io.open(path, "rb") if file then file:close() end return file ~= nil end, Delete = function (path) local ok, err = remove(path) if not ok then throw(IOException(err)) end end }) end ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/IO/File.lua.meta ================================================ fileFormatVersion: 2 guid: 7f24d0b1606f2a14685f4fa7e9121232 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/IO.meta ================================================ fileFormatVersion: 2 guid: 8dbc6ed8a3af14d448e678d22a14d94d folderAsset: yes timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Interfaces.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local defInf = System.defInf local emptyFn = System.emptyFn local IComparable = defInf("System.IComparable") local IFormattable = defInf("System.IFormattable") local IConvertible = defInf("System.IConvertible") defInf("System.IFormatProvider") defInf("System.ICloneable") defInf("System.IComparable_1", emptyFn) defInf("System.IEquatable_1", emptyFn) defInf("System.IPromise") defInf("System.IDisposable") local IEnumerable = defInf("System.IEnumerable") local IEnumerator = defInf("System.IEnumerator") local ICollection = defInf("System.ICollection", { base = { IEnumerable } }) defInf("System.IList", { base = { ICollection } }) defInf("System.IDictionary", { base = { ICollection } }) defInf("System.IEnumerator_1", function(T) return { base = { IEnumerator } } end) local IEnumerable_1 = defInf("System.IEnumerable_1", function(T) return { base = { IEnumerable } } end) local ICollection_1 = defInf("System.ICollection_1", function(T) return { base = { IEnumerable_1(T) } } end) local IReadOnlyCollection_1 = defInf("System.IReadOnlyCollection_1", function (T) return { base = { IEnumerable_1(T) } } end) defInf("System.IReadOnlyList_1", function (T) return { base = { IReadOnlyCollection_1(T) } } end) defInf('System.IDictionary_2', function(TKey, TValue) return { base = { ICollection_1(System.KeyValuePair(TKey, TValue)) } } end) defInf("System.IReadOnlyDictionary_2", function(TKey, TValue) return { base = { IReadOnlyCollection_1(System.KeyValuePair(TKey, TValue)) } } end) defInf("System.IList_1", function(T) return { base = { ICollection_1(T) } } end) defInf("System.ISet_1", function(T) return { base = { ICollection_1(T) } } end) defInf("System.IComparer") defInf("System.IComparer_1", emptyFn) defInf("System.IEqualityComparer") defInf("System.IEqualityComparer_1", emptyFn) System.enumMetatable.interface = { IComparable, IFormattable, IConvertible } ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Interfaces.lua.meta ================================================ fileFormatVersion: 2 guid: 1c03169af44be8445afa781e14cd3d47 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Math.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local trunc = System.trunc local math = math local floor = math.floor local min = math.min local max = math.max local abs = math.abs local function bigMul(a, b) return a * b end local function divRem(a, b) local remainder = a % b return (a - remainder) / b, remainder end local function round(value, digits, mode) local mult = 10 ^ (digits or 0) local i = value * mult if mode == 1 then value = trunc(i + (value >= 0 and 0.5 or -0.5)) else value = trunc(i) if value ~= i then local dif = i - value if value >= 0 then if dif > 0.5 or (dif == 0.5 and value % 2 ~= 0) then value = value + 1 end else if dif < -0.5 or (dif == -0.5 and value % 2 ~= 0) then value = value - 1 end end end end return value / mult end local function sign(v) return v == 0 and 0 or (v > 0 and 1 or -1) end local function IEEERemainder(x, y) if x ~= x then return x end if y ~= y then return y end local regularMod = System.mod(x, y) if regularMod ~= regularMod then return regularMod end if regularMod == 0 and x < 0 then return -0.0 end local alternativeResult = regularMod - abs(y) * sign(x) local i, j = abs(alternativeResult), abs(regularMod) if i == j then local divisionResult = x / y local roundedResult = round(divisionResult) if abs(roundedResult) > abs(divisionResult) then return alternativeResult else return regularMod end end if i < j then return alternativeResult else return regularMod end end local function clamp(a, b, c) return min(max(a, b), c) end local function truncate(d) return trunc(d) * 1.0 end local exp = math.exp local cosh = math.cosh or function(x) return (exp(x) + exp(-x)) / 2.0 end local pow = math.pow or function(x, y) return x ^ y end local sinh = math.sinh or function(x) return (exp(x) - exp(-x)) / 2.0 end local tanh = math.tanh or function(x) return sinh(x) / cosh(x) end local Math = math Math.Abs = abs Math.Acos = math.acos Math.Asin = math.asin Math.Atan = math.atan Math.Atan2 = math.atan2 or math.atan Math.BigMul = bigMul Math.Ceiling = math.ceil Math.Clamp = clamp Math.Cos = math.cos Math.Cosh = cosh Math.DivRem = divRem Math.Exp = exp Math.Floor = math.floor Math.IEEERemainder = IEEERemainder Math.Log = math.log Math.Log10 = math.log10 Math.Max = math.max Math.Min = math.min Math.Pow = pow Math.Round = round Math.Sign = sign Math.Sin = math.sin Math.Sinh = sinh Math.Sqrt = math.sqrt Math.Tan = math.tan Math.Tanh = tanh Math.Truncate = truncate System.define("System.Math", Math) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Math.lua.meta ================================================ fileFormatVersion: 2 guid: 1af4aec83bd8a5e46a73731c06f0d5ca timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Number.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local define = System.defStc local equals = System.equals local zeroFn = System.zeroFn local identityFn = System.identityFn local debugsetmetatable = System.debugsetmetatable local IComparable = System.IComparable local IComparable_1 = System.IComparable_1 local IEquatable_1 = System.IEquatable_1 local IConvertible = System.IConvertible local IFormattable = System.IFormattable local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local FormatException = System.FormatException local OverflowException = System.OverflowException local type = type local tonumber = tonumber local floor = math.floor local setmetatable = setmetatable local tostring = tostring local function hexForamt(x, n) return n == "" and "%" .. x or "%0" .. n .. x end local function floatForamt(x, n) return n == "" and "%.f" or "%." .. n .. 'f' end local function integerFormat(x, n) return n == "" and "%d" or "%0" .. n .. 'd' end local function exponentialFormat(x, n) return n == "" and "%" .. x or "%." .. n .. x end local formats = { ['x'] = hexForamt, ['X'] = hexForamt, ['f'] = floatForamt, ['F'] = floatForamt, ['d'] = integerFormat, ['D'] = integerFormat, ['e'] = exponentialFormat, ['E'] = exponentialFormat } local function toStringWithFormat(this, format) if #format ~= 0 then local i, j, x, n = format:find("^%s*([xXdDfFeE])(%d?)%s*$") if i then local f = formats[x] if f then format = f(x, n) end return format:format(this) end end return tostring(this) end local function toString(this, format) if format then return toStringWithFormat(this, format) end return tostring(this) end local function compareInt(this, v) if this < v then return -1 end if this > v then return 1 end return 0 end local function inherits(_, T) return { IComparable, IComparable_1(T), IEquatable_1(T), IConvertible, IFormattable } end local Int = define("System.Int", { base = inherits, default = zeroFn, CompareTo = compareInt, Equals = equals, ToString = toString, GetHashCode = identityFn, CompareToObj = function (this, v) if v == nil then return 1 end if type(v) ~= "number" then throw(ArgumentException("Arg_MustBeInt")) end return compareInt(this, v) end, EqualsObj = function (this, v) if type(v) ~= "number" then return false end return this == v end }) Int.__call = zeroFn local function parseInt(s, min, max) if s == nil then return nil, 1 end local v = tonumber(s) if v == nil or v ~= floor(v) then return nil, 2 end if v < min or v > max then return nil, 3 end return v end local function tryParseInt(s, min, max) local v = parseInt(s, min, max) if v then return true, v end return false, 0 end local function parseIntWithException(s, min, max) local v, err = parseInt(s, min, max) if v then return v end if err == 1 then throw(ArgumentNullException()) elseif err == 2 then throw(FormatException()) else throw(OverflowException()) end end local SByte = define("System.SByte", { Parse = function (s) return parseIntWithException(s, -128, 127) end, TryParse = function (s) return tryParseInt(s, -128, 127) end }) setmetatable(SByte, Int) local Byte = define("System.Byte", { Parse = function (s) return parseIntWithException(s, 0, 255) end, TryParse = function (s) return tryParseInt(s, 0, 255) end }) setmetatable(Byte, Int) local Int16 = define("System.Int16", { Parse = function (s) return parseIntWithException(s, -32768, 32767) end, TryParse = function (s) return tryParseInt(s, -32768, 32767) end }) setmetatable(Int16, Int) local UInt16 = define("System.UInt16", { Parse = function (s) return parseIntWithException(s, 0, 65535) end, TryParse = function (s) return tryParseInt(s, 0, 65535) end }) setmetatable(UInt16, Int) local Int32 = define("System.Int32", { Parse = function (s) return parseIntWithException(s, -2147483648, 2147483647) end, TryParse = function (s) return tryParseInt(s, -2147483648, 2147483647) end }) setmetatable(Int32, Int) local UInt32 = define("System.UInt32", { Parse = function (s) return parseIntWithException(s, 0, 4294967295) end, TryParse = function (s) return tryParseInt(s, 0, 4294967295) end }) setmetatable(UInt32, Int) local Int64 = define("System.Int64", { Parse = function (s) return parseIntWithException(s, -9223372036854775808, 9223372036854775807) end, TryParse = function (s) return tryParseInt(s, -9223372036854775808, 9223372036854775807) end }) setmetatable(Int64, Int) local UInt64 = define("System.UInt64", { Parse = function (s) return parseIntWithException(s, 0, 18446744073709551615.0) end, TryParse = function (s) return tryParseInt(s, 0, 18446744073709551615.0) end }) setmetatable(UInt64, Int) local nan = 0 / 0 local posInf = 1 / 0 local negInf = - 1 / 0 local nanHashCode = {} --http://lua-users.org/wiki/InfAndNanComparisons local function isNaN(v) return v ~= v end local function compareDouble(this, v) if this < v then return -1 end if this > v then return 1 end if this == v then return 0 end if isNaN(this) then return isNaN(v) and 0 or -1 else return 1 end end local function equalsDouble(this, v) if this == v then return true end return isNaN(this) and isNaN(v) end local function equalsObj(this, v) if type(v) ~= "number" then return false end return equalsDouble(this, v) end local function getHashCode(this) return isNaN(this) and nanHashCode or this end local Number = define("System.Number", { base = inherits, default = zeroFn, CompareTo = compareDouble, Equals = equalsDouble, ToString = toString, NaN = nan, IsNaN = isNaN, NegativeInfinity = negInf, PositiveInfinity = posInf, EqualsObj = equalsObj, GetHashCode = getHashCode, CompareToObj = function (this, v) if v == nil then return 1 end if type(v) ~= "number" then throw(ArgumentException("Arg_MustBeNumber")) end return compareDouble(this, v) end, IsFinite = function (v) return v ~= posInf and v ~= negInf and not isNaN(v) end, IsInfinity = function (v) return v == posInf or v == negInf end, IsNegativeInfinity = function (v) return v == negInf end, IsPositiveInfinity = function (v) return v == posInf end }) Number.__call = zeroFn if debugsetmetatable then debugsetmetatable(0, Number) end local function parseDouble(s) if s == nil then return nil, 1 end local v = tonumber(s) if v == nil then return nil, 2 end return v end local function parseDoubleWithException(s) local v, err = parseDouble(s) if v then return v end if err == 1 then throw(ArgumentNullException()) else throw(FormatException()) end end local Single = define("System.Single", { Parse = function (s) local v = parseDoubleWithException(s) if v < -3.40282347E+38 or v > 3.40282347E+38 then throw(OverflowException()) end return v end, TryParse = function (s) local v = parseDouble(s) if v and v >= -3.40282347E+38 and v < 3.40282347E+38 then return true, v end return false, 0 end }) setmetatable(Single, Number) local Double = define("System.Double", { Parse = parseDoubleWithException, TryParse = function (s) local v = parseDouble(s) if v then return true, v end return false, 0 end }) setmetatable(Double, Number) if not debugsetmetatable then local NullReferenceException = System.NullReferenceException local systemToString = System.toString function System.ObjectEqualsObj(this, obj) if this == nil then throw(NullReferenceException()) end local t = type(this) if t == "number" then return equalsObj(this, obj) elseif t == "table" then return this:EqualsObj(obj) end return this == obj end function System.ObjectGetHashCode(this) if this == nil then throw(NullReferenceException()) end local t = type(this) if t == "number" then return getHashCode(this) elseif t == "table" then return this:GetHashCode() end return this end function System.ObjectToString(this) if this == nil then throw(NullReferenceException()) end return systemToString(this) end function System.IComparableCompareTo(this, other) if this == nil then throw(NullReferenceException()) end local t = type(this) if t == "number" then return compareDouble(this, other) elseif t == "boolean" then return System.Boolean.CompareTo(this, other) end return this:CompareTo(other) end function System.IEquatableEquals(this, other) if this == nil then throw(NullReferenceException()) end local t = type(this) if t == "number" then return equalsDouble(this, other) elseif t == "boolean" then return System.Boolean.Equals(this, other) end return this:Equals(other) end function System.IFormattableToString(this, format, formatProvider) if this == nil then throw(NullReferenceException()) end local t = type(this) if t == "number" then return toString(this, format, formatProvider) end return this:ToString(format, formatProvider) end end ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Number.lua.meta ================================================ fileFormatVersion: 2 guid: 2eecf846c651b94499eb8d2a1eab202a DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Random.lua ================================================ -- Compiled from https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/Random.cs -- Generated by CSharp.lua Compiler -- Licensed to the .NET Foundation under one or more agreements. -- The .NET Foundation licenses this file to you under the MIT license. -- See the LICENSE file in the project root for more information. local System = System local ArrayInt32 = System.Array(System.Int32) System.define("System.Random", (function () local Sample, InternalSample, GenerateSeed, Next, GetSampleForLargeRange, NextDouble, NextBytes, internal, __ctor__, rnd internal = function (this) this._seedArray = ArrayInt32:new(56) end __ctor__ = function (this, Seed) if not Seed then Seed = GenerateSeed() end internal(this) local ii = 0 local mj, mk --Initialize our Seed array. local subtraction = (Seed == -2147483648 --[[Int32.MinValue]]) and 2147483647 --[[Int32.MaxValue]] or math.Abs(Seed) mj = 161803398 --[[Random.MSEED]] - subtraction this._seedArray:set(55, mj) mk = 1 for i = 1, 54 do --Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position. ii = ii + 21 if ii >= 55 then ii = ii - 55 end this._seedArray:set(ii, mk) mk = mj - mk if mk < 0 then mk = mk + 2147483647 --[[Random.MBIG]] end mj = this._seedArray:get(ii) end for k = 1, 4 do for i = 1, 55 do local n = i + 30 if n >= 55 then n = n - 55 end local v = this._seedArray:get(i) - this._seedArray:get(1 + n) this._seedArray:set(i, System.toInt32(v)) if this._seedArray:get(i) < 0 then this._seedArray:set(i, this._seedArray:get(i) + 2147483647 --[[Random.MBIG]]) end end end this._inext = 0 this._inextp = 21 Seed = 1 end Sample = function (this) --Including this division at the end gives us significantly improved --random number distribution. return (InternalSample(this) * (4.6566128752457969E-10 --[[1.0 / MBIG]])) end InternalSample = function (this) local retVal local locINext = this._inext local locINextp = this._inextp locINext = locINext + 1 if locINext >= 56 then locINext = 1 end locINextp = locINextp + 1 if locINextp >= 56 then locINextp = 1 end retVal = this._seedArray:get(locINext) - this._seedArray:get(locINextp) if retVal == 2147483647 --[[Random.MBIG]] then retVal = retVal - 1 end if retVal < 0 then retVal = retVal + 2147483647 --[[Random.MBIG]] end this._seedArray:set(locINext, retVal) this._inext = locINext this._inextp = locINextp return retVal end GenerateSeed = function () if not rnd then math.randomseed(os.time()) rnd = math.random end return rnd(0, 2147483647) end Next = function (this, minValue, maxValue) if not minValue then return InternalSample(this) end if not maxValue then maxValue = minValue if maxValue < 0 then System.throw(System.ArgumentOutOfRangeException("maxValue" --[[nameof(maxValue)]], "'maxValue' must be greater than zero.")) end return System.ToInt32((Sample(this) * maxValue)) end if minValue > maxValue then System.throw(System.ArgumentOutOfRangeException("minValue" --[[nameof(minValue)]], "'minValue' cannot be greater than maxValue.")) end local range = maxValue - minValue if range <= 2147483647 --[[Int32.MaxValue]] then return (System.ToInt32((Sample(this) * range)) + minValue) else return System.toInt32((System.ToInt64((GetSampleForLargeRange(this) * range)) + minValue)) end end GetSampleForLargeRange = function (this) -- The distribution of double value returned by Sample -- is not distributed well enough for a large range. -- If we use Sample for a range [int.MinValue..int.MaxValue) -- We will end up getting even numbers only. local result = InternalSample(this) -- Note we can't use addition here. The distribution will be bad if we do that. local negative = (InternalSample(this) % 2 == 0) and true or false -- decide the sign based on second sample if negative then result = - result end local d = result d = d + (2147483646 --[[int.MaxValue - 1]]) -- get a number in range [0 .. 2 * Int32MaxValue - 1) d = d / (4294967293 --[[2 * (uint)int.MaxValue - 1]]) return d end NextDouble = function (this) return Sample(this) end NextBytes = function (this, buffer) if buffer == nil then System.throw(System.ArgumentNullException("buffer" --[[nameof(buffer)]])) end do local i = 0 while i < #buffer do buffer:set(i, System.toByte(InternalSample(this))) i = i + 1 end end end return { _inext = 0, _inextp = 0, Sample = Sample, Next = Next, NextDouble = NextDouble, NextBytes = NextBytes, __ctor__ = __ctor__ } end)()) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Random.lua.meta ================================================ fileFormatVersion: 2 guid: cd34ae8a3389fae4cbf545d1d2d997b2 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Reflection/Assembly.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local div = System.div local Type = System.Type local typeof = System.typeof local getClass = System.getClass local is = System.is local band = System.band local arrayFromTable = System.arrayFromTable local toLuaTable = System.toLuaTable local Exception = System.Exception local NotSupportedException = System.NotSupportedException local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local assert = assert local pairs = pairs local getmetatable = getmetatable local setmetatable = setmetatable local rawget = rawget local type = type local unpack = table.unpack local select = select local TargetException = define("System.Reflection.TargetException", { __tostring = Exception.ToString, base = { Exception } }) local TargetParameterCountException = define("System.Reflection.TargetParameterCountException", { __tostring = Exception.ToString, base = { Exception }, __ctor__ = function(this, message, innerException) Exception.__ctor__(this, message or "Parameter count mismatch.", innerException) end, }) local AmbiguousMatchException = define("System.Reflection.AmbiguousMatchException", { __tostring = Exception.ToString, base = { System.SystemException }, __ctor__ = function(this, message, innerException) Exception.__ctor__(this, message or "Ambiguous match found.", innerException) end, }) local MissingMethodException = define("System.MissingMethodException", { __tostring = Exception.ToString, base = { Exception }, __ctor__ = function(this, message, innerException) Exception.__ctor__(this, message or "Specified method could not be found.", innerException) end }) local function throwNoMatadata(sign) throw(NotSupportedException("not found metadata for " .. sign), 1) end local function eq(left, right) return left[1] == right[1] and left.name == right.name end local function getName(this) return this.name end local function isAccessibility(memberInfo, kind) local metadata = memberInfo.metadata if not metadata then throwNoMatadata(memberInfo.c.__name__ .. "." .. memberInfo.name) end return band(metadata[2], 0x7) == kind end local MemberInfo = define("System.Reflection.MemberInfo", { getName = getName, EqualsObj = function (this, obj) if getmetatable(this) ~= getmetatable(obj) then return false end return eq(this, obj) end, getMemberType = function (this) return this.memberType end, getDeclaringType = function (this) return typeof(this.c) end, getIsStatic = function (this) local metadata = this.metadata if not metadata then throwNoMatadata(this.c.__name__ .. "." .. this.name) end return band(metadata[2], 0x8) == 1 end, getIsPrivate = function (this) return isAccessibility(this, 1) end, getIsFamilyAndAssembly = function (this) return isAccessibility(this, 2) end, getIsFamily = function (this) return isAccessibility(this, 3) end, getIsAssembly = function (this) return isAccessibility(this, 4) end, getIsFamilyOrAssembly = function (this) return isAccessibility(this, 5) end, getIsPublic = function (this) return isAccessibility(this, 6) end }) local function getFieldOrPropertyType(this) local metadata = this.metadata if not metadata then throwNoMatadata(this.c.__name__ .. "." .. this.name) end return typeof(metadata[3]) end local function checkObj(obj, cls) if not is(obj, cls) then throw(ArgumentException("Object does not match target type.", "obj"), 1) end end local function checkTarget(cls, obj, metadata) if band(metadata[2], 0x8) == 0 then if obj == nil then throw(TargetException()) end checkObj(obj, cls) else return true end end local function checkValue(value, valueClass) if value == nil then if valueClass.class == "S" then value = valueClass:default() end else checkObj(value, valueClass) end return value end local function getOrSetField(this, obj, isSet, value) local cls, metadata = this.c, this.metadata if metadata then if checkTarget(cls, obj, metadata) then obj = cls end local name = metadata[4] if type(name) ~= "string" then name = this.name end if isSet then obj[name] = checkValue(value, metadata[3]) else return obj[name] end else if obj ~= nil then checkObj(obj, cls) else obj = cls end if isSet then obj[this.name] = value else return obj[this.name] end end end local function isMetadataDefined(metadata, index, attributeType) attributeType = attributeType[1] for i = index, #metadata do if is(metadata[i], attributeType) then return true end end return false end local function fillMetadataCustomAttributes(t, metadata, index, attributeType) local count = #t + 1 if attributeType then attributeType = attributeType[1] for i = index, #metadata do if is(metadata[i], attributeType) then t[count] = metadata[i] count = count + 1 end end else for i = index, #metadata do t[count] = metadata[i] count = count + 1 end end end local FieldInfo = define("System.Reflection.FieldInfo", { __eq = eq, base = { MemberInfo }, memberType = 4, getFieldType = getFieldOrPropertyType, GetValue = getOrSetField, SetValue = function (this, obj, value) getOrSetField(this, obj, true, value) end, IsDefined = function (this, attributeType) if attributeType == nil then throw(ArgumentNullException()) end local metadata = this.metadata if metadata then return isMetadataDefined(metadata, 4, attributeType) end return false end, GetCustomAttributes = function (this, attributeType, inherit) if type(attributeType) == "boolean" then attributeType, inherit = nil, attributeType else if attributeType == nil then throw(ArgumentNullException()) end end local t = {} local metadata = this.metadata if metadata then local index = 4 if type(metadata[index]) == "string" then index = 5 end fillMetadataCustomAttributes(t, metadata, index, attributeType) end return arrayFromTable(t, System.Attribute) end }) local function getOrSetProperty(this, obj, isSet, value) local cls, metadata = this.c, this.metadata if metadata then local isStatic if checkTarget(cls, obj, metadata) then obj = cls isStatic = true end if isSet then value = checkValue(value, metadata[3]) end local kind = band(metadata[2], 0x300) if kind == 0 then local name = metadata[4] if type(name) ~= "string" then name = this.name end if isSet then obj[name] = value else return obj[name] end else local index if kind == 0x100 then index = isSet and 5 or 4 elseif kind == 0x200 then if isSet then throw(ArgumentException("Property Set method was not found.")) end index = 4 else if not isSet then throw(ArgumentException("Property Get method was not found.")) end index = 4 end local fn = metadata[index] if type(fn) == "table" then fn = fn[1] end if isSet then if isStatic then fn(value) else fn(obj, value) end else return fn(obj) end end else local isStatic if obj ~= nil then checkObj(obj, cls) else obj = cls isStatic = true end if this.isField then if isSet then obj[this.name] = value else return obj[this.name] end else if isSet then local fn = obj["set" .. this.name] if fn == nil then throw(ArgumentException("Property Set method not found.")) end if isStatic then fn(value) else fn(obj, value) end else local fn = obj["get" .. this.name] if fn == nil then throw(ArgumentException("Property Get method not found.")) end return fn(obj) end end end end local function getPropertyAttributesIndex(metadata) local kind = band(metadata[2], 0x300) local index if kind == 0 then index = 4 elseif kind == 0x100 then index = 6 else index = 5 end return index end local PropertyInfo = define("System.Reflection.PropertyInfo", { __eq = eq, base = { MemberInfo }, memberType = 16, getPropertyType = getFieldOrPropertyType, GetValue = getOrSetProperty, SetValue = function (this, obj, value) getOrSetProperty(this, obj, true, value) end, IsDefined = function (this, attributeType) if attributeType == nil then throw(ArgumentNullException()) end local metadata = this.metadata if metadata then local index = getPropertyAttributesIndex(metadata) return isMetadataDefined(metadata, index, attributeType) end return false end, GetCustomAttributes = function (this, attributeType, inherit) if type(attributeType) == "boolean" then attributeType, inherit = nil, attributeType else if attributeType == nil then throw(ArgumentNullException()) end end local t = {} local metadata = this.metadata if metadata then local index = getPropertyAttributesIndex(metadata) fillMetadataCustomAttributes(t, metadata, index, attributeType) end return arrayFromTable(t, System.Attribute) end }) local function hasPublicFlag(flags) return band(flags, 0x7) == 6 end local function getMethodParameterCount(flags) local count = band(flags, 0xFF00) if count ~= 0 then count = count / 256 end return count end local function getMethodAttributesIndex(metadata) local flags = metadata[2] local index local typeParametersCount = band(flags, 0xFF0000) if typeParametersCount == 0 then local parameterCount = getMethodParameterCount(flags) if band(flags, 0x80) == 0 then index = 4 + parameterCount else index = 5 + parameterCount end else index = 5 end return index end local MethodInfo = define("System.Reflection.MethodInfo", { __eq = eq, base = { MemberInfo }, memberType = 8, getReturnType = function (this) local metadata = this.metadata if not metadata then throwNoMatadata(this.c.__name__ .. "." .. this.name) end local flags = metadata[2] if band(flags, 0x80) == 0 then return Type.Void end if band(flags, 0xC00) > 0 then assert(false, "not implement for generic method") end local parameterCount = band(flags, 0x300) return typeof(metadata[4 + parameterCount]) end, Invoke = function (this, obj, parameters) local cls, metadata = this.c, this.metadata if metadata then local isStatic if checkTarget(cls, obj, metadata) then isStatic = true end local t local parameterCount = band(metadata[2], 0x300) if parameterCount == 0 then if parameters ~= nil and #parameters > 0 then throw(TargetParameterCountException()) end else if parameters == nil and #parameters ~= parameterCount then throw(TargetParameterCountException()) end for i = 4, 3 + parameterCount do local j = #t t[j + 1] = checkValue(parameters:get(j), metadata[i]) end end local f = metadata[3] if isStatic then if t then return f(unpack(t, 1, parameterCount)) else return f() end else if t then return f(obj, unpack(t, 1, parameterCount)) else return f(obj) end end else local f = assert(this.f) if obj ~= nil then checkObj(obj, cls) if parameters ~= nil then local t = toLuaTable(parameters) return f(obj, unpack(t, 1, #parameters)) else return f(obj) end else if parameters ~= nil then local t = toLuaTable(parameters) return f(unpack(t, 1, #parameters)) else return f() end end end end, IsDefined = function (this, attributeType, inherit) if attributeType == nil then throw(ArgumentNullException()) end local metadata = this.metadata if metadata then local index = getMethodAttributesIndex(metadata) return isMetadataDefined(metadata, index, attributeType) end return false end, GetCustomAttributes = function (this, attributeType, inherit) if type(attributeType) == "boolean" then attributeType, inherit = nil, attributeType else if attributeType == nil then throw(ArgumentNullException()) end end local t = {} local metadata = this.metadata if metadata then local index = getMethodAttributesIndex(metadata) fillMetadataCustomAttributes(t, metadata, index, attributeType) end return arrayFromTable(t, System.Attribute) end }) local function buildFieldInfo(cls, name, metadata) return setmetatable({ c = cls, name = name, metadata = metadata }, FieldInfo) end local function buildPropertyInfo(cls, name, metadata, isField) return setmetatable({ c = cls, name = name, metadata = metadata, isField = isField }, PropertyInfo) end local function buildMethodInfo(cls, name, metadata, f) return setmetatable({ c = cls, name = name, metadata = metadata, f = f }, MethodInfo) end -- https://en.cppreference.com/w/cpp/algorithm/lower_bound local function lowerBound(t, first, last, value, comp) local count = last - first local it, step while count > 0 do it = first step = div(count, 2) it = it + step if comp(t[it], value) then it = it + 1 first = it count = count - (step + 1) else count = step end end return first end local function metadataItemCompByName(item, name) return item[1] < name end local function binarySearchByName(metadata, name) local last = #metadata + 1 local index = lowerBound(metadata, 1, last, name, metadataItemCompByName) if index ~= last then return metadata[index], index end return nil end function Type.GetField(this, name) if name == nil then throw(ArgumentNullException()) end local cls = this[1] local metadata = cls.__metadata__ if metadata then local fields = metadata.fields if fields then local field = binarySearchByName(fields, name) if field then return buildFieldInfo(cls, name, field) end return nil end end if type(cls[name]) ~= "function" then return buildFieldInfo(cls, name) end end function Type.GetFields(this) local t = {} local cls = this[1] local count = 1 repeat local metadata = rawget(cls, "__metadata__") if metadata then local fields = metadata.fields if fields then for i = 1, #fields do local field = fields[i] if hasPublicFlag(field[2]) then t[count] = buildFieldInfo(cls, field[1], field) count = count + 1 end end else metadata = nil end end if not metadata then for k, v in pairs(cls) do if type(v) ~= "function" then t[count] = buildFieldInfo(cls, k) count = count + 1 end end end cls = getmetatable(cls) until cls == nil return arrayFromTable(t, FieldInfo) end function Type.GetProperty(this, name) if name == nil then throw(ArgumentNullException()) end local cls = this[1] local metadata = cls.__metadata__ if metadata then local properties = metadata.properties if properties then local property = binarySearchByName(properties, name) if property then return buildPropertyInfo(cls, name, property) end return nil end end if cls["get" .. name] or cls["set" .. name] then return buildPropertyInfo(cls, name) else return buildPropertyInfo(cls, name, nil, true) end end function Type.GetProperties(this) local t = {} local cls = this[1] local count = 1 repeat local metadata = rawget(cls, "__metadata__") if metadata then local properties = metadata.properties if properties then for i = 1, #properties do local property = properties[i] if hasPublicFlag(property[2]) then t[count] = buildPropertyInfo(cls, property[1], property) count = count + 1 end end end end cls = getmetatable(cls) until cls == nil return arrayFromTable(t, PropertyInfo) end function Type.GetMethod(this, name) if name == nil then throw(ArgumentNullException()) end local cls = this[1] local metadata = cls.__metadata__ if metadata then local methods = metadata.methods if methods then local item, index = binarySearchByName(methods, name) if item then local next = methods[index + 1] if next and next[1] == name then throw(AmbiguousMatchException()) end return buildMethodInfo(cls, name, item) end return nil end end local f = cls[name] if type(f) == "function" then return buildMethodInfo(cls, name, nil, f) end end function Type.GetMethods(this) local t = {} local cls = this[1] local count = 1 repeat local metadata = rawget(cls, "__metadata__") if metadata then local methods = metadata.methods if methods then for i = 1, #methods do local method = methods[i] if hasPublicFlag(method[2]) then t[count] = buildMethodInfo(cls, method[1], method) count = count + 1 end end else metadata = nil end end if not metadata then for k, v in pairs(cls) do if type(v) == "function" then t[count] = buildMethodInfo(cls, k, nil, v) count = count + 1 end end end cls = getmetatable(cls) until cls == nil return arrayFromTable(t, MethodInfo) end function Type.GetMembers(this) local t = arrayFromTable({}, MemberInfo) t:addRange(this:GetFields()) t:addRange(this:GetProperties()) t:addRange(this:GetMethods()) return t end function Type.IsDefined(this, attributeType, inherit) if attributeType == nil then throw(ArgumentNullException()) end local cls = this[1] if not inherit then local metadata = rawget(cls, "__metadata__") if metadata then local class = metadata.class if class then return isMetadataDefined(class, 2, attributeType) end end return false else repeat local metadata = rawget(cls, "__metadata__") if metadata then local class = metadata.class if class then if isMetadataDefined(class, 2, attributeType) then return true end end end cls = getmetatable(cls) until cls == nil return false end end function Type.GetCustomAttributes(this, attributeType, inherit) if type(attributeType) == "boolean" then attributeType, inherit = nil, attributeType else if attributeType == nil then throw(ArgumentNullException()) end end local cls = this[1] local t = {} if not inherit then local metadata = rawget(cls, "__metadata__") if metadata then local class = metadata.class if class then fillMetadataCustomAttributes(t, class, 2, attributeType) end end else repeat local metadata = rawget(cls, "__metadata__") if metadata then local class = metadata.class if class then fillMetadataCustomAttributes(t, class, 2, attributeType) end end cls = getmetatable(cls) until cls == nil end return arrayFromTable(t, System.Attribute) end local Assembly, coreSystemAssembly local function getAssembly(t) local assembly = t[1].__assembly__ if assembly then return setmetatable(assembly, Assembly) end return coreSystemAssembly end local function getAssemblyName(this) local name = this.name or "CSharpLua.CoreLib" return name .. ", Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" end Assembly = define("System.Reflection.Assembly", { GetName = getAssemblyName, getFullName = getAssemblyName, GetAssembly = getAssembly, GetTypeFrom = Type.GetTypeFrom, GetEntryAssembly = function () local entryAssembly = System.entryAssembly if entryAssembly then return setmetatable(entryAssembly, Assembly) end return nil end, getEntryPoint = function (this) local entryPoint = this.entryPoint if entryPoint ~= nil then local _, _, t, name = entryPoint:find("(.*)%.(.*)") local cls = getClass(t) local f = assert(cls[name]) return buildMethodInfo(cls, name, nil, f) end return nil end, GetExportedTypes = function (this) if this.exportedTypes then return this.exportedTypes end local t = {} local classes = this.classes if classes then for i = 1, #classes do t[i] = typeof(classes[i]) end end local array = arrayFromTable(t, Type, true) this.exportedTypes = array return array end }) coreSystemAssembly = Assembly() function System.GetExecutingAssembly(assembly) return setmetatable(assembly, Assembly) end Type.getAssembly = getAssembly function Type.getAssemblyQualifiedName(this) return this:getName() .. ', ' .. getName(assembly) end function Type.getAttributes(this) local cls = this[1] local metadata = rawget(cls, "__metadata__") if metadata then metadata = metadata.class if metadata then return metadata[1] end end throwNoMatadata(cls.__name__) end function Type.GetGenericArguments(this) local t = {} local count = 1 local cls = this[1] local metadata = rawget(cls, "__metadata__") if metadata then metadata = metadata.class if metadata then local flags = metadata[1] local typeParameterCount = band(flags, 0xFF00) if typeParameterCount ~= 0 then typeParameterCount = typeParameterCount / 256 for i = 2, 1 + typeParameterCount do t[count] = typeof(metadata[i]) count = count + 1 end end return arrayFromTable(t, Type) end end local name = cls.__name__ local i = name:find("%[") if i then while true do i = i + 1 local j = name:find(",", i) or -1 local clsName = name:sub(i, j - 1) t[count] = typeof(System.getClass(clsName)) count = count + 1 if j == -1 then break end end end return arrayFromTable(t, Type) end local Attribute = System.Attribute function Attribute.GetCustomAttribute(element, attributeType, inherit) return element:GetCustomAttribute(attributeType, inherit) end function Attribute.GetCustomAttributes(element, attributeType, inherit) return element:GetCustomAttributes(attributeType, inherit) end function Attribute.IsDefined(element, attributeType, inherit) return element:IsDefined(attributeType, inherit) end local function createInstance(T, nonPublic) local metadata = rawget(T, "__metadata__") if metadata then local methods = metadata.methods if methods then local ctorMetadata = methods[1] if ctorMetadata[1] == ".ctor" then local flags = ctorMetadata[2] if nonPublic or hasPublicFlag(flags) then local parameterCount = getMethodParameterCount(flags) if parameterCount == 0 then return T() end end throw(MissingMethodException()) end end end return T() end local function isCtorMatch(method, n, f, ...) local flags = method[2] if hasPublicFlag(flags) then local parameterCount = getMethodParameterCount(flags) if parameterCount == n then for j = 4, 3 + parameterCount do local p = f(j - 3, ...) if not is(p, method[j]) then return false end end return true end end return false end local function findMatchCtor(T, n, f, ...) local metadata = rawget(T, "__metadata__") if metadata then local hasCtor local methods = metadata.methods for i = 1, #methods do local method = methods[i] if method[1] == ".ctor" then if isCtorMatch(method, n, f, ...) then return i end hasCtor = true else break end end if hasCtor then throw(MissingMethodException()) end end end define("System.Activator", { CreateInstance = function (type, ...) if type == nil then throw(ArgumentNullException("type")) end if getmetatable(type) ~= Type then return createInstance(type) end local T, n = type[1], select("#", ...) if n == 0 then return createInstance(T) elseif n == 1 then local args = ... if System.isArrayLike(args) then n = #args if n == 0 then return createInstance(T) end local i = findMatchCtor(T, n, function (i, args) return args:get(i - 1) end, args) if i and i ~= 1 then return System.new(T, i, unpack(args, 1, n)) end return T(unpack(args, 1, n)) end end local i = findMatchCtor(T, n, select, ...) if i and i ~= 1 then return System.new(T, i, ...) end return T(...) end, CreateInstance1 = function (type, nonPublic) if type == nil then throw(ArgumentNullException("type")) end return createInstance(type[1], nonPublic) end }) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Reflection/Assembly.lua.meta ================================================ fileFormatVersion: 2 guid: c05cd872a9424a24ca906af0a900fbdd timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Reflection.meta ================================================ fileFormatVersion: 2 guid: a35613a01cc419e4d80e4f2a08931462 folderAsset: yes timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/String.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local Char = System.Char local throw = System.throw local emptyFn = System.emptyFn local lengthFn = System.lengthFn local systemToString = System.toString local debugsetmetatable = System.debugsetmetatable local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local FormatException = System.FormatException local IndexOutOfRangeException = System.IndexOutOfRangeException local string = string local char = string.char local rep = string.rep local lower = string.lower local upper = string.upper local byte = string.byte local sub = string.sub local find = string.find local gsub = string.gsub local table = table local tconcat = table.concat local unpack = table.unpack local getmetatable = getmetatable local setmetatable = setmetatable local select = select local type = type local String local function toString(t, isch) if isch then return char(t) end return systemToString(t) end local function checkIndex(value, startIndex, count) if value == nil then throw(ArgumentNullException("value")) end local len = #value if not startIndex then startIndex, count = 0, len elseif not count then if startIndex < 0 or startIndex > len then throw(ArgumentOutOfRangeException("startIndex")) end count = len - startIndex else if startIndex < 0 or startIndex > len then throw(ArgumentOutOfRangeException("startIndex")) end if count < 0 or count > len - startIndex then throw(ArgumentOutOfRangeException("count")) end end return startIndex, count, len end local function ctor(String, value, startIndex, count) if type(value) == "number" then if startIndex <= 0 then throw(ArgumentOutOfRangeException("count")) end return rep(char(value), startIndex) end startIndex, count = checkIndex(value, startIndex, count) return char(unpack(value, startIndex + 1, startIndex + count)) end local function get(this, index) local c = byte(this, index + 1) if not c then throw(IndexOutOfRangeException()) end return c end local function compare(strA, strB, ignoreCase) if strA == nil then if strB == nil then return 0 end return -1 elseif strB == nil then return 1 end if ignoreCase then strA, strB = lower(strA), lower(strB) end if strA < strB then return -1 end if strA > strB then return 1 end return 0 end local function compareFull(...) local n = select("#", ...) if n == 2 then return compare(...) elseif n == 3 then local strA, strB, ignoreCase = ... if type(ignoreCase) == "number" then ignoreCase = ignoreCase % 2 ~= 0 end return compare(strA, strB, ignoreCase) elseif n == 4 then local strA, strB, ignoreCase, options = ... if type(options) == "number" then ignoreCase = options == 1 or options == 268435456 end return compare(strA, strB, ignoreCase) else local strA, indexA, strB, indexB, length, ignoreCase, options = ... if type(ignoreCase) == "number" then ignoreCase = ignoreCase % 2 ~= 0 elseif type(options) == "number" then ignoreCase = options == 1 or options == 268435456 end checkIndex(strA, indexA, length) checkIndex(strB, indexB, length) strA, strB = sub(strA, indexA + 1, indexA + length), sub(strB, indexB + 1, indexB + length) return compare(strA, strB, ignoreCase) end end local function concat(...) local t = {} local count = 1 local len = select("#", ...) if len == 1 then local v = ... if System.isEnumerableLike(v) then local isch = v.__genericT__ == Char for _, v in System.each(v) do t[count] = toString(v, isch) count = count + 1 end else return toString(v) end else for i = 1, len do local v = select(i, ...) t[count] = toString(v) count = count + 1 end end return tconcat(t) end local function equals(this, value, comparisonType) if not comparisonType then return this == value end return compare(this, value, comparisonType % 2 ~= 0) == 0 end local function throwFormatError() throw(FormatException("Input string was not in a correct format.")) end local function formatBuild(format, len, select, ...) local t, count = {}, 1 local i, j, s = 1 while true do local startPos = i while true do i, j, s = find(format, "([{}])", i) if not i then if count == 1 then return format end t[count] = sub(format, startPos) return table.concat(t) end local pos = i - 1 i = i + 1 local c = byte(format, i) if not c then throwFormatError() end if s == '{' then if c == 123 then i = i + 1 else pos = i - 2 if pos >= startPos then t[count] = sub(format, startPos, pos) count = count + 1 end break end else if c == 125 then i = i + 1 else throwFormatError() end end if pos >= startPos then t[count] = sub(format, startPos, pos) count = count + 1 end t[count] = s count = count + 1 startPos = i end i, j, s = find(format, "^(%d+)}", i) if not i then throwFormatError() end s = s + 1 if s > len then throwFormatError() end s = select(s, ...) s = (s ~= nil and s ~= System.null) and toString(s) t[count] = s count = count + 1 i = j + 1 end end local function selectTable(i, t) return t[i] end local function format(format, ...) if format == nil then throw(ArgumentNullException()) end local len = select("#", ...) if len == 1 then local args = ... if System.isArrayLike(args) then return formatBuild(format, #args, selectTable, args) end end return formatBuild(format, len, select, ...) end local function isNullOrEmpty(value) return value == nil or #value == 0 end local function isNullOrWhiteSpace(value) return value == nil or find(value, "^%s*$") ~= nil end local function joinEnumerable(separator, values) if values == nil then throw(ArgumentNullException("values")) end if type(separator) == "number" then separator = char(separator) end local isch = values.__genericT__ == Char local t = {} local len = 1 for _, v in System.each(values) do if v ~= nil then t[len] = toString(v, isch) len = len + 1 end end return tconcat(t, separator) end local function joinParams(separator, ...) if type(separator) == "number" then separator = char(separator) end local t = {} local len = 1 local n = select("#", ...) if n == 1 then local values = ... if System.isArrayLike(values) then for i = 0, #values - 1 do local v = values:get(i) if v ~= nil then t[len] = toString(v) len = len + 1 end end return tconcat(t, separator) end end for i = 1, n do local v = select(i, ...) if v ~= nil then t[len] = toString(v) len = len + 1 end end return tconcat(t, separator) end local function join(separator, value, startIndex, count) if type(separator) == "number" then separator = char(separator) end local t = {} local len = 1 if startIndex then checkIndex(value, startIndex, count) for i = startIndex + 1, startIndex + count do local v = value[i] if v ~= System.null then t[len] = v len = len + 1 end end else for _, v in System.each(value) do if v ~= nil then t[len] = v len = len + 1 end end end return tconcat(t, separator) end local function compareToObj(this, v) if v == nil then return 1 end if type(v) ~= "string" then throw(ArgumentException("Arg_MustBeString")) end return compare(this, v) end local function escape(s) return gsub(s, "([%%%^%.])", "%%%1") end local function contains(this, value, comparisonType) if value == nil then throw(ArgumentNullException("value")) end if type(value) == "number" then value = char(value) end if comparisonType then local ignoreCase = comparisonType % 2 ~= 0 if ignoreCase then this, value = lower(this), lower(value) end end return find(this, escape(value)) ~= nil end local function copyTo(this, sourceIndex, destination, destinationIndex, count) if destination == nil then throw(ArgumentNullException("destination")) end if count < 0 then throw(ArgumentOutOfRangeException("count")) end local len = #this if sourceIndex < 0 or count > len - sourceIndex then throw(ArgumentOutOfRangeException("sourceIndex")) end if destinationIndex > #destination - count or destinationIndex < 0 then throw(ArgumentOutOfRangeException("destinationIndex")) end if count > 0 then destinationIndex = destinationIndex + 1 for i = sourceIndex + 1, sourceIndex + count do destination[destinationIndex] = byte(this, i) destinationIndex = destinationIndex + 1 end end end local function endsWith(this, suffix) return suffix == "" or sub(this, -#suffix) == suffix end local function equalsObj(this, v) if type(v) == "string" then return this == v end return false end local CharEnumerator = System.define("System.CharEnumerator", { base = { System.IEnumerator_1(System.Char), System.IDisposable, System.ICloneable }, getCurrent = System.getCurrent, Dispose = emptyFn, MoveNext = function (this) local index, s = this.index, this.s if index <= #s then this.current = byte(s, index) this.index = index + 1 return true end return false end }) local function getEnumerator(this) return setmetatable({ s = this, index = 1 }, CharEnumerator) end local function getTypeCode() return 18 end local function indexOf(this, value, startIndex, count, comparisonType) if value == nil then throw(ArgumentNullException("value")) end startIndex, count = checkIndex(this, startIndex, count) if type(value) == "number" then value = char(value) end local ignoreCase = comparisonType and comparisonType % 2 ~= 0 if ignoreCase then this, value = lower(this), lower(value) end local i, j = find(this, escape(value), startIndex + 1) if i then local e = startIndex + count if j <= e then return i - 1 end return - 1 end return -1 end local function indexOfAny(this, anyOf, startIndex, count) if anyOf == nil then throw(ArgumentNullException("chars")) end startIndex, count = checkIndex(this, startIndex, count) anyOf = "[" .. escape(char(unpack(anyOf))) .. "]" local i, j = find(this, anyOf, startIndex + 1) if i then local e = startIndex + count if j <= e then return i - 1 end return - 1 end return -1 end local function insert(this, startIndex, value) if value == nil then throw(ArgumentNullException("value")) end if startIndex < 0 or startIndex > #this then throw(ArgumentOutOfRangeException("startIndex")) end return sub(this, 1, startIndex) .. value .. sub(this, startIndex + 1) end local function chechLastIndexOf(value, startIndex, count) if value == nil then throw(ArgumentNullException("value")) end local len = #value if not startIndex then startIndex, count = len - 1, len elseif not count then count = len == 0 and 0 or (startIndex + 1) end if len == 0 then if startIndex ~= -1 and startIndex ~= 0 then throw(ArgumentOutOfRangeException("startIndex")) end if count ~= 0 then throw(ArgumentOutOfRangeException("count")) end end if startIndex < 0 or startIndex >= len then throw(ArgumentOutOfRangeException("startIndex")) end if count < 0 or startIndex - count + 1 < 0 then throw(ArgumentOutOfRangeException("count")) end return startIndex, count, len end local function lastIndexOf(this, value, startIndex, count, comparisonType) if value == nil then throw(ArgumentNullException("value")) end startIndex, count = chechLastIndexOf(this, startIndex, count) if type(value) == "number" then value = char(value) end local ignoreCase = comparisonType and comparisonType % 2 ~= 0 if ignoreCase then this, value = lower(this), lower(value) end value = escape(value) local e = startIndex + 1 local f = e - count + 1 local index = -1 while true do local i, j = find(this, value, f) if not i or j > e then break end index = i - 1 f = j + 1 end return index end local function lastIndexOfAny(this, anyOf, startIndex, count) if anyOf == nil then throw(ArgumentNullException("chars")) end startIndex, count = chechLastIndexOf(this, startIndex, count) anyOf = "[" .. escape(char(unpack(anyOf))) .. "]" local f, e = startIndex - count + 1, startIndex + 1 local index = -1 while true do local i, j = find(this, anyOf, f) if not i or j > e then break end index = i - 1 f = j + 1 end return index end local function padLeft(this, totalWidth, paddingChar) local len = #this; if len >= totalWidth then return this else paddingChar = paddingChar or 0x20 return rep(char(paddingChar), totalWidth - len) .. this end end local function padRight(this, totalWidth, paddingChar) local len = #this if len >= totalWidth then return this else paddingChar = paddingChar or 0x20 return this .. rep(char(paddingChar), totalWidth - len) end end local function remove(this, startIndex, count) startIndex, count = checkIndex(this, startIndex, count) return sub(this, 1, startIndex) .. sub(this, startIndex + 1 + count) end local function replace(this, a, b) if type(a) == "number" then a, b = char(a), char(b) end return gsub(this, escape(a), b) end local function findAny(s, strings, startIndex) local findBegin, findEnd for i = 1, #strings do local posBegin, posEnd = find(s, escape(strings[i]), startIndex) if posBegin then if not findBegin or posBegin < findBegin then findBegin, findEnd = posBegin, posEnd else break end end end return findBegin, findEnd end local function split(this, strings, count, options) local t = {} local find = find if type(strings) == "table" then if #strings == 0 then return t end if type(strings[1]) == "string" then find = findAny else strings = char(unpack(strings)) strings = escape(strings) strings = "[" .. strings .. "]" end elseif type(strings) == "string" then strings = escape(strings) else strings = char(strings) strings = escape(strings) end local len = 1 local startIndex = 1 while true do local posBegin, posEnd = find(this, strings, startIndex) posBegin = posBegin or 0 local subStr = sub(this, startIndex, posBegin -1) if options ~= 1 or #subStr > 0 then t[len] = subStr len = len + 1 if count then count = count -1 if count == 0 then if posBegin ~= 0 then t[len - 1] = sub(this, startIndex) end break end end end if posBegin == 0 then break end startIndex = posEnd + 1 end return System.arrayFromTable(t, String) end local function startsWith(this, prefix) return sub(this, 1, #prefix) == prefix end local function substring(this, startIndex, count) startIndex, count = checkIndex(this, startIndex, count) return sub(this, startIndex + 1, startIndex + count) end local function toCharArray(str, startIndex, count) startIndex, count = checkIndex(str, startIndex, count) local t = {} local len = 1 for i = startIndex + 1, startIndex + count do t[len] = byte(str, i) len = len + 1 end return System.arrayFromTable(t, System.Char) end local function trim(this, chars, ...) if not chars then chars = "^%s*(.-)%s*$" else if type(chars) == "table" then chars = char(unpack(chars)) else chars = char(chars, ...) end chars = escape(chars) chars = "^[" .. chars .. "]*(.-)[" .. chars .. "]*$" end return (gsub(this, chars, "%1")) end local function trimEnd(this, chars, ...) if not chars then chars = "(.-)%s*$" else if type(chars) == "table" then chars = char(unpack(chars)) else chars = char(chars, ...) end chars = escape(chars) chars = "(.-)[" .. chars .. "]*$" end return (gsub(this, chars, "%1")) end local function trimStart(this, chars, ...) if not chars then chars = "^%s*(.-)" else if type(chars) == "table" then chars = char(unpack(chars)) else chars = char(chars, ...) end chars = escape(chars) chars = "^[" .. chars .. "]*(.-)" end return (gsub(this, chars, "%1")) end local function inherits(_, T) return { System.IEnumerable_1(System.Char), System.IComparable, System.IComparable_1(T), System.IConvertible, System.IEquatable_1(T), System.ICloneable } end string.traceback = emptyFn -- make throw(str) not fail string.getLength = lengthFn string.getCount = lengthFn string.get = get string.Compare = compareFull string.CompareOrdinal = compareFull string.Concat = concat string.Copy = System.identityFn string.Equals = equals string.Format = format string.IsNullOrEmpty = isNullOrEmpty string.IsNullOrWhiteSpace = isNullOrWhiteSpace string.JoinEnumerable = joinEnumerable string.JoinParams = joinParams string.Join = join string.CompareTo = compare string.CompareToObj = compareToObj string.Contains = contains string.CopyTo = copyTo string.EndsWith = endsWith string.EqualsObj = equalsObj string.GetEnumerator = getEnumerator string.GetTypeCode = getTypeCode string.IndexOf = indexOf string.IndexOfAny = indexOfAny string.Insert = insert string.LastIndexOf = lastIndexOf string.LastIndexOfAny = lastIndexOfAny string.PadLeft = padLeft string.PadRight = padRight string.Remove = remove string.Replace = replace string.Split = split string.StartsWith = startsWith string.Substring = substring string.ToCharArray = toCharArray string.ToLower = lower string.ToLowerInvariant = lower string.ToString = System.identityFn string.ToUpper = upper string.ToUpperInvariant = upper string.Trim = trim string.TrimEnd = trimEnd string.TrimStart = trimStart if debugsetmetatable then String = string String.__genericT__ = System.Char String.base = inherits System.define("System.String", String) debugsetmetatable("", String) local Object = System.Object local StringMetaTable = setmetatable({ __index = Object, __call = ctor }, Object) setmetatable(String, StringMetaTable) else string.__call = ctor string.__index = string String = getmetatable("") String.__genericT__ = System.Char String.base = inherits System.define("System.String", String) String.__index = string setmetatable(String, string) setmetatable(string, System.Object) end ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/String.lua.meta ================================================ fileFormatVersion: 2 guid: 2df704fc85793bd4fb8aa99961168c75 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Text/StringBuilder.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local clear = System.Array.clear local toString = System.toString local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local IndexOutOfRangeException = System.IndexOutOfRangeException local table = table local tconcat = table.concat local schar = string.char local ssub = string.sub local sbyte = string.byte local type = type local select = select local function build(this, value, startIndex, length) value = value:Substring(startIndex, length) local len = #value if len > 0 then this[#this + 1] = value this.Length = len end end local function getItemIndex(this, index) for i = 1, #this do local s = this[i] local len = #s local begin = index index = index - len if index < 0 then begin = begin + 1 local ch = sbyte(s, begin) if not ch then break end return i, s, begin, ch end end end local function getLength(this) return this.Length end local StringBuilder = System.define("System.Text.StringBuilder", { Length = 0, ToString = tconcat, __tostring = tconcat, __ctor__ = function (this, ...) local len = select("#", ...) if len == 0 then elseif len == 1 or len == 2 then local value = ... if type(value) == "string" then build(this, value, 0, #value) else build(this, "", 0, 0) end else local value, startIndex, length = ... build(this, value, startIndex, length) end end, get = function (this, index) local _, _, _, ch = getItemIndex(this, index) if not _ then throw(IndexOutOfRangeException()) end return ch end, set = function (this, index, value) local i, s, j = getItemIndex(this, index) if not i then throw(ArgumentOutOfRangeException("index")) end this[i] = ssub(s, 1, j - 1) .. schar(value) .. ssub(s, j + 1) end, setCapacity = function (this, value) if value < this.Length then throw(ArgumentOutOfRangeException()) end end, getCapacity = getLength, getMaxCapacity = getLength, getLength = getLength, setLength = function (this, value) if value < 0 then throw(ArgumentOutOfRangeException("value")) end if value == 0 then this:Clear() return end local delta = value - this.Length if delta > 0 then this:AppendCharRepeat(0, delta) else local length, remain = #this, value for i = 1, length do local s = this[i] local len = #s if len >= remain then if len ~= remain then s = ssub(s, 0, remain) this[i] = s end for j = i + 1, length do this[j] = nil end break end remain = remain - len end this.Length = this.Length + delta end end, Append = function (this, value, startIndex, count) if not startIndex then if value ~= nil then value = toString(value) if value ~= nil then this[#this + 1] = value this.Length = this.Length + #value end end else if value == nil then throw(ArgumentNullException("value")) end value = value:Substring(startIndex, count) this[#this + 1] = value this.Length = this.Length + #value end return this end, AppendChar = function (this, v) v = schar(v) this[#this + 1] = v this.Length = this.Length + 1 return this end, AppendCharRepeat = function (this, v, repeatCount) if repeatCount < 0 then throw(ArgumentOutOfRangeException("repeatCount")) end if repeatCount == 0 then return this end v = schar(v) local count = #this + 1 for i = 1, repeatCount do this[count] = v count = count + 1 end this.Length = this.Length + repeatCount return this end, AppendFormat = function (this, format, ...) local value = format:Format(...) this[#this + 1] = value this.Length = this.Length + #value return this end, AppendLine = function (this, value) local count = 1 local len = #this + 1 if value ~= nil then this[len] = value len = len + 1 count = count + #value end this[len] = "\n" this.Length = this.Length + count return this end, Clear = function (this) clear(this) this.Length = 0 return this end, Insert = function (this, index, value) local length = this.Length if value ~= nil then if index == length then this:Append(value) else value = toString(value) if value ~= nil then local i, s, j = getItemIndex(this, index) if not i then throw(ArgumentOutOfRangeException("index")) end this[i] = ssub(s, 1, j - 1) .. value .. ssub(s, j) this.Length = length + #value end end end end }) System.StringBuilder = StringBuilder ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Text/StringBuilder.lua.meta ================================================ fileFormatVersion: 2 guid: 064061fdecc8f34428c91d8c361b02d0 timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Text.meta ================================================ fileFormatVersion: 2 guid: 89aaeb8f66fbcee4d96bac4f042d8c99 folderAsset: yes timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threading/Task.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local defStc = System.defStc local throw = System.throw local try = System.try local trunc = System.trunc local Void = System.Void local post = System.post local addTimer = System.addTimer local removeTimer = System.removeTimer local waitTask = System.Thread.waitTask local arrayFromTable = System.arrayFromTable local Exception = System.Exception local NullReferenceException = System.NullReferenceException local NotImplementedException = System.NotImplementedException local ArgumentException = System.ArgumentException local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local InvalidOperationException = System.InvalidOperationException local AggregateException = System.AggregateException local ObjectDisposedException = System.ObjectDisposedException local ccreate = System.ccreate local cpool = System.cpool local cresume = System.cresume local cyield = System.yield local type = type local table = table local select = select local assert = assert local getmetatable = getmetatable local setmetatable = setmetatable local tremove = table.remove local pack = table.pack local unpack = table.unpack local error = error local TaskCanceledException = define("System.Threading.Tasks.TaskCanceledException", { __tostring = Exception.ToString, base = { Exception }, __ctor__ = function (this, task) this.task = task Exception.__ctor__(this, "A task was canceled.") end, getTask = function(this) return this.task end }) System.TaskCanceledException = TaskCanceledException local TaskStatusCreated = 0 local TaskStatusWaitingForActivation = 1 local TaskStatusWaitingToRun = 2 local TaskStatusRunning = 3 local TaskStatusWaitingForChildrenToComplete = 4 local TaskStatusRanToCompletion = 5 local TaskStatusCanceled = 6 local TaskStatusFaulted = 7 System.TaskStatus = System.defEnum("System.Threading.Tasks.TaskStatus", { Created = TaskStatusCreated, WaitingForActivation = TaskStatusWaitingForActivation, WaitingToRun = TaskStatusWaitingToRun, Running = TaskStatusRunning, WaitingForChildrenToComplete = TaskStatusWaitingForChildrenToComplete, RanToCompletion = TaskStatusRanToCompletion, Canceled = TaskStatusCanceled, Faulted = TaskStatusFaulted, }) local UnobservedTaskExceptionEventArgs = define("System.Threading.Tasks.UnobservedTaskExceptionEventArgs", { __ctor__ = function (this, exception) this.exception = exception end, SetObserved = function (this) this.observed = true end, getObserved = function (this) if this.observed then return true end return false end, getException = function (this) return this.exception end }) System.UnobservedTaskExceptionEventArgs = UnobservedTaskExceptionEventArgs local unobservedTaskException local function publishUnobservedTaskException(sender, ueea) local handler = unobservedTaskException if handler then handler(sender, ueea) end end local TaskScheduler = define("System.Threading.Tasks.TaskScheduler", { addUnobservedTaskException = function (value) unobservedTaskException = unobservedTaskException + value end, removeUnobservedTaskException = function (value) unobservedTaskException = unobservedTaskException - value end }) System.TaskScheduler = TaskScheduler local TaskExceptionHolder = { __index = false, __gc = function (this) if not this.isHandled then local e = this.exception if e then local ueea = UnobservedTaskExceptionEventArgs(e) publishUnobservedTaskException(this.task, ueea) if not ueea.observed then print("Warning: TaskExceptionHolder" , e) end end end end } TaskExceptionHolder.__index = TaskExceptionHolder local function newTaskExceptionHolder(task, exception) return setmetatable({ task = task, exception = exception }, TaskExceptionHolder) end local function getException(task, await) local holder = task.data if not holder.isHandled then holder.isHandled = true end local e = holder.exception if await then return e end return AggregateException(e) end local Task local nextTaskId = 1 local currentTask local completedTask local function getNewId() local id = nextTaskId nextTaskId = nextTaskId + 1 return id end local function getId(this) local id = this.id if id == nil then id = getNewId() this.id = id end return id end local function isCompleted(this) local status = this.status return status == TaskStatusRanToCompletion or status == TaskStatusFaulted or status == TaskStatusCanceled end local function newTask(status, data) return setmetatable({ status = status, data = data }, Task) end local function fromResult(result) return newTask(TaskStatusRanToCompletion, result) end local function fromCanceled(cancellationToken) if cancellationToken and cancellationToken:getIsCancellationRequested() then throw(ArgumentOutOfRangeException("cancellationToken")) end return newTask(TaskStatusCanceled, cancellationToken) end local function fromException(exception) local data = newTaskExceptionHolder(false, exception) local t = newTask(TaskStatusFaulted, data) data.task = t return t end local function getCompletedTask() local t = completedTask if t == nil then t = fromResult() completedTask = t end return t end local function trySetComplete(this, status, data) if isCompleted(this) then return false end this.status = status this.data = data local continueActions = this.continueActions if continueActions then for i = 1, #continueActions do continueActions[i](this) end this.continueActions = nil end return true end local function trySetResult(this, result) return trySetComplete(this, TaskStatusRanToCompletion, result) end local function trySetException(this, exception) if this.data == Void then throw(exception) end return trySetComplete(this, TaskStatusFaulted, newTaskExceptionHolder(this, exception)) end local function trySetCanceled(this, cancellationToken) return trySetComplete(this, TaskStatusCanceled, cancellationToken) end local function newWaitingTask(isVoid) return newTask(TaskStatusWaitingForActivation, isVoid and Void) end local function getContinueActions(task) local continueActions = task.continueActions if continueActions == nil then continueActions = {} task.continueActions = continueActions end return continueActions end local function addContinueAction(task, f) local continueActions = getContinueActions(task) continueActions[#continueActions + 1] = assert(f) end local function checkTasks(...) local tasks local n = select("#", ...) if n == 1 then local args = ... if args == nil then throw(ArgumentNullException("tasks")) end if System.isArrayLike(args) then tasks = args elseif System.isEnumerableLike(args) then tasks = System.Array.toArray(args) end end if not tasks then tasks = System.Array(Task)(...) end for i = 1, #tasks do if tasks[i] == System.null then throw(ArgumentNullException()) end end return tasks end local function getDelay(delay) if type(delay) == "table" then delay = trunc(delay:getTotalMilliseconds()) if delay < -1 or delay > 2147483647 then throw(ArgumentOutOfRangeException("delay")) end elseif delay < -1 then throw(ArgumentOutOfRangeException("millisecondsDelay")) end return delay end local waitToken = {} local function getResult(this, await) local status = this.status if status == TaskStatusRanToCompletion then return this.data elseif status == TaskStatusFaulted then throw(getException(this, await)) elseif status == TaskStatusCanceled then local e = TaskCanceledException(this) if not await then e = AggregateException(e) end throw(e) end return waitToken end local function getAwaitResult(task) local status = task.status local ok, v if status == TaskStatusRanToCompletion then ok, v = true, task.data elseif status == TaskStatusFaulted then ok, v = false, getException(task, true) elseif status == TaskStatusCanceled then ok, v = false, TaskCanceledException(task) else assert(false) end return ok, v end local factory = { StartNew = function (_, f, state) local t = newWaitingTask() post(function () try(function () assert(trySetResult(t, f(state))) end, function (e) assert(trySetException(t, e)) end) end) return t end } Task = define("System.Threading.Tasks.Task", { Dispose = System.emptyFn, __ctor__ = function (this, action, state) if action == nil then throw(ArgumentNullException("action")) end this.status = TaskStatusCreated this.data = function () return action(state) end end, getId = getId, getCurrentId = function () local t = currentTask if t then return getId(t) end end, getFactory = function () return factory end, getStatus = function (this) return this.status end, getException = function (this) if this.status == TaskStatusFaulted then return getException(this) end return nil end, getResult = function (this) local result = getResult(this) if result == waitToken then waitTask(getContinueActions(this)) result = getResult(this) assert(result ~= waitToken) end return result end, getIsCompleted = isCompleted, getIsCanceled = function (this) return this.status == TaskStatusCanceled end, getIsFaulted = function (this) return this.status == TaskStatusFaulted end, FromResult = fromResult, FromCanceled = fromCanceled, FromException = fromException, getCompletedTask = getCompletedTask, Delay = function (delay, cancellationToken) delay = getDelay(delay) if cancellationToken and cancellationToken:getIsCancellationRequested() then return fromCanceled(cancellationToken) elseif delay == 0 then return getCompletedTask() end local t = newWaitingTask() local timerId, registration if cancellationToken and cancellationToken:getCanBeCanceled() then registration = cancellationToken:Register(function () local success = trySetCanceled(t, cancellationToken) if success and timerId then removeTimer(timerId) end end) end if delay ~= -1 then timerId = addTimer(function () local success = trySetResult(t) if success and registration then registration:Dispose() end end, delay) end return t end, Run = function (f, cancellationToken) local t = Task(f) t:Start() return t end, WhenAll = function (T, ...) local tasks = checkTasks(...) local count = #tasks if count == 0 then return getCompletedTask() end local result, exceptions, cancelled = {}, {} local t = newWaitingTask() local function f(task) local status = task.status if status == TaskStatusRanToCompletion then result[#result + 1] = task.data elseif status == TaskStatusFaulted then local exception = getException(task, true) exceptions[#exceptions + 1] = exception elseif status == TaskStatusCanceled then cancelled = true end count = count - 1 if count == 0 then if #exceptions > 0 then trySetException(t, arrayFromTable(exceptions, Exception)) elseif cancelled then trySetCanceled(t) else if T then trySetResult(t, arrayFromTable(result, T)) end trySetResult(t) end end end for i = 1, count do local task = tasks[i] if isCompleted(task) then post(function () f(task) end) else addContinueAction(task, f) end end return t end, WhenAny = function (...) local tasks = checkTasks(...) local count = #tasks if count == 0 then throw(ArgumentException()) end local t = newWaitingTask() local function f(task) local status = task.status if status == TaskStatusRanToCompletion then trySetResult(t, task) elseif status == TaskStatusFaulted then trySetException(t, getException(task)) elseif status == TaskStatusCanceled then trySetCanceled(t) end end for i = 1, count do local task = tasks[i] if isCompleted(task) then post(function () f(task) end) else addContinueAction(task, f) end end return t end, ContinueWith = function (this, continuationAction) if continuationAction == nil then throw(ArgumentNullException("continuationAction")) end local t = newWaitingTask() local function f(task) try(function () t.status = TaskStatusRunning assert(trySetResult(t, continuationAction(task))) end, function (e) assert(trySetException(t, e)) end) end if isCompleted(this) then post(function () f(this) end) else addContinueAction(this, f) end return t end, Start = function (this) if this.status ~= TaskStatusCreated then throw(InvalidOperationException("Task was already started.")) end this.status = TaskStatusWaitingToRun post(function () try(function () this.status = TaskStatusRunning assert(trySetResult(this, this.data())) end, function (e) assert(trySetException(this, e)) end) end) end, Wait = function (this) waitTask(getContinueActions(this)) end, Await = function (this, t) local a = t:GetAwaiter() if a:getIsCompleted() then return a:GetResult() end a:OnCompleted(function () local ok, v try(function () ok, v = true, a:GetResult() end, function (e) ok, v = false, e end) ok, v = cresume(this.c, ok, v) if not ok then assert(trySetException(this, v)) end end) local ok, v = cyield() if ok then return v else error(v) end end, await = function (this, task) if getmetatable(task) ~= Task then return this:Await(task) end local result = getResult(task, true) if result ~= waitToken then return result end addContinueAction(task, function (task) local ok, v = getAwaitResult(task) ok, v = cresume(this.c, ok, v) if not ok then assert(trySetException(this, v)) end end) local ok, v = cyield() if ok then return v else error(v) end end }) System.Task = Task local TaskT_TransitionToFinal_AlreadyCompleted = "An attempt was made to transition a task to a final state when it had already completed." local TaskCompletionSource = define("System.Threading.Tasks.TaskCompletionSource", { __ctor__ = function (this) this.task = newWaitingTask() end, getTask = function (this) return this.task end, SetCanceled = function (this) if not trySetCanceled(this.task) then throw(InvalidOperationException(TaskT_TransitionToFinal_AlreadyCompleted)) end end, SetException = function (this, exception) if exception == nil then throw(ArgumentNullException("exception")) end if not trySetException(this.task, exception) then throw(InvalidOperationException(TaskT_TransitionToFinal_AlreadyCompleted)) end end, SetResult = function (this, result) if not trySetResult(this.task, result) then throw(InvalidOperationException(TaskT_TransitionToFinal_AlreadyCompleted)) end end, TrySetCanceled = trySetCanceled, TrySetException = trySetException, TrySetResult = trySetResult }) System.TaskCompletionSource = TaskCompletionSource local CancellationTokenRegistration = defStc("System.Threading.CancellationTokenRegistration", (function () local function unregister(this) local token = this.token if token then local f = this.f if f then this.f = nil return token.source:unRegister(f) end end return false end return { base = function(_, T) return { System.IDisposable, System.IEquatable_1(T) } end, __ctor__ = function (this, token, f) if not token then return end this.token = token this.f = f end, getToken = function (this) return this.token end, Equals = System.equals, Unregister = unregister, Dispose = unregister } end)()) System.CancellationTokenRegistration = CancellationTokenRegistration local OperationCanceledException = define("System.OperationCanceledException", { __tostring = Exception.ToString, base = { System.SystemException }, __ctor__ = function (this, message, innerException, token) Exception.__ctor__(this, message or "The operation was canceled.", innerException) this.tokne = token end, getCancellationToken = function (this) return this.token end }) local canceledSource local CancellationToken CancellationToken = defStc("System.Threading.CancellationToken", { __ctor__ = function (this, canceled) if canceled == nil then return end if canceled == true then this.source = canceledSource elseif canceled then this.source = canceled end end, getCanBeCanceled = function (this) return this.source ~= nil end, getIsCancellationRequested = function (this) local source = this.source if source then return source:getIsCancellationRequested() end return false end, getNone = function () return CancellationToken() end, Equals = System.equals, Register = function (this, callback, state) local source = this.source if source then if not source:getIsCancellationRequested() then local function f() callback(state) end this.source:register(f) return CancellationTokenRegistration(this, f) end callback(state) end return CancellationTokenRegistration() end, ThrowIfCancellationRequested = function (this) if this:getIsCancellationRequested() then throw(OperationCanceledException()) end end }) System.CancellationToken = CancellationToken local CancellationTokenSource CancellationTokenSource = define("System.Threading.CancellationTokenSource", (function () local function clean(this) local timerId = this.timerId if timerId then removeTimer(timerId) end local links = this.links if links then for i = 1, #links do links[i]:Dispose() end end end return { state = 0, base = { System.IDisposable }, __ctor__ = function (this, delay) if delay then delay = getDelay(delay) if delay == 0 then this.state = 1 else this.timerId = addTimer(function () this.Cancel() end, delay) end end end, Cancel = function (this, throwOnFirstException) if this.disposed then throw(ObjectDisposedException()) end if this.state == 1 then return end clean(this) this.state = 1 local actions = this.continueActions if actions then local t = {} for i = 1, #actions do try(function () actions[i]() end, function (e) if throwOnFirstException then throw(e) end t[#t + 1] = e end) end if #t > 0 then throw(AggregateException(arrayFromTable(t, Exception))) end end end, CancelAfter = function (this, delay) if this.disposed then throw(ObjectDisposedException()) end delay = getDelay(delay) if this.state == 1 then return end local timerId = this.timerId if timerId then removeTimer(timerId) end this.timerId = addTimer(function () this:Cancel() end, delay) end, Dispose = function (this) if this.disposed then return end clean(this) this.disposed = true end, getIsCancellationRequested = function (this) return this.state == 1 end, getToken = function (this) local t = this.token if not t then t = CancellationToken(this) this.token = t end return t end, register = addContinueAction, unRegister = function (this, f) local actions = this.continueActions if actions then for i = 1, #actions do if actions[i] == f then tremove(actions, i) return true end end end return false end, CreateLinkedTokenSource = function (...) local cts, links, count = CancellationTokenSource(), {}, 1 cts.links = links local n = select("#", ...) if n == 1 then local args = ... if System.isArrayLike(args) then for i = 1, #args do links[count] = args[i]:Register(cts.Cancel, cts) count = count + 1 end return cts end end for i = 1, n do local token = select(i, ...) links[count] = token:Register(cts.Cancel, cts) count = count + 1 end return cts end } end)()) System.CancellationTokenSource = CancellationTokenSource canceledSource = setmetatable({ state = 1 }, CancellationTokenSource) local function taskCoroutineCreate(t, f) local c = ccreate(function (...) local r = f(t, ...) assert(trySetResult(t, r)) end) t.c = c return c end function System.async(f, void, ...) local t = newWaitingTask(void) local c = taskCoroutineCreate(t, f) local ok, v = cresume(c, ...) if not ok then assert(trySetException(t, v)) end return t end local IAsyncDisposable = System.defInf("System.IAsyncDisposable") local IAsyncEnumerable = System.defInf("System.Collections.Generic.IAsyncEnumerable", System.emptyFn) local IAsyncEnumerator = System.defInf("System.Collections.Generic.IAsyncEnumerator", System.emptyFn) System.IAsyncEnumerable_1 = IAsyncEnumerable System.IAsyncEnumerator_1 = IAsyncEnumerator local yieldAsync local function checkYieldAsync(this, ok, v, current) if ok then if v == yieldAsync then this.e.current = current assert(trySetResult(this.t, true)) elseif v == cpool then this.c = nil this.e.current = nil assert(trySetResult(this.t, false)) end else assert(trySetException(this.t, v)) end end yieldAsync = { __index = false, await = function (this, task) local result = getResult(task, true) if result ~= waitToken then return result end addContinueAction(task, function (task) local current local ok, v = getAwaitResult(task) ok, v, current = cresume(this.c, ok, v) checkYieldAsync(this, ok, v, current) end) local ok, v = cyield() if ok then return v else error(v) end end, yield = function (this, v) cyield(yieldAsync, v) end } yieldAsync.__index = yieldAsync local YieldAsyncEnumerable YieldAsyncEnumerable = define("System.YieldAsyncEnumerable", function (T) return { base = { IAsyncEnumerable(T), IAsyncEnumerator(T), IAsyncDisposable }, __genericT__ = T } end, { getCurrent = System.getCurrent, GetAsyncEnumerator = function (this) return setmetatable({ f = this.f, args = this.args }, YieldAsyncEnumerable(this.__genericT__)) end, DisposeAsync = function (this) return getCompletedTask() end, MoveNextAsync = function (this) local a = this.a if a and a.c == nil then return fromResult(false) end local t = newWaitingTask() local ok, v, current if a == nil then local c = ccreate(this.f) a = setmetatable({ t = t, c = c, e = this }, yieldAsync) this.a = a local args = this.args ok, v, current = cresume(c, a, unpack(args, 1, args.n)) this.args = nil else a.t = t ok, v, current = cresume(a.c) end checkYieldAsync(a, ok, v, current) return t end }) local function yieldIAsyncEnumerable(f, T, ...) return setmetatable({ f = f, args = pack(...) }, YieldAsyncEnumerable(T)) end System.yieldIAsyncEnumerable = yieldIAsyncEnumerable System.yieldIAsyncEnumerator = yieldIAsyncEnumerable local function eachFn(en, async) if async:await(en:MoveNextAsync()) then return async, en:getCurrent() end return nil end local function each(async, t) if t == nil then throw(NullReferenceException(), 1) end local en = t:GetAsyncEnumerator() return eachFn, en, async end System.asynceach = each ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threading/Task.lua.meta ================================================ fileFormatVersion: 2 guid: b511ea33303bc1846b6900af803a85fc DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threading/Thread.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local trunc = System.trunc local post = System.post local addTimer = System.addTimer local Exception = System.Exception local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local NotSupportedException = System.NotSupportedException local assert = assert local type = type local setmetatable = setmetatable local coroutine = coroutine local ccreate = coroutine.create local cresume = coroutine.resume local cstatus = coroutine.status local cyield = coroutine.yield local mainThread local ThreadStateException = define("System.Threading.ThreadStateException", { __tostring = Exception.ToString, base = { Exception }, __ctor__ = function(this, message, innerException) Exception.__ctor__(this, message or "Thread is running or terminated; it cannot restart.", innerException) end }) local ThreadAbortException = define("System.Threading.ThreadAbortException", { __tostring = Exception.ToString, base = { Exception }, __ctor__ = function(this, message, innerException) Exception.__ctor__(this, message or "Thread aborted.", innerException) end }) local nextThreadId = 1 local currentThread local function getThreadId() local id = nextThreadId nextThreadId = nextThreadId + 1 return id end local function checkTimeout(timeout) if type(timeout) == "table" then timeout = trunc(timeout:getTotalMilliseconds()) end if timeout < -1 or timeout > 2147483647 then throw(ArgumentOutOfRangeException("timeout")) end return timeout end local function resume(t, obj) local prevThread = currentThread currentThread = t local co = assert(t.co) local ok, v = cresume(co, obj) currentThread = prevThread if ok then if type(v) == "function" then v() elseif cstatus(co) == "dead" then local joinThread = t.joinThread if joinThread then resume(joinThread, true) end t.co = false end else t.co = false print("Warning: Thread.run" , v) end end local function run(t, obj) post(function () resume(t, obj) end) end local Thread = define("System.Threading.Thread", { IsBackground = false, IsThreadPoolThread = false, Priority = 2, ApartmentState = 2, Abort = function () throw(ThreadAbortException()) end, getCurrentThread = function () return currentThread end, __ctor__ = function (this, start) if start == nil then throw(ArgumentNullException("start")) end this.start = start end, getIsAlive = function (this) local co = this.co return co and cstatus(co) ~= "dead" end, ManagedThreadId = function (this) local id = this.id if not id then id = getThreadId() this.id = id end return id end, Sleep = function (timeout) local current = currentThread if current == mainThread then throw(NotSupportedException("mainThread not support")) end timeout = checkTimeout(timeout) local f if timeout ~= -1 then f = function () addTimer(function () resume(current) end, timeout) end end cyield(f) end, Yield = function () local current = currentThread if current == mainThread then return false end cyield(function () run(current) end) return true end, Join = function (this, timeout) if currentThread == mainThread then throw(NotSupportedException("mainThread not support")) end if this.joinThread then throw(ThreadStateException()) end this.joinThread = currentThread if timeout == nil then cyield() else timeout = checkTimeout(timeout) local f if timeout ~= -1 then f = function () addTimer(function () resume(currentThread, false) end, timeout) end end return cyield(f) end end, Start = function (this, parameter) if this.co ~= nil then throw(ThreadStateException()) end local co = ccreate(this.start) this.co = co this.start = nil run(this, parameter) end, waitTask = function (taskContinueActions) if currentThread == mainThread then throw(NotSupportedException("mainThread not support")) end taskContinueActions[#taskContinueActions + 1] = function () resume(currentThread) end cyield() end, }) mainThread = setmetatable({ id = getThreadId() }, Thread) currentThread = mainThread System.ThreadStateException = ThreadStateException System.ThreadAbortException = ThreadAbortException System.Thread = Thread ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threading/Thread.lua.meta ================================================ fileFormatVersion: 2 guid: 879d7ccf94cad2a4abafc063a63417ee DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threading/Timer.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local define = System.define local throw = System.throw local currentTimeMillis = System.currentTimeMillis local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local NotImplementedException = System.NotImplementedException local ObjectDisposedException = System.ObjectDisposedException local type = type local config = System.config local setTimeout = config.setTimeout local clearTimeout = config.clearTimeout if setTimeout and clearTimeout then System.post = function (fn) setTimeout(fn, 0) end else System.post = function (fn) fn() end local function notset() throw(NotImplementedException("System.config.setTimeout or clearTimeout is not registered.")) end setTimeout = notset clearTimeout = notset end local maxExpiration = 9223372036854775807 --[[Int64.MaxValue]] local LinkedListEvent = System.LinkedList(System.Object) local TimeoutQueue = define("System.TimeoutQueue", (function () local getNextId, Insert, Add, AddRepeating, AddRepeating1, getNextExpiration, Erase, RunLoop, getCount, Contains, IsNext, __ctor__ __ctor__ = function (this) this.ids_ = {} this.events_ = LinkedListEvent() end getNextId = function (this) local default = this.nextId_ this.nextId_ = default + 1 return default end Insert = function (this, e) this.ids_[e.Id] = e local next = this.events_:getFirst() while next ~= nil and next.Value.Expiration <= e.Expiration do next = next:getNext() end if next ~= nil then e.LinkNode = this.events_:AddBefore(next, e) else e.LinkNode = this.events_:AddLast(e) end end Add = function (this, now, delay, callback) return AddRepeating1(this, now, delay, 0, callback) end AddRepeating = function (this, now, interval, callback) return AddRepeating1(this, now, interval, interval, callback) end AddRepeating1 = function (this, now, delay, interval, callback) local id = getNextId(this) Insert(this, { Id = id, Expiration = now + delay, RepeatInterval = interval, Callback = callback }) return id end getNextExpiration = function (this) return this.events_.Count > 0 and this.events_:getFirst().Value.Expiration or maxExpiration end Erase = function (this, id) local e = this.ids_[id] if e then this.ids_[id] = nil this.events_:RemoveNode(e.LinkNode) return true end return false end RunLoop = function (this, now) while true do local nextExp = getNextExpiration(this) if nextExp <= now then local e = this.events_:getFirst().Value Erase(this, e.Id) if e.RepeatInterval > 0 then e.Expiration = now + e.RepeatInterval Insert(this, e) end e.Callback(e.Id, now) else return nextExp end end end getCount = function (this) return this.events_.Count end Contains = function (this, id) return this.ids_[id] ~= nil end IsNext = function (this, id) local first = this.events_:getFirst() local nextId = first and first.Value.Id return nextId == id end return { MaxExpiration = maxExpiration, nextId_ = 1, Add = Add, AddRepeating = AddRepeating, AddRepeating1 = AddRepeating1, getNextExpiration = getNextExpiration, Erase = Erase, RunLoop = RunLoop, getCount = getCount, Contains = Contains, __ctor__ = __ctor__, IsNext = IsNext } end)()) local timerQueue = TimeoutQueue() local driverTimer local function runTimerQueue() local now = currentTimeMillis() local nextExpiration = timerQueue:RunLoop(now) if nextExpiration ~= maxExpiration then driverTimer = setTimeout(runTimerQueue, nextExpiration - now) else driverTimer = nil end end local function addTimer(fn, dueTime, period) local now = currentTimeMillis() local id = timerQueue:AddRepeating1(now, dueTime, period or 0, fn) if timerQueue:IsNext(id) then if driverTimer then clearTimeout(driverTimer) end driverTimer = setTimeout(runTimerQueue, dueTime) end return id end local function removeTimer(id) local isNext = timerQueue:IsNext(id) timerQueue:Erase(id) if isNext then clearTimeout(driverTimer) local delay = timerQueue:getNextExpiration() - currentTimeMillis() driverTimer = setTimeout(runTimerQueue, delay) end end System.addTimer = addTimer System.removeTimer = removeTimer local function close(this) local id = this.id if id then removeTimer(id) end end local function change(this, dueTime, period) if type(dueTime) == "table" then dueTime = dueTime:getTotalMilliseconds() period = period:getTotalMilliseconds() end if dueTime < -1 or dueTime > 0xfffffffe then throw(ArgumentOutOfRangeException("dueTime")) end if period < -1 or period > 0xfffffffe then throw(ArgumentOutOfRangeException("period")) end if this.id == -1 then throw(ObjectDisposedException()) end close(this) if dueTime ~= -1 then this.id = addTimer(this.callback, dueTime, period) end return true end System.Timer = define("System.Threading.Timer", { __ctor__ = function (this, callback, state, dueTime, period) if callback == nil then throw(ArgumentNullException("callback")) end this.callback = function () callback(state) end change(this, dueTime, period) end, Change = change, Dispose = function (this) close(this) this.id = -1 end, __gc = close }) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threading/Timer.lua.meta ================================================ fileFormatVersion: 2 guid: bdc40b5bf02c0e2418211c3ea4fa4b8e DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threading.meta ================================================ fileFormatVersion: 2 guid: e91b659d8aba50548b8f6d890ff7e573 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Threads.meta ================================================ fileFormatVersion: 2 guid: d1d009652a7b2644eaf9ca2d19663fa9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/TimeSpan.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local div = System.div local trunc = System.trunc local ArgumentException = System.ArgumentException local OverflowException = System.OverflowException local ArgumentNullException = System.ArgumentNullException local FormatException = System.FormatException local assert = assert local getmetatable = getmetatable local select = select local sformat = string.format local sfind = string.find local tostring = tostring local tonumber = tonumber local floor = math.floor local log10 = math.log10 local TimeSpan local zero local function compare(t1, t2) if t1.ticks > t2.ticks then return 1 end if t1.ticks < t2.ticks then return -1 end return 0 end local function add(this, ts) return TimeSpan(this.ticks + ts.ticks) end local function subtract(this, ts) return TimeSpan(this.ticks - ts.ticks) end local function negate(this) local ticks = this.ticks if ticks == -9223372036854775808 then throw(OverflowException("Overflow_NegateTwosCompNum")) end return TimeSpan(-ticks) end local function interval(value, scale) if value ~= value then throw(ArgumentException("Arg_CannotBeNaN")) end local tmp = value * scale local millis = tmp + (value >=0 and 0.5 or -0.5) if millis > 922337203685477 or millis < -922337203685477 then throw(OverflowException("Overflow_TimeSpanTooLong")) end return TimeSpan(trunc(millis) * 10000) end local function getPart(this, i, j) local t = this.ticks local v = div(t, i) % j if v ~= 0 and t < 0 then return v - j end return v end local function parse(s) if s == nil then return nil, 1 end local i, j, k, sign, ch local day, hour, minute, second, milliseconds = 0, 0, 0, 0, 0 i, j, sign, day = sfind(s, "^%s*([-]?)(%d+)") if not i then return end k = j + 1 i, j, ch = sfind(s, "^([%.:])", k) if not i then i, j = sfind(s, "^%s*$", k) if not i then return end k = -1 else k = j + 1 if ch == '.' then i, j, hour, minute = sfind(s, "^(%d+):(%d+)", k) if not i then return end k = j + 1 i, j, second = sfind(s, "^:(%d+)", k) if not i then return end else i, j, hour = sfind(s, "^(%d+)", k) if not i then return end k = j + 1 i, j, minute = sfind(s, "^:(%d+)", k) if not i then i, j = sfind(s, "^%s*$", k) if not i then return end day, hour, minute = 0, day, hour k = -1 else k = j i, j, second = sfind(s, "^:(%d+)", k + 1) if not i then day, hour, minute, second = 0, day, hour, minute j = k end end end end if k ~= -1 then k = j + 1 i, j, milliseconds = sfind(s, "^%.(%d+)%s*$", k) if not i then i, j = sfind(s, "^%s*$", k) if not i then return end milliseconds = 0 else milliseconds = tonumber(milliseconds) local n = floor(log10(milliseconds) + 1) if n > 3 then if n > 7 then return end milliseconds = milliseconds / (10 ^ (n - 3)) end end end if sign == '-' then day, hour, minute, second, milliseconds = -day, -hour, -minute, -second, -milliseconds end return TimeSpan(day, hour, minute, second, milliseconds) end TimeSpan = System.defStc("System.TimeSpan", { ticks = 0, __ctor__ = function (this, ...) local ticks local length = select("#", ...) if length == 0 then elseif length == 1 then ticks = ... elseif length == 3 then local hours, minutes, seconds = ... ticks = (((hours * 60 + minutes) * 60) + seconds) * 10000000 elseif length == 4 then local days, hours, minutes, seconds = ... ticks = ((((days * 24 + hours) * 60 + minutes) * 60) + seconds) * 10000000 elseif length == 5 then local days, hours, minutes, seconds, milliseconds = ... ticks = (((((days * 24 + hours) * 60 + minutes) * 60) + seconds) * 1000 + milliseconds) * 10000 else assert(ticks) end this.ticks = ticks end, Compare = compare, CompareTo = compare, CompareToObj = function (this, t) if t == nil then return 1 end if getmetatable(t) ~= TimeSpan then throw(ArgumentException("Arg_MustBeTimeSpan")) end compare(this, t) end, Equals = function (t1, t2) return t1.ticks == t2.ticks end, EqualsObj = function(this, t) if getmetatable(t) == TimeSpan then return this.ticks == t.ticks end return false end, GetHashCode = function (this) return this.ticks end, getTicks = function (this) return this.ticks end, getDays = function (this) return div(this.ticks, 864000000000) end, getHours = function(this) return getPart(this, 36000000000, 24) end, getMinutes = function (this) return getPart(this, 600000000, 60) end, getSeconds = function (this) return getPart(this, 10000000, 60) end, getMilliseconds = function (this) return getPart(this, 10000, 1000) end, getTotalDays = function (this) return this.ticks / 864000000000 end, getTotalHours = function (this) return this.ticks / 36000000000 end, getTotalMilliseconds = function (this) return this.ticks / 10000 end, getTotalMinutes = function (this) return this.ticks / 600000000 end, getTotalSeconds = function (this) return this.ticks / 10000000 end, Add = add, Subtract = subtract, Duration = function (this) local ticks = this.ticks if ticks == -9223372036854775808 then throw(OverflowException("Overflow_Duration")) end return TimeSpan(ticks >= 0 and ticks or - ticks) end, Negate = negate, ToString = function (this) local day, milliseconds = this:getDays(), this.ticks % 10000000 local daysStr = day == 0 and "" or (day .. ".") local millisecondsStr = milliseconds == 0 and "" or (".%07d"):format(milliseconds) return sformat("%s%02d:%02d:%02d%s", daysStr, this:getHours(), this:getMinutes(), this:getSeconds(), millisecondsStr) end, Parse = function (s) local v, err = parse(s) if v then return v end if err == 1 then throw(ArgumentNullException()) else throw(FormatException()) end end, TryParse = function (s) local v = parse(s) if v then return true, v end return false, zero end, __add = add, __sub = subtract, __unm = negate, __eq = function (t1, t2) return t1.ticks == t2.ticks end, __lt = function (t1, t2) return t1.ticks < t2.ticks end, __le = function (t1, t2) return t1.ticks <= t2.ticks end, FromDays = function (value) return interval(value, 864e5) end, FromHours = function (value) return interval(value, 36e5) end, FromMilliseconds = function (value) return interval(value, 1) end, FromMinutes = function (value) return interval(value, 6e4) end, FromSeconds = function (value) return interval(value, 1000) end, FromTicks = function (value) return TimeSpan(value) end, base = function (_, T) return { System.IComparable, System.IComparable_1(T), System.IEquatable_1(T) } end, default = function () return zero end, Zero = false, MaxValue = false, MinValue = false }) zero = TimeSpan(0) TimeSpan.Zero = zero TimeSpan.MaxValue = TimeSpan(9223372036854775807) TimeSpan.MinValue = TimeSpan(-9223372036854775808) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/TimeSpan.lua.meta ================================================ fileFormatVersion: 2 guid: 8d3b7ec8b56191547ab3ab10d026b51b timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Type.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local Object = System.Object local Boolean = System.Boolean local Delegate = System.Delegate local getClass = System.getClass local arrayFromTable = System.arrayFromTable local InvalidCastException = System.InvalidCastException local ArgumentNullException = System.ArgumentNullException local MissingMethodException = System.MissingMethodException local TypeLoadException = System.TypeLoadException local NullReferenceException = System.NullReferenceException local Char = System.Char local SByte = System.SByte local Byte = System.Byte local Int16 = System.Int16 local UInt16 = System.UInt16 local Int32 = System.Int32 local UInt32 = System.UInt32 local Int64 = System.Int64 local UInt64 = System.UInt64 local Single = System.Single local Double = System.Double local Int = System.Int local Number = System.Number local ValueType = System.ValueType local assert = assert local type = type local setmetatable = setmetatable local getmetatable = getmetatable local select = select local unpack = table.unpack local floor = math.floor local Type, typeof local function isGenericName(name) return name:byte(#name) == 93 end local function getBaseType(this) local baseType = this.baseType if baseType == nil then local baseCls = getmetatable(this[1]) if baseCls ~= nil then baseType = typeof(baseCls) this.baseType = baseType end end return baseType end local function isSubclassOf(this, c) local p = this if p == c then return false end while p ~= nil do if p == c then return true end p = getmetatable(p) end return false end local function getIsInterface(this) return this[1].class == "I" end local function fillInterfaces(t, cls, set) local base = getmetatable(cls) if base then fillInterfaces(t, base, set) end local interface = cls.interface if interface then for i = 1, #interface do local it = interface[i] if not set[it] then t[#t + 1] = typeof(it) set[it] = true end fillInterfaces(t, it, set) end end end local function getInterfaces(this) local t = this.interfaces if t == nil then t = arrayFromTable({}, Type, true) fillInterfaces(t, this[1], {}) this.interfaces = t end return t end local function implementInterface(this, ifaceType) local t = this while t ~= nil do local interfaces = getInterfaces(this) if interfaces ~= nil then for i = 1, #interfaces do local it = interfaces[i] if it == ifaceType or implementInterface(it, ifaceType) then return true end end end t = getBaseType(t) end return false end local function isAssignableFrom(this, c) if c == nil then return false end if this == c then return true end local left, right = this[1], c[1] if left == Object then return true end if isSubclassOf(right, left) then return true end if left.class == "I" then return implementInterface(c, this) end return false end local function isGenericTypeDefinition(this) return not rawget(this[1], "__name__") end Type = System.define("System.Type", { Equals = System.equals, getIsGenericType = function (this) return isGenericName(this[1].__name__) end, getContainsGenericParameters = function (this) return isGenericName(this[1].__name__) end, getIsGenericTypeDefinition = isGenericTypeDefinition, GetGenericTypeDefinition = function (this) if isGenericTypeDefinition(this) then return this end local name = this[1].__name__ local i = name:find('`') if i then local genericTypeName = name:sub(1, i - 1) return typeof(System.getClass(genericTypeName)) end throw(System.InvalidOperationException()) end, MakeGenericType = function (this, ...) local args = { ... } for i = 1, #args do args[i] = args[i][1] end return typeof(this[1](unpack(args))) end, getIsEnum = function (this) return this[1].class == "E" end, getIsClass = function (this) return this[1].class == "C" end, getIsValueType = function (this) return this[1].class == "S" end, getName = function (this) local name = this.name if name == nil then local clsName = this[1].__name__ local pattern = isGenericName(clsName) and "^.*()%.(.*)%[.+%]$" or "^.*()%.(.*)$" name = clsName:gsub(pattern, "%2") this.name = name end return name end, getFullName = function (this) return this[1].__name__ end, getNamespace = function (this) local namespace = this.namespace if namespace == nil then local clsName = this[1].__name__ local pattern = isGenericName(clsName) and "^(.*)()%..*%[.+%]$" or "^(.*)()%..*$" namespace = clsName:gsub(pattern, "%1") this.namespace = namespace end return namespace end, getBaseType = function (this) local cls = this[1] if cls.class ~= "I" and cls ~= Object then while true do local base = getmetatable(cls) if not base then break end if base.__index == base then return typeof(base) end cls = base end end return nil end, IsSubclassOf = function (this, c) return isSubclassOf(this[1], c[1]) end, getIsInterface = getIsInterface, GetInterfaces = getInterfaces, IsAssignableFrom = isAssignableFrom, IsInstanceOfType = function (this, obj) if obj == nil then return false end return isAssignableFrom(this, obj:GetType()) end, ToString = function (this) return this[1].__name__ end, GetTypeFrom = function (typeName, throwOnError, ignoreCase) if typeName == nil then throw(ArgumentNullException("typeName")) end if #typeName == 0 then if throwOnError then throw(TypeLoadException("Arg_TypeLoadNullStr")) end return nil end assert(not ignoreCase, "ignoreCase is not support") local cls = getClass(typeName) if cls ~= nil then return typeof(cls) end if throwOnError then throw(TypeLoadException(typeName .. ": failed to load.")) end return nil end }) local NumberType = { __index = Type, __eq = function (a, b) local c1, c2 = a[1], b[1] if c1 == c2 then return true end if c1 == Number or c2 == Number then return true end return false end } local function newNumberType(c) return setmetatable({ c }, NumberType) end local types = { [Char] = newNumberType(Char), [SByte] = newNumberType(SByte), [Byte] = newNumberType(Byte), [Int16] = newNumberType(Int16), [UInt16] = newNumberType(UInt16), [Int32] = newNumberType(Int32), [UInt32] = newNumberType(UInt32), [Int64] = newNumberType(Int64), [UInt64] = newNumberType(UInt64), [Single] = newNumberType(Single), [Double] = newNumberType(Double), [Int] = newNumberType(Int), [Number] = newNumberType(Number), } local customTypeof = System.config.customTypeof function typeof(cls) assert(cls) local t = types[cls] if t == nil then if customTypeof then t = customTypeof(cls) if t then types[cls] = t return t end end t = setmetatable({ cls }, Type) types[cls] = t end return t end local function getType(obj) return typeof(getmetatable(obj)) end System.typeof = typeof System.Object.GetType = getType local function addCheckInterface(set, cls) local interface = cls.interface if interface then for i = 1, #interface do local it = interface[i] set[it] = true addCheckInterface(set, it) end end end local function getCheckSet(cls) local set = {} local p = cls repeat set[p] = true addCheckInterface(set, p) p = getmetatable(p) until not p return set end local customTypeCheck = System.config.customTypeCheck local checks = setmetatable({}, { __index = function (checks, cls) if customTypeCheck then local f, add = customTypeCheck(cls) if f then if add then checks[cls] = f end return f end end local set = getCheckSet(cls) local function check(obj, T) return set[T] == true end checks[cls] = check return check end }) checks[Number] = function (obj, T) local set = getCheckSet(Number) local numbers = { [Char] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 65535 and floor(obj) == obj end, [SByte] = function (obj) return type(obj) == "number" and obj >= -128 and obj <= 127 and floor(obj) == obj end, [Byte] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 255 and floor(obj) == obj end, [Int16] = function (obj) return type(obj) == "number" and obj >= -32768 and obj <= 32767 and floor(obj) == obj end, [UInt16] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 32767 and floor(obj) == obj end, [Int32] = function (obj) return type(obj) == "number" and obj >= -2147483648 and obj <= 2147483647 and floor(obj) == obj end, [UInt32] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 4294967295 and floor(obj) == obj end, [Int64] = function (obj) return type(obj) == "number" and obj >= -9223372036854775808 and obj <= 9223372036854775807 and floor(obj) == obj end, [UInt64] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 18446744073709551615 and floor(obj) == obj end, [Single] = function (obj) return type(obj) == "number" and obj >= -3.40282347E+38 and obj <= 3.40282347E+38 end, [Double] = function (obj) return type(obj) == "number" end } local function check(obj, T) local number = numbers[T] if number then return number(obj) end return set[T] == true end checks[Number] = check return check(obj, T) end local is, getName if System.debugsetmetatable then is = function (obj, T) return checks[getmetatable(obj)](obj, T) end getName = function (obj) return obj.__name__ end System.getClassFromObj = getmetatable else local function getClassFromObj(obj) local t = type(obj) if t == "number" then return Number elseif t == "boolean" then return Boolean elseif t == "function" then return Delegate end return getmetatable(obj) end function System.ObjectGetType(this) if this == nil then throw(NullReferenceException()) end return typeof(getClassFromObj(this)) end is = function (obj, T) local base = getClassFromObj(obj) if base then return checks[base](obj, T) end return false end getName = function (obj) return getClassFromObj(obj).__name__ end System.getClassFromObj = getClassFromObj end System.is = is function System.as(obj, cls) if obj ~= nil and is(obj, cls) then return obj end return nil end local function cast(cls, obj, nullable) if obj ~= nil then if is(obj, cls) then return obj end throw(InvalidCastException(("Unable to cast object of type '%s' to type '%s'."):format(getName(obj), cls.__name__)), 1) else if cls.class ~= "S" or nullable then return nil end throw(NullReferenceException(), 1) end end System.cast = cast function System.castWithNullable(cls, obj) if System.isNullable(cls) then return cast(cls.__genericT__, obj, true) end return cast(cls, obj) end ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Type.lua.meta ================================================ fileFormatVersion: 2 guid: e04c3d45c30677947a46f7bae4c7aadd timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Utilities.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] local System = System local throw = System.throw local define = System.define local trunc = System.trunc local sl = System.sl local bor = System.bor local TimeSpan = System.TimeSpan local ArgumentNullException = System.ArgumentNullException local select = select local type = type local os = os local clock = os.clock local tostring = tostring local collectgarbage = collectgarbage define("System.Environment", { Exit = os.exit, getStackTrace = System.traceback, getTickCount = function () return System.currentTimeMillis() % 2147483648 end }) define("System.GC", { Collect = function () collectgarbage("collect") end, GetTotalMemory = function (forceFullCollection) if forceFullCollection then collectgarbage("collect") end return collectgarbage("count") * 1024 end }) local Lazy = { created = false, __ctor__ = function (this, ...) local n = select("#", ...) if n == 0 then elseif n == 1 then local valueFactory = ... if valueFactory == nil then throw(ArgumentNullException("valueFactory")) elseif type(valueFactory) ~= "boolean" then this.valueFactory = valueFactory end elseif n == 2 then local valueFactory = ... if valueFactory == nil then throw(ArgumentNullException("valueFactory")) end this.valueFactory = valueFactory end end, getIsValueCreated = function (this) return this.created end, getValue = function (this) if not this.created then local valueFactory = this.valueFactory if valueFactory then this.value = valueFactory() this.valueFactory = nil else this.value = this.__genericT__() end this.created = true end return this.value end, ToString = function (this) if this.created then return this.value:ToString() end return "Value is not created." end } define("System.Lazy", function (T) return { __genericT__ = T } end, Lazy) local ticker, frequency local time = System.config.time if time then ticker = time frequency = 10000 else ticker = clock frequency = 1000 end local function getRawElapsedSeconds(this) local timeElapsed = this.elapsed if this.running then local currentTimeStamp = ticker() local elapsedUntilNow = currentTimeStamp - this.startTimeStamp timeElapsed = timeElapsed + elapsedUntilNow end return timeElapsed end local Stopwatch Stopwatch = define("System.Diagnostics.Stopwatch", { elapsed = 0, running = false, IsHighResolution = false, Frequency = frequency, StartNew = function () local t = Stopwatch() t:Start() return t end, GetTimestamp = function () return trunc(ticker() * frequency) end, Start = function (this) if not this.running then this.startTimeStamp = ticker() this.running = true end end, Stop = function (this) if this.running then local endTimeStamp = ticker() local elapsedThisPeriod = endTimeStamp - this.startTimeStamp local elapsed = this.elapsed + elapsedThisPeriod this.running = false if elapsed < 0 then -- os.clock may be return negative value elapsed = 0 end this.elapsed = elapsed end end, Reset = function (this) this.elapsed = 0 this.running = false this.startTimeStamp = 0 end, Restart = function (this) this.elapsed = 0 this.startTimeStamp = ticker() this.running = true end, getIsRunning = function (this) return this.running end, getElapsed = function (this) return TimeSpan(trunc(getRawElapsedSeconds(this) * 1e7)) end, getElapsedMilliseconds = function (this) return trunc(getRawElapsedSeconds(this) * 1000) end, getElapsedTicks = function (this) return trunc(getRawElapsedSeconds(this) * frequency) end }) System.Stopwatch = Stopwatch local weaks = setmetatable({}, { __mode = "kv" }) local function setWeakTarget(this, target) weaks[this] = target end define("System.WeakReference", { trackResurrection = false, SetTarget = setWeakTarget, setTarget = setWeakTarget, __ctor__ = function (this, target, trackResurrection) if trackResurrection then this.trackResurrection = trackResurrection end weaks[this] = target end, TryGetTarget = function (this) local target = weaks[this] return target ~= nil, target end, getIsAlive = function (this) return weaks[this] ~= nil end, getTrackResurrection = function (this) return this.trackResurrection end, getTarget = function (this) return weaks[this] end }) define("System.Guid", {}) define("System.ArraySegment", {}) ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem/Utilities.lua.meta ================================================ fileFormatVersion: 2 guid: 78d6ea4ba4295854389822aa7fb53ca5 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/CoreSystem.meta ================================================ fileFormatVersion: 2 guid: 2138a9006de9313498422cd95a8c4124 folderAsset: yes timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/Sample/test.lua ================================================ require('mobdebug').coro() require("strict") local socket = require("socket") local now = 0 local timeoutQueue local conf = { time = socket and socket.gettime or os.time, setTimeout = function (f, delay) if not timeoutQueue then timeoutQueue = System.TimeoutQueue() end return timeoutQueue:Add(now, delay, f) end, clearTimeout = function (t) timeoutQueue:Erase(t) end } local function runTimeout() if timeoutQueue then while true do local nextExpiration = timeoutQueue:getNextExpiration() if nextExpiration ~= timeoutQueue.MaxExpiration then now = nextExpiration timeoutQueue:RunLoop(now) else break end end end end package.path = package.path .. ";CSharp.lua/Coresystem.lua/?.lua" require("All")("", conf) collectgarbage("collect") print(collectgarbage("count")) local function test(f, name) print("-----------------------------", name) f() print("\n") end local function printList(list) assert(list) local t = {} for _, i in System.each(list) do table.insert(t, i:ToString()) end print(table.concat(t, " ")) end local function testDateTimeAndTimeSpan() local date = System.DateTime.getNow() print(date:getTicks()) print(date:ToString(), date:getYear(), date:getMonth(), date:getDay(), date:getHour(), date:getMinute(), date:getSecond()) local ts = System.TimeSpan.FromSeconds(20) print(ts:ToString()) date = date + System.TimeSpan.FromDays(2) print(date:ToString()) date = date:AddMonths(2); print(date:ToString()) local baseTime = System.DateTime(1970, 1, 1) print(baseTime:ToString()) print(baseTime:AddMilliseconds(1458032204643):ToString()) end local function testArray() local arr = System.Array(System.Int32):new(10) print(arr:ToString(), #arr) printList(arr) arr:set(0, 2) arr:set(6, 4) printList(arr) print(arr:get(0), arr:get(6), arr:get(9)) end local function testList() local list = System.List(System.Int)() list:Add(20) list:Add(15) list:Add(6) print(list:ToString(), #list) printList(list) local subList = list:GetRange(1, 2) printList(subList) list:set(1, 8) list:Sort() printList(list) print(list:Contains(10), list:Contains(15), list:IndexOf(20)) list:RemoveAll(function(i) return i >= 10 end) print(#list, list:get(1)) printList(list) end local function testDictionary() local dict = System.Dictionary(System.String, System.Int)() dict:Add("a", 1) dict:Add("b", 12) dict:Add("c", 25) dict:Add("d", 30) for _, pair in System.each(dict) do print(pair.Key, pair.Value) end print("-------------") for k, v in System.pairs(dict) do print(k, v) end end local function testYeild() local enumerable = function (begin, _end) return System.yieldIEnumerable(function (begin, _end) while begin < _end do System.yield(begin) begin = begin + 1 end end, System.Int, begin, _end) end local e = enumerable(1, 10) printList(e) printList(e) end local function testDelegate() local prints = "" local function printExt(s) prints = prints .. s print(s) end local function assertExt(s) assert(prints == s, s) prints = "" end local d1 = function() printExt("d1") end local d2 = function() printExt("d2") end local d3 = function() printExt("d3") end local f = nil + d1 f() assertExt("d1") print("--") f = d1 + nil f() assertExt("d1") print("--") f = d1 + d2 f() assertExt("d1d2") print("--") f = d1 + (d2 + d3) f() assertExt("d1d2d3") print("--") f = (d1 + d2) + (d2 + d3) f() assertExt("d1d2d2d3") print("--") f = d1 + d2 - d1 f() assertExt("d2") print("--") f = d1 + d2 - d2 f() assertExt("d1") print("--") f = d1 + d2 + d1 - d1 f() assertExt("d1d2") print("--") f = d1 + d2 + d3 - (d1 + d2) f() assertExt("d3") print("--") f = d1 + d2 + d3 - (d2 + d1) f() assertExt("d1d2d3") print("--") f = (d1 + d2) + (d3 + d1 + d2) local f1 = d1 + d2 f = f - f1 f() assertExt("d1d2d3") print("--") f = (d1 + d2) - (d1 + d2) print(f == nil) end local function testLinq() local Linq = System.Linq.Enumerable local list = System.List(System.Int)() list:Add(10) list:Add(2) list:Add(30) list:Add(4) list:Add(5) list:Add(6) list:Add(7) list:Add(8) printList(Linq.Where(list, function(i) return i >= 4 end)) printList(Linq.Take(list, 4)) printList(Linq.Select(list, function(i) return i + 2 end, System.Int)) print(Linq.Min(list), Linq.Max(list)) print(Linq.ElementAtOrDefault(Linq.Where(list, function(i) return i <= 4 end), 5)) local ll = Linq.Where(list, function(i) return i <= 4 end) print(Linq.Count(ll)) Linq.Any(ll) print(Linq.Count(ll)) printList(Linq.OrderByDescending(list, function(i) return i end, nil, System.Int)) list = System.List(System.Object)() local super = { ToString = function(t) return t[1] .. ',' .. t[2] .. ',' .. t[3] .. '|' end } super.__index = super list:Add(setmetatable({ 4, 2, 3 }, super)) list:Add(setmetatable({ 3, 1, 3 }, super)) list:Add(setmetatable({ 1, 2, 3 }, super)) list:Add(setmetatable({ 3, 2, 4 }, super)) list:Add(setmetatable({ 3, 2, 3 }, super)) local t1 = Linq.OrderBy(list, function(i) return i[1] end, nil, System.Int) printList(t1) t1 = Linq.ThenBy(t1, function(i) return i[2] end, nil, System.Int) t1 = Linq.ThenBy(t1, function(i) return i[3] end, nil, System.Int) printList(t1) end local function testGroupBy() local Linq = System.Linq.Enumerable local list = System.List(System.Object)() list:Add({ id = 5, Template = 30 }) list:Add({ id = 6, Template = 30 }) list:Add({ id = 1, Template = 1 }) list:Add({ id = 2, Template = 2 }) list:Add({ id = 3, Template = 1 }) list:Add({ id = 4, Template = 2 }) local groups = Linq.GroupBy(list, function (i) return i.Template end, System.Int) local s = "" for _, group in System.each(groups) do for _, item in System.each(group) do s = s .. item.id end end print(s) assert(s == "561324"); end local function testType() local ins = 2 print(System.is(ins, System.Double)) local t = ins:GetType() print(t:getName()) print(System.is("ddd", System.String)) print(System.as("ddd", System.String)) print(System.cast(System.String, "ddd")) end local function testNumCast() assert(System.toInt32(-2147483659) == 2147483637) assert(System.toUInt32(-2147483659) == 2147483637) assert(System.toUInt64(-1) == 18446744073709551615) end local function testSplit() local a = "a, b" local aa = a:Split(44 --[[',']]) printList(aa) end local function testConsole() print("enter your name") local name = System.Console.ReadLine() print("enter your age") local age = System.Console.ReadLine() System.Console.WriteLine("name {0}, age {1}", name, age) end local function testIO() local path = "iotest.txt" local s = "hero, CSharp.lua\nIO" local File = System.IO.File File.WriteAllText(path, s) local text = File.ReadAllText(path) assert(text == s) File.Delete(path) end local function testStringBuilder() local sb = System.StringBuilder() sb:Append("aa") sb:Append("bbcc") sb:setLength(5) print(sb, sb:getLength()) end local function testAsync() -- Generated by CSharp.lua Compiler local System = System local Test System.import(function (global) Test = global.Test end) System.namespace("Test", function (namespace) namespace.class("TestAsync", function (namespace) local f, __ctor__ __ctor__ = function (this) local t = f(this) System.Console.WriteLine(("{0}, {1}"):Format(t:getStatus():EnumToString(System.TaskStatus), t:getException())) end f = function (this) return System.async(function (async, this) local t = System.Task.Delay(2000) async:await(t) async:await(t) System.Console.WriteLine(("Delay {0}"):Format(t:getStatus():ToEnumString(System.TaskStatus))) end, nil, this) end return { f = f, __ctor__ = __ctor__ } end) namespace.class("Program", function (namespace) local Main Main = function () Test.TestAsync() end return { Main = Main } end) end) System.init({ "Test.Program", "Test.TestAsync" }, { Main = "Test.Program.Main" }) Test.Program.Main() runTimeout() end local function testAsyncForeach() local System = System local ListInt32 = System.List(System.Int32) System.namespace("Test", function (namespace) namespace.class("Program", function (namespace) local GenerateSequence, Main, Test GenerateSequence = function (n) return System.yieldIAsyncEnumerable(function (async, n) for i = 0, n - 1 do async:yield(i) end end, System.Int32, n) end Main = function (args) Test() end Test = function () System.async(function (async) local l = ListInt32() for _, number in System.asynceach(async, GenerateSequence(10)) do System.Console.WriteLine(number) l:Add(number) end async:await(System.Task.Delay(200)) System.Console.WriteLine(System.String.JoinEnumerable(",", l)) end, true) end return { GenerateSequence = GenerateSequence, Main = Main } end) end) System.init({ "Test.Program" }, { Main = "Test.Program.Main" }) Test.Program.Main() runTimeout() end test(testDateTimeAndTimeSpan, "DateTime & TimeSpan") test(testArray, "Array") test(testList, "List") test(testDictionary, "Dictionary") test(testYeild, "Yeild") test(testDelegate, "Delegate") test(testLinq, "Linq") test(testGroupBy, "GroupBy") test(testType, "Type") test(testNumCast, "NumCast") test(testSplit, "testSplit") test(testStringBuilder, "StringBuilder") test(testIO, "IO") --test(testConsole, "Console") --test(testAsync, "Async") --test(testAsyncForeach, "testAsyncForeach") ================================================ FILE: Assets/Lua/CoreSystemLua/Sample/test.lua.meta ================================================ fileFormatVersion: 2 guid: 629a921622d88ad4592c0de841bdb4cb timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua/Sample.meta ================================================ fileFormatVersion: 2 guid: 1888b99286c3c2f48af9dee1c96c1581 folderAsset: yes timeCreated: 1526899278 licenseType: Free DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/CoreSystemLua.meta ================================================ fileFormatVersion: 2 guid: 473f2c916afc7094d96142fec01bf9a9 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/Main.lua ================================================ require("Classloader") --主入口函数。从这里开始lua逻辑 function Main() print("logic start") end --场景切换通知 function OnLevelWasLoaded(level) collectgarbage("collect") Time.timeSinceLevelLoad = 0 end function OnApplicationQuit() end ================================================ FILE: Assets/Lua/Main.lua.meta ================================================ fileFormatVersion: 2 guid: 091b02c3490daac4f8ed8cd5b62090b1 DefaultImporter: userData: ================================================ FILE: Assets/Lua/ProtobufAdapter.lua ================================================ require("3rd.pbc.protobuf") local protobuf = protobuf local pairs = pairs local ipairs = ipairs local protobuf = protobuf local type = type local getmetatable = getmetatable local assert = assert local enums = {} local function toEnumInt(name, T, str) local t = enums[T] if t then local v = t[str] if v then return v end else t = {} enums[T] = t end for k, cls in pairs(T) do if cls.class == "E" then local v = cls[str] if v then t[str] = v return v end end end assert(false, str .. " is not in " .. name) end local function decode(name, data) local proto, error = protobuf.decode(name, data) assert(proto, error) local T = System.getClass(name) local t = T() for k, v in pairs(proto) do if type(v) == "table" then if getmetatable(v) ~= nil then v = decode(v[1], v[2]) t[k] = v else local list = t[k] assert(list) for _, v in ipairs(v) do if type(v) == "table" then v = decode(v[1], v[2]) end list:Add(v) end end else --is enum string if type(v) == "string" and type(T[k]) == "number" then v = toEnumInt(name, T, v) end t[k] = v end end return t end function encodeProtobuf(t) local name = t.__name__ return protobuf.encode(name, t) end function decodeProtobuf(data, T) return decode(T.__name__, data) end ================================================ FILE: Assets/Lua/ProtobufAdapter.lua.meta ================================================ fileFormatVersion: 2 guid: 3b3987b905cf20f43ab7c46782a49808 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua/UnityAdapter.Lua ================================================ local System = System local throw = System.throw local emptyFn = System.emptyFn local getClass = System.getClass local is = System.is local NotSupportedException = System.NotSupportedException local SystemType = System.Type local SystemListObject = System.List(System.Object) local SystemTypeof = System.typeof local SystemIEnumerator = System.IEnumerator local arrayFromList = System.arrayFromList local ArgumentNullException = System.ArgumentNullException local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException local CSharpLua = CSharpLua local assert = assert local setmetatable = setmetatable local getmetatable = getmetatable local rawget = rawget local rawset = rawset local type = type local tinsert = table.insert local sformat = string.format local sbyte = string.byte local loadstring = loadstring local ipairs = ipairs local pairs = pairs local typeof = typeof local pcall = pcall local Clamp01 = Mathf.Clamp01 local Debugger = Debugger local BridgeMonoBehaviour = CSharpLua.BridgeMonoBehaviour local UnityEngine = UnityEngine local toluaSystem = toluaSystem local isFromCSharp = UnityEngine.isFromCSharp System.define("UnityEngine.Debug", { Log = Debugger.Log, LogFormat = function (format, ...) Debugger.Log(format:Format(...)) end, LogErrorFormat = function (format, ...) Debugger.LogError(format:Format(...)) end, }) System.typeof = function (cls) if isFromCSharp(cls) then return typeof(cls) end return SystemTypeof(cls) end local UnityEngineMonoBehaviour = UnityEngine.MonoBehaviour UnityEngine.MonoBehaviour = nil local MonoBehaviour = System.define("UnityEngine.MonoBehaviour", { __ctor__ = emptyFn, class = "C", GetType = System.Object.GetType, print = UnityEngineMonoBehaviour.print, Awake = emptyFn, Start = emptyFn, Update = emptyFn, FixedUpdate = emptyFn, LateUpdate = emptyFn, ToString = function (this) return sformat("%s (%s)", this.ref.gameObject.name, this.__name__) end, }) SystemTypeof(MonoBehaviour)[1] = UnityEngineMonoBehaviour local function getMonoBehaviourFunction(metatableOfMonoBehaviour, name) return metatableOfMonoBehaviour[name] end local metatableOfMonoBehaviour = getmetatable(BridgeMonoBehaviour) setmetatable(MonoBehaviour, { __index = function (t, k) if type(k) == "string" then local c = sbyte(k, 1) if c ~= 95 and c ~= 46 then -- not '.' or '_' local ok, f = pcall(getMonoBehaviourFunction, metatableOfMonoBehaviour, k) if ok then local v = function (this, ...) return f(this.ref, ...) end t[k] = v return v end end end return nil end }) local updateIndexs = { Update = 0, FixedUpdate = 1, LateUpdate = 2 } local function registerUpdate(this, bridgeMonoBehaviour, nameOfFn) local f = this[nameOfFn] if f ~= emptyFn and type(f) == "function" then bridgeMonoBehaviour:RegisterUpdate(updateIndexs[nameOfFn], f) end end local typeofBridgeMonoBehaviour = typeof(BridgeMonoBehaviour) local isInstanceOfType = typeofBridgeMonoBehaviour.IsInstanceOfType local function isBridgeInstance(t) return isInstanceOfType(typeofBridgeMonoBehaviour, t) end local makeBridge local function checkBridgeMonoBehaviour(t) if isBridgeInstance(t) then local bridge = t t = bridge.Table if t == nil then local luaClass = bridge.LuaClass local T = getClass(luaClass) assert(T, luaClass .. " is not found") t = setmetatable({}, T) T.__ctor__(t) makeBridge(t, bridge, true, bridge.SerializeData, bridge.SerializeObjects) bridge:Bind(t) end end return t end function makeBridge(this, bridgeMonoBehaviour, state, serializeData, serializeObjects) this.ref = assert(bridgeMonoBehaviour) if not state then bridgeMonoBehaviour:Bind(this, this.__name__) else if serializeData and #serializeData > 0 then local datas = loadstring(serializeData)() local normals = datas[1] if normals then for k, v in pairs(normals) do if type(v) == "table" then local n = #v local T = v[n] v[n] = nil setmetatable(v, T) end this[k] = v end end local objects = datas[2] if objects then for k, v in pairs(objects) do if type(v) == "table" then local n = #v local T = v[n] v[n] = nil for i = 1, n - 1 do v[i] = checkBridgeMonoBehaviour(serializeObjects[v[i]]) end setmetatable(v, T) else v = checkBridgeMonoBehaviour(serializeObjects[v]) end this[k] = v end end end end registerUpdate(this, bridgeMonoBehaviour, "Update") registerUpdate(this, bridgeMonoBehaviour, "FixedUpdate") registerUpdate(this, bridgeMonoBehaviour, "LateUpdate") end local function newMonoBehaviour(T, bridgeMonoBehaviour, state, serializeData, serializeObjects) local this = setmetatable({}, T) T.__ctor__(this) makeBridge(this, bridgeMonoBehaviour, state, serializeData, serializeObjects) this:Awake() return this end function System.IsIEnumerator(t) return is(t, SystemIEnumerator) end local function isSystemType(t) return getmetatable(t) == SystemType end local metatableOfGameObject = getmetatable(UnityEngine.GameObject) local sourceAddComponent = rawget(metatableOfGameObject, "AddComponent") local sourceGetComponent = rawget(metatableOfGameObject, "GetComponent") local sourceGetComponentInChildren = rawget(metatableOfGameObject, "GetComponentInChildren") local sourceGetComponentInParent = rawget(metatableOfGameObject, "GetComponentInParent") local sourceGetComponents = rawget(metatableOfGameObject, "GetComponents") local sourceGetComponentsInChildren = rawget(metatableOfGameObject, "GetComponentsInChildren") local sourceGetComponentsInParent = rawget(metatableOfGameObject, "GetComponentsInParent") local function addBridgeMonoBehaviour(gameObject, T) local monoBehaviour = sourceAddComponent(gameObject, typeofBridgeMonoBehaviour) return newMonoBehaviour(T, monoBehaviour) end local function addComponent(gameObject, T) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] end if isFromCSharp(T) then if type(T) ~= "userdata" then T = typeof(T) end return sourceAddComponent(gameObject, T) elseif type(T) == "string" then local cls = getClass(T) if cls ~= nil and not isFromCSharp(cls) then return addBridgeMonoBehaviour(gameObject, cls) end local type_ = typeof(T) assert(type_, T .. " is not found") return sourceAddComponent(gameObject, type_) else return addBridgeMonoBehaviour(gameObject, T) end end rawset(metatableOfGameObject, "AddComponent", addComponent) local function getBridgeComponent(sourceGetComponents, component, T, ...) local coms = sourceGetComponents(component, typeofBridgeMonoBehaviour, ...) for i = 0, coms.Length - 1 do local t = assert(coms[i].Table) if is(t, T) then return t end end end local function getComponent(component, T) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] end if isFromCSharp(T) then if type(T) ~= "userdata" then T = typeof(T) end return sourceGetComponent(component, T) elseif type(T) == "string" then local cls = getClass(T) if cls ~= nil and not isFromCSharp(cls) then return getBridgeComponent(sourceGetComponents, component, cls) end return sourceGetComponent(component, T) else return getBridgeComponent(sourceGetComponents, component, T) end end rawset(metatableOfGameObject, "GetComponent", getComponent) local function getComponentInChildren(component, T, includeInactive) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then if includeInactive == nil then includeInactive = false end T = T[1] else if type(T) == "boolean" then T, includeInactive = includeInactive, T else includeInactive = false end end if isFromCSharp(T) then if type(T) ~= "userdata" then T = typeof(T) end return checkBridgeMonoBehaviour(sourceGetComponentInChildren(component, T, includeInactive)) end return getBridgeComponent(sourceGetComponentsInChildren, component, T, includeInactive) end rawset(metatableOfGameObject, "GetComponentInChildren", getComponentInChildren) local function getComponentInParent(component, T) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] end if isFromCSharp(T) then if type(T) ~= "userdata" then T = typeof(T) end return checkBridgeMonoBehaviour(sourceGetComponentInParent(component, T)) else return getBridgeComponent(sourceGetComponentsInParent, component, T, false) end end rawset(metatableOfGameObject, "GetComponentInParent", getComponentInParent) local function getBridgeComponents(sourceGetComponents, component, T, results, ...) local hasReturn = results == nil if hasReturn then results = SystemListObject() end if isFromCSharp(T) then if type(T) ~= "userdata" then T = typeof(T) end local coms = sourceGetComponents(component, T, ...) for i = 0, coms.Length - 1 do local t = coms[i] results:Add(t) end else local coms = sourceGetComponents(component, typeofBridgeMonoBehaviour, ...) for i = 0, coms.Length - 1 do local t = coms[i].Table if is(t, T) then results:Add(t) end end end if hasReturn then return arrayFromList(results) end end local function getComponents(component, T, results) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] elseif results then T, results = results, T end return getBridgeComponents(sourceGetComponents, component, T, results) end rawset(metatableOfGameObject, "GetComponents", getComponents) local function getComponentsInChildren(component, T, includeInactive, results) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] if includeInactive == nil then includeInactive = false end elseif isFromCSharp(T) then if includeInactive == nil then includeInactive = false end else if type(T) == "boolean" then if not results then T, includeInactive = includeInactive, T else T, includeInactive, results = results, T, includeInactive end else if not includeInactive then includeInactive = false else T, includeInactive, results = includeInactive, false, T end end end return getBridgeComponents(sourceGetComponentsInChildren, component, T, results, includeInactive) end rawset(metatableOfGameObject, "GetComponentsInChildren", getComponentsInChildren) local function getComponentsInParent(component, T, includeInactive, results) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] if includeInactive == nil then includeInactive = false end elseif isFromCSharp(T) then if includeInactive == nil then includeInactive = false end else if type(T) == "boolean" then if not results then T, includeInactive = includeInactive, T else T, includeInactive, results = results, T, includeInactive end else includeInactive = false end end return getBridgeComponents(sourceGetComponentsInParent, component, T, results, includeInactive) end rawset(metatableOfGameObject, "GetComponentsInParent", getComponentsInParent) local metatableOfComponent = getmetatable(UnityEngine.Component) rawset(metatableOfComponent, "GetComponent", function (this, ...) return this.gameObject:GetComponent(...) end) rawset(metatableOfComponent, "GetComponentInChildren", function (this, ...) return this.gameObject:GetComponentInChildren(...) end) rawset(metatableOfComponent, "GetComponentInParent", function (this, ...) return this.gameObject:GetComponentInParent(...) end) rawset(metatableOfComponent, "GetComponents", function (this, ...) return this.gameObject:GetComponents(...) end) rawset(metatableOfComponent, "GetComponentsInChildren", function (this, ...) return this.gameObject:GetComponentsInChildren(...) end) rawset(metatableOfComponent, "GetComponentsInParent", function (this, ...) return this.gameObject:GetComponentsInParent(...) end) local metatableOfObject = getmetatable(UnityEngine.Object) local sourceDestroy = rawget(metatableOfObject, "Destroy") local sourceDestroyImmediate = rawget(metatableOfObject, "DestroyImmediate") local sourceDontDestroyOnLoad = rawget(metatableOfObject, "DontDestroyOnLoad") local sourceFindObjectOfType = rawget(metatableOfObject, "FindObjectOfType") local sourceFindObjectsOfType = rawget(metatableOfObject, "FindObjectsOfType") local sourceFindObjectsOfTypeAll = rawget(metatableOfObject, "FindObjectsOfTypeAll") local sourceFindObjectsOfTypeIncludingAssets = rawget(metatableOfObject, "FindObjectsOfTypeIncludingAssets") local sourceFindSceneObjectsOfType = rawget(metatableOfObject, "FindSceneObjectsOfType") local source__eq = rawget(metatableOfObject, "__eq") local function destroy(obj, t) if obj and not isFromCSharp(obj) then obj = assert(obj.ref) end if t then sourceDestroy(obj, t) else sourceDestroy(obj) end end local function destroyImmediate(obj, t) if obj and not isFromCSharp(obj) then obj = assert(obj.ref) end if t then sourceDestroyImmediate(obj, t) else sourceDestroyImmediate(obj) end end local function dontDestroyOnLoad(obj) if obj and not isFromCSharp(obj) then obj = assert(obj.ref) end sourceDontDestroyOnLoad(obj) end local function findObjectOfType(T) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] end if isFromCSharp(T) then if type(T) ~= "userdata" then T = typeof(T) end return checkBridgeMonoBehaviour(sourceFindObjectOfType(T)) else local objs = sourceFindObjectsOfType(typeofBridgeMonoBehaviour) for i = 0, objs.Length - 1 do local t = objs[i].Table if is(t, T) then return t end end end end local function findBridgeObjectsOfType(sourceFindObjectsOfType, T) local results = SystemListObject() if isFromCSharp(T) then if type(T) ~= "userdata" then T = typeof(T) end local objs = sourceFindObjectsOfType(T) for i = 0, objs.Length - 1 do local t = objs[i] results:Add(checkBridgeMonoBehaviour(t)) end else local objs = sourceFindObjectsOfType(typeofBridgeMonoBehaviour) for i = 0, objs.Length - 1 do local t = objs[i].Table if is(t, T) then results:Add(t) end end end return arrayFromList(results) end local function findObjectsOfType(T) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] end return findBridgeObjectsOfType(sourceFindObjectsOfType, T) end local function findObjectsOfTypeAll(t) if t == nil then throw(ArgumentNullException("type")) end return findBridgeObjectsOfType(sourceFindObjectsOfTypeAll, t[1]) end local function findObjectsOfTypeIncludingAssets(t) if t == nil then throw(ArgumentNullException("type")) end return findBridgeObjectsOfType(sourceFindObjectsOfTypeIncludingAssets, t[1]) end local function findSceneObjectsOfType(t) if t == nil then throw(ArgumentNullException("type")) end return findBridgeObjectsOfType(sourceFindSceneObjectsOfType, t[1]) end local function op_Equality(x, y) if x == nil and y == nil then return true end if x and not isFromCSharp(x) then x = assert(x.ref) end if y and not isFromCSharp(y) then y = assert(y.ref) end return source__eq(x, y) end local function op_Inequality(x, y) return not op_Equality(x, y) end local function op_Implicit(x) return not op_Equality(x, nil) end local function equalsObj(this, other) if other ~= nil then if not isFromCSharp(other) then other = other.ref if other == nil or not isFromCSharp(other) then return false end end end this:Equals(other) end rawset(metatableOfObject, "Destroy", destroy) rawset(metatableOfObject, "DestroyImmediate", destroyImmediate) rawset(metatableOfObject, "DontDestroyOnLoad", dontDestroyOnLoad) rawset(metatableOfObject, "FindObjectOfType", findObjectOfType) rawset(metatableOfObject, "FindObjectsOfType", findObjectsOfType) rawset(metatableOfObject, "FindObjectsOfTypeAll", findObjectsOfTypeAll) rawset(metatableOfObject, "FindObjectsOfTypeIncludingAssets", findObjectsOfTypeIncludingAssets) rawset(metatableOfObject, "FindSceneObjectsOfType", findSceneObjectsOfType) rawset(metatableOfObject, "EqualsObj", equalsObj) local metatableOfSystemObject = getmetatable(toluaSystem.Object) local equals = rawget(metatableOfSystemObject, "Equals") local function getType(this) local name = assert(this.__name__) local cls = getClass(name) return SystemTypeof(cls) end rawset(metatableOfSystemObject, "class", "C") rawset(metatableOfSystemObject, "default", System.emptyFn) rawset(metatableOfSystemObject, "EqualsObj", equals) rawset(metatableOfSystemObject, "GetType", getType) function UnityEngine.addComponent(gameObject, componentString) local pos = componentString:find(",") if pos then local name = componentString:sub(1, pos - 1) local cls = getClass(name) if cls ~= nil and not isFromCSharp(cls) then return addBridgeMonoBehaviour(gameObject, cls) end end local type_ = typeof(componentString) assert(type_, componentString .. " is not found") return sourceAddComponent(gameObject, type_) end UnityEngine.op_Equality = op_Equality UnityEngine.op_Inequality = op_Inequality UnityEngine.op_Implicit = op_Implicit function UnityEngine.bind(monoBehaviour, luaClass, serializeData, serializeObjects) local T = getClass(luaClass) assert(T, luaClass .. " is not found") return newMonoBehaviour(T, monoBehaviour, true, serializeData, serializeObjects) end local cjson = require("cjson") local cjsonDecode = cjson.decode local function fromJsonTable(t, T) for k, v in pairs(t) do if v == cjson.null then t[k] = nil elseif type(v) == "table" then if #v > 0 then -- is list fromJsonTable(v, System.List(System.Object)) else fromJsonTable(v, System.Object) end end end setmetatable(t, T) end System.define("UnityEngine.JsonUtility", { ToJson = cjson.encode, FromJson = function (json, T) if T == nil then throw(ArgumentNullException("type")) end if isSystemType(T) then T = T[1] end local t = cjsonDecode(json) fromJsonTable(t, T) return t end }) local function defineUnityStruct(name, T) local __call = T.__call local __index = T.__index setmetatable(T, nil) System.defStc(name, T) local super = getmetatable(T) setmetatable(T, { __call = __call, __index = function (t, k) local v = __index(t, k) if v == nil then v = super[k] end return v end }) end local function inherits(_, T) return { System.IEquatable_1(T) } end local Vector2 = UnityEngine.Vector2 Vector2.x, Vector2.y = 0, 0 local newVector2 = Vector2.New UnityEngine.Vector2 = nil function Vector2.get(this, index) if index < 0 or index > 1 then throw(ArgumentOutOfRangeException("Invalid Vector2 index!")) end return index == 0 and this.x or this.y end function Vector2.set(this, index, value) if index < 0 or index > 1 then throw(ArgumentOutOfRangeException("Invalid Vector2 index!")) end if index == 0 then this.x = value else this.y = value end end local PositiveInfinity = System.Double.PositiveInfinity local NegativeInfinity = System.Double.NegativeInfinity Vector2.getdown = function() return newVector2(0, -1) end Vector2.getleft = function() return newVector2(-1, 0) end Vector2.getup = function() return newVector2(0, 1) end Vector2.getright = function() return newVector2(1, 0) end Vector2.getzero = function() return newVector2(0, 0) end Vector2.getone = function() return newVector2(1, 1) end Vector2.getpositiveInfinityVector = function() return newVector2(PositiveInfinity, PositiveInfinity) end Vector2.getnegativeInfinityVector = function() return newVector2(NegativeInfinity, NegativeInfinity) end Vector2.getmagnitude = Vector2.Magnitude Vector2.getsqrMagnitude = Vector2.SqrMagnitude Vector2.getnormalized = Vector2.Normalize local function equalsOfVector2(this, other) return this.x:Equals(other.x) and this.y:Equals(other.y) end function Vector2.EqualsObj(this, other) if getmetatable(other) ~= Vector2 then return false end return equalsOfVector2(this, other) end Vector2.Equals = equalsOfVector2 Vector2.ToString = Vector2.__tostring Vector2.__clone__ = Vector2.Clone Vector2.base = inherits defineUnityStruct("UnityEngine.Vector2", Vector2) local Vector3 = UnityEngine.Vector3 Vector3.x, Vector3.y, Vector3.z = 0, 0, 0 local newVector3 = Vector3.New UnityEngine.Vector3 = nil function Vector3.get(this, index) if index < 0 or index > 2 then throw(ArgumentOutOfRangeException("Invalid Vector3 index!")) end if index == 0 then return this.x elseif index == 1 then return this.y else return this.z end end function Vector3.set(this, index, value) if index < 0 or index > 2 then throw(ArgumentOutOfRangeException("Invalid Vector3 index!")) end if index == 0 then this.x = value elseif index == 1 then this.y = value else this.z = value end end Vector3.getup = function() return newVector3(0, 1, 0) end Vector3.getdown = function() return newVector3(0, -1, 0) end Vector3.getright = function() return newVector3(1, 0, 0) end Vector3.getleft = function() return newVector3(-1, 0, 0) end Vector3.getforward = function() return newVector3(0, 0, 1) end Vector3.getback = function() return newVector3(0, 0, -1) end Vector3.getzero = function() return newVector3(0, 0, 0) end Vector3.getone = function() return newVector3(1, 1, 1) end Vector3.getmagnitude = Vector3.Magnitude Vector3.getsqrMagnitude = Vector3.SqrMagnitude Vector3.getnormalized = Vector3.Normalize function Vector3.LerpUnclamped(a, b, t) return newVector3(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t) end local function equalsOfVector3(this, other) return this.x:Equals(other.x) and this.y:Equals(other.y) and this.z:Equals(other.z) end function Vector3.EqualsObj(this, other) if getmetatable(other) ~= Vector3 then return false end return equalsOfVector3(this, other) end Vector3.Equals = equalsOfVector3 Vector3.ToString = Vector3.__tostring Vector3.__clone__ = Vector3.Clone Vector3.base = inherits defineUnityStruct("UnityEngine.Vector3", Vector3) local Vector4 = UnityEngine.Vector4 Vector4.x, Vector4.y, Vector4.z, Vector4.w = 0, 0, 0, 0 local newVector4 = Vector4.New UnityEngine.Vector4 = nil local function getOfVector4(this, index, error) if index < 0 or index > 2 then throw(ArgumentOutOfRangeException(error), 1) end if index == 0 then return this.x elseif index == 1 then return this.y elseif index == 2 then return this.z else return this.w end end function Vector4.get(this, index) return getOfVector4(this, index, "Invalid Vector4 index!") end local function setOfVector4(this, index, value, error) if index < 0 or index > 2 then throw(ArgumentOutOfRangeException(error), 1) end if index == 0 then this.x = value elseif index == 1 then this.y = value elseif index == 2 then this.z = value else this.w = value end end function Vector4.set(this, index, value) setOfVector4(this, index, value, "Invalid Vector4 index!") end Vector4.getzero = function() return newVector4(0, 0, 0, 0) end Vector4.getone = function() return newVector4(1, 1, 1, 1) end Vector4.getsqrMagnitude = Vector4.SqrMagnitude Vector4.getmagnitude = Vector4.Magnitude Vector4.getnormalized = Vector4.Normalize local function equalsOfVector4(this, other) return this.x:Equals(other.x) and this.y:Equals(other.y) and this.z:Equals(other.z) and this.w:Equals(other.w) end function Vector4.EqualsObj(this, other) if getmetatable(other) ~= Vector4 then return false end return equalsOfVector4(this, other) end Vector4.Equals = equalsOfVector4 Vector4.ToString = Vector4.__tostring Vector4.__clone__ = Vector4.Clone Vector4.base = inherits defineUnityStruct("UnityEngine.Vector4", Vector4) function UnityEngine.ToVector2(v) return newVector2(v.x, v.y) end function UnityEngine.ToVector3(v) return newVector3(v.x, v.y, v.z) end function UnityEngine.ToVector4(v) return newVector4(v.x, v.y, v.z, v.w) end local Color = UnityEngine.Color local newColor = Color.New UnityEngine.Color = nil function Color.get(this, index) if index < 0 or index > 2 then throw(ArgumentOutOfRangeException("Invalid Color index!")) end if index == 0 then return this.r elseif index == 1 then return this.g elseif index == 2 then return this.b else return this.a end end function Color.set(this, index, value) if index < 0 or index > 2 then throw(ArgumentOutOfRangeException("Invalid Color index!")) end if index == 0 then this.r = value elseif index == 1 then this.g = value elseif index == 2 then this.b = value else this.a = value end end local Mathf = Mathf local LinearToGammaSpace = Mathf.LinearToGammaSpace local GammaToLinearSpace = Mathf.GammaToLinearSpace local Max = Mathf.Max Color.getred = function() return newColor(1, 0, 0, 1) end Color.getgreen = function() return newColor(0, 1, 0, 1) end Color.getblue = function() return newColor(0, 0, 1, 1) end Color.getwhite = function() return newColor(1, 1, 1, 1) end Color.getblack = function() return newColor(0, 0, 0, 1) end Color.getyellow = function() return newColor(1, 0.9215686, 0.01568628, 1) end Color.getcyan = function() return newColor(0, 1, 1, 1) end Color.getmagenta = function() return newColor(1, 0, 1, 1) end Color.getgray = function() return newColor(0.5, 0.5, 0.5, 1) end Color.getclear = function() return newColor(0, 0, 0, 0) end Color.getgrey = Color.gray Color.getgrayscale = Color.GrayScale Color.getgamma = function(c) return newColor(LinearToGammaSpace(c.r), LinearToGammaSpace(c.g), LinearToGammaSpace(c.b), c.a) end Color.getlinear = function(c) return newColor(GammaToLinearSpace(c.r), GammaToLinearSpace(c.g), GammaToLinearSpace(c.b), c.a) end Color.getmaxColorComponent = function(c) return Max(Max(c.r, c.g), c.b) end local function equalsOfColor(this, other) return this.r:Equals(other.r) and this.g:Equals(other.g) and this.b:Equals(other.b) and this.a:Equals(other.a) end function Color.EqualsObj(this, other) if getmetatable(other) ~= Color then return false end return equalsOfColor(this, other) end Color.Equals = equalsOfColor Color.ToString = Color.__tostring Color.__clone__ = function(this) return newColor(this.r, this.g, this.b, this.a) end Color.base = inherits defineUnityStruct("UnityEngine.Color", Color) function UnityEngine.ToColorFromVector4(v) return newColor(v.x ,v.y, v.z, v.w) end function UnityEngine.ToVector4FromColor(v) return newVector4(v.r, v.g, v.b, b.a) end local Color32 = UnityEngine.Color32 local newColor32 = Color32.New local equalsOfColor32 = Color32.Equals UnityEngine.Color32 = nil Color32.ToString = Color32.__tostring Color32.__clone__ = function (this) return newColor32(this.r, this.g, this.b, this.a) end Color32.base = System.emptyFn function Color32.EqualsObj(this, other) if getmetatable(other) ~= Color32 then return false end return equalsOfColor32(this, other) end defineUnityStruct("UnityEngine.Color32", Color32) function UnityEngine.ToColor32FromColor(c) return newColor32(Clamp01(c.r) * 255, Clamp01(c.g) * 255, Clamp01(c.b) * 255, Clamp01(c.a) * 255) end function UnityEngine.ToColorFromColor32(c) return newColor(c.r / 255, c.g / 255, c.b / 255, c.a / 255) end local Quaternion = UnityEngine.Quaternion local newQuaternion = Quaternion.New UnityEngine.Quaternion = nil function Quaternion.get(this, index) return getOfVector4(this, index, "Invalid Quaternion index!") end function Quaternion.set(this, index, value) setOfVector4(this, index, value, "Invalid Quaternion index!") end Quaternion.getidentity = function() return newQuaternion(0, 0, 0, 1) end Quaternion.geteulerAngles = Quaternion.ToEulerAngles Quaternion.seteulerAngles = Quaternion.SetEuler Quaternion.getnormalized = Quaternion.Normalize function Quaternion.EqualsObj(this, other) if getmetatable(other) ~= Quaternion then return false end return equalsOfVector4(this, other) end Quaternion.Equals = equalsOfVector4 Quaternion.ToString = Quaternion.__tostring Quaternion.__clone__ = Quaternion.Clone Quaternion.base = inherits defineUnityStruct("UnityEngine.Quaternion", Quaternion) local Bounds = UnityEngine.Bounds local newBounds = Bounds.New UnityEngine.Bounds = nil Bounds.getsize = Bounds.GetSize Bounds.getmin = Bounds.GetMin Bounds.getmax = Bounds.GetMax local function equalsOfBounds(this, other) return this.center:Equals(other.center) and this.extents:Equals(other.extents) end function Bounds.EqualsObj(this, other) if getmetatable(other) ~= Bounds then return false end return equalsOfBounds(this, other) end Bounds.Equals = equalsOfBounds Bounds.ToString = Quaternion.__tostring Bounds.__clone__ = function (this) return newBounds(this.center, this.extents) end Bounds.base = inherits defineUnityStruct("UnityEngine.Bounds", Bounds) local Plane = UnityEngine.Plane local newPlane = Plane.New UnityEngine.Plane = nil Plane.ToString = function (this) local normal = this.normal return sformat("(normal:(%.1f, %.1f, %.1f), distance:%1.f)", normal.x, normal.y, normal.z, this.distance) end Plane.__clone__ = function (this) return newPlane(this.normal, this.distance) end local Set3Points = Plane.Set3Points local SetNormalAndPosition = Plane.SetNormalAndPosition Plane.__call = function (cls, a, b, c) if c ~= nil then local this = setmetatable({ normal = false, distance = false }, Plane) Set3Points(this, a, b, c) return this elseif type(b) == "number" then return newPlane(a, b) else local this = setmetatable({ normal = false, distance = false }, Plane) SetNormalAndPosition(this, a, b) return this end end Plane.base = System.emptyFn defineUnityStruct("UnityEngine.Plane", Plane) local LayerMask = UnityEngine.LayerMask local newLayerMask = LayerMask.New UnityEngine.LayerMask = nil LayerMask.__clone__ = function (this) return newLayerMask(this.value) end UnityEngine.ToLayerMask = newLayerMask LayerMask.base = System.emptyFn defineUnityStruct("UnityEngine.LayerMask", LayerMask) local Ray = UnityEngine.Ray local newRay = Ray.New UnityEngine.Ray = nil Ray.__clone__ = function (this) return newRay(this.direction, this.origin) end Ray.ToString = Ray.__tostring Ray.base = System.emptyFn defineUnityStruct("UnityEngine.Ray", Ray) local RaycastHit = UnityEngine.RaycastHit local newRaycastHit = RaycastHit.New UnityEngine.RaycastHit = nil RaycastHit.distance = 0.0 RaycastHit.normal = Vector3.zero RaycastHit.point = Vector3.zero RaycastHit.__clone__ = function (this) return newRaycastHit(this.collider, this.distance, this.normal, this.point, this.rigidbody, this.transform) end RaycastHit.base = System.emptyFn defineUnityStruct("UnityEngine.RaycastHit", RaycastHit) ================================================ FILE: Assets/Lua/UnityAdapter.Lua.meta ================================================ fileFormatVersion: 2 guid: d6dad4765632b864f8a13b8a7e96eddc DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Lua.meta ================================================ fileFormatVersion: 2 guid: 379b0ef2d43e1bd4fa5da0ccdf1f8bbd folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins/3rd/protobuf-net.dll.meta ================================================ fileFormatVersion: 2 guid: ca3ef49e23838bb4a9371c975ff18748 timeCreated: 1517916505 licenseType: Free PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: Any: second: enabled: 1 settings: {} - first: Editor: Editor second: enabled: 0 settings: DefaultValueInitialized: true - first: Windows Store Apps: WindowsStoreApps second: enabled: 0 settings: CPU: AnyCPU userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/3rd.meta ================================================ fileFormatVersion: 2 guid: 60b870ca8c7b92f49bf9ccd5243a1a74 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/Android/libs/arm64-v8a/libtolua.so.meta ================================================ fileFormatVersion: 2 guid: 2b0ac09514a9a424daeda08c003864b0 PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: Android: Android second: enabled: 1 settings: CPU: ARM64 - first: Any: second: enabled: 0 settings: {} - first: Editor: Editor second: enabled: 0 settings: DefaultValueInitialized: true userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/Android/libs/arm64-v8a.meta ================================================ fileFormatVersion: 2 guid: 0aad78b86e3fe134db823a509dd8971e folderAsset: yes timeCreated: 1557889915 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/Android/libs/armeabi-v7a/libtolua.so.meta ================================================ fileFormatVersion: 2 guid: 4fb9a29f65e536b4293f7f9affd19158 PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: Android: Android second: enabled: 1 settings: CPU: ARMv7 - first: Any: second: enabled: 0 settings: {} - first: Editor: Editor second: enabled: 0 settings: DefaultValueInitialized: true userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/Android/libs/armeabi-v7a.meta ================================================ fileFormatVersion: 2 guid: 034154e518117d842b99fd1f19efa3a3 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins/Android/libs/x86/libtolua.so.meta ================================================ fileFormatVersion: 2 guid: 3bf04aa9e8715d047898e94157e2decd PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: Android: Android second: enabled: 1 settings: CPU: x86 - first: Any: second: enabled: 0 settings: {} - first: Editor: Editor second: enabled: 0 settings: DefaultValueInitialized: true userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/Android/libs/x86.meta ================================================ fileFormatVersion: 2 guid: d76e3311efeac224996b0cb7a06a7a3a folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins/Android/libs.meta ================================================ fileFormatVersion: 2 guid: 72b436146481b3f40b05eb161ca7f39c folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins/Android.meta ================================================ fileFormatVersion: 2 guid: 729c01aec7bba814d88608249c8a170b folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins/CString.dll.meta ================================================ fileFormatVersion: 2 guid: 4f630c0f54674a246a65918d24eeab8a PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: Any: second: enabled: 1 settings: {} - first: Editor: Editor second: enabled: 0 settings: DefaultValueInitialized: true - first: Windows Store Apps: WindowsStoreApps second: enabled: 0 settings: CPU: AnyCPU userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/Debugger.dll.meta ================================================ fileFormatVersion: 2 guid: c33668af923d0aa4ebd48ebe80ef943a PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: Any: second: enabled: 1 settings: {} - first: Editor: Editor second: enabled: 0 settings: DefaultValueInitialized: true - first: Windows Store Apps: WindowsStoreApps second: enabled: 0 settings: CPU: AnyCPU userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/iOS/libtolua.a.meta ================================================ fileFormatVersion: 2 guid: 8492849dccfbfce4485d383c0ce84651 PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: '': Any second: enabled: 0 settings: Exclude Android: 1 Exclude Editor: 1 Exclude Linux: 1 Exclude Linux64: 1 Exclude LinuxUniversal: 1 Exclude OSXUniversal: 1 Exclude Win: 1 Exclude Win64: 1 - first: Android: Android second: enabled: 0 settings: CPU: ARMv7 - first: Any: second: enabled: 0 settings: {} - first: Editor: Editor second: enabled: 0 settings: CPU: AnyCPU DefaultValueInitialized: true OS: AnyOS - first: Facebook: Win second: enabled: 0 settings: CPU: AnyCPU - first: Facebook: Win64 second: enabled: 0 settings: CPU: AnyCPU - first: Standalone: Linux second: enabled: 0 settings: CPU: x86 - first: Standalone: Linux64 second: enabled: 0 settings: CPU: x86_64 - first: Standalone: LinuxUniversal second: enabled: 0 settings: CPU: None - first: Standalone: OSXUniversal second: enabled: 0 settings: CPU: AnyCPU - first: Standalone: Win second: enabled: 0 settings: CPU: AnyCPU - first: Standalone: Win64 second: enabled: 0 settings: CPU: AnyCPU userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/iOS.meta ================================================ fileFormatVersion: 2 guid: 48e42b60abfb25b488c56d81b63e4646 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Info.plist ================================================ BuildMachineOSBuild 18A391 CFBundleDevelopmentRegion English CFBundleExecutable tolua CFBundleIdentifier ameng.tolua CFBundleInfoDictionaryVersion 6.0 CFBundleName tolua CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleSupportedPlatforms MacOSX CFBundleVersion 1 CFPlugInDynamicRegisterFunction CFPlugInDynamicRegistration NO CFPlugInFactories 00000000-0000-0000-0000-000000000000 MyFactoryFunction CFPlugInTypes 00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000 CFPlugInUnloadFunction DTCompiler com.apple.compilers.llvm.clang.1_0 DTPlatformBuild 10B61 DTPlatformVersion GM DTSDKBuild 18B71 DTSDKName macosx10.14 DTXcode 1010 DTXcodeBuild 10B61 NSHumanReadableCopyright Copyright © 2013 topameng. All rights reserved. ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Info.plist.meta ================================================ fileFormatVersion: 2 guid: c70484778b37241228e041d528df2f81 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/MacOS/tolua.meta ================================================ fileFormatVersion: 2 guid: 3ad2d3f39b17a4505951dcdc9ef15320 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/MacOS.meta ================================================ fileFormatVersion: 2 guid: 9bd8f6fa32a614c10b4789e20b57ff8f folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 codingnow.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/LICENSE.meta ================================================ fileFormatVersion: 2 guid: 686e4b0c52e6bc54a8c42c0477db291c DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/README.md ================================================ Introduction ====== Sproto is an efficient serialization library for C, and focuses on lua binding. It's like Google protocol buffers, but much faster. The design is simple. It only supports a few types that lua supports. It can be easily bound to other dynamic languages, or be used directly in C. In my i5-2500 @3.3GHz CPU, the benchmark is below: The schema in sproto: ``` .Person { name 0 : string id 1 : integer email 2 : string .PhoneNumber { number 0 : string type 1 : integer } phone 3 : *PhoneNumber } .AddressBook { person 0 : *Person } ``` It's equal to: ``` message Person { required string name = 1; required int32 id = 2; optional string email = 3; message PhoneNumber { required string number = 1; optional int32 type = 2 ; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1; } ``` Use the data: ```lua local ab = { person = { { name = "Alice", id = 10000, phone = { { number = "123456789" , type = 1 }, { number = "87654321" , type = 2 }, } }, { name = "Bob", id = 20000, phone = { { number = "01234567890" , type = 3 }, } } } } ``` library| encode 1M times | decode 1M times | size -------| --------------- | --------------- | ---- sproto | 2.15s | 7.84s | 83 bytes sproto (nopack) |1.58s | 6.93s | 130 bytes pbc-lua | 6.94s | 16.9s | 69 bytes lua-cjson | 4.92s | 8.30s | 183 bytes * pbc-lua is a google protocol buffers library https://github.com/cloudwu/pbc * lua-cjson is a json library https://github.com/efelix/lua-cjson Parser ======= ```lua local parser = require "sprotoparser" ``` * `parser.parse` parses a sproto schema to a binary string. The parser is needed for parsing the sproto schema. You can use it to generate binary string offline. The schema text and the parser is not needed when your program is running. Lua API ======= ```lua local sproto = require "sproto" local sprotocore = require "sproto.core" -- optional ``` * `sproto.new(spbin)` creates a sproto object by a schema binary string (generates by parser). * `sprotocore.newproto(spbin)` creates a sproto c object by a schema binary string (generates by parser). * `sproto.sharenew(spbin)` share a sproto object from a sproto c object (generates by sprotocore.newproto). * `sproto.parse(schema)` creares a sproto object by a schema text string (by calling parser.parse) * `sproto:exist_type(typename)` detect whether a type exist in sproto object. * `sproto:encode(typename, luatable)` encodes a lua table with typename into a binary string. * `sproto:decode(typename, blob [,sz])` decodes a binary string generated by sproto.encode with typename. If blob is a lightuserdata (C ptr), sz (integer) is needed. * `sproto:pencode(typename, luatable)` The same with sproto:encode, but pack (compress) the results. * `sproto:pdecode(typename, blob [,sz])` The same with sproto.decode, but unpack the blob (generated by sproto:pencode) first. * `sproto:default(typename, type)` Create a table with default values of typename. Type can be nil , "REQUEST", or "RESPONSE". RPC API ======= There is a lua wrapper for the core API for RPC . `sproto:host([packagename])` creates a host object to deliver the rpc message. `host:dispatch(blob [,sz])` unpack and decode (sproto:pdecode) the binary string with type the host created (packagename). If .type is exist, it's a REQUEST message with .type , returns "REQUEST", protoname, message, responser, .ud. The responser is a function for encode the response message. The responser will be nil when .session is not exist. If .type is not exist, it's a RESPONSE message for .session . Returns "RESPONSE", .session, message, .ud . `host:attach(sprotoobj)` creates a function(protoname, message, session, ud) to pack and encode request message with sprotoobj. If you don't want to use host object, you can also use these following apis to encode and decode the rpc message: `sproto:request_encode(protoname, tbl)` encode a request message with protoname. `sproto:response_encode(protoname, tbl)` encode a response message with protoname. `sproto:request_decode(protoname, blob [,sz])` decode a request message with protoname. `sproto:response_decode(protoname, blob [,sz]` decode a response message with protoname. Read testrpc.lua for detail. Schema Language ========== Like Protocol Buffers (but unlike json), sproto messages are strongly-typed and are not self-describing. You must define your message structure in a special language. You can use sprotoparser library to parse the schema text to a binary string, so that the sproto library can use it. You can parse them offline and save the string, or you can parse them during your program running. The schema text is like this: ``` # This is a comment. .Person { # . means a user defined type name 0 : string # string is a build-in type. id 1 : integer email 2 : string .PhoneNumber { # user defined type can be nest. number 0 : string type 1 : integer } phone 3 : *PhoneNumber # *PhoneNumber means an array of PhoneNumber. height 4 : integer(2) # (2) means a 1/100 fixed-point number. data 5 : binary # Some binary data } .AddressBook { person 0 : *Person(id) # (id) is optional, means Person.id is main index. } foobar 1 { # define a new protocol (for RPC used) with tag 1 request Person # Associate the type Person with foobar.request response { # define the foobar.response type ok 0 : boolean } } ``` A schema text can be self-described by the sproto schema language. ``` .type { .field { name 0 : string buildin 1 : integer type 2 : integer # type is fixed-point number precision when buildin is SPROTO_TINTEGER; When buildin is SPROTO_TSTRING, it means binary string when type is 1. tag 3 : integer array 4 : boolean key 5 : integer # If key exists, array must be true, and it's a map. } name 0 : string fields 1 : *field } .protocol { name 0 : string tag 1 : integer request 2 : integer # index response 3 : integer # index confirm 4 : boolean # response nil where confirm == true } .group { type 0 : *type protocol 1 : *protocol } ``` Types ======= * **string** : string * **binary** : binary string (it's a sub type of string) * **integer** : integer, the max length of an integer is signed 64bit. It can be a fixed-point number with specified precision. * **boolean** : true or false You can add * before the typename to declare an array. You can also specify a main index, the array whould be encode as an unordered map. User defined type can be any name in alphanumeric characters except the build-in typenames, and nested types are supported. * Where are double or real types? I have been using Google protocol buffers for many years in many projects, and I found the real types were seldom used. If you really need it, you can use string to serialize the double numbers. When you need decimal, you can specify the fixed-point presision. * Where is enum? In lua, enum types are not very useful. You can use integer to define an enum table in lua. Wire protocol ======== Each integer number must be serialized in little-endian format. The sproto message must be a user defined type struct, and a struct is encoded in three parts. The header, the field part, and the data part. The tag and small integer or boolean will be encoded in field part, and others are in data part. All the fields must be encoded in ascending order (by tag, base 0). The tags of fields can be discontinuous, if a field is nil. (default value in lua), don't encode it in message. The header is a 16bit integer. It is the number of fields. Each field in field part is a 16bit integer (n). If n is zero, that means the field data is encoded in data part ; If n is even (and not zero), the value of this field is n/2-1 , and the tag increases 1; If n is odd, that means the tags is not continuous, and we should add current tag by (n+1)/2 . Arrays are always encode in data part, 4 bytes header for the size, and the following bytes is the contents. See the example 2 for the struct array; example 3/4 for the integer array ; example 5 for the boolean array. For integer array, an additional byte (4 or 8) to indicate the value is 32bit or 64bit. Read the examples below to see more details. Notice: If the tag is not declared in schema, the decoder will simply ignore the field for protocol version compatibility. ``` .Person { name 0 : string age 1 : integer marital 2 : boolean children 3 : *Person } .Data { numbers 0 : *integer bools 1 : *boolean number 2 : integer bignumber 3 : integer } ``` Example 1: ``` person { name = "Alice" , age = 13, marital = false } 03 00 (fn = 3) 00 00 (id = 0, value in data part) 1C 00 (id = 1, value = 13) 02 00 (id = 2, value = false) 05 00 00 00 (sizeof "Alice") 41 6C 69 63 65 ("Alice") ``` Example 2: ``` person { name = "Bob", age = 40, children = { { name = "Alice" , age = 13 }, { name = "Carol" , age = 5 }, } } 04 00 (fn = 4) 00 00 (id = 0, value in data part) 52 00 (id = 1, value = 40) 01 00 (skip id = 2) 00 00 (id = 3, value in data part) 03 00 00 00 (sizeof "Bob") 42 6F 62 ("Bob") 26 00 00 00 (sizeof children) 0F 00 00 00 (sizeof child 1) 02 00 (fn = 2) 00 00 (id = 0, value in data part) 1C 00 (id = 1, value = 13) 05 00 00 00 (sizeof "Alice") 41 6C 69 63 65 ("Alice") 0F 00 00 00 (sizeof child 2) 02 00 (fn = 2) 00 00 (id = 0, value in data part) 0C 00 (id = 1, value = 5) 05 00 00 00 (sizeof "Carol") 43 61 72 6F 6C ("Carol") ``` Example 3: ``` data { numbers = { 1,2,3,4,5 } } 01 00 (fn = 1) 00 00 (id = 0, value in data part) 15 00 00 00 (sizeof numbers) 04 ( sizeof int32 ) 01 00 00 00 (1) 02 00 00 00 (2) 03 00 00 00 (3) 04 00 00 00 (4) 05 00 00 00 (5) ``` Example 4: ``` data { numbers = { (1<<32)+1, (1<<32)+2, (1<<32)+3, } } 01 00 (fn = 1) 00 00 (id = 0, value in data part) 19 00 00 00 (sizeof numbers) 08 ( sizeof int64 ) 01 00 00 00 01 00 00 00 ( (1<32) + 1) 02 00 00 00 01 00 00 00 ( (1<32) + 2) 03 00 00 00 01 00 00 00 ( (1<32) + 3) ``` Example 5: ``` data { bools = { false, true, false } } 02 00 (fn = 2) 01 00 (skip id = 0) 00 00 (id = 1, value in data part) 03 00 00 00 (sizeof bools) 00 (false) 01 (true) 00 (false) ``` Example 6: ``` data { number = 100000, bignumber = -10000000000, } 03 00 (fn = 3) 03 00 (skip id = 1) 00 00 (id = 2, value in data part) 00 00 (id = 3, value in data part) 04 00 00 00 (sizeof number, data part) A0 86 01 00 (100000, 32bit integer) 08 00 00 00 (sizeof bignumber, data part) 00 1C F4 AB FD FF FF FF (-10000000000, 64bit integer) ``` 0 Packing ======= The algorithm is very similar to [Cap'n proto](http://kentonv.github.io/capnproto/), but 0x00 is not treated specially. In packed format, the message is padding to 8. Each 8 byte is reduced to a tag byte followed by zero to eight content bytes. The bits of the tag byte correspond to the bytes of the unpacked word, with the least-significant bit corresponding to the first byte. Each zero bit indicates that the corresponding byte is zero. The non-zero bytes are packed following the tag. For example: ``` unpacked (hex): 08 00 00 00 03 00 02 00 19 00 00 00 aa 01 00 00 packed (hex): 51 08 03 02 31 19 aa 01 ``` Tag 0xff is treated specially. A number N is following the 0xff tag. N means (N+1)\*8 bytes should be copied directly. The bytes may or may not contain zeros. Because of this rule, the worst-case space overhead of packing is 2 bytes per 2 KiB of input. For example: ``` unpacked (hex): 8a (x 30 bytes) packed (hex): ff 03 8a (x 30 bytes) 00 00 ``` C API ===== ```C struct sproto * sproto_create(const void * proto, size_t sz); ``` Create a sproto object with a schema string encoded by sprotoparser: ```C void sproto_release(struct sproto *); ``` Release the sproto object: ```C int sproto_prototag(struct sproto *, const char * name); const char * sproto_protoname(struct sproto *, int proto); // SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response struct sproto_type * sproto_protoquery(struct sproto *, int proto, int what); ``` Convert between tag and name of a protocol, and query the type object of it: ```C struct sproto_type * sproto_type(struct sproto *, const char * typename); ``` Query the type object from a sproto object: ```C struct sproto_arg { void *ud; const char *tagname; int tagid; int type; struct sproto_type *subtype; void *value; int length; int index; // array base 1 int mainindex; // for map int extra; // SPROTO_TINTEGER: fixed-point presision ; SPROTO_TSTRING 0:utf8 string 1:binary }; typedef int (*sproto_callback)(const struct sproto_arg *args); int sproto_decode(struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud); int sproto_encode(struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud); ``` encode and decode the sproto message with a user defined callback function. Read the implementation of lsproto.c for more details. ```C int sproto_pack(const void * src, int srcsz, void * buffer, int bufsz); int sproto_unpack(const void * src, int srcsz, void * buffer, int bufsz); ``` pack and unpack the message with the 0 packing algorithm. Other Implementions and bindings ===== See Wiki https://github.com/cloudwu/sproto/wiki Question? ========== * Send me an email: http://www.codingnow.com/2000/gmail.gif * My Blog: http://blog.codingnow.com * Design: http://blog.codingnow.com/2014/07/ejoyproto.html (in Chinese) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/README.md.meta ================================================ fileFormatVersion: 2 guid: 67caed6d2702fdb4684d0884268df1c1 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/print_r.lua ================================================ local print = print local tconcat = table.concat local tinsert = table.insert local srep = string.rep local type = type local pairs = pairs local tostring = tostring local next = next local function print_r(root) local cache = { [root] = "." } local function _dump(t,space,name) local temp = {} for k,v in pairs(t) do local key = tostring(k) if cache[v] then tinsert(temp,"+" .. key .. " {" .. cache[v].."}") elseif type(v) == "table" then local new_key = name .. "." .. key cache[v] = new_key tinsert(temp,"+" .. key .. _dump(v,space .. (next(t,k) and "|" or " " ).. srep(" ",#key),new_key)) else tinsert(temp,"+" .. key .. " [" .. tostring(v).."]") end end return tconcat(temp,"\n"..space) end print(_dump(root, "","")) end return print_r ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/print_r.lua.meta ================================================ fileFormatVersion: 2 guid: 39f7f75a80c0f32498f199fdb0da24a5 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.lua ================================================ local core = require "sproto.core" local assert = assert local sproto = {} local host = {} local weak_mt = { __mode = "kv" } local sproto_mt = { __index = sproto } local sproto_nogc = { __index = sproto } local host_mt = { __index = host } function sproto_mt:__gc() core.deleteproto(self.__cobj) end function sproto.new(bin) local cobj = assert(core.newproto(bin)) local self = { __cobj = cobj, __tcache = setmetatable( {} , weak_mt ), __pcache = setmetatable( {} , weak_mt ), } return setmetatable(self, sproto_mt) end function sproto.sharenew(cobj) local self = { __cobj = cobj, __tcache = setmetatable( {} , weak_mt ), __pcache = setmetatable( {} , weak_mt ), } return setmetatable(self, sproto_nogc) end function sproto.parse(ptext) local parser = require "sprotoparser" local pbin = parser.parse(ptext) return sproto.new(pbin) end function sproto:host( packagename ) packagename = packagename or "package" local obj = { __proto = self, __package = assert(core.querytype(self.__cobj, packagename), "type package not found"), __session = {}, } return setmetatable(obj, host_mt) end local function querytype(self, typename) local v = self.__tcache[typename] if not v then v = assert(core.querytype(self.__cobj, typename), "type not found") self.__tcache[typename] = v end return v end function sproto:exist_type(typename) local v = self.__tcache[typename] if not v then return core.querytype(self.__cobj, typename) ~= nil else return true end end function sproto:encode(typename, tbl) local st = querytype(self, typename) return core.encode(st, tbl) end function sproto:decode(typename, ...) local st = querytype(self, typename) return core.decode(st, ...) end function sproto:pencode(typename, tbl) local st = querytype(self, typename) return core.pack(core.encode(st, tbl)) end function sproto:pdecode(typename, ...) local st = querytype(self, typename) return core.decode(st, core.unpack(...)) end local function queryproto(self, pname) local v = self.__pcache[pname] if not v then local tag, req, resp = core.protocol(self.__cobj, pname) assert(tag, pname .. " not found") if tonumber(pname) then pname, tag = tag, pname end v = { request = req, response =resp, name = pname, tag = tag, } self.__pcache[pname] = v self.__pcache[tag] = v end return v end function sproto:exist_proto(pname) local v = self.__pcache[pname] if not v then return core.protocol(self.__cobj, pname) ~= nil else return true end end function sproto:request_encode(protoname, tbl) local p = queryproto(self, protoname) local request = p.request if request then return core.encode(request,tbl) , p.tag else return "" , p.tag end end function sproto:response_encode(protoname, tbl) local p = queryproto(self, protoname) local response = p.response if response then return core.encode(response,tbl) else return "" end end function sproto:request_decode(protoname, ...) local p = queryproto(self, protoname) local request = p.request if request then return core.decode(request,...) , p.name else return nil, p.name end end function sproto:response_decode(protoname, ...) local p = queryproto(self, protoname) local response = p.response if response then return core.decode(response,...) end end sproto.pack = core.pack sproto.unpack = core.unpack function sproto:default(typename, type) if type == nil then return core.default(querytype(self, typename)) else local p = queryproto(self, typename) if type == "REQUEST" then if p.request then return core.default(p.request) end elseif type == "RESPONSE" then if p.response then return core.default(p.response) end else error "Invalid type" end end end local header_tmp = {} local function gen_response(self, response, session) return function(args, ud) header_tmp.type = nil header_tmp.session = session header_tmp.ud = ud local header = core.encode(self.__package, header_tmp) if response then local content = core.encode(response, args) return core.pack(header .. content) else return core.pack(header) end end end function host:dispatch(...) local bin = core.unpack(...) header_tmp.type = nil header_tmp.session = nil header_tmp.ud = nil local header, size = core.decode(self.__package, bin, header_tmp) local content = bin:sub(size + 1) if header.type then -- request local proto = queryproto(self.__proto, header.type) local result if proto.request then result = core.decode(proto.request, content) end if header_tmp.session then return "REQUEST", proto.name, result, gen_response(self, proto.response, header_tmp.session), header.ud else return "REQUEST", proto.name, result, nil, header.ud end else -- response local session = assert(header_tmp.session, "session not found") local response = assert(self.__session[session], "Unknown session") self.__session[session] = nil if response == true then return "RESPONSE", session, nil, header.ud else local result = core.decode(response, content) return "RESPONSE", session, result, header.ud end end end function host:attach(sp) return function(name, args, session, ud) local proto = queryproto(sp, name) header_tmp.type = proto.tag header_tmp.session = session header_tmp.ud = ud local header = core.encode(self.__package, header_tmp) if session then self.__session[session] = proto.response or true end if proto.request then local content = core.encode(proto.request, args) return core.pack(header .. content) else return core.pack(header) end end end return sproto ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.lua.meta ================================================ fileFormatVersion: 2 guid: 4fb76b30430c9454c9a05c22fc014d63 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 codingnow.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/LICENSE.meta ================================================ fileFormatVersion: 2 guid: 0b6dfee1e673bca4eae9a6d22a86a4a7 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/Makefile ================================================ .PHONY : all win clean all : linux win : sproto.dll # For Linux linux: make sproto.so "DLLFLAGS = -shared -fPIC" # For Mac OS macosx: make sproto.so "DLLFLAGS = -bundle -undefined dynamic_lookup" sproto.so : sproto.c lsproto.c env gcc -O2 -Wall $(DLLFLAGS) -o $@ $^ sproto.dll : sproto.c lsproto.c gcc -O2 -Wall --shared -o $@ $^ -I/usr/local/include -L/usr/local/bin -llua53 clean : rm -f sproto.so sproto.dll ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/Makefile.meta ================================================ fileFormatVersion: 2 guid: d5ac1a9b0e7cf2e40b29b7e6fe75a1a2 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/README.md ================================================ Introduction ====== Sproto is an efficient serialization library for C, and focuses on lua binding. It's like Google protocol buffers, but much faster. The design is simple. It only supports a few types that lua supports. It can be easily bound to other dynamic languages, or be used directly in C. In my i5-2500 @3.3GHz CPU, the benchmark is below: The schema in sproto: ``` .Person { name 0 : string id 1 : integer email 2 : string .PhoneNumber { number 0 : string type 1 : integer } phone 3 : *PhoneNumber } .AddressBook { person 0 : *Person } ``` It's equal to: ``` message Person { required string name = 1; required int32 id = 2; optional string email = 3; message PhoneNumber { required string number = 1; optional int32 type = 2 ; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1; } ``` Use the data: ```lua local ab = { person = { { name = "Alice", id = 10000, phone = { { number = "123456789" , type = 1 }, { number = "87654321" , type = 2 }, } }, { name = "Bob", id = 20000, phone = { { number = "01234567890" , type = 3 }, } } } } ``` library| encode 1M times | decode 1M times | size -------| --------------- | --------------- | ---- sproto | 2.15s | 7.84s | 83 bytes sproto (nopack) |1.58s | 6.93s | 130 bytes pbc-lua | 6.94s | 16.9s | 69 bytes lua-cjson | 4.92s | 8.30s | 183 bytes * pbc-lua is a google protocol buffers library https://github.com/cloudwu/pbc * lua-cjson is a json library https://github.com/efelix/lua-cjson Parser ======= ```lua local parser = require "sprotoparser" ``` * `parser.parse` parses a sproto schema to a binary string. The parser is needed for parsing the sproto schema. You can use it to generate binary string offline. The schema text and the parser is not needed when your program is running. Lua API ======= ```lua local sproto = require "sproto" local sprotocore = require "sproto.core" -- optional ``` * `sproto.new(spbin)` creates a sproto object by a schema binary string (generates by parser). * `sprotocore.newproto(spbin)` creates a sproto c object by a schema binary string (generates by parser). * `sproto.sharenew(spbin)` share a sproto object from a sproto c object (generates by sprotocore.newproto). * `sproto.parse(schema)` creares a sproto object by a schema text string (by calling parser.parse) * `sproto:exist_type(typename)` detect whether a type exist in sproto object. * `sproto:encode(typename, luatable)` encodes a lua table with typename into a binary string. * `sproto:decode(typename, blob [,sz])` decodes a binary string generated by sproto.encode with typename. If blob is a lightuserdata (C ptr), sz (integer) is needed. * `sproto:pencode(typename, luatable)` The same with sproto:encode, but pack (compress) the results. * `sproto:pdecode(typename, blob [,sz])` The same with sproto.decode, but unpack the blob (generated by sproto:pencode) first. * `sproto:default(typename, type)` Create a table with default values of typename. Type can be nil , "REQUEST", or "RESPONSE". RPC API ======= There is a lua wrapper for the core API for RPC . `sproto:host([packagename])` creates a host object to deliver the rpc message. `host:dispatch(blob [,sz])` unpack and decode (sproto:pdecode) the binary string with type the host created (packagename). If .type is exist, it's a REQUEST message with .type , returns "REQUEST", protoname, message, responser, .ud. The responser is a function for encode the response message. The responser will be nil when .session is not exist. If .type is not exist, it's a RESPONSE message for .session . Returns "RESPONSE", .session, message, .ud . `host:attach(sprotoobj)` creates a function(protoname, message, session, ud) to pack and encode request message with sprotoobj. If you don't want to use host object, you can also use these following apis to encode and decode the rpc message: `sproto:request_encode(protoname, tbl)` encode a request message with protoname. `sproto:response_encode(protoname, tbl)` encode a response message with protoname. `sproto:request_decode(protoname, blob [,sz])` decode a request message with protoname. `sproto:response_decode(protoname, blob [,sz]` decode a response message with protoname. Read testrpc.lua for detail. Schema Language ========== Like Protocol Buffers (but unlike json), sproto messages are strongly-typed and are not self-describing. You must define your message structure in a special language. You can use sprotoparser library to parse the schema text to a binary string, so that the sproto library can use it. You can parse them offline and save the string, or you can parse them during your program running. The schema text is like this: ``` # This is a comment. .Person { # . means a user defined type name 0 : string # string is a build-in type. id 1 : integer email 2 : string .PhoneNumber { # user defined type can be nest. number 0 : string type 1 : integer } phone 3 : *PhoneNumber # *PhoneNumber means an array of PhoneNumber. height 4 : integer(2) # (2) means a 1/100 fixed-point number. data 5 : binary # Some binary data } .AddressBook { person 0 : *Person(id) # (id) is optional, means Person.id is main index. } foobar 1 { # define a new protocol (for RPC used) with tag 1 request Person # Associate the type Person with foobar.request response { # define the foobar.response type ok 0 : boolean } } ``` A schema text can be self-described by the sproto schema language. ``` .type { .field { name 0 : string buildin 1 : integer type 2 : integer # type is fixed-point number precision when buildin is SPROTO_TINTEGER; When buildin is SPROTO_TSTRING, it means binary string when type is 1. tag 3 : integer array 4 : boolean key 5 : integer # If key exists, array must be true, and it's a map. } name 0 : string fields 1 : *field } .protocol { name 0 : string tag 1 : integer request 2 : integer # index response 3 : integer # index confirm 4 : boolean # response nil where confirm == true } .group { type 0 : *type protocol 1 : *protocol } ``` Types ======= * **string** : string * **binary** : binary string (it's a sub type of string) * **integer** : integer, the max length of an integer is signed 64bit. It can be a fixed-point number with specified precision. * **boolean** : true or false You can add * before the typename to declare an array. You can also specify a main index, the array whould be encode as an unordered map. User defined type can be any name in alphanumeric characters except the build-in typenames, and nested types are supported. * Where are double or real types? I have been using Google protocol buffers for many years in many projects, and I found the real types were seldom used. If you really need it, you can use string to serialize the double numbers. When you need decimal, you can specify the fixed-point presision. * Where is enum? In lua, enum types are not very useful. You can use integer to define an enum table in lua. Wire protocol ======== Each integer number must be serialized in little-endian format. The sproto message must be a user defined type struct, and a struct is encoded in three parts. The header, the field part, and the data part. The tag and small integer or boolean will be encoded in field part, and others are in data part. All the fields must be encoded in ascending order (by tag, base 0). The tags of fields can be discontinuous, if a field is nil. (default value in lua), don't encode it in message. The header is a 16bit integer. It is the number of fields. Each field in field part is a 16bit integer (n). If n is zero, that means the field data is encoded in data part ; If n is even (and not zero), the value of this field is n/2-1 , and the tag increases 1; If n is odd, that means the tags is not continuous, and we should add current tag by (n+1)/2 . Arrays are always encode in data part, 4 bytes header for the size, and the following bytes is the contents. See the example 2 for the struct array; example 3/4 for the integer array ; example 5 for the boolean array. For integer array, an additional byte (4 or 8) to indicate the value is 32bit or 64bit. Read the examples below to see more details. Notice: If the tag is not declared in schema, the decoder will simply ignore the field for protocol version compatibility. ``` .Person { name 0 : string age 1 : integer marital 2 : boolean children 3 : *Person } .Data { numbers 0 : *integer bools 1 : *boolean number 2 : integer bignumber 3 : integer } ``` Example 1: ``` person { name = "Alice" , age = 13, marital = false } 03 00 (fn = 3) 00 00 (id = 0, value in data part) 1C 00 (id = 1, value = 13) 02 00 (id = 2, value = false) 05 00 00 00 (sizeof "Alice") 41 6C 69 63 65 ("Alice") ``` Example 2: ``` person { name = "Bob", age = 40, children = { { name = "Alice" , age = 13 }, { name = "Carol" , age = 5 }, } } 04 00 (fn = 4) 00 00 (id = 0, value in data part) 52 00 (id = 1, value = 40) 01 00 (skip id = 2) 00 00 (id = 3, value in data part) 03 00 00 00 (sizeof "Bob") 42 6F 62 ("Bob") 26 00 00 00 (sizeof children) 0F 00 00 00 (sizeof child 1) 02 00 (fn = 2) 00 00 (id = 0, value in data part) 1C 00 (id = 1, value = 13) 05 00 00 00 (sizeof "Alice") 41 6C 69 63 65 ("Alice") 0F 00 00 00 (sizeof child 2) 02 00 (fn = 2) 00 00 (id = 0, value in data part) 0C 00 (id = 1, value = 5) 05 00 00 00 (sizeof "Carol") 43 61 72 6F 6C ("Carol") ``` Example 3: ``` data { numbers = { 1,2,3,4,5 } } 01 00 (fn = 1) 00 00 (id = 0, value in data part) 15 00 00 00 (sizeof numbers) 04 ( sizeof int32 ) 01 00 00 00 (1) 02 00 00 00 (2) 03 00 00 00 (3) 04 00 00 00 (4) 05 00 00 00 (5) ``` Example 4: ``` data { numbers = { (1<<32)+1, (1<<32)+2, (1<<32)+3, } } 01 00 (fn = 1) 00 00 (id = 0, value in data part) 19 00 00 00 (sizeof numbers) 08 ( sizeof int64 ) 01 00 00 00 01 00 00 00 ( (1<32) + 1) 02 00 00 00 01 00 00 00 ( (1<32) + 2) 03 00 00 00 01 00 00 00 ( (1<32) + 3) ``` Example 5: ``` data { bools = { false, true, false } } 02 00 (fn = 2) 01 00 (skip id = 0) 00 00 (id = 1, value in data part) 03 00 00 00 (sizeof bools) 00 (false) 01 (true) 00 (false) ``` Example 6: ``` data { number = 100000, bignumber = -10000000000, } 03 00 (fn = 3) 03 00 (skip id = 1) 00 00 (id = 2, value in data part) 00 00 (id = 3, value in data part) 04 00 00 00 (sizeof number, data part) A0 86 01 00 (100000, 32bit integer) 08 00 00 00 (sizeof bignumber, data part) 00 1C F4 AB FD FF FF FF (-10000000000, 64bit integer) ``` 0 Packing ======= The algorithm is very similar to [Cap'n proto](http://kentonv.github.io/capnproto/), but 0x00 is not treated specially. In packed format, the message is padding to 8. Each 8 byte is reduced to a tag byte followed by zero to eight content bytes. The bits of the tag byte correspond to the bytes of the unpacked word, with the least-significant bit corresponding to the first byte. Each zero bit indicates that the corresponding byte is zero. The non-zero bytes are packed following the tag. For example: ``` unpacked (hex): 08 00 00 00 03 00 02 00 19 00 00 00 aa 01 00 00 packed (hex): 51 08 03 02 31 19 aa 01 ``` Tag 0xff is treated specially. A number N is following the 0xff tag. N means (N+1)\*8 bytes should be copied directly. The bytes may or may not contain zeros. Because of this rule, the worst-case space overhead of packing is 2 bytes per 2 KiB of input. For example: ``` unpacked (hex): 8a (x 30 bytes) packed (hex): ff 03 8a (x 30 bytes) 00 00 ``` C API ===== ```C struct sproto * sproto_create(const void * proto, size_t sz); ``` Create a sproto object with a schema string encoded by sprotoparser: ```C void sproto_release(struct sproto *); ``` Release the sproto object: ```C int sproto_prototag(struct sproto *, const char * name); const char * sproto_protoname(struct sproto *, int proto); // SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response struct sproto_type * sproto_protoquery(struct sproto *, int proto, int what); ``` Convert between tag and name of a protocol, and query the type object of it: ```C struct sproto_type * sproto_type(struct sproto *, const char * typename); ``` Query the type object from a sproto object: ```C struct sproto_arg { void *ud; const char *tagname; int tagid; int type; struct sproto_type *subtype; void *value; int length; int index; // array base 1 int mainindex; // for map int extra; // SPROTO_TINTEGER: fixed-point presision ; SPROTO_TSTRING 0:utf8 string 1:binary }; typedef int (*sproto_callback)(const struct sproto_arg *args); int sproto_decode(struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud); int sproto_encode(struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud); ``` encode and decode the sproto message with a user defined callback function. Read the implementation of lsproto.c for more details. ```C int sproto_pack(const void * src, int srcsz, void * buffer, int bufsz); int sproto_unpack(const void * src, int srcsz, void * buffer, int bufsz); ``` pack and unpack the message with the 0 packing algorithm. Other Implementions and bindings ===== See Wiki https://github.com/cloudwu/sproto/wiki Question? ========== * Send me an email: http://www.codingnow.com/2000/gmail.gif * My Blog: http://blog.codingnow.com * Design: http://blog.codingnow.com/2014/07/ejoyproto.html (in Chinese) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/README.md.meta ================================================ fileFormatVersion: 2 guid: eea3f95ffce580c488d1c0da8487c18b DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/lsproto.c ================================================ #define LUA_LIB #include #include #include "msvcint.h" #include "lua.h" #include "lauxlib.h" #include "sproto.h" #define MAX_GLOBALSPROTO 16 #define ENCODE_BUFFERSIZE 2050 #define ENCODE_MAXSIZE 0x1000000 #define ENCODE_DEEPLEVEL 64 #ifndef luaL_newlib /* using LuaJIT */ /* ** set functions from list 'l' into table at top - 'nup'; each ** function gets the 'nup' elements at the top as upvalues. ** Returns with only the table at the stack. LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { #ifdef luaL_checkversion luaL_checkversion(L); #endif luaL_checkstack(L, nup, "too many upvalues"); for (; l->name != NULL; l++) { // fill the table with given functions int i; for (i = 0; i < nup; i++) // copy upvalues to the top lua_pushvalue(L, -nup); lua_pushcclosure(L, l->func, nup); // closure with those upvalues lua_setfield(L, -(nup + 2), l->name); } lua_pop(L, nup); // remove upvalues } */ #define luaL_newlibtable(L,l) \ lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) #define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) #endif #if LUA_VERSION_NUM < 503 /*if LUA_VERSION_NUM < 502 static lua_Integer lua_tointegerx(lua_State *L, int idx, int *isnum) { if (lua_isnumber(L, idx)) { if (isnum) *isnum = 1; return lua_tointeger(L, idx); } else { if (isnum) *isnum = 0; return 0; } } #endif */ // work around , use push & lua_gettable may be better #define lua_geti lua_rawgeti #define lua_seti lua_rawseti #endif static int lnewproto(lua_State *L) { struct sproto * sp; size_t sz; void * buffer = (void *)luaL_checklstring(L,1,&sz); sp = sproto_create(buffer, sz); if (sp) { lua_pushlightuserdata(L, sp); return 1; } return 0; } static int ldeleteproto(lua_State *L) { struct sproto * sp = lua_touserdata(L,1); if (sp == NULL) { return luaL_argerror(L, 1, "Need a sproto object"); } sproto_release(sp); return 0; } static int lquerytype(lua_State *L) { const char * type_name; struct sproto *sp = lua_touserdata(L,1); struct sproto_type *st; if (sp == NULL) { return luaL_argerror(L, 1, "Need a sproto object"); } type_name = luaL_checkstring(L,2); st = sproto_type(sp, type_name); if (st) { lua_pushlightuserdata(L, st); return 1; } return 0; } struct encode_ud { lua_State *L; struct sproto_type *st; int tbl_index; const char * array_tag; int array_index; int deep; int iter_index; }; static int encode(const struct sproto_arg *args) { struct encode_ud *self = args->ud; lua_State *L = self->L; if (self->deep >= ENCODE_DEEPLEVEL) return luaL_error(L, "The table is too deep"); if (args->index > 0) { if (args->tagname != self->array_tag) { // a new array self->array_tag = args->tagname; lua_getfield(L, self->tbl_index, args->tagname); if (lua_isnil(L, -1)) { if (self->array_index) { lua_replace(L, self->array_index); } self->array_index = 0; return SPROTO_CB_NOARRAY; } if (!lua_istable(L, -1)) { return luaL_error(L, ".*%s(%d) should be a table (Is a %s)", args->tagname, args->index, lua_typename(L, lua_type(L, -1))); } if (self->array_index) { lua_replace(L, self->array_index); } else { self->array_index = lua_gettop(L); } } if (args->mainindex >= 0) { // use lua_next to iterate the table // todo: check the key is equal to mainindex value lua_pushvalue(L,self->iter_index); if (!lua_next(L, self->array_index)) { // iterate end lua_pushnil(L); lua_replace(L, self->iter_index); return SPROTO_CB_NIL; } lua_insert(L, -2); lua_replace(L, self->iter_index); } else { lua_geti(L, self->array_index, args->index); } } else { lua_getfield(L, self->tbl_index, args->tagname); } if (lua_isnil(L, -1)) { lua_pop(L,1); return SPROTO_CB_NIL; } switch (args->type) { case SPROTO_TINTEGER: { lua_Integer v; lua_Integer vh; int isnum; if (args->extra) { // It's decimal. lua_Number vn = lua_tonumber(L, -1); v = (lua_Integer)(vn * args->extra + 0.5); } else { v = lua_tointegerx(L, -1, &isnum); if(!isnum) { return luaL_error(L, ".%s[%d] is not an integer (Is a %s)", args->tagname, args->index, lua_typename(L, lua_type(L, -1))); } } lua_pop(L,1); // notice: in lua 5.2, lua_Integer maybe 52bit vh = v >> 31; if (vh == 0 || vh == -1) { *(uint32_t *)args->value = (uint32_t)v; return 4; } else { *(uint64_t *)args->value = (uint64_t)v; return 8; } } case SPROTO_TBOOLEAN: { int v = lua_toboolean(L, -1); if (!lua_isboolean(L,-1)) { return luaL_error(L, ".%s[%d] is not a boolean (Is a %s)", args->tagname, args->index, lua_typename(L, lua_type(L, -1))); } *(int *)args->value = v; lua_pop(L,1); return 4; } case SPROTO_TSTRING: { size_t sz = 0; const char * str; if (!lua_isstring(L, -1)) { return luaL_error(L, ".%s[%d] is not a string (Is a %s)", args->tagname, args->index, lua_typename(L, lua_type(L, -1))); } else { str = lua_tolstring(L, -1, &sz); } if (sz > args->length) return SPROTO_CB_ERROR; memcpy(args->value, str, sz); lua_pop(L,1); return sz; } case SPROTO_TSTRUCT: { struct encode_ud sub; int r; int top = lua_gettop(L); if (!lua_istable(L, top)) { return luaL_error(L, ".%s[%d] is not a table (Is a %s)", args->tagname, args->index, lua_typename(L, lua_type(L, -1))); } sub.L = L; sub.st = args->subtype; sub.tbl_index = top; sub.array_tag = NULL; sub.array_index = 0; sub.deep = self->deep + 1; lua_pushnil(L); // prepare an iterator slot sub.iter_index = sub.tbl_index + 1; r = sproto_encode(args->subtype, args->value, args->length, encode, &sub); lua_settop(L, top-1); // pop the value if (r < 0) return SPROTO_CB_ERROR; return r; } default: return luaL_error(L, "Invalid field type %d", args->type); } } static void * expand_buffer(lua_State *L, int osz, int nsz) { void *output; do { osz *= 2; } while (osz < nsz); if (osz > ENCODE_MAXSIZE) { luaL_error(L, "object is too large (>%d)", ENCODE_MAXSIZE); return NULL; } output = lua_newuserdata(L, osz); lua_replace(L, lua_upvalueindex(1)); lua_pushinteger(L, osz); lua_replace(L, lua_upvalueindex(2)); return output; } /* lightuserdata sproto_type table source return string */ static int lencode(lua_State *L) { struct encode_ud self; void * buffer = lua_touserdata(L, lua_upvalueindex(1)); int sz = lua_tointeger(L, lua_upvalueindex(2)); int tbl_index = 2; struct sproto_type * st = lua_touserdata(L, 1); if (st == NULL) { luaL_checktype(L, tbl_index, LUA_TNIL); lua_pushstring(L, ""); return 1; // response nil } luaL_checktype(L, tbl_index, LUA_TTABLE); luaL_checkstack(L, ENCODE_DEEPLEVEL*2 + 8, NULL); self.L = L; self.st = st; self.tbl_index = tbl_index; for (;;) { int r; self.array_tag = NULL; self.array_index = 0; self.deep = 0; lua_settop(L, tbl_index); lua_pushnil(L); // for iterator (stack slot 3) self.iter_index = tbl_index+1; r = sproto_encode(st, buffer, sz, encode, &self); if (r<0) { buffer = expand_buffer(L, sz, sz*2); sz *= 2; } else { lua_pushlstring(L, buffer, r); return 1; } } } struct decode_ud { lua_State *L; const char * array_tag; int array_index; int result_index; int deep; int mainindex_tag; int key_index; }; static int decode(const struct sproto_arg *args) { struct decode_ud * self = args->ud; lua_State *L = self->L; if (self->deep >= ENCODE_DEEPLEVEL) return luaL_error(L, "The table is too deep"); if (args->index != 0) { // It's array if (args->tagname != self->array_tag) { self->array_tag = args->tagname; lua_newtable(L); lua_pushvalue(L, -1); lua_setfield(L, self->result_index, args->tagname); if (self->array_index) { lua_replace(L, self->array_index); } else { self->array_index = lua_gettop(L); } if (args->index < 0) { // It's a empty array, return now. return 0; } } } switch (args->type) { case SPROTO_TINTEGER: { // notice: in lua 5.2, 52bit integer support (not 64) if (args->extra) { // lua_Integer is 32bit in small lua. int64_t v = *(int64_t*)args->value; lua_Number vn = (lua_Number)v; vn /= args->extra; lua_pushnumber(L, vn); } else { lua_Integer v = *(int64_t*)args->value; lua_pushinteger(L, v); } break; } case SPROTO_TBOOLEAN: { int v = *(uint64_t*)args->value; lua_pushboolean(L,v); break; } case SPROTO_TSTRING: { lua_pushlstring(L, args->value, args->length); break; } case SPROTO_TSTRUCT: { struct decode_ud sub; int r; lua_newtable(L); sub.L = L; sub.result_index = lua_gettop(L); sub.deep = self->deep + 1; sub.array_index = 0; sub.array_tag = NULL; if (args->mainindex >= 0) { // This struct will set into a map, so mark the main index tag. sub.mainindex_tag = args->mainindex; lua_pushnil(L); sub.key_index = lua_gettop(L); r = sproto_decode(args->subtype, args->value, args->length, decode, &sub); if (r < 0) return SPROTO_CB_ERROR; if (r != args->length) return r; lua_pushvalue(L, sub.key_index); if (lua_isnil(L, -1)) { luaL_error(L, "Can't find main index (tag=%d) in [%s]", args->mainindex, args->tagname); } lua_pushvalue(L, sub.result_index); lua_settable(L, self->array_index); lua_settop(L, sub.result_index-1); return 0; } else { sub.mainindex_tag = -1; sub.key_index = 0; r = sproto_decode(args->subtype, args->value, args->length, decode, &sub); if (r < 0) return SPROTO_CB_ERROR; if (r != args->length) return r; lua_settop(L, sub.result_index); break; } } default: luaL_error(L, "Invalid type"); } if (args->index > 0) { lua_seti(L, self->array_index, args->index); } else { if (self->mainindex_tag == args->tagid) { // This tag is marked, save the value to key_index // assert(self->key_index > 0); lua_pushvalue(L,-1); lua_replace(L, self->key_index); } lua_setfield(L, self->result_index, args->tagname); } return 0; } static const void * getbuffer(lua_State *L, int index, size_t *sz) { const void * buffer = NULL; int t = lua_type(L, index); if (t == LUA_TSTRING) { buffer = lua_tolstring(L, index, sz); } else { if (t != LUA_TUSERDATA && t != LUA_TLIGHTUSERDATA) { luaL_argerror(L, index, "Need a string or userdata"); return NULL; } buffer = lua_touserdata(L, index); *sz = luaL_checkinteger(L, index+1); } return buffer; } /* lightuserdata sproto_type string source / (lightuserdata , integer) return table */ static int ldecode(lua_State *L) { struct sproto_type * st = lua_touserdata(L, 1); const void * buffer; struct decode_ud self; size_t sz; int r; if (st == NULL) { // return nil return 0; } sz = 0; buffer = getbuffer(L, 2, &sz); if (!lua_istable(L, -1)) { lua_newtable(L); } luaL_checkstack(L, ENCODE_DEEPLEVEL*3 + 8, NULL); self.L = L; self.result_index = lua_gettop(L); self.array_index = 0; self.array_tag = NULL; self.deep = 0; self.mainindex_tag = -1; self.key_index = 0; r = sproto_decode(st, buffer, (int)sz, decode, &self); if (r < 0) { return luaL_error(L, "decode error"); } lua_settop(L, self.result_index); lua_pushinteger(L, r); return 2; } static int ldumpproto(lua_State *L) { struct sproto * sp = lua_touserdata(L, 1); if (sp == NULL) { return luaL_argerror(L, 1, "Need a sproto_type object"); } sproto_dump(sp); return 0; } /* string source / (lightuserdata , integer) return string */ static int lpack(lua_State *L) { size_t sz=0; const void * buffer = getbuffer(L, 1, &sz); // the worst-case space overhead of packing is 2 bytes per 2 KiB of input (256 words = 2KiB). size_t maxsz = (sz + 2047) / 2048 * 2 + sz + 2; void * output = lua_touserdata(L, lua_upvalueindex(1)); int bytes; int osz = lua_tointeger(L, lua_upvalueindex(2)); if (osz < maxsz) { output = expand_buffer(L, osz, maxsz); } bytes = sproto_pack(buffer, sz, output, maxsz); if (bytes > maxsz) { return luaL_error(L, "packing error, return size = %d", bytes); } lua_pushlstring(L, output, bytes); return 1; } static int lunpack(lua_State *L) { size_t sz=0; const void * buffer = getbuffer(L, 1, &sz); void * output = lua_touserdata(L, lua_upvalueindex(1)); int osz = lua_tointeger(L, lua_upvalueindex(2)); int r = sproto_unpack(buffer, sz, output, osz); if (r < 0) return luaL_error(L, "Invalid unpack stream"); if (r > osz) { output = expand_buffer(L, osz, r); r = sproto_unpack(buffer, sz, output, r); if (r < 0) return luaL_error(L, "Invalid unpack stream"); } lua_pushlstring(L, output, r); return 1; } static void pushfunction_withbuffer(lua_State *L, const char * name, lua_CFunction func) { lua_newuserdata(L, ENCODE_BUFFERSIZE); lua_pushinteger(L, ENCODE_BUFFERSIZE); lua_pushcclosure(L, func, 2); lua_setfield(L, -2, name); } static int lprotocol(lua_State *L) { struct sproto * sp = lua_touserdata(L, 1); struct sproto_type * request; struct sproto_type * response; int t; int tag; if (sp == NULL) { return luaL_argerror(L, 1, "Need a sproto_type object"); } t = lua_type(L,2); if (t == LUA_TNUMBER) { const char * name; tag = lua_tointeger(L, 2); name = sproto_protoname(sp, tag); if (name == NULL) return 0; lua_pushstring(L, name); } else { const char * name = lua_tostring(L, 2); if (name == NULL) { return luaL_argerror(L, 2, "Should be number or string"); } tag = sproto_prototag(sp, name); if (tag < 0) return 0; lua_pushinteger(L, tag); } request = sproto_protoquery(sp, tag, SPROTO_REQUEST); if (request == NULL) { lua_pushnil(L); } else { lua_pushlightuserdata(L, request); } response = sproto_protoquery(sp, tag, SPROTO_RESPONSE); if (response == NULL) { if (sproto_protoresponse(sp, tag)) { lua_pushlightuserdata(L, NULL); // response nil } else { lua_pushnil(L); } } else { lua_pushlightuserdata(L, response); } return 3; } /* global sproto pointer for multi states NOTICE : It is not thread safe */ static struct sproto * G_sproto[MAX_GLOBALSPROTO]; static int lsaveproto(lua_State *L) { struct sproto * sp = lua_touserdata(L, 1); int index = luaL_optinteger(L, 2, 0); if (index < 0 || index >= MAX_GLOBALSPROTO) { return luaL_error(L, "Invalid global slot index %d", index); } /* TODO : release old object (memory leak now, but thread safe)*/ G_sproto[index] = sp; return 0; } static int lloadproto(lua_State *L) { int index = luaL_optinteger(L, 1, 0); struct sproto * sp; if (index < 0 || index >= MAX_GLOBALSPROTO) { return luaL_error(L, "Invalid global slot index %d", index); } sp = G_sproto[index]; if (sp == NULL) { return luaL_error(L, "nil sproto at index %d", index); } lua_pushlightuserdata(L, sp); return 1; } static int encode_default(const struct sproto_arg *args) { lua_State *L = args->ud; lua_pushstring(L, args->tagname); if (args->index > 0) { lua_newtable(L); lua_rawset(L, -3); return SPROTO_CB_NOARRAY; } else { switch(args->type) { case SPROTO_TINTEGER: lua_pushinteger(L, 0); break; case SPROTO_TBOOLEAN: lua_pushboolean(L, 0); break; case SPROTO_TSTRING: lua_pushliteral(L, ""); break; case SPROTO_TSTRUCT: lua_createtable(L, 0, 1); lua_pushstring(L, sproto_name(args->subtype)); lua_setfield(L, -2, "__type"); break; } lua_rawset(L, -3); return SPROTO_CB_NIL; } } /* lightuserdata sproto_type return default table */ static int ldefault(lua_State *L) { int ret; // 64 is always enough for dummy buffer, except the type has many fields ( > 27). char dummy[64]; struct sproto_type * st = lua_touserdata(L, 1); if (st == NULL) { return luaL_argerror(L, 1, "Need a sproto_type object"); } lua_newtable(L); ret = sproto_encode(st, dummy, sizeof(dummy), encode_default, L); if (ret<0) { // try again int sz = sizeof(dummy) * 2; void * tmp = lua_newuserdata(L, sz); lua_insert(L, -2); for (;;) { ret = sproto_encode(st, tmp, sz, encode_default, L); if (ret >= 0) break; sz *= 2; tmp = lua_newuserdata(L, sz); lua_replace(L, -3); } } return 1; } int luaopen_sproto_core(lua_State *L) { #ifdef luaL_checkversion luaL_checkversion(L); #endif luaL_Reg l[] = { { "newproto", lnewproto }, { "deleteproto", ldeleteproto }, { "dumpproto", ldumpproto }, { "querytype", lquerytype }, { "decode", ldecode }, { "protocol", lprotocol }, { "loadproto", lloadproto }, { "saveproto", lsaveproto }, { "default", ldefault }, { NULL, NULL }, }; //luaL_newlib(L,l); luaL_register(L, "sproto.core", l); pushfunction_withbuffer(L, "encode", lencode); pushfunction_withbuffer(L, "pack", lpack); pushfunction_withbuffer(L, "unpack", lunpack); return 1; } ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/lsproto.c.meta ================================================ fileFormatVersion: 2 guid: 6a348fc15e22d9f4e87804b9da6b4164 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/msvcint.h ================================================ #ifndef msvc_int_h #define msvc_int_h #ifdef _MSC_VER # define inline __inline # ifndef _MSC_STDINT_H_ # if (_MSC_VER < 1300) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; # else typedef signed __int8 int8_t; typedef signed __int16 int16_t; typedef signed __int32 int32_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; # endif typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; # endif #else #include #endif #endif ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/msvcint.h.meta ================================================ fileFormatVersion: 2 guid: 8582e4d772778894ab36a7c59347e48f DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/print_r.lua ================================================ local print = print local tconcat = table.concat local tinsert = table.insert local srep = string.rep local type = type local pairs = pairs local tostring = tostring local next = next local function print_r(root) local cache = { [root] = "." } local function _dump(t,space,name) local temp = {} for k,v in pairs(t) do local key = tostring(k) if cache[v] then tinsert(temp,"+" .. key .. " {" .. cache[v].."}") elseif type(v) == "table" then local new_key = name .. "." .. key cache[v] = new_key tinsert(temp,"+" .. key .. _dump(v,space .. (next(t,k) and "|" or " " ).. srep(" ",#key),new_key)) else tinsert(temp,"+" .. key .. " [" .. tostring(v).."]") end end return tconcat(temp,"\n"..space) end print(_dump(root, "","")) end return print_r ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/print_r.lua.meta ================================================ fileFormatVersion: 2 guid: f158e5a0852b8e347ac6a433f28fbc83 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.c ================================================ #include #include #include #include #include "msvcint.h" #include "sproto.h" #define SPROTO_TARRAY 0x80 #define CHUNK_SIZE 1000 #define SIZEOF_LENGTH 4 #define SIZEOF_HEADER 2 #define SIZEOF_FIELD 2 struct field { int tag; int type; const char * name; struct sproto_type * st; int key; int extra; }; struct sproto_type { const char * name; int n; int base; int maxn; struct field *f; }; struct protocol { const char *name; int tag; int confirm; // confirm == 1 where response nil struct sproto_type * p[2]; }; struct chunk { struct chunk * next; }; struct pool { struct chunk * header; struct chunk * current; int current_used; }; struct sproto { struct pool memory; int type_n; int protocol_n; struct sproto_type * type; struct protocol * proto; }; static void pool_init(struct pool *p) { p->header = NULL; p->current = NULL; p->current_used = 0; } static void pool_release(struct pool *p) { struct chunk * tmp = p->header; while (tmp) { struct chunk * n = tmp->next; free(tmp); tmp = n; } } static void * pool_newchunk(struct pool *p, size_t sz) { struct chunk * t = malloc(sz + sizeof(struct chunk)); if (t == NULL) return NULL; t->next = p->header; p->header = t; return t+1; } static void * pool_alloc(struct pool *p, size_t sz) { // align by 8 sz = (sz + 7) & ~7; if (sz >= CHUNK_SIZE) { return pool_newchunk(p, sz); } if (p->current == NULL) { if (pool_newchunk(p, CHUNK_SIZE) == NULL) return NULL; p->current = p->header; } if (sz + p->current_used <= CHUNK_SIZE) { void * ret = (char *)(p->current+1) + p->current_used; p->current_used += sz; return ret; } if (sz >= p->current_used) { return pool_newchunk(p, sz); } else { void * ret = pool_newchunk(p, CHUNK_SIZE); p->current = p->header; p->current_used = sz; return ret; } } static inline int toword(const uint8_t * p) { return p[0] | p[1]<<8; } static inline uint32_t todword(const uint8_t *p) { return p[0] | p[1]<<8 | p[2]<<16 | p[3]<<24; } static int count_array(const uint8_t * stream) { uint32_t length = todword(stream); int n = 0; stream += SIZEOF_LENGTH; while (length > 0) { uint32_t nsz; if (length < SIZEOF_LENGTH) return -1; nsz = todword(stream); nsz += SIZEOF_LENGTH; if (nsz > length) return -1; ++n; stream += nsz; length -= nsz; } return n; } static int struct_field(const uint8_t * stream, size_t sz) { const uint8_t * field; int fn, header, i; if (sz < SIZEOF_LENGTH) return -1; fn = toword(stream); header = SIZEOF_HEADER + SIZEOF_FIELD * fn; if (sz < header) return -1; field = stream + SIZEOF_HEADER; sz -= header; stream += header; for (i=0;imemory, sz+1); memcpy(buffer, stream+SIZEOF_LENGTH, sz); buffer[sz] = '\0'; return buffer; } static int calc_pow(int base, int n) { int r; if (n == 0) return 1; r = calc_pow(base * base , n / 2); if (n&1) { r *= base; } return r; } static const uint8_t * import_field(struct sproto *s, struct field *f, const uint8_t * stream) { uint32_t sz; const uint8_t * result; int fn; int i; int array = 0; int tag = -1; f->tag = -1; f->type = -1; f->name = NULL; f->st = NULL; f->key = -1; f->extra = 0; sz = todword(stream); stream += SIZEOF_LENGTH; result = stream + sz; fn = struct_field(stream, sz); if (fn < 0) return NULL; stream += SIZEOF_HEADER; for (i=0;iname = import_string(s, stream + fn * SIZEOF_FIELD); continue; } if (value == 0) return NULL; value = value/2 - 1; switch(tag) { case 1: // buildin if (value >= SPROTO_TSTRUCT) return NULL; // invalid buildin type f->type = value; break; case 2: // type index if (f->type == SPROTO_TINTEGER) { f->extra = calc_pow(10, value); } else if (f->type == SPROTO_TSTRING) { f->extra = value; // string if 0 ; binary is 1 } else { if (value >= s->type_n) return NULL; // invalid type index if (f->type >= 0) return NULL; f->type = SPROTO_TSTRUCT; f->st = &s->type[value]; } break; case 3: // tag f->tag = value; break; case 4: // array if (value) array = SPROTO_TARRAY; break; case 5: // key f->key = value; break; default: return NULL; } } if (f->tag < 0 || f->type < 0 || f->name == NULL) return NULL; f->type |= array; return result; } /* .type { .field { name 0 : string buildin 1 : integer type 2 : integer tag 3 : integer array 4 : boolean } name 0 : string fields 1 : *field } */ static const uint8_t * import_type(struct sproto *s, struct sproto_type *t, const uint8_t * stream) { const uint8_t * result; uint32_t sz = todword(stream); int i; int fn; int n; int maxn; int last; stream += SIZEOF_LENGTH; result = stream + sz; fn = struct_field(stream, sz); if (fn <= 0 || fn > 2) return NULL; for (i=0;iname = import_string(s, stream); if (fn == 1) { return result; } stream += todword(stream)+SIZEOF_LENGTH; // second data n = count_array(stream); if (n<0) return NULL; stream += SIZEOF_LENGTH; maxn = n; last = -1; t->n = n; t->f = pool_alloc(&s->memory, sizeof(struct field) * n); for (i=0;if[i]; stream = import_field(s, f, stream); if (stream == NULL) return NULL; tag = f->tag; if (tag <= last) return NULL; // tag must in ascending order if (tag > last+1) { ++maxn; } last = tag; } t->maxn = maxn; t->base = t->f[0].tag; n = t->f[n-1].tag - t->base + 1; if (n != t->n) { t->base = -1; } return result; } /* .protocol { name 0 : string tag 1 : integer request 2 : integer response 3 : integer } */ static const uint8_t * import_protocol(struct sproto *s, struct protocol *p, const uint8_t * stream) { const uint8_t * result; uint32_t sz = todword(stream); int fn; int i; int tag; stream += SIZEOF_LENGTH; result = stream + sz; fn = struct_field(stream, sz); stream += SIZEOF_HEADER; p->name = NULL; p->tag = -1; p->p[SPROTO_REQUEST] = NULL; p->p[SPROTO_RESPONSE] = NULL; p->confirm = 0; tag = 0; for (i=0;iname = import_string(s, stream + SIZEOF_FIELD *fn); break; case 1: // tag if (value < 0) { return NULL; } p->tag = value; break; case 2: // request if (value < 0 || value>=s->type_n) return NULL; p->p[SPROTO_REQUEST] = &s->type[value]; break; case 3: // response if (value < 0 || value>=s->type_n) return NULL; p->p[SPROTO_RESPONSE] = &s->type[value]; break; case 4: // confirm p->confirm = value; break; default: return NULL; } } if (p->name == NULL || p->tag<0) { return NULL; } return result; } static struct sproto * create_from_bundle(struct sproto *s, const uint8_t * stream, size_t sz) { const uint8_t * content; const uint8_t * typedata = NULL; const uint8_t * protocoldata = NULL; int fn = struct_field(stream, sz); int i; if (fn < 0 || fn > 2) return NULL; stream += SIZEOF_HEADER; content = stream + fn*SIZEOF_FIELD; for (i=0;itype_n = n; s->type = pool_alloc(&s->memory, n * sizeof(*s->type)); } else { protocoldata = content+SIZEOF_LENGTH; s->protocol_n = n; s->proto = pool_alloc(&s->memory, n * sizeof(*s->proto)); } content += todword(content) + SIZEOF_LENGTH; } for (i=0;itype_n;i++) { typedata = import_type(s, &s->type[i], typedata); if (typedata == NULL) { return NULL; } } for (i=0;iprotocol_n;i++) { protocoldata = import_protocol(s, &s->proto[i], protocoldata); if (protocoldata == NULL) { return NULL; } } return s; } struct sproto * sproto_create(const void * proto, size_t sz) { struct pool mem; struct sproto * s; pool_init(&mem); s = pool_alloc(&mem, sizeof(*s)); if (s == NULL) return NULL; memset(s, 0, sizeof(*s)); s->memory = mem; if (create_from_bundle(s, proto, sz) == NULL) { pool_release(&s->memory); return NULL; } return s; } void sproto_release(struct sproto * s) { if (s == NULL) return; pool_release(&s->memory); } void sproto_dump(struct sproto *s) { int i,j; printf("=== %d types ===\n", s->type_n); for (i=0;itype_n;i++) { struct sproto_type *t = &s->type[i]; printf("%s\n", t->name); for (j=0;jn;j++) { char array[2] = { 0, 0 }; const char * type_name = NULL; struct field *f = &t->f[j]; int type = f->type & ~SPROTO_TARRAY; if (f->type & SPROTO_TARRAY) { array[0] = '*'; } else { array[0] = 0; } if (type == SPROTO_TSTRUCT) { type_name = f->st->name; } else { switch(type) { case SPROTO_TINTEGER: if (f->extra) { type_name = "decimal"; } else { type_name = "integer"; } break; case SPROTO_TBOOLEAN: type_name = "boolean"; break; case SPROTO_TSTRING: if (f->extra == SPROTO_TSTRING_BINARY) type_name = "binary"; else type_name = "string"; break; default: type_name = "invalid"; break; } } printf("\t%s (%d) %s%s", f->name, f->tag, array, type_name); if (type == SPROTO_TINTEGER && f->extra > 0) { printf("(%d)", f->extra); } if (f->key >= 0) { printf("[%d]", f->key); } printf("\n"); } } printf("=== %d protocol ===\n", s->protocol_n); for (i=0;iprotocol_n;i++) { struct protocol *p = &s->proto[i]; if (p->p[SPROTO_REQUEST]) { printf("\t%s (%d) request:%s", p->name, p->tag, p->p[SPROTO_REQUEST]->name); } else { printf("\t%s (%d) request:(null)", p->name, p->tag); } if (p->p[SPROTO_RESPONSE]) { printf(" response:%s", p->p[SPROTO_RESPONSE]->name); } else if (p->confirm) { printf(" response nil"); } printf("\n"); } } // query int sproto_prototag(const struct sproto *sp, const char * name) { int i; for (i=0;iprotocol_n;i++) { if (strcmp(name, sp->proto[i].name) == 0) { return sp->proto[i].tag; } } return -1; } static struct protocol * query_proto(const struct sproto *sp, int tag) { int begin = 0, end = sp->protocol_n; while(beginproto[mid].tag; if (t==tag) { return &sp->proto[mid]; } if (tag > t) { begin = mid+1; } else { end = mid; } } return NULL; } struct sproto_type * sproto_protoquery(const struct sproto *sp, int proto, int what) { struct protocol * p; if (what <0 || what >1) { return NULL; } p = query_proto(sp, proto); if (p) { return p->p[what]; } return NULL; } int sproto_protoresponse(const struct sproto * sp, int proto) { struct protocol * p = query_proto(sp, proto); return (p!=NULL && (p->p[SPROTO_RESPONSE] || p->confirm)); } const char * sproto_protoname(const struct sproto *sp, int proto) { struct protocol * p = query_proto(sp, proto); if (p) { return p->name; } return NULL; } struct sproto_type * sproto_type(const struct sproto *sp, const char * type_name) { int i; for (i=0;itype_n;i++) { if (strcmp(type_name, sp->type[i].name) == 0) { return &sp->type[i]; } } return NULL; } const char * sproto_name(struct sproto_type * st) { return st->name; } static struct field * findtag(const struct sproto_type *st, int tag) { int begin, end; if (st->base >=0 ) { tag -= st->base; if (tag < 0 || tag >= st->n) return NULL; return &st->f[tag]; } begin = 0; end = st->n; while (begin < end) { int mid = (begin+end)/2; struct field *f = &st->f[mid]; int t = f->tag; if (t == tag) { return f; } if (tag > t) { begin = mid + 1; } else { end = mid; } } return NULL; } // encode & decode // sproto_callback(void *ud, int tag, int type, struct sproto_type *, void *value, int length) // return size, -1 means error static inline int fill_size(uint8_t * data, int sz) { data[0] = sz & 0xff; data[1] = (sz >> 8) & 0xff; data[2] = (sz >> 16) & 0xff; data[3] = (sz >> 24) & 0xff; return sz + SIZEOF_LENGTH; } static int encode_integer(uint32_t v, uint8_t * data, int size) { if (size < SIZEOF_LENGTH + sizeof(v)) return -1; data[4] = v & 0xff; data[5] = (v >> 8) & 0xff; data[6] = (v >> 16) & 0xff; data[7] = (v >> 24) & 0xff; return fill_size(data, sizeof(v)); } static int encode_uint64(uint64_t v, uint8_t * data, int size) { if (size < SIZEOF_LENGTH + sizeof(v)) return -1; data[4] = v & 0xff; data[5] = (v >> 8) & 0xff; data[6] = (v >> 16) & 0xff; data[7] = (v >> 24) & 0xff; data[8] = (v >> 32) & 0xff; data[9] = (v >> 40) & 0xff; data[10] = (v >> 48) & 0xff; data[11] = (v >> 56) & 0xff; return fill_size(data, sizeof(v)); } /* //#define CB(tagname,type,index,subtype,value,length) cb(ud, tagname,type,index,subtype,value,length) static int do_cb(sproto_callback cb, void *ud, const char *tagname, int type, int index, struct sproto_type *subtype, void *value, int length) { if (subtype) { if (type >= 0) { printf("callback: tag=%s[%d], subtype[%s]:%d\n",tagname,index, subtype->name, type); } else { printf("callback: tag=%s[%d], subtype[%s]\n",tagname,index, subtype->name); } } else if (index > 0) { printf("callback: tag=%s[%d]\n",tagname,index); } else if (index == 0) { printf("callback: tag=%s\n",tagname); } else { printf("callback: tag=%s [mainkey]\n",tagname); } return cb(ud, tagname,type,index,subtype,value,length); } #define CB(tagname,type,index,subtype,value,length) do_cb(cb,ud, tagname,type,index,subtype,value,length) */ static int encode_object(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int size) { int sz; if (size < SIZEOF_LENGTH) return -1; args->value = data+SIZEOF_LENGTH; args->length = size-SIZEOF_LENGTH; sz = cb(args); if (sz < 0) { if (sz == SPROTO_CB_NIL) return 0; return -1; // sz == SPROTO_CB_ERROR } assert(sz <= size-SIZEOF_LENGTH); // verify buffer overflow return fill_size(data, sz); } static inline void uint32_to_uint64(int negative, uint8_t *buffer) { if (negative) { buffer[4] = 0xff; buffer[5] = 0xff; buffer[6] = 0xff; buffer[7] = 0xff; } else { buffer[4] = 0; buffer[5] = 0; buffer[6] = 0; buffer[7] = 0; } } static uint8_t * encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffer, int size, int *noarray) { uint8_t * header = buffer; int intlen; int index; if (size < 1) return NULL; buffer++; size--; intlen = sizeof(uint32_t); index = 1; *noarray = 0; for (;;) { int sz; union { uint64_t u64; uint32_t u32; } u; args->value = &u; args->length = sizeof(u); args->index = index; sz = cb(args); if (sz <= 0) { if (sz == SPROTO_CB_NIL) // nil object, end of array break; if (sz == SPROTO_CB_NOARRAY) { // no array, don't encode it *noarray = 1; break; } return NULL; // sz == SPROTO_CB_ERROR } if (size < sizeof(uint64_t)) return NULL; if (sz == sizeof(uint32_t)) { uint32_t v = u.u32; buffer[0] = v & 0xff; buffer[1] = (v >> 8) & 0xff; buffer[2] = (v >> 16) & 0xff; buffer[3] = (v >> 24) & 0xff; if (intlen == sizeof(uint64_t)) { uint32_to_uint64(v & 0x80000000, buffer); } } else { uint64_t v; if (sz != sizeof(uint64_t)) return NULL; if (intlen == sizeof(uint32_t)) { int i; // rearrange size -= (index-1) * sizeof(uint32_t); if (size < sizeof(uint64_t)) return NULL; buffer += (index-1) * sizeof(uint32_t); for (i=index-2;i>=0;i--) { int negative; memcpy(header+1+i*sizeof(uint64_t), header+1+i*sizeof(uint32_t), sizeof(uint32_t)); negative = header[1+i*sizeof(uint64_t)+3] & 0x80; uint32_to_uint64(negative, header+1+i*sizeof(uint64_t)); } intlen = sizeof(uint64_t); } v = u.u64; buffer[0] = v & 0xff; buffer[1] = (v >> 8) & 0xff; buffer[2] = (v >> 16) & 0xff; buffer[3] = (v >> 24) & 0xff; buffer[4] = (v >> 32) & 0xff; buffer[5] = (v >> 40) & 0xff; buffer[6] = (v >> 48) & 0xff; buffer[7] = (v >> 56) & 0xff; } size -= intlen; buffer += intlen; index++; } if (buffer == header + 1) { return header; } *header = (uint8_t)intlen; return buffer; } static int encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int size) { uint8_t * buffer; int sz; if (size < SIZEOF_LENGTH) return -1; size -= SIZEOF_LENGTH; buffer = data + SIZEOF_LENGTH; switch (args->type) { case SPROTO_TINTEGER: { int noarray; buffer = encode_integer_array(cb,args,buffer,size, &noarray); if (buffer == NULL) return -1; if (noarray) { return 0; } break; } case SPROTO_TBOOLEAN: args->index = 1; for (;;) { int v = 0; args->value = &v; args->length = sizeof(v); sz = cb(args); if (sz < 0) { if (sz == SPROTO_CB_NIL) // nil object , end of array break; if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it return 0; return -1; // sz == SPROTO_CB_ERROR } if (size < 1) return -1; buffer[0] = v ? 1: 0; size -= 1; buffer += 1; ++args->index; } break; default: args->index = 1; for (;;) { if (size < SIZEOF_LENGTH) return -1; size -= SIZEOF_LENGTH; args->value = buffer+SIZEOF_LENGTH; args->length = size; sz = cb(args); if (sz < 0) { if (sz == SPROTO_CB_NIL) { break; } if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it return 0; return -1; // sz == SPROTO_CB_ERROR } fill_size(buffer, sz); buffer += SIZEOF_LENGTH+sz; size -=sz; ++args->index; } break; } sz = buffer - (data + SIZEOF_LENGTH); return fill_size(data, sz); } int sproto_encode(const struct sproto_type *st, void * buffer, int size, sproto_callback cb, void *ud) { struct sproto_arg args; uint8_t * header = buffer; uint8_t * data; int header_sz = SIZEOF_HEADER + st->maxn * SIZEOF_FIELD; int i; int index; int lasttag; int datasz; if (size < header_sz) return -1; args.ud = ud; data = header + header_sz; size -= header_sz; index = 0; lasttag = -1; for (i=0;in;i++) { struct field *f = &st->f[i]; int type = f->type; int value = 0; int sz = -1; args.tagname = f->name; args.tagid = f->tag; args.subtype = f->st; args.mainindex = f->key; args.extra = f->extra; if (type & SPROTO_TARRAY) { args.type = type & ~SPROTO_TARRAY; sz = encode_array(cb, &args, data, size); } else { args.type = type; args.index = 0; switch(type) { case SPROTO_TINTEGER: case SPROTO_TBOOLEAN: { union { uint64_t u64; uint32_t u32; } u; args.value = &u; args.length = sizeof(u); sz = cb(&args); if (sz < 0) { if (sz == SPROTO_CB_NIL) continue; if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it return 0; return -1; // sz == SPROTO_CB_ERROR } if (sz == sizeof(uint32_t)) { if (u.u32 < 0x7fff) { value = (u.u32+1) * 2; sz = 2; // sz can be any number > 0 } else { sz = encode_integer(u.u32, data, size); } } else if (sz == sizeof(uint64_t)) { sz= encode_uint64(u.u64, data, size); } else { return -1; } break; } case SPROTO_TSTRUCT: case SPROTO_TSTRING: sz = encode_object(cb, &args, data, size); break; } } if (sz < 0) return -1; if (sz > 0) { uint8_t * record; int tag; if (value == 0) { data += sz; size -= sz; } record = header+SIZEOF_HEADER+SIZEOF_FIELD*index; tag = f->tag - lasttag - 1; if (tag > 0) { // skip tag tag = (tag - 1) * 2 + 1; if (tag > 0xffff) return -1; record[0] = tag & 0xff; record[1] = (tag >> 8) & 0xff; ++index; record += SIZEOF_FIELD; } ++index; record[0] = value & 0xff; record[1] = (value >> 8) & 0xff; lasttag = f->tag; } } header[0] = index & 0xff; header[1] = (index >> 8) & 0xff; datasz = data - (header + header_sz); data = header + header_sz; if (index != st->maxn) { memmove(header + SIZEOF_HEADER + index * SIZEOF_FIELD, data, datasz); } return SIZEOF_HEADER + index * SIZEOF_FIELD + datasz; } static int decode_array_object(sproto_callback cb, struct sproto_arg *args, uint8_t * stream, int sz) { uint32_t hsz; int index = 1; while (sz > 0) { if (sz < SIZEOF_LENGTH) return -1; hsz = todword(stream); stream += SIZEOF_LENGTH; sz -= SIZEOF_LENGTH; if (hsz > sz) return -1; args->index = index; args->value = stream; args->length = hsz; if (cb(args)) return -1; sz -= hsz; stream += hsz; ++index; } return 0; } static inline uint64_t expand64(uint32_t v) { uint64_t value = v; if (value & 0x80000000) { value |= (uint64_t)~0 << 32 ; } return value; } static int decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) { uint32_t sz = todword(stream); int type = args->type; int i; if (sz == 0) { // It's empty array, call cb with index == -1 to create the empty array. args->index = -1; args->value = NULL; args->length = 0; cb(args); return 0; } stream += SIZEOF_LENGTH; switch (type) { case SPROTO_TINTEGER: { int len = *stream; ++stream; --sz; if (len == sizeof(uint32_t)) { if (sz % sizeof(uint32_t) != 0) return -1; for (i=0;iindex = i+1; args->value = &value; args->length = sizeof(value); cb(args); } } else if (len == sizeof(uint64_t)) { if (sz % sizeof(uint64_t) != 0) return -1; for (i=0;iindex = i+1; args->value = &value; args->length = sizeof(value); cb(args); } } else { return -1; } break; } case SPROTO_TBOOLEAN: for (i=0;iindex = i+1; args->value = &value; args->length = sizeof(value); cb(args); } break; case SPROTO_TSTRING: case SPROTO_TSTRUCT: return decode_array_object(cb, args, stream, sz); default: return -1; } return 0; } int sproto_decode(const struct sproto_type *st, const void * data, int size, sproto_callback cb, void *ud) { struct sproto_arg args; int total = size; uint8_t * stream; uint8_t * datastream; int fn; int i; int tag; if (size < SIZEOF_HEADER) return -1; // debug print // printf("sproto_decode[%p] (%s)\n", ud, st->name); stream = (void *)data; fn = toword(stream); stream += SIZEOF_HEADER; size -= SIZEOF_HEADER ; if (size < fn * SIZEOF_FIELD) return -1; datastream = stream + fn * SIZEOF_FIELD; size -= fn * SIZEOF_FIELD; args.ud = ud; tag = -1; for (i=0;iname; args.tagid = f->tag; args.type = f->type & ~SPROTO_TARRAY; args.subtype = f->st; args.index = 0; args.mainindex = f->key; args.extra = f->extra; if (value < 0) { if (f->type & SPROTO_TARRAY) { if (decode_array(cb, &args, currentdata)) { return -1; } } else { switch (f->type) { case SPROTO_TINTEGER: { uint32_t sz = todword(currentdata); if (sz == sizeof(uint32_t)) { uint64_t v = expand64(todword(currentdata + SIZEOF_LENGTH)); args.value = &v; args.length = sizeof(v); cb(&args); } else if (sz != sizeof(uint64_t)) { return -1; } else { uint32_t low = todword(currentdata + SIZEOF_LENGTH); uint32_t hi = todword(currentdata + SIZEOF_LENGTH + sizeof(uint32_t)); uint64_t v = (uint64_t)low | (uint64_t) hi << 32; args.value = &v; args.length = sizeof(v); cb(&args); } break; } case SPROTO_TSTRING: case SPROTO_TSTRUCT: { uint32_t sz = todword(currentdata); args.value = currentdata+SIZEOF_LENGTH; args.length = sz; if (cb(&args)) return -1; break; } default: return -1; } } } else if (f->type != SPROTO_TINTEGER && f->type != SPROTO_TBOOLEAN) { return -1; } else { uint64_t v = value; args.value = &v; args.length = sizeof(v); cb(&args); } } return total - size; } // 0 pack static int pack_seg(const uint8_t *src, uint8_t * buffer, int sz, int n) { uint8_t header = 0; int notzero = 0; int i; uint8_t * obuffer = buffer; ++buffer; --sz; if (sz < 0) obuffer = NULL; for (i=0;i<8;i++) { if (src[i] != 0) { notzero++; header |= 1< 0) { *buffer = src[i]; ++buffer; --sz; } } } if ((notzero == 7 || notzero == 6) && n > 0) { notzero = 8; } if (notzero == 8) { if (n > 0) { return 8; } else { return 10; } } if (obuffer) { *obuffer = header; } return notzero + 1; } static inline void write_ff(const uint8_t * src, uint8_t * des, int n) { int i; int align8_n = (n+7)&(~7); des[0] = 0xff; des[1] = align8_n/8 - 1; memcpy(des+2, src, n); for(i=0; i< align8_n-n; i++){ des[n+2+i] = 0; } } int sproto_pack(const void * srcv, int srcsz, void * bufferv, int bufsz) { uint8_t tmp[8]; int i; const uint8_t * ff_srcstart = NULL; uint8_t * ff_desstart = NULL; int ff_n = 0; int size = 0; const uint8_t * src = srcv; uint8_t * buffer = bufferv; for (i=0;i 0) { int j; memcpy(tmp, src, 8-padding); for (j=0;j0) { ++ff_n; if (ff_n == 256) { if (bufsz >= 0) { write_ff(ff_srcstart, ff_desstart, 256*8); } ff_n = 0; } } else { if (ff_n > 0) { if (bufsz >= 0) { write_ff(ff_srcstart, ff_desstart, ff_n*8); } ff_n = 0; } } src += 8; buffer += n; size += n; } if(bufsz >= 0){ if(ff_n == 1) write_ff(ff_srcstart, ff_desstart, 8); else if (ff_n > 1) write_ff(ff_srcstart, ff_desstart, srcsz - (intptr_t)(ff_srcstart - (const uint8_t*)srcv)); } return size; } int sproto_unpack(const void * srcv, int srcsz, void * bufferv, int bufsz) { const uint8_t * src = srcv; uint8_t * buffer = bufferv; int size = 0; while (srcsz > 0) { uint8_t header = src[0]; --srcsz; ++src; if (header == 0xff) { int n; if (srcsz < 0) { return -1; } n = (src[0] + 1) * 8; if (srcsz < n + 1) return -1; srcsz -= n + 1; ++src; if (bufsz >= n) { memcpy(buffer, src, n); } bufsz -= n; buffer += n; src += n; size += n; } else { int i; for (i=0;i<8;i++) { int nz = (header >> i) & 1; if (nz) { if (srcsz < 0) return -1; if (bufsz > 0) { *buffer = *src; --bufsz; ++buffer; } ++src; --srcsz; } else { if (bufsz > 0) { *buffer = 0; --bufsz; ++buffer; } } ++size; } } } return size; } ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.c.meta ================================================ fileFormatVersion: 2 guid: f9be0a941ac952540a994fe1c4561001 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.h ================================================ #ifndef sproto_h #define sproto_h #include struct sproto; struct sproto_type; #define SPROTO_REQUEST 0 #define SPROTO_RESPONSE 1 // type (sproto_arg.type) #define SPROTO_TINTEGER 0 #define SPROTO_TBOOLEAN 1 #define SPROTO_TSTRING 2 #define SPROTO_TSTRUCT 3 // sub type of string (sproto_arg.extra) #define SPROTO_TSTRING_STRING 0 #define SPROTO_TSTRING_BINARY 1 #define SPROTO_CB_ERROR -1 #define SPROTO_CB_NIL -2 #define SPROTO_CB_NOARRAY -3 struct sproto * sproto_create(const void * proto, size_t sz); void sproto_release(struct sproto *); int sproto_prototag(const struct sproto *, const char * name); const char * sproto_protoname(const struct sproto *, int proto); // SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response struct sproto_type * sproto_protoquery(const struct sproto *, int proto, int what); int sproto_protoresponse(const struct sproto *, int proto); struct sproto_type * sproto_type(const struct sproto *, const char * type_name); int sproto_pack(const void * src, int srcsz, void * buffer, int bufsz); int sproto_unpack(const void * src, int srcsz, void * buffer, int bufsz); struct sproto_arg { void *ud; const char *tagname; int tagid; int type; struct sproto_type *subtype; void *value; int length; int index; // array base 1 int mainindex; // for map int extra; // SPROTO_TINTEGER: decimal ; SPROTO_TSTRING 0:utf8 string 1:binary }; typedef int (*sproto_callback)(const struct sproto_arg *args); int sproto_decode(const struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud); int sproto_encode(const struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud); // for debug use void sproto_dump(struct sproto *); const char * sproto_name(struct sproto_type *); #endif ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.h.meta ================================================ fileFormatVersion: 2 guid: f6d6ff16b7056e34abe86ede4d3e7692 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.lua ================================================ local core = require "sproto.core" local assert = assert local sproto = {} local host = {} local weak_mt = { __mode = "kv" } local sproto_mt = { __index = sproto } local sproto_nogc = { __index = sproto } local host_mt = { __index = host } function sproto_mt:__gc() core.deleteproto(self.__cobj) end function sproto.new(bin) local cobj = assert(core.newproto(bin)) local self = { __cobj = cobj, __tcache = setmetatable( {} , weak_mt ), __pcache = setmetatable( {} , weak_mt ), } return setmetatable(self, sproto_mt) end function sproto.sharenew(cobj) local self = { __cobj = cobj, __tcache = setmetatable( {} , weak_mt ), __pcache = setmetatable( {} , weak_mt ), } return setmetatable(self, sproto_nogc) end function sproto.parse(ptext) local parser = require "sprotoparser" local pbin = parser.parse(ptext) return sproto.new(pbin) end function sproto:host( packagename ) packagename = packagename or "package" local obj = { __proto = self, __package = assert(core.querytype(self.__cobj, packagename), "type package not found"), __session = {}, } return setmetatable(obj, host_mt) end local function querytype(self, typename) local v = self.__tcache[typename] if not v then v = assert(core.querytype(self.__cobj, typename), "type not found") self.__tcache[typename] = v end return v end function sproto:exist_type(typename) local v = self.__tcache[typename] if not v then return core.querytype(self.__cobj, typename) ~= nil else return true end end function sproto:encode(typename, tbl) local st = querytype(self, typename) return core.encode(st, tbl) end function sproto:decode(typename, ...) local st = querytype(self, typename) return core.decode(st, ...) end function sproto:pencode(typename, tbl) local st = querytype(self, typename) return core.pack(core.encode(st, tbl)) end function sproto:pdecode(typename, ...) local st = querytype(self, typename) return core.decode(st, core.unpack(...)) end local function queryproto(self, pname) local v = self.__pcache[pname] if not v then local tag, req, resp = core.protocol(self.__cobj, pname) assert(tag, pname .. " not found") if tonumber(pname) then pname, tag = tag, pname end v = { request = req, response =resp, name = pname, tag = tag, } self.__pcache[pname] = v self.__pcache[tag] = v end return v end function sproto:exist_proto(pname) local v = self.__pcache[pname] if not v then return core.protocol(self.__cobj, pname) ~= nil else return true end end function sproto:request_encode(protoname, tbl) local p = queryproto(self, protoname) local request = p.request if request then return core.encode(request,tbl) , p.tag else return "" , p.tag end end function sproto:response_encode(protoname, tbl) local p = queryproto(self, protoname) local response = p.response if response then return core.encode(response,tbl) else return "" end end function sproto:request_decode(protoname, ...) local p = queryproto(self, protoname) local request = p.request if request then return core.decode(request,...) , p.name else return nil, p.name end end function sproto:response_decode(protoname, ...) local p = queryproto(self, protoname) local response = p.response if response then return core.decode(response,...) end end sproto.pack = core.pack sproto.unpack = core.unpack function sproto:default(typename, type) if type == nil then return core.default(querytype(self, typename)) else local p = queryproto(self, typename) if type == "REQUEST" then if p.request then return core.default(p.request) end elseif type == "RESPONSE" then if p.response then return core.default(p.response) end else error "Invalid type" end end end local header_tmp = {} local function gen_response(self, response, session) return function(args, ud) header_tmp.type = nil header_tmp.session = session header_tmp.ud = ud local header = core.encode(self.__package, header_tmp) if response then local content = core.encode(response, args) return core.pack(header .. content) else return core.pack(header) end end end function host:dispatch(...) local bin = core.unpack(...) header_tmp.type = nil header_tmp.session = nil header_tmp.ud = nil local header, size = core.decode(self.__package, bin, header_tmp) local content = bin:sub(size + 1) if header.type then -- request local proto = queryproto(self.__proto, header.type) local result if proto.request then result = core.decode(proto.request, content) end if header_tmp.session then return "REQUEST", proto.name, result, gen_response(self, proto.response, header_tmp.session), header.ud else return "REQUEST", proto.name, result, nil, header.ud end else -- response local session = assert(header_tmp.session, "session not found") local response = assert(self.__session[session], "Unknown session") self.__session[session] = nil if response == true then return "RESPONSE", session, nil, header.ud else local result = core.decode(response, content) return "RESPONSE", session, result, header.ud end end end function host:attach(sp) return function(name, args, session, ud) local proto = queryproto(sp, name) header_tmp.type = proto.tag header_tmp.session = session header_tmp.ud = ud local header = core.encode(self.__package, header_tmp) if session then self.__session[session] = proto.response or true end if proto.request then local content = core.encode(proto.request, args) return core.pack(header .. content) else return core.pack(header) end end end return sproto ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.lua.meta ================================================ fileFormatVersion: 2 guid: c305eb9af5293a54d9e5159527184f35 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.new.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXFileReference section */ 44C04F89228C0E000073049F /* lsproto.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lsproto.c; sourceTree = ""; }; 44C04F8A228C0E010073049F /* sproto.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sproto.c; sourceTree = ""; }; 44C04F8B228C0E010073049F /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 44C04F8C228C0E010073049F /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 44C04F8D228C0E010073049F /* testrpc.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = testrpc.lua; sourceTree = ""; }; 44C04F8E228C0E010073049F /* sprotoparser.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = sprotoparser.lua; sourceTree = ""; }; 44C04F8F228C0E010073049F /* sproto.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = sproto.lua; sourceTree = ""; }; 44C04F90228C0E010073049F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 44C04F91228C0E010073049F /* test.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = test.lua; sourceTree = ""; }; 44C04F92228C0E010073049F /* msvcint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = msvcint.h; sourceTree = ""; }; 44C04F93228C0E010073049F /* sproto.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sproto.h; sourceTree = ""; }; 44C04F94228C0E010073049F /* testall.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = testall.lua; sourceTree = ""; }; 44C04F95228C0E010073049F /* print_r.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = print_r.lua; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ 44C04F83228C0E000073049F = { isa = PBXGroup; children = ( 44C04F89228C0E000073049F /* lsproto.c */, 44C04F8A228C0E010073049F /* sproto.c */, 44C04F8B228C0E010073049F /* LICENSE */, 44C04F8C228C0E010073049F /* Makefile */, 44C04F8D228C0E010073049F /* testrpc.lua */, 44C04F8E228C0E010073049F /* sprotoparser.lua */, 44C04F8F228C0E010073049F /* sproto.lua */, 44C04F90228C0E010073049F /* README.md */, 44C04F91228C0E010073049F /* test.lua */, 44C04F92228C0E010073049F /* msvcint.h */, 44C04F93228C0E010073049F /* sproto.h */, 44C04F94228C0E010073049F /* testall.lua */, 44C04F95228C0E010073049F /* print_r.lua */, ); sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXLegacyTarget section */ 44C04F88228C0E000073049F /* sproto.new */ = { isa = PBXLegacyTarget; buildArgumentsString = "$(ACTION)"; buildConfigurationList = 44C04F96228C0E010073049F /* Build configuration list for PBXLegacyTarget "sproto.new" */; buildPhases = ( ); buildToolPath = /usr/bin/make; buildWorkingDirectory = /Users/averson/Averson/Unity/UnitySourceCode/jarjin_tolua_rumtime/sproto.new; dependencies = ( ); name = sproto.new; passBuildSettingsInEnvironment = 1; productName = sproto.new; }; /* End PBXLegacyTarget section */ /* Begin PBXProject section */ 44C04F84228C0E000073049F /* Project object */ = { isa = PBXProject; attributes = { }; buildConfigurationList = 44C04F87228C0E000073049F /* Build configuration list for PBXProject "sproto.new" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = 44C04F83228C0E000073049F; projectDirPath = ""; projectRoot = ""; targets = ( 44C04F88228C0E000073049F /* sproto.new */, ); }; /* End PBXProject section */ /* Begin XCBuildConfiguration section */ 44C04F85228C0E000073049F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; COPY_PHASE_STRIP = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx10.6; }; name = Debug; }; 44C04F86228C0E000073049F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; COPY_PHASE_STRIP = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; SDKROOT = macosx10.6; }; name = Release; }; 44C04F97228C0E010073049F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = sproto.new; }; name = Debug; }; 44C04F98228C0E010073049F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = sproto.new; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 44C04F87228C0E000073049F /* Build configuration list for PBXProject "sproto.new" */ = { isa = XCConfigurationList; buildConfigurations = ( 44C04F85228C0E000073049F /* Debug */, 44C04F86228C0E000073049F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 44C04F96228C0E010073049F /* Build configuration list for PBXLegacyTarget "sproto.new" */ = { isa = XCConfigurationList; buildConfigurations = ( 44C04F97228C0E010073049F /* Debug */, 44C04F98228C0E010073049F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 44C04F84228C0E000073049F /* Project object */; } ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.new.xcodeproj/project.pbxproj.meta ================================================ fileFormatVersion: 2 guid: c51513cc997bc6c46baf4f36e2a99423 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sproto.new.xcodeproj.meta ================================================ fileFormatVersion: 2 guid: b0a3f0970b9952e4897f249798035d7e folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sprotoparser.lua ================================================ local lpeg = require "lpeg" local table = require "table" local packbytes local packvalue if _VERSION == "Lua 5.3" then function packbytes(str) return string.pack("=0 and id < 65536) local a = id % 256 local b = math.floor(id / 256) return string.char(a) .. string.char(b) end end local P = lpeg.P local S = lpeg.S local R = lpeg.R local C = lpeg.C local Ct = lpeg.Ct local Cg = lpeg.Cg local Cc = lpeg.Cc local V = lpeg.V local function count_lines(_,pos, parser_state) if parser_state.pos < pos then parser_state.line = parser_state.line + 1 parser_state.pos = pos end return pos end local exception = lpeg.Cmt( lpeg.Carg(1) , function ( _ , pos, parser_state) error(string.format("syntax error at [%s] line (%d)", parser_state.file or "", parser_state.line)) return pos end) local eof = P(-1) local newline = lpeg.Cmt((P"\n" + "\r\n") * lpeg.Carg(1) ,count_lines) local line_comment = "#" * (1 - newline) ^0 * (newline + eof) local blank = S" \t" + newline + line_comment local blank0 = blank ^ 0 local blanks = blank ^ 1 local alpha = R"az" + R"AZ" + "_" local alnum = alpha + R"09" local word = alpha * alnum ^ 0 local name = C(word) local typename = C(word * ("." * word) ^ 0) local tag = R"09" ^ 1 / tonumber local mainkey = "(" * blank0 * name * blank0 * ")" local decimal = "(" * blank0 * C(tag) * blank0 * ")" local function multipat(pat) return Ct(blank0 * (pat * blanks) ^ 0 * pat^0 * blank0) end local function namedpat(name, pat) return Ct(Cg(Cc(name), "type") * Cg(pat)) end local typedef = P { "ALL", FIELD = namedpat("field", (name * blanks * tag * blank0 * ":" * blank0 * (C"*")^-1 * typename * (mainkey + decimal)^0)), STRUCT = P"{" * multipat(V"FIELD" + V"TYPE") * P"}", TYPE = namedpat("type", P"." * name * blank0 * V"STRUCT" ), SUBPROTO = Ct((C"request" + C"response") * blanks * (typename + V"STRUCT")), PROTOCOL = namedpat("protocol", name * blanks * tag * blank0 * P"{" * multipat(V"SUBPROTO") * P"}"), ALL = multipat(V"TYPE" + V"PROTOCOL"), } local proto = blank0 * typedef * blank0 local convert = {} function convert.protocol(all, obj) local result = { tag = obj[2] } for _, p in ipairs(obj[3]) do assert(result[p[1]] == nil) local typename = p[2] if type(typename) == "table" then local struct = typename typename = obj[1] .. "." .. p[1] all.type[typename] = convert.type(all, { typename, struct }) end if typename == "nil" then if p[1] == "response" then result.confirm = true end else result[p[1]] = typename end end return result end function convert.type(all, obj) local result = {} local typename = obj[1] local tags = {} local names = {} for _, f in ipairs(obj[2]) do if f.type == "field" then local name = f[1] if names[name] then error(string.format("redefine %s in type %s", name, typename)) end names[name] = true local tag = f[2] if tags[tag] then error(string.format("redefine tag %d in type %s", tag, typename)) end tags[tag] = true local field = { name = name, tag = tag } table.insert(result, field) local fieldtype = f[3] if fieldtype == "*" then field.array = true fieldtype = f[4] end local mainkey = f[5] if mainkey then if fieldtype == "integer" then field.decimal = mainkey else assert(field.array) field.key = mainkey end end field.typename = fieldtype else assert(f.type == "type") -- nest type local nesttypename = typename .. "." .. f[1] f[1] = nesttypename assert(all.type[nesttypename] == nil, "redefined " .. nesttypename) all.type[nesttypename] = convert.type(all, f) end end table.sort(result, function(a,b) return a.tag < b.tag end) return result end local function adjust(r) local result = { type = {} , protocol = {} } for _, obj in ipairs(r) do local set = result[obj.type] local name = obj[1] assert(set[name] == nil , "redefined " .. name) set[name] = convert[obj.type](result,obj) end return result end local buildin_types = { integer = 0, boolean = 1, string = 2, binary = 2, -- binary is a sub type of string } local function checktype(types, ptype, t) if buildin_types[t] then return t end local fullname = ptype .. "." .. t if types[fullname] then return fullname else ptype = ptype:match "(.+)%..+$" if ptype then return checktype(types, ptype, t) elseif types[t] then return t end end end local function check_protocol(r) local map = {} local type = r.type for name, v in pairs(r.protocol) do local tag = v.tag local request = v.request local response = v.response local p = map[tag] if p then error(string.format("redefined protocol tag %d at %s", tag, name)) end if request and not type[request] then error(string.format("Undefined request type %s in protocol %s", request, name)) end if response and not type[response] then error(string.format("Undefined response type %s in protocol %s", response, name)) end map[tag] = v end return r end local function flattypename(r) for typename, t in pairs(r.type) do for _, f in pairs(t) do local ftype = f.typename local fullname = checktype(r.type, typename, ftype) if fullname == nil then error(string.format("Undefined type %s in type %s", ftype, typename)) end f.typename = fullname end end return r end local function parser(text,filename) local state = { file = filename, pos = 0, line = 1 } local r = lpeg.match(proto * -1 + exception , text , 1, state ) return flattypename(check_protocol(adjust(r))) end --[[ -- The protocol of sproto .type { .field { name 0 : string buildin 1 : integer type 2 : integer tag 3 : integer array 4 : boolean key 5 : integer # If key exists, array must be true, and it's a map. } name 0 : string fields 1 : *field } .protocol { name 0 : string tag 1 : integer request 2 : integer # index response 3 : integer # index confirm 4 : boolean # true means response nil } .group { type 0 : *type protocol 1 : *protocol } ]] local function packfield(f) local strtbl = {} if f.array then if f.key then table.insert(strtbl, "\6\0") -- 6 fields else table.insert(strtbl, "\5\0") -- 5 fields end else table.insert(strtbl, "\4\0") -- 4 fields end table.insert(strtbl, "\0\0") -- name (tag = 0, ref an object) if f.buildin then table.insert(strtbl, packvalue(f.buildin)) -- buildin (tag = 1) if f.extra then table.insert(strtbl, packvalue(f.extra)) -- f.buildin can be integer or string else table.insert(strtbl, "\1\0") -- skip (tag = 2) end table.insert(strtbl, packvalue(f.tag)) -- tag (tag = 3) else table.insert(strtbl, "\1\0") -- skip (tag = 1) table.insert(strtbl, packvalue(f.type)) -- type (tag = 2) table.insert(strtbl, packvalue(f.tag)) -- tag (tag = 3) end if f.array then table.insert(strtbl, packvalue(1)) -- array = true (tag = 4) end if f.key then table.insert(strtbl, packvalue(f.key)) -- key tag (tag = 5) end table.insert(strtbl, packbytes(f.name)) -- external object (name) return packbytes(table.concat(strtbl)) end local function packtype(name, t, alltypes) local fields = {} local tmp = {} for _, f in ipairs(t) do tmp.array = f.array tmp.name = f.name tmp.tag = f.tag tmp.extra = f.decimal tmp.buildin = buildin_types[f.typename] if f.typename == "binary" then tmp.extra = 1 -- binary is sub type of string end local subtype if not tmp.buildin then subtype = assert(alltypes[f.typename]) tmp.type = subtype.id else tmp.type = nil end if f.key then tmp.key = subtype.fields[f.key] if not tmp.key then error("Invalid map index :" .. f.key) end else tmp.key = nil end table.insert(fields, packfield(tmp)) end local data if #fields == 0 then data = { "\1\0", -- 1 fields "\0\0", -- name (id = 0, ref = 0) packbytes(name), } else data = { "\2\0", -- 2 fields "\0\0", -- name (tag = 0, ref = 0) "\0\0", -- field[] (tag = 1, ref = 1) packbytes(name), packbytes(table.concat(fields)), } end return packbytes(table.concat(data)) end local function packproto(name, p, alltypes) if p.request then local request = alltypes[p.request] if request == nil then error(string.format("Protocol %s request type %s not found", name, p.request)) end request = request.id end local tmp = { "\4\0", -- 4 fields "\0\0", -- name (id=0, ref=0) packvalue(p.tag), -- tag (tag=1) } if p.request == nil and p.response == nil and p.confirm == nil then tmp[1] = "\2\0" -- only two fields else if p.request then table.insert(tmp, packvalue(alltypes[p.request].id)) -- request typename (tag=2) else table.insert(tmp, "\1\0") -- skip this field (request) end if p.response then table.insert(tmp, packvalue(alltypes[p.response].id)) -- request typename (tag=3) elseif p.confirm then tmp[1] = "\5\0" -- add confirm field table.insert(tmp, "\1\0") -- skip this field (response) table.insert(tmp, packvalue(1)) -- confirm = true else tmp[1] = "\3\0" -- only three fields end end table.insert(tmp, packbytes(name)) return packbytes(table.concat(tmp)) end local function packgroup(t,p) if next(t) == nil then assert(next(p) == nil) return "\0\0" end local tt, tp local alltypes = {} for name in pairs(t) do table.insert(alltypes, name) end table.sort(alltypes) -- make result stable for idx, name in ipairs(alltypes) do local fields = {} for _, type_fields in ipairs(t[name]) do if buildin_types[type_fields.typename] then fields[type_fields.name] = type_fields.tag end end alltypes[name] = { id = idx - 1, fields = fields } end tt = {} for _,name in ipairs(alltypes) do table.insert(tt, packtype(name, t[name], alltypes)) end tt = packbytes(table.concat(tt)) if next(p) then local tmp = {} for name, tbl in pairs(p) do table.insert(tmp, tbl) tbl.name = name end table.sort(tmp, function(a,b) return a.tag < b.tag end) tp = {} for _, tbl in ipairs(tmp) do table.insert(tp, packproto(tbl.name, tbl, alltypes)) end tp = packbytes(table.concat(tp)) end local result if tp == nil then result = { "\1\0", -- 1 field "\0\0", -- type[] (id = 0, ref = 0) tt, } else result = { "\2\0", -- 2fields "\0\0", -- type array (id = 0, ref = 0) "\0\0", -- protocol array (id = 1, ref =1) tt, tp, } end return table.concat(result) end local function encodeall(r) return packgroup(r.type, r.protocol) end local sparser = {} function sparser.dump(str) local tmp = "" for i=1,#str do tmp = tmp .. string.format("%02X ", string.byte(str,i)) if i % 8 == 0 then if i % 16 == 0 then print(tmp) tmp = "" else tmp = tmp .. "- " end end end print(tmp) end function sparser.parse(text, name) local r = parser(text, name or "=text") local data = encodeall(r) return data end return sparser ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/sprotoparser.lua.meta ================================================ fileFormatVersion: 2 guid: 1029deb59a2e22741ae8bb6de18d55e3 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/test.lua ================================================ local sproto = require "sproto" local core = require "sproto.core" local print_r = require "print_r" local sp = sproto.parse [[ .Person { name 0 : string id 1 : integer email 2 : string .PhoneNumber { number 0 : string type 1 : integer } phone 3 : *PhoneNumber } .AddressBook { person 0 : *Person(id) others 1 : *Person } ]] -- core.dumpproto only for debug use core.dumpproto(sp.__cobj) local def = sp:default "Person" print("default table for Person") print_r(def) print("--------------") local ab = { person = { [10000] = { name = "Alice", id = 10000, phone = { { number = "123456789" , type = 1 }, { number = "87654321" , type = 2 }, } }, [20000] = { name = "Bob", id = 20000, phone = { { number = "01234567890" , type = 3 }, } } }, others = { { name = "Carol", id = 30000, phone = { { number = "9876543210" }, } }, } } collectgarbage "stop" local code = sp:encode("AddressBook", ab) local addr = sp:decode("AddressBook", code) print_r(addr) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/test.lua.meta ================================================ fileFormatVersion: 2 guid: 8d9128acb663de141bc4315bb57648c3 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/testall.lua ================================================ local sproto = require "sproto" local print_r = require "print_r" local sp = sproto.parse [[ .foobar { .nest { a 1 : string b 3 : boolean c 5 : integer d 6 : integer(3) } a 0 : string b 1 : integer c 2 : boolean d 3 : *nest(a) e 4 : *string f 5 : *integer g 6 : *boolean h 7 : *foobar i 8 : *integer(2) j 9 : binary } ]] local obj = { a = "hello", b = 1000000, c = true, d = { { a = "one", -- skip b c = -1, }, { a = "two", b = true, }, { a = "", b = false, c = 1, }, { a = "decimal", d = 1.235, } }, e = { "ABC", "", "def" }, f = { -3, -2, -1, 0 , 1, 2}, g = { true, false, true }, h = { { b = 100 }, {}, { b = -100, c= false }, { b = 0, e = { "test" } }, }, i = { 1,2.1,3.21,4.321 }, j = "\0\1\2\3", } local code = sp:encode("foobar", obj) obj = sp:decode("foobar", code) print_r(obj) -- core.dumpproto only for debug use local core = require "sproto.core" core.dumpproto(sp.__cobj) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/testall.lua.meta ================================================ fileFormatVersion: 2 guid: 228d5abe9cc3cdd40a7a63bda3a3a273 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/testrpc.lua ================================================ local sproto = require "sproto" local print_r = require "print_r" local server_proto = sproto.parse [[ .package { type 0 : integer session 1 : integer } foobar 1 { request { what 0 : string } response { ok 0 : boolean } } foo 2 { response { ok 0 : boolean } } bar 3 { response nil } blackhole 4 { } ]] local client_proto = sproto.parse [[ .package { type 0 : integer session 1 : integer } ]] assert(server_proto:exist_type "package") assert(server_proto:exist_proto "foobar") print("=== default table") print_r(server_proto:default("package")) print_r(server_proto:default("foobar", "REQUEST")) assert(server_proto:default("foo", "REQUEST")==nil) assert(server_proto:request_encode("foo")=="") server_proto:response_encode("foo", { ok = true }) assert(server_proto:request_decode("blackhole")==nil) assert(server_proto:response_decode("blackhole")==nil) print("=== test 1") -- The type package must has two field : type and session local server = server_proto:host "package" local client = client_proto:host "package" local client_request = client:attach(server_proto) print("client request foobar") local req = client_request("foobar", { what = "foo" }, 1) print("request foobar size =", #req) local type, name, request, response = server:dispatch(req) assert(type == "REQUEST" and name == "foobar") print_r(request) print("server response") local resp = response { ok = true } print("response package size =", #resp) print("client dispatch") local type, session, response = client:dispatch(resp) assert(type == "RESPONSE" and session == 1) print_r(response) local req = client_request("foo", nil, 2) print("request foo size =", #req) local type, name, request, response = server:dispatch(req) assert(type == "REQUEST" and name == "foo" and request == nil) local resp = response { ok = false } print("response package size =", #resp) print("client dispatch") local type, session, response = client:dispatch(resp) assert(type == "RESPONSE" and session == 2) print_r(response) local req = client_request("bar", nil, 3) print("request bar size =", #req) local type, name, request, response = server:dispatch(req) assert(type == "REQUEST" and name == "bar" and request == nil) assert(select(2,client:dispatch(response())) == 3) local req = client_request "blackhole" -- no response print("request blackhole size = ", #req) print("=== test 2") local v, tag = server_proto:request_encode("foobar", { what = "hello"}) assert(tag == 1) -- foobar : 1 print("tag =", tag) print_r(server_proto:request_decode("foobar", v)) local v = server_proto:response_encode("foobar", { ok = true }) print_r(server_proto:response_decode("foobar", v)) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new/testrpc.lua.meta ================================================ fileFormatVersion: 2 guid: 400fb0a0e87b312488b39e8370915feb DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sproto.new.meta ================================================ fileFormatVersion: 2 guid: 51f3c40d92337c04f9b7b816f11e2166 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sprotoparser.lua ================================================ local lpeg = require "lpeg" local table = require "table" local packbytes local packvalue if _VERSION == "Lua 5.3" then function packbytes(str) return string.pack("=0 and id < 65536) local a = id % 256 local b = math.floor(id / 256) return string.char(a) .. string.char(b) end end local P = lpeg.P local S = lpeg.S local R = lpeg.R local C = lpeg.C local Ct = lpeg.Ct local Cg = lpeg.Cg local Cc = lpeg.Cc local V = lpeg.V local function count_lines(_,pos, parser_state) if parser_state.pos < pos then parser_state.line = parser_state.line + 1 parser_state.pos = pos end return pos end local exception = lpeg.Cmt( lpeg.Carg(1) , function ( _ , pos, parser_state) error(string.format("syntax error at [%s] line (%d)", parser_state.file or "", parser_state.line)) return pos end) local eof = P(-1) local newline = lpeg.Cmt((P"\n" + "\r\n") * lpeg.Carg(1) ,count_lines) local line_comment = "#" * (1 - newline) ^0 * (newline + eof) local blank = S" \t" + newline + line_comment local blank0 = blank ^ 0 local blanks = blank ^ 1 local alpha = R"az" + R"AZ" + "_" local alnum = alpha + R"09" local word = alpha * alnum ^ 0 local name = C(word) local typename = C(word * ("." * word) ^ 0) local tag = R"09" ^ 1 / tonumber local mainkey = "(" * blank0 * name * blank0 * ")" local decimal = "(" * blank0 * C(tag) * blank0 * ")" local function multipat(pat) return Ct(blank0 * (pat * blanks) ^ 0 * pat^0 * blank0) end local function namedpat(name, pat) return Ct(Cg(Cc(name), "type") * Cg(pat)) end local typedef = P { "ALL", FIELD = namedpat("field", (name * blanks * tag * blank0 * ":" * blank0 * (C"*")^-1 * typename * (mainkey + decimal)^0)), STRUCT = P"{" * multipat(V"FIELD" + V"TYPE") * P"}", TYPE = namedpat("type", P"." * name * blank0 * V"STRUCT" ), SUBPROTO = Ct((C"request" + C"response") * blanks * (typename + V"STRUCT")), PROTOCOL = namedpat("protocol", name * blanks * tag * blank0 * P"{" * multipat(V"SUBPROTO") * P"}"), ALL = multipat(V"TYPE" + V"PROTOCOL"), } local proto = blank0 * typedef * blank0 local convert = {} function convert.protocol(all, obj) local result = { tag = obj[2] } for _, p in ipairs(obj[3]) do assert(result[p[1]] == nil) local typename = p[2] if type(typename) == "table" then local struct = typename typename = obj[1] .. "." .. p[1] all.type[typename] = convert.type(all, { typename, struct }) end if typename == "nil" then if p[1] == "response" then result.confirm = true end else result[p[1]] = typename end end return result end function convert.type(all, obj) local result = {} local typename = obj[1] local tags = {} local names = {} for _, f in ipairs(obj[2]) do if f.type == "field" then local name = f[1] if names[name] then error(string.format("redefine %s in type %s", name, typename)) end names[name] = true local tag = f[2] if tags[tag] then error(string.format("redefine tag %d in type %s", tag, typename)) end tags[tag] = true local field = { name = name, tag = tag } table.insert(result, field) local fieldtype = f[3] if fieldtype == "*" then field.array = true fieldtype = f[4] end local mainkey = f[5] if mainkey then if fieldtype == "integer" then field.decimal = mainkey else assert(field.array) field.key = mainkey end end field.typename = fieldtype else assert(f.type == "type") -- nest type local nesttypename = typename .. "." .. f[1] f[1] = nesttypename assert(all.type[nesttypename] == nil, "redefined " .. nesttypename) all.type[nesttypename] = convert.type(all, f) end end table.sort(result, function(a,b) return a.tag < b.tag end) return result end local function adjust(r) local result = { type = {} , protocol = {} } for _, obj in ipairs(r) do local set = result[obj.type] local name = obj[1] assert(set[name] == nil , "redefined " .. name) set[name] = convert[obj.type](result,obj) end return result end local buildin_types = { integer = 0, boolean = 1, string = 2, binary = 2, -- binary is a sub type of string } local function checktype(types, ptype, t) if buildin_types[t] then return t end local fullname = ptype .. "." .. t if types[fullname] then return fullname else ptype = ptype:match "(.+)%..+$" if ptype then return checktype(types, ptype, t) elseif types[t] then return t end end end local function check_protocol(r) local map = {} local type = r.type for name, v in pairs(r.protocol) do local tag = v.tag local request = v.request local response = v.response local p = map[tag] if p then error(string.format("redefined protocol tag %d at %s", tag, name)) end if request and not type[request] then error(string.format("Undefined request type %s in protocol %s", request, name)) end if response and not type[response] then error(string.format("Undefined response type %s in protocol %s", response, name)) end map[tag] = v end return r end local function flattypename(r) for typename, t in pairs(r.type) do for _, f in pairs(t) do local ftype = f.typename local fullname = checktype(r.type, typename, ftype) if fullname == nil then error(string.format("Undefined type %s in type %s", ftype, typename)) end f.typename = fullname end end return r end local function parser(text,filename) local state = { file = filename, pos = 0, line = 1 } local r = lpeg.match(proto * -1 + exception , text , 1, state ) return flattypename(check_protocol(adjust(r))) end --[[ -- The protocol of sproto .type { .field { name 0 : string buildin 1 : integer type 2 : integer tag 3 : integer array 4 : boolean key 5 : integer # If key exists, array must be true, and it's a map. } name 0 : string fields 1 : *field } .protocol { name 0 : string tag 1 : integer request 2 : integer # index response 3 : integer # index confirm 4 : boolean # true means response nil } .group { type 0 : *type protocol 1 : *protocol } ]] local function packfield(f) local strtbl = {} if f.array then if f.key then table.insert(strtbl, "\6\0") -- 6 fields else table.insert(strtbl, "\5\0") -- 5 fields end else table.insert(strtbl, "\4\0") -- 4 fields end table.insert(strtbl, "\0\0") -- name (tag = 0, ref an object) if f.buildin then table.insert(strtbl, packvalue(f.buildin)) -- buildin (tag = 1) if f.extra then table.insert(strtbl, packvalue(f.extra)) -- f.buildin can be integer or string else table.insert(strtbl, "\1\0") -- skip (tag = 2) end table.insert(strtbl, packvalue(f.tag)) -- tag (tag = 3) else table.insert(strtbl, "\1\0") -- skip (tag = 1) table.insert(strtbl, packvalue(f.type)) -- type (tag = 2) table.insert(strtbl, packvalue(f.tag)) -- tag (tag = 3) end if f.array then table.insert(strtbl, packvalue(1)) -- array = true (tag = 4) end if f.key then table.insert(strtbl, packvalue(f.key)) -- key tag (tag = 5) end table.insert(strtbl, packbytes(f.name)) -- external object (name) return packbytes(table.concat(strtbl)) end local function packtype(name, t, alltypes) local fields = {} local tmp = {} for _, f in ipairs(t) do tmp.array = f.array tmp.name = f.name tmp.tag = f.tag tmp.extra = f.decimal tmp.buildin = buildin_types[f.typename] if f.typename == "binary" then tmp.extra = 1 -- binary is sub type of string end local subtype if not tmp.buildin then subtype = assert(alltypes[f.typename]) tmp.type = subtype.id else tmp.type = nil end if f.key then tmp.key = subtype.fields[f.key] if not tmp.key then error("Invalid map index :" .. f.key) end else tmp.key = nil end table.insert(fields, packfield(tmp)) end local data if #fields == 0 then data = { "\1\0", -- 1 fields "\0\0", -- name (id = 0, ref = 0) packbytes(name), } else data = { "\2\0", -- 2 fields "\0\0", -- name (tag = 0, ref = 0) "\0\0", -- field[] (tag = 1, ref = 1) packbytes(name), packbytes(table.concat(fields)), } end return packbytes(table.concat(data)) end local function packproto(name, p, alltypes) if p.request then local request = alltypes[p.request] if request == nil then error(string.format("Protocol %s request type %s not found", name, p.request)) end request = request.id end local tmp = { "\4\0", -- 4 fields "\0\0", -- name (id=0, ref=0) packvalue(p.tag), -- tag (tag=1) } if p.request == nil and p.response == nil and p.confirm == nil then tmp[1] = "\2\0" -- only two fields else if p.request then table.insert(tmp, packvalue(alltypes[p.request].id)) -- request typename (tag=2) else table.insert(tmp, "\1\0") -- skip this field (request) end if p.response then table.insert(tmp, packvalue(alltypes[p.response].id)) -- request typename (tag=3) elseif p.confirm then tmp[1] = "\5\0" -- add confirm field table.insert(tmp, "\1\0") -- skip this field (response) table.insert(tmp, packvalue(1)) -- confirm = true else tmp[1] = "\3\0" -- only three fields end end table.insert(tmp, packbytes(name)) return packbytes(table.concat(tmp)) end local function packgroup(t,p) if next(t) == nil then assert(next(p) == nil) return "\0\0" end local tt, tp local alltypes = {} for name in pairs(t) do table.insert(alltypes, name) end table.sort(alltypes) -- make result stable for idx, name in ipairs(alltypes) do local fields = {} for _, type_fields in ipairs(t[name]) do if buildin_types[type_fields.typename] then fields[type_fields.name] = type_fields.tag end end alltypes[name] = { id = idx - 1, fields = fields } end tt = {} for _,name in ipairs(alltypes) do table.insert(tt, packtype(name, t[name], alltypes)) end tt = packbytes(table.concat(tt)) if next(p) then local tmp = {} for name, tbl in pairs(p) do table.insert(tmp, tbl) tbl.name = name end table.sort(tmp, function(a,b) return a.tag < b.tag end) tp = {} for _, tbl in ipairs(tmp) do table.insert(tp, packproto(tbl.name, tbl, alltypes)) end tp = packbytes(table.concat(tp)) end local result if tp == nil then result = { "\1\0", -- 1 field "\0\0", -- type[] (id = 0, ref = 0) tt, } else result = { "\2\0", -- 2fields "\0\0", -- type array (id = 0, ref = 0) "\0\0", -- protocol array (id = 1, ref =1) tt, tp, } end return table.concat(result) end local function encodeall(r) return packgroup(r.type, r.protocol) end local sparser = {} function sparser.dump(str) local tmp = "" for i=1,#str do tmp = tmp .. string.format("%02X ", string.byte(str,i)) if i % 8 == 0 then if i % 16 == 0 then print(tmp) tmp = "" else tmp = tmp .. "- " end end end print(tmp) end function sparser.parse(text, name) local r = parser(text, name or "=text") local data = encodeall(r) return data end return sparser ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/sprotoparser.lua.meta ================================================ fileFormatVersion: 2 guid: 3b6c96a99e1b8fd4aae2bcc27d800ebc DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/test.lua ================================================ local sproto = require "sproto" local core = require "sproto.core" local print_r = require "print_r" local sp = sproto.parse [[ .Person { name 0 : string id 1 : integer email 2 : string .PhoneNumber { number 0 : string type 1 : integer } phone 3 : *PhoneNumber } .AddressBook { person 0 : *Person(id) others 1 : *Person } ]] -- core.dumpproto only for debug use core.dumpproto(sp.__cobj) local def = sp:default "Person" print("default table for Person") print_r(def) print("--------------") local ab = { person = { [10000] = { name = "Alice", id = 10000, phone = { { number = "123456789" , type = 1 }, { number = "87654321" , type = 2 }, } }, [20000] = { name = "Bob", id = 20000, phone = { { number = "01234567890" , type = 3 }, } } }, others = { { name = "Carol", id = 30000, phone = { { number = "9876543210" }, } }, } } collectgarbage "stop" local code = sp:encode("AddressBook", ab) local addr = sp:decode("AddressBook", code) print_r(addr) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/test.lua.meta ================================================ fileFormatVersion: 2 guid: a955d75e03673da40b51a1c34364118f DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/testall.lua ================================================ local sproto = require "sproto" local print_r = require "print_r" local sp = sproto.parse [[ .foobar { .nest { a 1 : string b 3 : boolean c 5 : integer d 6 : integer(3) } a 0 : string b 1 : integer c 2 : boolean d 3 : *nest(a) e 4 : *string f 5 : *integer g 6 : *boolean h 7 : *foobar i 8 : *integer(2) j 9 : binary } ]] local obj = { a = "hello", b = 1000000, c = true, d = { { a = "one", -- skip b c = -1, }, { a = "two", b = true, }, { a = "", b = false, c = 1, }, { a = "decimal", d = 1.235, } }, e = { "ABC", "", "def" }, f = { -3, -2, -1, 0 , 1, 2}, g = { true, false, true }, h = { { b = 100 }, {}, { b = -100, c= false }, { b = 0, e = { "test" } }, }, i = { 1,2.1,3.21,4.321 }, j = "\0\1\2\3", } local code = sp:encode("foobar", obj) obj = sp:decode("foobar", code) print_r(obj) -- core.dumpproto only for debug use local core = require "sproto.core" core.dumpproto(sp.__cobj) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/testall.lua.meta ================================================ fileFormatVersion: 2 guid: 6f0ca69e73aad4b488d5071e00b384a8 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/testrpc.lua ================================================ local sproto = require "sproto" local print_r = require "print_r" local server_proto = sproto.parse [[ .package { type 0 : integer session 1 : integer } foobar 1 { request { what 0 : string } response { ok 0 : boolean } } foo 2 { response { ok 0 : boolean } } bar 3 { response nil } blackhole 4 { } ]] local client_proto = sproto.parse [[ .package { type 0 : integer session 1 : integer } ]] assert(server_proto:exist_type "package") assert(server_proto:exist_proto "foobar") print("=== default table") print_r(server_proto:default("package")) print_r(server_proto:default("foobar", "REQUEST")) assert(server_proto:default("foo", "REQUEST")==nil) assert(server_proto:request_encode("foo")=="") server_proto:response_encode("foo", { ok = true }) assert(server_proto:request_decode("blackhole")==nil) assert(server_proto:response_decode("blackhole")==nil) print("=== test 1") -- The type package must has two field : type and session local server = server_proto:host "package" local client = client_proto:host "package" local client_request = client:attach(server_proto) print("client request foobar") local req = client_request("foobar", { what = "foo" }, 1) print("request foobar size =", #req) local type, name, request, response = server:dispatch(req) assert(type == "REQUEST" and name == "foobar") print_r(request) print("server response") local resp = response { ok = true } print("response package size =", #resp) print("client dispatch") local type, session, response = client:dispatch(resp) assert(type == "RESPONSE" and session == 1) print_r(response) local req = client_request("foo", nil, 2) print("request foo size =", #req) local type, name, request, response = server:dispatch(req) assert(type == "REQUEST" and name == "foo" and request == nil) local resp = response { ok = false } print("response package size =", #resp) print("client dispatch") local type, session, response = client:dispatch(resp) assert(type == "RESPONSE" and session == 2) print_r(response) local req = client_request("bar", nil, 3) print("request bar size =", #req) local type, name, request, response = server:dispatch(req) assert(type == "REQUEST" and name == "bar" and request == nil) assert(select(2,client:dispatch(response())) == 3) local req = client_request "blackhole" -- no response print("request blackhole size = ", #req) print("=== test 2") local v, tag = server_proto:request_encode("foobar", { what = "hello"}) assert(tag == 1) -- foobar : 1 print("tag =", tag) print_r(server_proto:request_decode("foobar", v)) local v = server_proto:response_encode("foobar", { ok = true }) print_r(server_proto:response_decode("foobar", v)) ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources/testrpc.lua.meta ================================================ fileFormatVersion: 2 guid: 666350acbed6d6d46ae2175b5bf12b56 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents/Resources.meta ================================================ fileFormatVersion: 2 guid: 2bc3127b3b551e44da3235a21c051ee0 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle/Contents.meta ================================================ fileFormatVersion: 2 guid: 22990b789b0594c8785404a854b20a60 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/tolua.bundle.meta ================================================ fileFormatVersion: 2 guid: d67965ea35e33fa4f8179bc8f4f3ce74 folderAsset: yes PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: '': OSXIntel second: enabled: 1 settings: {} - first: '': OSXIntel64 second: enabled: 1 settings: {} - first: Any: second: enabled: 0 settings: {} - first: Editor: Editor second: enabled: 1 settings: DefaultValueInitialized: true - first: Standalone: OSXUniversal second: enabled: 1 settings: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/x86/tolua.dll.meta ================================================ fileFormatVersion: 2 guid: f3b9938f609831e41b7ffc0f4108166b PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: '': Any second: enabled: 0 settings: Exclude Android: 1 Exclude Editor: 1 Exclude Linux: 1 Exclude Linux64: 1 Exclude LinuxUniversal: 1 Exclude OSXUniversal: 1 Exclude Win: 1 Exclude Win64: 1 Exclude iOS: 1 - first: '': OSXIntel second: enabled: 1 settings: CPU: AnyCPU - first: '': OSXIntel64 second: enabled: 0 settings: CPU: None - first: Android: Android second: enabled: 0 settings: CPU: ARMv7 - first: Any: second: enabled: 0 settings: {} - first: Editor: Editor second: enabled: 0 settings: CPU: x86 DefaultValueInitialized: true OS: AnyOS - first: Facebook: Win second: enabled: 1 settings: CPU: AnyCPU - first: Facebook: Win64 second: enabled: 0 settings: CPU: None - first: Standalone: Linux second: enabled: 0 settings: CPU: x86 - first: Standalone: Linux64 second: enabled: 0 settings: CPU: None - first: Standalone: LinuxUniversal second: enabled: 0 settings: CPU: None - first: Standalone: OSXUniversal second: enabled: 0 settings: CPU: x86 - first: Standalone: Win second: enabled: 0 settings: CPU: AnyCPU - first: Standalone: Win64 second: enabled: 0 settings: CPU: None - first: iPhone: iOS second: enabled: 0 settings: AddToEmbeddedBinaries: false CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/x86.meta ================================================ fileFormatVersion: 2 guid: 8b0b0c4ffe67d2f4292c5211de91e55f folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins/x86_64/tolua.dll.meta ================================================ fileFormatVersion: 2 guid: 82bce848ef6ade348a8220c2ada7da08 PluginImporter: externalObjects: {} serializedVersion: 2 iconMap: {} executionOrder: {} isPreloaded: 0 isOverridable: 0 platformData: - first: '': Any second: enabled: 0 settings: Exclude Android: 0 Exclude Editor: 0 Exclude Linux: 0 Exclude Linux64: 0 Exclude LinuxUniversal: 0 Exclude OSXUniversal: 0 Exclude Win: 0 Exclude Win64: 0 Exclude iOS: 0 - first: '': OSXIntel second: enabled: 0 settings: CPU: None - first: '': OSXIntel64 second: enabled: 1 settings: CPU: AnyCPU - first: Android: Android second: enabled: 1 settings: CPU: ARMv7 - first: Any: second: enabled: 0 settings: {} - first: Editor: Editor second: enabled: 1 settings: CPU: x86_64 DefaultValueInitialized: true OS: AnyOS - first: Facebook: Win second: enabled: 0 settings: CPU: None - first: Facebook: Win64 second: enabled: 1 settings: CPU: AnyCPU - first: Standalone: Linux second: enabled: 1 settings: CPU: None - first: Standalone: Linux64 second: enabled: 1 settings: CPU: x86_64 - first: Standalone: LinuxUniversal second: enabled: 1 settings: CPU: AnyCPU - first: Standalone: OSXUniversal second: enabled: 1 settings: CPU: x86_64 - first: Standalone: Win second: enabled: 1 settings: CPU: None - first: Standalone: Win64 second: enabled: 1 settings: CPU: AnyCPU - first: iPhone: iOS second: enabled: 1 settings: AddToEmbeddedBinaries: false CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Plugins/x86_64.meta ================================================ fileFormatVersion: 2 guid: 7ea0a8e1f899b1148badb9e92b431566 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Plugins.meta ================================================ fileFormatVersion: 2 guid: e34dc6e361156f0439e74fa578a45650 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/Source/Generate.meta ================================================ fileFormatVersion: 2 guid: 31754e6228da68f4685ee6a121455def folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/Source/LuaConst.cs ================================================ using UnityEngine; public static class LuaConst { public static string luaDir = Application.dataPath + "/Lua"; //lua逻辑代码目录 public static string toluaDir = Application.dataPath + "/ToLua/Lua"; //tolua lua文件目录 #if UNITY_STANDALONE public static string osDir = "Win"; #elif UNITY_ANDROID public static string osDir = "Android"; #elif UNITY_IPHONE public static string osDir = "iOS"; #else public static string osDir = ""; #endif public static string luaResDir = string.Format("{0}/{1}/Lua", Application.persistentDataPath, osDir); //手机运行时lua文件下载目录 #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN public static string zbsDir = "D:/ZeroBraneStudio/lualibs/mobdebug"; //ZeroBraneStudio目录 #elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX public static string zbsDir = "/Applications/ZeroBraneStudio.app/Contents/ZeroBraneStudio/lualibs/mobdebug"; #else public static string zbsDir = luaResDir + "/mobdebug/"; #endif public static bool openLuaSocket = true; //是否打开Lua Socket库 public static bool openLuaDebugger = false; //是否连接lua调试器 } ================================================ FILE: Assets/Source/LuaConst.cs.meta ================================================ fileFormatVersion: 2 guid: 35b0c8bef181f2d4dacd3c860eb546a7 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/Source.meta ================================================ fileFormatVersion: 2 guid: 51d939fde26e0e14891f186ff8635b87 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_EventObjectWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class LuaInterface_EventObjectWrap { public static void Register(LuaState L) { L.BeginClass(typeof(LuaInterface.EventObject), typeof(System.Object)); L.RegFunction("__add", op_Addition); L.RegFunction("__sub", op_Subtraction); L.RegFunction("__tostring", ToLua.op_ToString); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Subtraction(IntPtr L) { try { EventObject arg0 = (EventObject)ToLua.CheckObject(L, 1, typeof(EventObject)); arg0.func = ToLua.CheckDelegate(arg0.type, L, 2); arg0.op = EventOp.Sub; ToLua.Push(L, arg0); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Addition(IntPtr L) { try { EventObject arg0 = (EventObject)ToLua.CheckObject(L, 1, typeof(EventObject)); arg0.func = ToLua.CheckDelegate(arg0.type, L, 2); arg0.op = EventOp.Add; ToLua.Push(L, arg0); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_EventObjectWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 9eec90316b4c2da499dee7c75f1f94ae MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaConstructorWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class LuaInterface_LuaConstructorWrap { public static void Register(LuaState L) { L.BeginClass(typeof(LuaInterface.LuaConstructor), typeof(System.Object)); L.RegFunction("Call", Call); L.RegFunction("Destroy", Destroy); L.RegFunction("__tostring", ToLua.op_ToString); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Call(IntPtr L) { try { LuaConstructor obj = (LuaConstructor)ToLua.CheckObject(L, 1, typeof(LuaConstructor)); return obj.Call(L); } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Destroy(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); LuaConstructor obj = (LuaConstructor)ToLua.CheckObject(L, 1, typeof(LuaConstructor)); obj.Destroy(); ToLua.Destroy(L); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaConstructorWrap.cs.meta ================================================ fileFormatVersion: 2 guid: be39bc8579dccd14bb20b24e64a68faf MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaFieldWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class LuaInterface_LuaFieldWrap { public static void Register(LuaState L) { L.BeginClass(typeof(LuaInterface.LuaField), typeof(System.Object)); L.RegFunction("Get", Get); L.RegFunction("Set", Set); L.RegFunction("__tostring", ToLua.op_ToString); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Get(IntPtr L) { try { LuaField obj = (LuaField)ToLua.CheckObject(L, 1, typeof(LuaField)); return obj.Get(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Set(IntPtr L) { try { LuaField obj = (LuaField)ToLua.CheckObject(L, 1, typeof(LuaField)); return obj.Set(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaFieldWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 58e0ce586689f58419f26062891e1fc1 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaMethodWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class LuaInterface_LuaMethodWrap { public static void Register(LuaState L) { L.BeginClass(typeof(LuaInterface.LuaMethod), typeof(System.Object)); L.RegFunction("Destroy", Destroy); L.RegFunction("Call", Call); L.RegFunction("__tostring", ToLua.op_ToString); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Destroy(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); LuaMethod obj = (LuaMethod)ToLua.CheckObject(L, 1, typeof(LuaMethod)); obj.Destroy(); ToLua.Destroy(L); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Call(IntPtr L) { try { LuaMethod obj = (LuaMethod)ToLua.CheckObject(L, 1, typeof(LuaMethod)); return obj.Call(L); } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaMethodWrap.cs.meta ================================================ fileFormatVersion: 2 guid: bd62b7af99a9c284cb3b8c9c8a177e8c MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaOutWrap.cs ================================================ using System; using LuaInterface; public class LuaInterface_LuaOutWrap { public static void Register(LuaState L) { L.BeginPreLoad(); L.RegFunction("tolua.out", LuaOpen_ToLua_Out); L.EndPreLoad(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LuaOpen_ToLua_Out(IntPtr L) { try { LuaDLL.lua_newtable(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); RawSetOutType(L); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } static void RawSetOutType(IntPtr L) { string str = TypeTraits.GetTypeName(); LuaDLL.lua_pushstring(L, str); ToLua.PushOut(L, new LuaOut()); LuaDLL.lua_rawset(L, -3); } } ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaOutWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 6ba873a052f57bc45890275ec67bb4dc MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaPropertyWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class LuaInterface_LuaPropertyWrap { public static void Register(LuaState L) { L.BeginClass(typeof(LuaInterface.LuaProperty), typeof(System.Object)); L.RegFunction("Get", Get); L.RegFunction("Set", Set); L.RegFunction("__tostring", ToLua.op_ToString); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Get(IntPtr L) { try { LuaProperty obj = (LuaProperty)ToLua.CheckObject(L, 1, typeof(LuaProperty)); return obj.Get(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Set(IntPtr L) { try { LuaProperty obj = (LuaProperty)ToLua.CheckObject(L, 1, typeof(LuaProperty)); return obj.Set(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/BaseType/LuaInterface_LuaPropertyWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 5b401947a631ece4487e44f4b8ef9418 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_ArrayWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; using UnityEngine; public class System_ArrayWrap { public static void Register(LuaState L) { L.BeginClass(typeof(Array), typeof(System.Object)); L.RegFunction(".geti", get_Item); L.RegFunction("get", get_Item); L.RegFunction(".seti", set_Item); L.RegFunction("set", set_Item); L.RegFunction("ToTable", ToTable); L.RegFunction("GetLength", GetLength); L.RegFunction("GetLongLength", GetLongLength); L.RegFunction("GetLowerBound", GetLowerBound); L.RegFunction("GetValue", GetValue); L.RegFunction("SetValue", SetValue); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("GetUpperBound", GetUpperBound); L.RegFunction("CreateInstance", CreateInstance); L.RegFunction("BinarySearch", BinarySearch); L.RegFunction("Clear", Clear); L.RegFunction("Clone", Clone); L.RegFunction("Copy", Copy); L.RegFunction("IndexOf", IndexOf); L.RegFunction("Initialize", Initialize); L.RegFunction("LastIndexOf", LastIndexOf); L.RegFunction("Reverse", Reverse); L.RegFunction("Sort", Sort); L.RegFunction("CopyTo", CopyTo); L.RegFunction("ConstrainedCopy", ConstrainedCopy); L.RegFunction("__tostring", ToLua.op_ToString); L.RegFunction("__len", get_Length); L.RegVar("Length", get_Length, null); L.RegVar("LongLength", get_LongLength, null); L.RegVar("Rank", get_Rank, null); L.RegVar("IsSynchronized", get_IsSynchronized, null); L.RegVar("SyncRoot", get_SyncRoot, null); L.RegVar("IsFixedSize", get_IsFixedSize, null); L.RegVar("IsReadOnly", get_IsReadOnly, null); L.EndClass(); } static bool GetPrimitiveValue(IntPtr L, object obj, Type t, int index) { bool flag = true; if (t == typeof(System.Single)) { float[] array = obj as float[]; float ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else if (t == typeof(System.Int32)) { int[] array = obj as int[]; int ret = array[index]; LuaDLL.lua_pushinteger(L, ret); } else if (t == typeof(System.Double)) { double[] array = obj as double[]; double ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else if (t == typeof(System.Boolean)) { bool[] array = obj as bool[]; bool ret = array[index]; LuaDLL.lua_pushboolean(L, ret); } else if (t == typeof(System.Int64)) { long[] array = obj as long[]; long ret = array[index]; LuaDLL.tolua_pushint64(L, ret); } else if (t == typeof(System.UInt64)) { ulong[] array = obj as ulong[]; ulong ret = array[index]; LuaDLL.tolua_pushuint64(L, ret); } else if (t == typeof(System.SByte)) { sbyte[] array = obj as sbyte[]; sbyte ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else if (t == typeof(System.Byte)) { byte[] array = obj as byte[]; byte ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else if (t == typeof(System.Int16)) { short[] array = obj as short[]; short ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else if (t == typeof(System.UInt16)) { ushort[] array = obj as ushort[]; ushort ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else if (t == typeof(System.Char)) { char[] array = obj as char[]; char ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else if (t == typeof(System.UInt32)) { uint[] array = obj as uint[]; uint ret = array[index]; LuaDLL.lua_pushnumber(L, ret); } else { flag = false; } return flag; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Item(IntPtr L) { try { Array obj = ToLua.ToObject(L, 1) as Array; if (obj == null) { throw new LuaException("trying to index an invalid object reference"); } int index = (int)LuaDLL.lua_tointeger(L, 2); if (index >= obj.Length) { throw new LuaException("array index out of bounds: " + index + " " + obj.Length); } Type t = obj.GetType().GetElementType(); if (t.IsValueType) { if (t.IsPrimitive) { if (GetPrimitiveValue(L, obj, t, index)) { return 1; } } else if (t == typeof(Vector3)) { Vector3[] array = obj as Vector3[]; Vector3 ret = array[index]; ToLua.Push(L, ret); return 1; } else if (t == typeof(Quaternion)) { Quaternion[] array = obj as Quaternion[]; Quaternion ret = array[index]; ToLua.Push(L, ret); return 1; } else if (t == typeof(Vector2)) { Vector2[] array = obj as Vector2[]; Vector2 ret = array[index]; ToLua.Push(L, ret); return 1; } else if (t == typeof(Vector4)) { Vector4[] array = obj as Vector4[]; Vector4 ret = array[index]; ToLua.Push(L, ret); return 1; } else if (t == typeof(Color)) { Color[] array = obj as Color[]; Color ret = array[index]; ToLua.Push(L, ret); return 1; } } object val = obj.GetValue(index); ToLua.Push(L, val); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } static bool SetPrimitiveValue(IntPtr L, object obj, Type t, int index) { bool flag = true; if (t == typeof(System.Single)) { float[] array = obj as float[]; float val = (float)LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else if (t == typeof(System.Int32)) { int[] array = obj as int[]; int val = (int)LuaDLL.luaL_checkinteger(L, 3); array[index] = val; } else if (t == typeof(System.Double)) { double[] array = obj as double[]; double val = LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else if (t == typeof(System.Boolean)) { bool[] array = obj as bool[]; bool val = LuaDLL.luaL_checkboolean(L, 3); array[index] = val; } else if (t == typeof(System.Int64)) { long[] array = obj as long[]; long val = LuaDLL.tolua_toint64(L, 3); array[index] = val; } else if (t == typeof(System.UInt64)) { ulong[] array = obj as ulong[]; ulong val = LuaDLL.tolua_touint64(L, 3); array[index] = val; } else if (t == typeof(System.SByte)) { sbyte[] array = obj as sbyte[]; sbyte val = (sbyte)LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else if (t == typeof(System.Byte)) { byte[] array = obj as byte[]; byte val = (byte)LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else if (t == typeof(System.Int16)) { short[] array = obj as short[]; short val = (short)LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else if (t == typeof(System.UInt16)) { ushort[] array = obj as ushort[]; ushort val = (ushort)LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else if (t == typeof(System.Char)) { char[] array = obj as char[]; char val = (char)LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else if (t == typeof(System.UInt32)) { uint[] array = obj as uint[]; uint val = (uint)LuaDLL.luaL_checknumber(L, 3); array[index] = val; } else { flag = false; } return flag; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_Item(IntPtr L) { try { Array obj = ToLua.ToObject(L, 1) as Array; if (obj == null) { throw new LuaException("trying to index an invalid object reference"); } int index = (int)LuaDLL.lua_tointeger(L, 2); Type t = obj.GetType().GetElementType(); if (t.IsValueType) { if (t.IsPrimitive) { if (SetPrimitiveValue(L, obj, t, index)) { return 0; } } else if (t == typeof(Vector3)) { Vector3[] array = obj as Vector3[]; Vector3 val = ToLua.ToVector3(L, 3); array[index] = val; return 0; } else if (t == typeof(Quaternion)) { Quaternion[] array = obj as Quaternion[]; Quaternion val = ToLua.ToQuaternion(L, 3); array[index] = val; return 0; } else if (t == typeof(Vector2)) { Vector2[] array = obj as Vector2[]; Vector2 val = ToLua.ToVector2(L, 3); array[index] = val; return 0; } else if (t == typeof(Vector4)) { Vector4[] array = obj as Vector4[]; Vector4 val = ToLua.ToVector4(L, 3); array[index] = val; return 0; } else if (t == typeof(Color)) { Color[] array = obj as Color[]; Color val = ToLua.ToColor(L, 3); array[index] = val; return 0; } } if (!TypeChecker.CheckType(L, t, 3)) { return LuaDLL.luaL_typerror(L, 3, LuaMisc.GetTypeName(t)); } object v = ToLua.CheckVarObject(L, 3, t); v = TypeChecker.ChangeType(v, t); obj.SetValue(v, index); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Length(IntPtr L) { try { Array obj = ToLua.ToObject(L, 1) as Array; if (obj == null) { throw new LuaException("trying to index an invalid object reference"); } LuaDLL.lua_pushinteger(L, obj.Length); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToTable(IntPtr L) { try { Array obj = ToLua.ToObject(L, 1) as Array; if (obj == null) { throw new LuaException("trying to index an invalid object reference"); } LuaDLL.lua_createtable(L, obj.Length, 0); Type t = obj.GetType().GetElementType(); if (t.IsValueType) { if (t.IsPrimitive) { if (t == typeof(System.Single)) { float[] array = obj as float[]; for (int i = 0; i < array.Length; i++) { float ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.Int32)) { int[] array = obj as int[]; for (int i = 0; i < array.Length; i++) { int ret = array[i]; LuaDLL.lua_pushinteger(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.Double)) { double[] array = obj as double[]; for (int i = 0; i < array.Length; i++) { double ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.Boolean)) { bool[] array = obj as bool[]; for (int i = 0; i < array.Length; i++) { bool ret = array[i]; LuaDLL.lua_pushboolean(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.Int64)) { long[] array = obj as long[]; for (int i = 0; i < array.Length; i++) { long ret = array[i]; LuaDLL.tolua_pushint64(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.UInt64)) { ulong[] array = obj as ulong[]; for (int i = 0; i < array.Length; i++) { ulong ret = array[i]; LuaDLL.tolua_pushuint64(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.Byte)) { byte[] array = obj as byte[]; for (int i = 0; i < array.Length; i++) { byte ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.SByte)) { sbyte[] array = obj as sbyte[]; for (int i = 0; i < array.Length; i++) { sbyte ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.Char)) { char[] array = obj as char[]; for (int i = 0; i < array.Length; i++) { char ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.UInt32)) { uint[] array = obj as uint[]; for (int i = 0; i < array.Length; i++) { uint ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.Int16)) { short[] array = obj as short[]; for (int i = 0; i < array.Length; i++) { short ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(System.UInt16)) { ushort[] array = obj as ushort[]; for (int i = 0; i < array.Length; i++) { ushort ret = array[i]; LuaDLL.lua_pushnumber(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } } else if (t == typeof(Vector3)) { Vector3[] array = obj as Vector3[]; for (int i = 0; i < array.Length; i++) { Vector3 ret = array[i]; ToLua.Push(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(Quaternion)) { Quaternion[] array = obj as Quaternion[]; for (int i = 0; i < array.Length; i++) { Quaternion ret = array[i]; ToLua.Push(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(Vector2)) { Vector2[] array = obj as Vector2[]; for (int i = 0; i < array.Length; i++) { Vector2 ret = array[i]; ToLua.Push(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(Vector4)) { Vector4[] array = obj as Vector4[]; for (int i = 0; i < array.Length; i++) { Vector4 ret = array[i]; ToLua.Push(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } else if (t == typeof(Color)) { Color[] array = obj as Color[]; for (int i = 0; i < array.Length; i++) { Color ret = array[i]; ToLua.Push(L, ret); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } } for (int i = 0; i < obj.Length; i++) { object val = obj.GetValue(i); ToLua.Push(L, val); LuaDLL.lua_rawseti(L, -2, i + 1); } return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetLength(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = obj.GetLength(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetLongLength(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); long o = obj.GetLongLength(arg0); LuaDLL.lua_pushnumber(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetLowerBound(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = obj.GetLowerBound(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetValue(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); long arg0 = (long)LuaDLL.lua_tonumber(L, 2); object o = obj.GetValue(arg0); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); long arg0 = (long)LuaDLL.lua_tonumber(L, 2); long arg1 = (long)LuaDLL.lua_tonumber(L, 3); object o = obj.GetValue(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); object o = obj.GetValue(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); long arg0 = (long)LuaDLL.lua_tonumber(L, 2); long arg1 = (long)LuaDLL.lua_tonumber(L, 3); long arg2 = (long)LuaDLL.lua_tonumber(L, 4); object o = obj.GetValue(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); object o = obj.GetValue(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (TypeChecker.CheckParamsType(L, 2, count - 1)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); long[] arg0 = ToLua.ToParamsNumber(L, 2, count - 1); object o = obj.GetValue(arg0); ToLua.Push(L, o); return 1; } else if (TypeChecker.CheckParamsType(L, 2, count - 1)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); int[] arg0 = ToLua.ToParamsNumber(L, 2, count - 1); object o = obj.GetValue(arg0); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.GetValue"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int SetValue(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2, obj.GetType().GetElementType()); long arg1 = (long)LuaDLL.lua_tonumber(L, 3); obj.SetValue(arg0, arg1); return 0; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2, obj.GetType().GetElementType()); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); obj.SetValue(arg0, arg1, arg2); return 0; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2, obj.GetType().GetElementType()); long arg1 = (long)LuaDLL.lua_tonumber(L, 3); long arg2 = (long)LuaDLL.lua_tonumber(L, 4); obj.SetValue(arg0, arg1, arg2); return 0; } else if (count == 5 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2, obj.GetType().GetElementType()); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); int arg3 = (int)LuaDLL.lua_tonumber(L, 5); obj.SetValue(arg0, arg1, arg2, arg3); return 0; } else if (count == 5 && TypeChecker.CheckTypes(L, 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2, obj.GetType().GetElementType()); long arg1 = (long)LuaDLL.lua_tonumber(L, 3); long arg2 = (long)LuaDLL.lua_tonumber(L, 4); long arg3 = (long)LuaDLL.lua_tonumber(L, 5); obj.SetValue(arg0, arg1, arg2, arg3); return 0; } else if (TypeChecker.CheckTypes(L, 2) && TypeChecker.CheckParamsType(L, 3, count - 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2, obj.GetType().GetElementType()); long[] arg1 = ToLua.ToParamsNumber(L, 3, count - 2); obj.SetValue(arg0, arg1); return 0; } else if (TypeChecker.CheckTypes(L, 2) && TypeChecker.CheckParamsType(L, 3, count - 2)) { System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2, obj.GetType().GetElementType()); int[] arg1 = ToLua.ToParamsNumber(L, 3, count - 2); obj.SetValue(arg0, arg1); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.SetValue"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); System.Collections.IEnumerator o = obj.GetEnumerator(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetUpperBound(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = obj.GetUpperBound(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CreateInstance(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); System.Array o = System.Array.CreateInstance(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); int[] arg1 = ToLua.CheckNumberArray(L, 2); int[] arg2 = ToLua.CheckNumberArray(L, 3); System.Array o = System.Array.CreateInstance(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); int arg2 = (int)LuaDLL.lua_tonumber(L, 3); System.Array o = System.Array.CreateInstance(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); int arg2 = (int)LuaDLL.lua_tonumber(L, 3); int arg3 = (int)LuaDLL.lua_tonumber(L, 4); System.Array o = System.Array.CreateInstance(arg0, arg1, arg2, arg3); ToLua.Push(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); long[] arg1 = ToLua.ToParamsNumber(L, 2, count - 1); System.Array o = System.Array.CreateInstance(arg0, arg1); ToLua.Push(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); int[] arg1 = ToLua.ToParamsNumber(L, 2, count - 1); System.Array o = System.Array.CreateInstance(arg0, arg1); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.CreateInstance"); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int BinarySearch(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); int o = System.Array.BinarySearch(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); System.Collections.IComparer arg2 = (System.Collections.IComparer)ToLua.CheckObject(L, 3); int o = System.Array.BinarySearch(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); object arg3 = ToLua.ToVarObject(L, 4, arg0.GetType().GetElementType()); int o = System.Array.BinarySearch(arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 5) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); object arg3 = ToLua.ToVarObject(L, 4, arg0.GetType().GetElementType()); System.Collections.IComparer arg4 = (System.Collections.IComparer)ToLua.CheckObject(L, 5); int o = System.Array.BinarySearch(arg0, arg1, arg2, arg3, arg4); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.BinarySearch"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Clear(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1, typeof(System.Array)); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); System.Array.Clear(arg0, arg1, arg2); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Clone(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); object o = obj.Clone(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Copy(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Array arg1 = (System.Array)ToLua.CheckObject(L, 2); long arg2 = LuaDLL.tolua_checkint64(L, 3); System.Array.Copy(arg0, arg1, arg2); return 0; } else if (count == 5 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); long arg1 = LuaDLL.tolua_toint64(L, 2); System.Array arg2 = (System.Array)ToLua.ToObject(L, 3); long arg3 = LuaDLL.tolua_toint64(L, 4); long arg4 = LuaDLL.tolua_toint64(L, 5); System.Array.Copy(arg0, arg1, arg2, arg3, arg4); return 0; } else if (count == 5 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); System.Array arg2 = (System.Array)ToLua.ToObject(L, 3); int arg3 = (int)LuaDLL.lua_tonumber(L, 4); int arg4 = (int)LuaDLL.lua_tonumber(L, 5); System.Array.Copy(arg0, arg1, arg2, arg3, arg4); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.Copy"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IndexOf(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); int o = System.Array.IndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); int o = System.Array.IndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int o = System.Array.IndexOf(arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.IndexOf"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Initialize(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); obj.Initialize(); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LastIndexOf(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); int o = System.Array.LastIndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); int o = System.Array.LastIndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2, arg0.GetType().GetElementType()); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int o = System.Array.LastIndexOf(arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.LastIndexOf"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Reverse(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Array.Reverse(arg0); return 0; } else if (count == 3) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); System.Array.Reverse(arg0, arg1, arg2); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.Reverse"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Sort(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Array.Sort(arg0); return 0; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Collections.IComparer arg1 = (System.Collections.IComparer)ToLua.ToObject(L, 2); System.Array.Sort(arg0, arg1); return 0; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Array arg1 = (System.Array)ToLua.ToObject(L, 2); System.Array.Sort(arg0, arg1); return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Array arg1 = (System.Array)ToLua.ToObject(L, 2); System.Collections.IComparer arg2 = (System.Collections.IComparer)ToLua.ToObject(L, 3); System.Array.Sort(arg0, arg1, arg2); return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); int arg2 = (int)LuaDLL.lua_tonumber(L, 3); System.Array.Sort(arg0, arg1, arg2); return 0; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); int arg2 = (int)LuaDLL.lua_tonumber(L, 3); System.Collections.IComparer arg3 = (System.Collections.IComparer)ToLua.ToObject(L, 4); System.Array.Sort(arg0, arg1, arg2, arg3); return 0; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Array arg1 = (System.Array)ToLua.ToObject(L, 2); int arg2 = (int)LuaDLL.lua_tonumber(L, 3); int arg3 = (int)LuaDLL.lua_tonumber(L, 4); System.Array.Sort(arg0, arg1, arg2, arg3); return 0; } else if (count == 5) { System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); System.Array arg1 = (System.Array)ToLua.CheckObject(L, 2); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); System.Collections.IComparer arg4 = (System.Collections.IComparer)ToLua.CheckObject(L, 5); System.Array.Sort(arg0, arg1, arg2, arg3, arg4); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Array.Sort"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Array obj = (System.Array)ToLua.CheckObject(L, 1); System.Array arg0 = (System.Array)ToLua.CheckObject(L, 2); long arg1 = (long)LuaDLL.luaL_checknumber(L, 3); obj.CopyTo(arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ConstrainedCopy(IntPtr L) { try { ToLua.CheckArgsCount(L, 5); System.Array arg0 = (System.Array)ToLua.CheckObject(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); System.Array arg2 = (System.Array)ToLua.CheckObject(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int arg4 = (int)LuaDLL.luaL_checknumber(L, 5); System.Array.ConstrainedCopy(arg0, arg1, arg2, arg3, arg4); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_LongLength(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Array obj = (System.Array)o; long ret = obj.LongLength; LuaDLL.lua_pushnumber(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index LongLength on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Rank(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Array obj = (System.Array)o; int ret = obj.Rank; LuaDLL.lua_pushinteger(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Rank on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsSynchronized(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Array obj = (System.Array)o; bool ret = obj.IsSynchronized; LuaDLL.lua_pushboolean(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsSynchronized on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_SyncRoot(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Array obj = (System.Array)o; object ret = obj.SyncRoot; ToLua.Push(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index SyncRoot on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsFixedSize(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Array obj = (System.Array)o; bool ret = obj.IsFixedSize; LuaDLL.lua_pushboolean(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsFixedSize on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsReadOnly(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Array obj = (System.Array)o; bool ret = obj.IsReadOnly; LuaDLL.lua_pushboolean(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsReadOnly on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_ArrayWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 270e5e13dbb276c47a14c00ec09f9254 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_DictionaryWrap.cs ================================================ using System; using LuaInterface; using System.Collections.Generic; using System.Runtime.Serialization; using System.Collections; public class System_Collections_Generic_DictionaryWrap { public static void Register(LuaState L) { L.BeginClass(typeof(Dictionary<,>), typeof(System.Object), "Dictionary"); L.RegFunction("get_Item", get_Item); L.RegFunction("get", get_Item); L.RegFunction("set_Item", set_Item); L.RegFunction("set", set_Item); L.RegFunction(".geti", _geti); L.RegFunction(".seti", _seti); L.RegFunction("Add", Add); L.RegFunction("Clear", Clear); L.RegFunction("ContainsKey", ContainsKey); L.RegFunction("ContainsValue", ContainsValue); L.RegFunction("GetObjectData", GetObjectData); L.RegFunction("OnDeserialization", OnDeserialization); L.RegFunction("Remove", Remove); L.RegFunction("TryGetValue", TryGetValue); L.RegFunction("GetEnumerator", GetEnumerator); L.RegVar("this", _this, null); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Count", get_Count, null); L.RegVar("Comparer", get_Comparer, null); L.RegVar("Keys", get_Keys, null); L.RegVar("Values", get_Values, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _get_this(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type kt = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt); object arg0 = ToLua.CheckVarObject(L, 2, kt); object o = LuaMethodCache.CallSingleMethod("get_Item", obj, arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _set_this(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type kt, vt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt, out vt); object arg0 = ToLua.CheckVarObject(L, 2, kt); object arg1 = ToLua.CheckVarObject(L, 3, vt); LuaMethodCache.CallSingleMethod("set_Item", obj, arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _this(IntPtr L) { try { LuaDLL.lua_pushvalue(L, 1); LuaDLL.tolua_bindthis(L, _get_this, _set_this); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Item(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type kt = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt); object arg0 = ToLua.CheckVarObject(L, 2, kt); object o = LuaMethodCache.CallSingleMethod("get_Item", obj, arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_Item(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type kt, vt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt, out vt); object arg0 = ToLua.CheckVarObject(L, 2, kt); object arg1 = ToLua.CheckVarObject(L, 3, vt); LuaMethodCache.CallSingleMethod("set_Item", obj, arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _geti(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type kt = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt); if (kt != typeof(int)) { LuaDLL.lua_pushnil(L); } else { object arg0 = ToLua.CheckVarObject(L, 2, kt); object o = LuaMethodCache.CallSingleMethod("get_Item", obj, arg0); ToLua.Push(L, o); } return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _seti(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type kt, vt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt, out vt); if (kt == typeof(int)) { object arg0 = ToLua.CheckVarObject(L, 2, kt); object arg1 = ToLua.CheckVarObject(L, 3, vt); LuaMethodCache.CallSingleMethod("set_Item", obj, arg0, arg1); } return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Add(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type kt, vt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt, out vt); object arg0 = ToLua.CheckVarObject(L, 2, kt); object arg1 = ToLua.CheckVarObject(L, 3, vt); LuaMethodCache.CallSingleMethod("Add", obj, arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Clear(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>)); LuaMethodCache.CallSingleMethod("Clear", obj); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ContainsKey(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type kt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt); object arg0 = ToLua.CheckVarObject(L, 2, kt); bool o = (bool)LuaMethodCache.CallSingleMethod("ContainsKey", obj, arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ContainsValue(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type kt, vt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt, out vt); object arg0 = ToLua.CheckVarObject(L, 2, vt); bool o = (bool)LuaMethodCache.CallSingleMethod("ContainsValue", obj, arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetObjectData(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>)); SerializationInfo arg0 = (SerializationInfo)ToLua.CheckObject(L, 2, typeof(SerializationInfo)); StreamingContext arg1 = (StreamingContext)ToLua.CheckObject(L, 3, typeof(StreamingContext)); LuaMethodCache.CallSingleMethod("GetObjectData", obj, arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int OnDeserialization(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>)); object arg0 = ToLua.ToVarObject(L, 2); LuaMethodCache.CallSingleMethod("OnDeserialization", obj, arg0); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Remove(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type kt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt); object arg0 = ToLua.CheckVarObject(L, 2, kt); bool o = (bool)LuaMethodCache.CallSingleMethod("Remove", obj, arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TryGetValue(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type kt; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>), out kt); object arg0 = ToLua.CheckVarObject(L, 2, kt); object arg1 = null; object[] args = new object[] { arg0, arg1 }; bool o = (bool)LuaMethodCache.CallSingleMethod("TryGetValue", obj, args); LuaDLL.lua_pushboolean(L, o); ToLua.Push(L, args[1]); return 2; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>)); IEnumerator o = (IEnumerator)LuaMethodCache.CallSingleMethod("GetEnumerator", obj); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); int ret = (int)LuaMethodCache.CallSingleMethod("get_Count", o); LuaDLL.lua_pushinteger(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Comparer(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); object ret = LuaMethodCache.CallSingleMethod("get_Comparer", o); ToLua.PushObject(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Comparer on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Keys(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); object ret = LuaMethodCache.CallSingleMethod("get_Keys", o); ToLua.PushObject(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Keys on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Values(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); object ret = LuaMethodCache.CallSingleMethod("get_Values", o); ToLua.PushObject(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Values on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_DictionaryWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 973a63c864c67f34b852be1021aa8445 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_Dictionary_KeyCollectionWrap.cs ================================================ using System; using LuaInterface; using System.Collections.Generic; using System.Collections; public class System_Collections_Generic_Dictionary_KeyCollectionWrap { public static void Register(LuaState L) { L.BeginClass(typeof(Dictionary<,>.KeyCollection), typeof(System.Object), "KeyCollection"); L.RegFunction("CopyTo", CopyTo); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("New", _CreateSystem_Collections_Generic_Dictionary_KeyCollection); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Count", get_Count, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_Collections_Generic_Dictionary_KeyCollection(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { object arg0 = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>)); Type kc = arg0.GetType().GetNestedType("KeyCollection"); object obj = Activator.CreateInstance(kc, arg0); ToLua.PushObject(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: System.Collections.Generic.Dictionary.KeyCollection.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type kt = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>.KeyCollection), out kt); object arg0 = ToLua.CheckObject(L, 2, kt.MakeArrayType()); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); LuaMethodCache.CallSingleMethod("CopyTo", obj, arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>.KeyCollection)); IEnumerator o = (IEnumerator)LuaMethodCache.CallSingleMethod("GetEnumerator", obj); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); int ret = (int)LuaMethodCache.CallSingleMethod("get_Count", o); LuaDLL.lua_pushinteger(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_Dictionary_KeyCollectionWrap.cs.meta ================================================ fileFormatVersion: 2 guid: b5a969e41ba260d4197ec05de2e0b107 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_Dictionary_ValueCollectionWrap.cs ================================================ using System; using LuaInterface; using System.Collections.Generic; using System.Collections; public class System_Collections_Generic_Dictionary_ValueCollectionWrap { public static void Register(LuaState L) { L.BeginClass(typeof(Dictionary<,>.ValueCollection), typeof(System.Object), "ValueCollection"); L.RegFunction("CopyTo", CopyTo); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("New", _CreateSystem_Collections_Generic_Dictionary_ValueCollection); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Count", get_Count, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_Collections_Generic_Dictionary_ValueCollection(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { object arg0 = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>)); Type kv = arg0.GetType().GetNestedType("ValueCollection"); object obj = Activator.CreateInstance(kv, arg0); ToLua.PushObject(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: System.Collections.Generic.Dictionary.ValueCollection.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type kt, kv; object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>.ValueCollection), out kt, out kv); object arg0 = ToLua.CheckObject(L, 2, kv.MakeArrayType()); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); LuaMethodCache.CallSingleMethod("CopyTo", obj, arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(Dictionary<,>.ValueCollection)); IEnumerator o = (IEnumerator)LuaMethodCache.CallSingleMethod("GetEnumerator", obj); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); int ret = (int)LuaMethodCache.CallSingleMethod("get_Count", o); LuaDLL.lua_pushinteger(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_Dictionary_ValueCollectionWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 8b073f28ab535d6478ab1e2f76f44547 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_KeyValuePairWrap.cs ================================================ using System; using LuaInterface; using System.Collections.Generic; public class System_Collections_Generic_KeyValuePairWrap { public static void Register(LuaState L) { L.BeginClass(typeof(KeyValuePair<,>), null, "KeyValuePair"); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Key", get_Key, null); L.RegVar("Value", get_Value, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Key(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); object ret = LuaMethodCache.CallSingleMethod("get_Key", o); ToLua.Push(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Key on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Value(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); object ret = LuaMethodCache.CallSingleMethod("get_Value", o); ToLua.Push(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Value on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_KeyValuePairWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 2bfe26e81faf9a1498eaae521869ecea MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_ListWrap.cs ================================================ using System; using LuaInterface; using System.Collections.Generic; using System.Reflection; using UnityEngine; using System.Collections; public class System_Collections_Generic_ListWrap { public static void Register(LuaState L) { L.BeginClass(typeof(List<>), typeof(System.Object), "List"); L.RegFunction("Add", Add); L.RegFunction("AddRange", AddRange); L.RegFunction("AsReadOnly", AsReadOnly); L.RegFunction("BinarySearch", BinarySearch); L.RegFunction("Clear", Clear); L.RegFunction("Contains", Contains); L.RegFunction("CopyTo", CopyTo); L.RegFunction("Exists", Exists); L.RegFunction("Find", Find); L.RegFunction("FindAll", FindAll); L.RegFunction("FindIndex", FindIndex); L.RegFunction("FindLast", FindLast); L.RegFunction("FindLastIndex", FindLastIndex); L.RegFunction("ForEach", ForEach); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("GetRange", GetRange); L.RegFunction("IndexOf", IndexOf); L.RegFunction("Insert", Insert); L.RegFunction("InsertRange", InsertRange); L.RegFunction("LastIndexOf", LastIndexOf); L.RegFunction("Remove", Remove); L.RegFunction("RemoveAll", RemoveAll); L.RegFunction("RemoveAt", RemoveAt); L.RegFunction("RemoveRange", RemoveRange); L.RegFunction("Reverse", Reverse); L.RegFunction("Sort", Sort); L.RegFunction("ToArray", ToArray); L.RegFunction("TrimExcess", TrimExcess); L.RegFunction("TrueForAll", TrueForAll); L.RegFunction("get_Item", get_Item); L.RegFunction("get", get_Item); L.RegFunction("set_Item", set_Item); L.RegFunction("set", set_Item); L.RegFunction(".geti", get_Item); L.RegFunction(".seti", set_Item); L.RegFunction("__tostring", ToLua.op_ToString); L.RegFunction("__len", get_Count); L.RegVar("Capacity", get_Capacity, set_Capacity); L.RegVar("Count", get_Count, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Add(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); object arg0 = ToLua.CheckVarObject(L, 2, argType); LuaMethodCache.CallSingleMethod("Add", obj, arg0); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int AddRange(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); object arg0 = ToLua.CheckObject(L, 2, typeof(IEnumerable<>).MakeGenericType(argType)); LuaMethodCache.CallSingleMethod("AddRange", obj, arg0); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int AsReadOnly(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); object o = LuaMethodCache.CallSingleMethod("AsReadOnly", obj); ToLua.Push(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int BinarySearch(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 2) { object arg0 = ToLua.CheckVarObject(L, 2, argType); int o = (int)LuaMethodCache.CallMethod("BinarySearch", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { object arg0 = ToLua.CheckVarObject(L, 2, argType); object arg1 = ToLua.CheckObject(L, 3, typeof(IComparer<>).MakeGenericType(argType)); int o = (int)LuaMethodCache.CallMethod("BinarySearch", obj, arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 5) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); object arg2 = ToLua.CheckVarObject(L, 4, argType); object arg3 = ToLua.CheckObject(L, 5, typeof(IComparer<>).MakeGenericType(argType)); int o = (int)LuaMethodCache.CallMethod("BinarySearch", obj, arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.BinarySearch", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Clear(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); LuaMethodCache.CallSingleMethod("Clear", obj); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Contains(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); object arg0 = ToLua.CheckVarObject(L, 2, argType); object o = LuaMethodCache.CallSingleMethod("Contains", obj, arg0); LuaDLL.lua_pushboolean(L, (bool)o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 2) { object arg0 = ToLua.CheckObject(L, 2, argType.MakeArrayType()); LuaMethodCache.CallMethod("CopyTo", obj, arg0); return 0; } else if (count == 3) { object arg0 = ToLua.CheckObject(L, 2, argType.MakeArrayType()); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); LuaMethodCache.CallMethod("CopyTo", obj, arg0, arg1); return 0; } else if (count == 5) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); object arg1 = ToLua.CheckObject(L, 3, argType.MakeArrayType()); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); int arg3 = (int)LuaDLL.luaL_checknumber(L, 5); LuaMethodCache.CallMethod("CopyTo", obj, arg0, arg1, arg2, arg3); return 0; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.CopyTo", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Exists(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); Delegate arg0 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 2); bool o = (bool)LuaMethodCache.CallMethod("Exists", obj, arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Find(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); Delegate arg0 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 2); object o = LuaMethodCache.CallMethod("Find", obj, arg0); ToLua.Push(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindAll(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); Delegate arg0 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 2); object o = LuaMethodCache.CallMethod("FindAll", obj, arg0); ToLua.Push(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindIndex(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 2) { Delegate arg0 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 2); int o = (int)LuaMethodCache.CallMethod("FindIndex", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); Delegate arg1 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 3); int o = (int)LuaMethodCache.CallMethod("FindIndex", obj, arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); Delegate arg2 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 4); int o = (int)LuaMethodCache.CallMethod("FindIndex", obj, arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.FindIndex", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindLast(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); Delegate arg0 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 2); object o = LuaMethodCache.CallSingleMethod("FindLast", obj, arg0); ToLua.Push(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindLastIndex(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 2) { Delegate arg0 = (Delegate)ToLua.CheckObject(L, 2, typeof(System.Predicate<>).MakeGenericType(argType)); int o = (int)LuaMethodCache.CallMethod("FindLastIndex", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); Delegate arg1 = (Delegate)ToLua.CheckObject(L, 3, typeof(System.Predicate<>).MakeGenericType(argType)); int o = (int)LuaMethodCache.CallMethod("FindLastIndex", obj, arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); Delegate arg2 = (Delegate)ToLua.CheckObject(L, 4, typeof(System.Predicate<>).MakeGenericType(argType)); int o = (int)LuaMethodCache.CallMethod("FindLastIndex", obj, arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.FindLastIndex", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ForEach(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); Delegate arg0 = ToLua.CheckDelegate(typeof(System.Action<>).MakeGenericType(argType), L, 2); LuaMethodCache.CallSingleMethod("ForEach", obj, arg0); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); IEnumerator o = LuaMethodCache.CallSingleMethod("GetEnumerator", obj) as IEnumerator; ToLua.Push(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetRange(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); object o = LuaMethodCache.CallSingleMethod("GetRange", obj, arg0, arg1); ToLua.PushObject(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IndexOf(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 2) { object arg0 = ToLua.CheckVarObject(L, 2, argType); int o = (int)LuaMethodCache.CallMethod("IndexOf", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { object arg0 = ToLua.CheckVarObject(L, 2, argType); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int o = (int)LuaMethodCache.CallMethod("IndexOf", obj, arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { object arg0 = ToLua.CheckVarObject(L, 2, argType); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); int o = (int)LuaMethodCache.CallMethod("IndexOf", obj, arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.IndexOf", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Insert(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); object arg1 = ToLua.CheckVarObject(L, 3, argType); LuaMethodCache.CallSingleMethod("Insert", obj, arg0, arg1); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int InsertRange(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); IEnumerable arg1 = (IEnumerable)ToLua.CheckObject(L, 3, typeof(IEnumerable<>).MakeGenericType(argType)); LuaMethodCache.CallSingleMethod("InsertRange", obj, arg0, arg1); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LastIndexOf(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 2) { object arg0 = ToLua.CheckVarObject(L, 2, argType); int o = (int)LuaMethodCache.CallMethod("LastIndexOf", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { object arg0 = ToLua.CheckVarObject(L, 2, argType); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int o = (int)LuaMethodCache.CallMethod("LastIndexOf", obj, arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { object arg0 = ToLua.CheckVarObject(L, 2, argType); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); int o = (int)LuaMethodCache.CallMethod("LastIndexOf", obj, arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.LastIndexOf", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Remove(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); object arg0 = ToLua.CheckVarObject(L, 2, argType); bool o = (bool)LuaMethodCache.CallSingleMethod("Remove", obj, arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int RemoveAll(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); Delegate arg0 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 2); int o = (int)LuaMethodCache.CallSingleMethod("RemoveAll", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int RemoveAt(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); LuaMethodCache.CallSingleMethod("RemoveAt", obj, arg0); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int RemoveRange(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); LuaMethodCache.CallSingleMethod("RemoveRange", obj, arg0, arg1); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Reverse(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 1) { LuaMethodCache.CallMethod("Reverse", obj); return 0; } else if (count == 3) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); LuaMethodCache.CallMethod("Reverse", obj, arg0, arg1); return 0; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.LastIndexOf", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Sort(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); if (count == 1) { LuaMethodCache.CallMethod("Sort", obj); return 0; } else if (count == 2 && TypeChecker.CheckTypes(L, 2, typeof(System.Comparison<>).MakeGenericType(argType))) { Delegate arg0 = (Delegate)ToLua.ToObject(L, 2); LuaMethodCache.CallMethod("Sort", obj, arg0); return 0; } else if (count == 2 && TypeChecker.CheckTypes(L, 2, typeof(IComparer<>).MakeGenericType(argType))) { object arg0 = ToLua.ToObject(L, 2); LuaMethodCache.CallMethod("Sort", obj, arg0); return 0; } else if (count == 4) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); object arg2 = ToLua.CheckObject(L, 4, typeof(IComparer<>).MakeGenericType(argType)); LuaMethodCache.CallMethod("Sort", obj, arg0, arg1, arg2); return 0; } else { return LuaDLL.luaL_throw(L, string.Format("invalid arguments to method: List<{0}>.LastIndexOf", LuaMisc.GetTypeName(argType))); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToArray(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); Array o = (Array)LuaMethodCache.CallSingleMethod("ToArray", obj); ToLua.Push(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TrimExcess(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); LuaMethodCache.CallSingleMethod("TrimExcess", obj); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TrueForAll(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); Delegate arg0 = ToLua.CheckDelegate(typeof(System.Predicate<>).MakeGenericType(argType), L, 2); bool o = (bool)LuaMethodCache.CallSingleMethod("TrueForAll", obj, arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Item(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); object o = LuaMethodCache.CallSingleMethod("get_Item", obj, arg0); ToLua.Push(L, o); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_Item(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(List<>), out argType); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); object arg1 = ToLua.CheckObject(L, 3, argType); LuaMethodCache.CallSingleMethod("set_Item", obj, arg0, arg1); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Capacity(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); int ret = (int)LuaMethodCache.CallSingleMethod("get_Capacity", o); LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Capacity on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); int ret = (int)LuaMethodCache.CallSingleMethod("get_Count", o); LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_Capacity(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); LuaMethodCache.CallSingleMethod("set_Capacity", o, arg0); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Capacity on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_Collections_Generic_ListWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 9806172156647e244b2fb905a4d02611 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_Collections_IEnumeratorWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_Collections_IEnumeratorWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Collections.IEnumerator), null); L.RegFunction("MoveNext", MoveNext); L.RegFunction("Reset", Reset); L.RegVar("Current", get_Current, null); L.RegFunction("getCurrent", get_Current); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int MoveNext(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Collections.IEnumerator obj = ToLua.CheckIter(L, 1); bool o = obj.MoveNext(); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Reset(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Collections.IEnumerator obj = ToLua.CheckIter(L, 1); obj.Reset(); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Current(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.IEnumerator obj = (System.Collections.IEnumerator)o; object ret = obj.Current; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Current on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_Collections_IEnumeratorWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 7eaa472c4f36f9d419d9bf704795f0d6 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_Collections_ObjectModel_ReadOnlyCollectionWrap.cs ================================================ using System; using LuaInterface; using System.Collections.ObjectModel; using System.Collections; public class System_Collections_ObjectModel_ReadOnlyCollectionWrap { public static void Register(LuaState L) { L.BeginClass(typeof(ReadOnlyCollection<>), typeof(System.Object), "ReadOnlyCollection"); L.RegFunction("Contains", Contains); L.RegFunction("CopyTo", CopyTo); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("IndexOf", IndexOf); L.RegFunction(".geti", get_Item); L.RegFunction("get_Item", get_Item); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Count", get_Count, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Contains(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(ReadOnlyCollection<>), out argType); object arg0 = ToLua.CheckVarObject(L, 2, argType); bool o = (bool)LuaMethodCache.CallSingleMethod("Contains", obj, arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(ReadOnlyCollection<>), out argType); object arg0 = ToLua.CheckObject(L, 2, argType.MakeArrayType()); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); LuaMethodCache.CallSingleMethod("CopyTo", obj, arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckGenericObject(L, 1, typeof(ReadOnlyCollection<>)); IEnumerator o = (IEnumerator)LuaMethodCache.CallSingleMethod("GetEnumerator", obj); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IndexOf(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Type argType = null; object obj = ToLua.CheckGenericObject(L, 1, typeof(ReadOnlyCollection<>), out argType); object arg0 = ToLua.CheckVarObject(L, 2, argType); int o = (int)LuaMethodCache.CallSingleMethod("IndexOf", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Item(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object obj = ToLua.CheckGenericObject(L, 1, typeof(ReadOnlyCollection<>)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = (int)LuaMethodCache.CallSingleMethod("get_Item", obj, arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); int ret = (int)LuaMethodCache.CallSingleMethod("get_Count", o); LuaDLL.lua_pushinteger(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_Collections_ObjectModel_ReadOnlyCollectionWrap.cs.meta ================================================ fileFormatVersion: 2 guid: fa5b181e2942520408fb4d6bac615d4f MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_DelegateWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using System.Collections.Generic; using LuaInterface; public class System_DelegateWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Delegate), typeof(System.Object)); L.RegFunction("CreateDelegate", CreateDelegate); L.RegFunction("DynamicInvoke", DynamicInvoke); L.RegFunction("Clone", Clone); L.RegFunction("GetObjectData", GetObjectData); L.RegFunction("GetInvocationList", GetInvocationList); L.RegFunction("Combine", Combine); L.RegFunction("Remove", Remove); L.RegFunction("RemoveAll", RemoveAll); L.RegFunction("Destroy", Destroy); L.RegFunction("GetHashCode", GetHashCode); L.RegFunction("Equals", Equals); L.RegFunction("__add", op_Addition); L.RegFunction("__sub", op_Subtraction); L.RegFunction("__eq", op_Equality); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Method", get_Method, null); L.RegFunction("getMethod", get_Method); L.RegVar("Target", get_Target, null); L.RegFunction("getTarget", get_Target); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CreateDelegate(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.Type arg0 = ToLua.CheckMonoType(L, 1); System.Reflection.MethodInfo arg1 = (System.Reflection.MethodInfo)ToLua.CheckObject(L, 2); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); System.Reflection.MethodInfo arg1 = (System.Reflection.MethodInfo)ToLua.ToObject(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); System.Type arg1 = (System.Type)ToLua.ToObject(L, 2); string arg2 = ToLua.ToString(L, 3); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); System.Reflection.MethodInfo arg2 = (System.Reflection.MethodInfo)ToLua.ToObject(L, 3); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); string arg2 = ToLua.ToString(L, 3); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); System.Type arg1 = (System.Type)ToLua.ToObject(L, 2); string arg2 = ToLua.ToString(L, 3); bool arg3 = LuaDLL.lua_toboolean(L, 4); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2, arg3); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); System.Reflection.MethodInfo arg2 = (System.Reflection.MethodInfo)ToLua.ToObject(L, 3); bool arg3 = LuaDLL.lua_toboolean(L, 4); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2, arg3); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); string arg2 = ToLua.ToString(L, 3); bool arg3 = LuaDLL.lua_toboolean(L, 4); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2, arg3); ToLua.Push(L, o); return 1; } else if (count == 5 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); System.Type arg1 = (System.Type)ToLua.ToObject(L, 2); string arg2 = ToLua.ToString(L, 3); bool arg3 = LuaDLL.lua_toboolean(L, 4); bool arg4 = LuaDLL.lua_toboolean(L, 5); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2, arg3, arg4); ToLua.Push(L, o); return 1; } else if (count == 5 && TypeChecker.CheckTypes(L, 2)) { System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); string arg2 = ToLua.ToString(L, 3); bool arg3 = LuaDLL.lua_toboolean(L, 4); bool arg4 = LuaDLL.lua_toboolean(L, 5); System.Delegate o = System.Delegate.CreateDelegate(arg0, arg1, arg2, arg3, arg4); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Delegate.CreateDelegate"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int DynamicInvoke(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); System.Delegate obj = (System.Delegate)ToLua.CheckObject(L, 1); object[] arg0 = ToLua.ToParamsObject(L, 2, count - 1); object o = obj.DynamicInvoke(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Clone(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Delegate obj = (System.Delegate)ToLua.CheckObject(L, 1); object o = obj.Clone(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetObjectData(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Delegate obj = (System.Delegate)ToLua.CheckObject(L, 1); System.Runtime.Serialization.SerializationInfo arg0 = (System.Runtime.Serialization.SerializationInfo)ToLua.CheckObject(L, 2, typeof(System.Runtime.Serialization.SerializationInfo)); System.Runtime.Serialization.StreamingContext arg1 = StackTraits.Check(L, 3); obj.GetObjectData(arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetInvocationList(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Delegate obj = (System.Delegate)ToLua.CheckObject(L, 1); System.Delegate[] o = obj.GetInvocationList(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Combine(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Delegate arg0 = (System.Delegate)ToLua.ToObject(L, 1); System.Delegate arg1 = (System.Delegate)ToLua.ToObject(L, 2); System.Delegate o = System.Delegate.Combine(arg0, arg1); ToLua.Push(L, o); return 1; } else if (TypeChecker.CheckParamsType(L, 1, count)) { System.Delegate[] arg0 = ToLua.ToParamsObject(L, 1, count); System.Delegate o = System.Delegate.Combine(arg0); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Delegate.Combine"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Remove(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Delegate arg0 = (System.Delegate)ToLua.CheckObject(L, 1); System.Delegate arg1 = (System.Delegate)ToLua.CheckObject(L, 2); System.Delegate o = System.Delegate.Remove(arg0, arg1); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int RemoveAll(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Delegate arg0 = (System.Delegate)ToLua.CheckObject(L, 1); System.Delegate arg1 = (System.Delegate)ToLua.CheckObject(L, 2); System.Delegate o = System.Delegate.RemoveAll(arg0, arg1); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Destroy(IntPtr L) { Delegate arg0 = (Delegate)ToLua.CheckObject(L, 1); Delegate[] ds = arg0.GetInvocationList(); for (int i = 0; i < ds.Length; i++) { LuaDelegate ld = ds[i].Target as LuaDelegate; if (ld != null) { ld.Dispose(); } } return 0; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetHashCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Delegate obj = (System.Delegate)ToLua.CheckObject(L, 1); int o = obj.GetHashCode(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Equals(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Delegate obj = (System.Delegate)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Subtraction(IntPtr L) { try { Delegate arg0 = (Delegate)ToLua.CheckObject(L, 1); LuaTypes type = LuaDLL.lua_type(L, 2); if (type == LuaTypes.LUA_TFUNCTION) { LuaState state = LuaState.Get(L); LuaFunction func = ToLua.ToLuaFunction(L, 2); Delegate[] ds = arg0.GetInvocationList(); for (int i = 0; i < ds.Length; i++) { LuaDelegate ld = ds[i].Target as LuaDelegate; if (ld != null && ld.func == func && ld.self == null) { arg0 = Delegate.Remove(arg0, ds[i]); state.DelayDispose(ld.func); break; } } func.Dispose(); ToLua.Push(L, arg0); return 1; } else { Delegate arg1 = (Delegate)ToLua.CheckObject(L, 2); arg0 = DelegateFactory.RemoveDelegate(arg0, arg1); ToLua.Push(L, arg0); return 1; } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Addition(IntPtr L) { try { LuaTypes type = LuaDLL.lua_type(L, 1); switch (type) { case LuaTypes.LUA_TFUNCTION: Delegate arg0 = ToLua.ToObject(L, 2) as Delegate; LuaFunction func = ToLua.ToLuaFunction(L, 1); Type t = arg0.GetType(); Delegate arg1 = DelegateFactory.CreateDelegate(t, func); Delegate arg2 = Delegate.Combine(arg0, arg1); ToLua.Push(L, arg2); return 1; case LuaTypes.LUA_TNIL: LuaDLL.lua_pushvalue(L, 2); return 1; case LuaTypes.LUA_TUSERDATA: Delegate a0 = ToLua.ToObject(L, 1) as Delegate; Delegate a1 = ToLua.CheckDelegate(a0.GetType(), L, 2); Delegate ret = Delegate.Combine(a0, a1); ToLua.Push(L, ret); return 1; default: LuaDLL.luaL_typerror(L, 1, "Delegate"); return 0; } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Equality(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Delegate arg0 = (System.Delegate)ToLua.ToObject(L, 1); System.Delegate arg1 = (System.Delegate)ToLua.ToObject(L, 2); bool o = arg0 == arg1; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Method(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Delegate obj = (System.Delegate)o; System.Reflection.MethodInfo ret = obj.Method; ToLua.PushObject(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Method on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Target(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Delegate obj = (System.Delegate)o; object ret = obj.Target; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Target on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_DelegateWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 86ed9798a2c5dc74e9018394dfc827ea MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_EnumWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_EnumWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Enum), null); L.RegFunction("GetUnderlyingType", GetUnderlyingType); L.RegFunction("GetValues", GetValues); L.RegFunction("GetName", GetName); L.RegFunction("GetNames", GetNames); L.RegFunction("IsDefined", IsDefined); L.RegFunction("Format", Format); L.RegFunction("Equals", Equals); L.RegFunction("GetHashCode", GetHashCode); L.RegFunction("ToString", ToString); L.RegFunction("CompareTo", CompareTo); L.RegFunction("HasFlag", HasFlag); L.RegFunction("GetTypeCode", GetTypeCode); L.RegFunction("Parse", Parse); L.RegFunction("ToObject", ToObject); L.RegFunction("ToInt", ToInt); L.RegFunction("__tostring", ToLua.op_ToString); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetUnderlyingType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 1); System.Type o = System.Enum.GetUnderlyingType(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetValues(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 1); System.Array o = System.Enum.GetValues(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetName(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); string o = System.Enum.GetName(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetNames(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 1); string[] o = System.Enum.GetNames(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsDefined(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); bool o = System.Enum.IsDefined(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Format(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Type arg0 = ToLua.CheckMonoType(L, 1); object arg1 = ToLua.ToVarObject(L, 2); string arg2 = ToLua.CheckString(L, 3); string o = System.Enum.Format(arg0, arg1, arg2); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Equals(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Enum obj = (System.Enum)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetHashCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Enum obj = (System.Enum)ToLua.CheckObject(L, 1); int o = obj.GetHashCode(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToString(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Enum obj = (System.Enum)ToLua.CheckObject(L, 1); string o = obj.ToString(); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 2) { System.Enum obj = (System.Enum)ToLua.CheckObject(L, 1); string arg0 = ToLua.CheckString(L, 2); string o = obj.ToString(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Enum.ToString"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CompareTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Enum obj = (System.Enum)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); int o = obj.CompareTo(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int HasFlag(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Enum obj = (System.Enum)ToLua.CheckObject(L, 1); System.Enum arg0 = (System.Enum)ToLua.CheckObject(L, 2); bool o = obj.HasFlag(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Enum obj = (System.Enum)ToLua.CheckObject(L, 1); System.TypeCode o = obj.GetTypeCode(); LuaDLL.lua_pushinteger(L, (int)o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Parse(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); object o = System.Enum.Parse(arg0, arg1); ToLua.Push(L, (Enum)o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); object o = System.Enum.Parse(arg0, arg1, arg2); ToLua.Push(L, (Enum)o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Enum.Parse"); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToObject(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); object o = System.Enum.ToObject(arg0, arg1); ToLua.Push(L, (Enum)o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2); object o = System.Enum.ToObject(arg0, arg1); ToLua.Push(L, (Enum)o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Enum.ToObject"); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToInt(IntPtr L) { try { object arg0 = ToLua.CheckObject(L, 1); int ret = Convert.ToInt32(arg0); LuaDLL.lua_pushinteger(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/BaseType/System_EnumWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 9fd9d683a50920540914bdd15aa75290 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_NullObjectWrap.cs ================================================ using System; using LuaInterface; public class System_NullObjectWrap { public static void Register(LuaState L) { L.BeginClass(typeof(NullObject), null, "null"); L.EndClass(); } } ================================================ FILE: Assets/ToLua/BaseType/System_NullObjectWrap.cs.meta ================================================ fileFormatVersion: 2 guid: bdcd3994912f4e145b1f12f3d76376b6 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_ObjectWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_ObjectWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Object), null); L.RegFunction("Equals", Equals); L.RegFunction("GetHashCode", GetHashCode); L.RegFunction("GetType", GetType); L.RegFunction("ToString", ToString); L.RegFunction("ReferenceEquals", ReferenceEquals); L.RegFunction("Destroy", Destroy); L.RegFunction("New", _CreateSystem_Object); L.RegFunction("__eq", op_Equality); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_Object(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 0) { System.Object obj = new System.Object(); ToLua.Push(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: System.Object.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Equals(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object obj = ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetHashCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckObject(L, 1); int o = obj.GetHashCode(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckObject(L, 1); System.Type o = obj.GetType(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToString(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object obj = ToLua.CheckObject(L, 1); string o = obj.ToString(); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ReferenceEquals(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object arg0 = ToLua.ToVarObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2); bool o = System.Object.ReferenceEquals(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Equality(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object arg0 = ToLua.ToVarObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2); bool o = arg0 == arg1; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Destroy(IntPtr L) { return ToLua.Destroy(L); } } ================================================ FILE: Assets/ToLua/BaseType/System_ObjectWrap.cs.meta ================================================ fileFormatVersion: 2 guid: fcf1094389eec494d9d80c46f54f2a7e MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_StringWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_StringWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.String), typeof(System.Object)); L.RegFunction("Join", Join); L.RegFunction("Equals", Equals); L.RegFunction("CopyTo", CopyTo); L.RegFunction("ToCharArray", ToCharArray); L.RegFunction("IsNullOrEmpty", IsNullOrEmpty); L.RegFunction("IsNullOrWhiteSpace", IsNullOrWhiteSpace); L.RegFunction("GetHashCode", GetHashCode); L.RegFunction("Split", Split); L.RegFunction("Substring", Substring); L.RegFunction("Trim", Trim); L.RegFunction("TrimStart", TrimStart); L.RegFunction("TrimEnd", TrimEnd); L.RegFunction("IsNormalized", IsNormalized); L.RegFunction("Normalize", Normalize); L.RegFunction("Compare", Compare); L.RegFunction("CompareTo", CompareTo); L.RegFunction("CompareOrdinal", CompareOrdinal); L.RegFunction("Contains", Contains); L.RegFunction("EndsWith", EndsWith); L.RegFunction("IndexOf", IndexOf); L.RegFunction("IndexOfAny", IndexOfAny); L.RegFunction("LastIndexOf", LastIndexOf); L.RegFunction("LastIndexOfAny", LastIndexOfAny); L.RegFunction("PadLeft", PadLeft); L.RegFunction("PadRight", PadRight); L.RegFunction("StartsWith", StartsWith); L.RegFunction("ToLower", ToLower); L.RegFunction("ToLowerInvariant", ToLowerInvariant); L.RegFunction("ToUpper", ToUpper); L.RegFunction("ToUpperInvariant", ToUpperInvariant); L.RegFunction("ToString", ToString); L.RegFunction("Clone", Clone); L.RegFunction("Insert", Insert); L.RegFunction("Replace", Replace); L.RegFunction("Remove", Remove); L.RegFunction("Format", Format); L.RegFunction("Copy", Copy); L.RegFunction("Concat", Concat); L.RegFunction("Intern", Intern); L.RegFunction("IsInterned", IsInterned); L.RegFunction("GetTypeCode", GetTypeCode); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("New", _CreateSystem_String); L.RegFunction("__eq", op_Equality); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Empty", get_Empty, null); L.RegVar("Length", get_Length, null); L.RegFunction("getLength", get_Length); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_String(IntPtr L) { try { LuaTypes luatype = LuaDLL.lua_type(L, 1); if (luatype == LuaTypes.LUA_TSTRING) { string arg0 = LuaDLL.lua_tostring(L, 1); ToLua.PushSealed(L, arg0); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to string's ctor method"); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Join(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes>(L, 1)) { string arg0 = ToLua.ToString(L, 1); System.Collections.Generic.IEnumerable arg1 = (System.Collections.Generic.IEnumerable)ToLua.ToObject(L, 2); string o = System.String.Join(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); string[] arg1 = ToLua.ToStringArray(L, 2); int arg2 = (int)LuaDLL.lua_tonumber(L, 3); int arg3 = (int)LuaDLL.lua_tonumber(L, 4); string o = System.String.Join(arg0, arg1, arg2, arg3); LuaDLL.lua_pushstring(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { string arg0 = ToLua.ToString(L, 1); string[] arg1 = ToLua.ToParamsString(L, 2, count - 1); string o = System.String.Join(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { string arg0 = ToLua.ToString(L, 1); object[] arg1 = ToLua.ToParamsObject(L, 2, count - 1); string o = System.String.Join(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Join"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Equals(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); System.StringComparison arg1 = (System.StringComparison)LuaDLL.luaL_checknumber(L, 3); bool o = obj.Equals(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Equals"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Equality(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); string arg0 = ToLua.ToString(L, 1); string arg1 = ToLua.ToString(L, 2); bool o = arg0 == arg1; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 5); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); char[] arg1 = ToLua.CheckCharBuffer(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); int arg3 = (int)LuaDLL.luaL_checknumber(L, 5); obj.CopyTo(arg0, arg1, arg2, arg3); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToCharArray(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] o = obj.ToCharArray(); ToLua.Push(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); char[] o = obj.ToCharArray(arg0, arg1); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.ToCharArray"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsNullOrEmpty(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); string arg0 = ToLua.CheckString(L, 1); bool o = System.String.IsNullOrEmpty(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsNullOrWhiteSpace(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); string arg0 = ToLua.CheckString(L, 1); bool o = System.String.IsNullOrWhiteSpace(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetHashCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int o = obj.GetHashCode(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Split(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); string[] o = obj.Split(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); char[] arg0 = ToLua.CheckCharBuffer(L, 2); System.StringSplitOptions arg1 = (System.StringSplitOptions)LuaDLL.lua_tonumber(L, 3); string[] o = obj.Split(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); string[] arg0 = ToLua.ToStringArray(L, 2); System.StringSplitOptions arg1 = (System.StringSplitOptions)LuaDLL.lua_tonumber(L, 3); string[] o = obj.Split(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); System.StringSplitOptions arg2 = (System.StringSplitOptions)LuaDLL.lua_tonumber(L, 4); string[] o = obj.Split(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); string[] arg0 = ToLua.ToStringArray(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); System.StringSplitOptions arg2 = (System.StringSplitOptions)LuaDLL.lua_tonumber(L, 4); string[] o = obj.Split(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); char[] arg0 = ToLua.ToParamsChar(L, 2, count - 1); string[] o = obj.Split(arg0); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Split"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Substring(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); string o = obj.Substring(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); string o = obj.Substring(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Substring"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Trim(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1 && TypeChecker.CheckTypes(L, 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); string o = obj.Trim(); LuaDLL.lua_pushstring(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { System.String obj = (System.String)ToLua.ToObject(L, 1); char[] arg0 = ToLua.ToParamsChar(L, 2, count - 1); string o = obj.Trim(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Trim"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TrimStart(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckParamsChar(L, 2, count - 1); string o = obj.TrimStart(arg0); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TrimEnd(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckParamsChar(L, 2, count - 1); string o = obj.TrimEnd(arg0); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsNormalized(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); bool o = obj.IsNormalized(); LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); System.Text.NormalizationForm arg0 = (System.Text.NormalizationForm)LuaDLL.luaL_checknumber(L, 2); bool o = obj.IsNormalized(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.IsNormalized"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Normalize(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string o = obj.Normalize(); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); System.Text.NormalizationForm arg0 = (System.Text.NormalizationForm)LuaDLL.luaL_checknumber(L, 2); string o = obj.Normalize(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Normalize"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Compare(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.CheckString(L, 2); int o = System.String.Compare(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 3)) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.CheckString(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); int o = System.String.Compare(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 3)) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.CheckString(L, 2); System.StringComparison arg2 = (System.StringComparison)LuaDLL.lua_tonumber(L, 3); int o = System.String.Compare(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 3)) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.CheckString(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); System.Globalization.CultureInfo arg3 = (System.Globalization.CultureInfo)ToLua.ToObject(L, 4); int o = System.String.Compare(arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 3)) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.CheckString(L, 2); System.Globalization.CultureInfo arg2 = (System.Globalization.CultureInfo)ToLua.ToObject(L, 3); System.Globalization.CompareOptions arg3 = (System.Globalization.CompareOptions)LuaDLL.lua_tonumber(L, 4); int o = System.String.Compare(arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 5) { string arg0 = ToLua.CheckString(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); string arg2 = ToLua.CheckString(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int arg4 = (int)LuaDLL.luaL_checknumber(L, 5); int o = System.String.Compare(arg0, arg1, arg2, arg3, arg4); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 6 && TypeChecker.CheckTypes(L, 6)) { string arg0 = ToLua.CheckString(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); string arg2 = ToLua.CheckString(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int arg4 = (int)LuaDLL.luaL_checknumber(L, 5); bool arg5 = LuaDLL.lua_toboolean(L, 6); int o = System.String.Compare(arg0, arg1, arg2, arg3, arg4, arg5); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 6 && TypeChecker.CheckTypes(L, 6)) { string arg0 = ToLua.CheckString(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); string arg2 = ToLua.CheckString(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int arg4 = (int)LuaDLL.luaL_checknumber(L, 5); System.StringComparison arg5 = (System.StringComparison)LuaDLL.lua_tonumber(L, 6); int o = System.String.Compare(arg0, arg1, arg2, arg3, arg4, arg5); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 7 && TypeChecker.CheckTypes(L, 6)) { string arg0 = ToLua.CheckString(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); string arg2 = ToLua.CheckString(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int arg4 = (int)LuaDLL.luaL_checknumber(L, 5); bool arg5 = LuaDLL.lua_toboolean(L, 6); System.Globalization.CultureInfo arg6 = (System.Globalization.CultureInfo)ToLua.ToObject(L, 7); int o = System.String.Compare(arg0, arg1, arg2, arg3, arg4, arg5, arg6); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 7 && TypeChecker.CheckTypes(L, 6)) { string arg0 = ToLua.CheckString(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); string arg2 = ToLua.CheckString(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int arg4 = (int)LuaDLL.luaL_checknumber(L, 5); System.Globalization.CultureInfo arg5 = (System.Globalization.CultureInfo)ToLua.ToObject(L, 6); System.Globalization.CompareOptions arg6 = (System.Globalization.CompareOptions)LuaDLL.lua_tonumber(L, 7); int o = System.String.Compare(arg0, arg1, arg2, arg3, arg4, arg5, arg6); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Compare"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CompareTo(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int o = obj.CompareTo(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); object arg0 = ToLua.ToVarObject(L, 2); int o = obj.CompareTo(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.CompareTo"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CompareOrdinal(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.CheckString(L, 2); int o = System.String.CompareOrdinal(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 5) { string arg0 = ToLua.CheckString(L, 1); int arg1 = (int)LuaDLL.luaL_checknumber(L, 2); string arg2 = ToLua.CheckString(L, 3); int arg3 = (int)LuaDLL.luaL_checknumber(L, 4); int arg4 = (int)LuaDLL.luaL_checknumber(L, 5); int o = System.String.CompareOrdinal(arg0, arg1, arg2, arg3, arg4); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.CompareOrdinal"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Contains(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); bool o = obj.Contains(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int EndsWith(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); bool o = obj.EndsWith(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); System.StringComparison arg1 = (System.StringComparison)LuaDLL.luaL_checknumber(L, 3); bool o = obj.EndsWith(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 4) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); bool arg1 = LuaDLL.luaL_checkboolean(L, 3); System.Globalization.CultureInfo arg2 = (System.Globalization.CultureInfo)ToLua.CheckObject(L, 4); bool o = obj.EndsWith(arg0, arg1, arg2); LuaDLL.lua_pushboolean(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.EndsWith"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IndexOf(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); int o = obj.IndexOf(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int o = obj.IndexOf(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int o = obj.IndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int o = obj.IndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); System.StringComparison arg1 = (System.StringComparison)LuaDLL.lua_tonumber(L, 3); int o = obj.IndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); int o = obj.IndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); int o = obj.IndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); System.StringComparison arg2 = (System.StringComparison)LuaDLL.lua_tonumber(L, 4); int o = obj.IndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 5) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); System.StringComparison arg3 = (System.StringComparison)LuaDLL.luaL_checknumber(L, 5); int o = obj.IndexOf(arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.IndexOf"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IndexOfAny(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int o = obj.IndexOfAny(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int o = obj.IndexOfAny(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); int o = obj.IndexOfAny(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.IndexOfAny"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LastIndexOf(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); int o = obj.LastIndexOf(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int o = obj.LastIndexOf(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int o = obj.LastIndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int o = obj.LastIndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); System.StringComparison arg1 = (System.StringComparison)LuaDLL.lua_tonumber(L, 3); int o = obj.LastIndexOf(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); int o = obj.LastIndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); int o = obj.LastIndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); System.StringComparison arg2 = (System.StringComparison)LuaDLL.lua_tonumber(L, 4); int o = obj.LastIndexOf(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 5) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); System.StringComparison arg3 = (System.StringComparison)LuaDLL.luaL_checknumber(L, 5); int o = obj.LastIndexOf(arg0, arg1, arg2, arg3); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.LastIndexOf"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LastIndexOfAny(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int o = obj.LastIndexOfAny(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int o = obj.LastIndexOfAny(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char[] arg0 = ToLua.CheckCharBuffer(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); int o = obj.LastIndexOfAny(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.LastIndexOfAny"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int PadLeft(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); string o = obj.PadLeft(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); char arg1 = (char)LuaDLL.luaL_checknumber(L, 3); string o = obj.PadLeft(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.PadLeft"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int PadRight(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); string o = obj.PadRight(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); char arg1 = (char)LuaDLL.luaL_checknumber(L, 3); string o = obj.PadRight(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.PadRight"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int StartsWith(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); bool o = obj.StartsWith(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); System.StringComparison arg1 = (System.StringComparison)LuaDLL.luaL_checknumber(L, 3); bool o = obj.StartsWith(arg0, arg1); LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 4) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.CheckString(L, 2); bool arg1 = LuaDLL.luaL_checkboolean(L, 3); System.Globalization.CultureInfo arg2 = (System.Globalization.CultureInfo)ToLua.CheckObject(L, 4); bool o = obj.StartsWith(arg0, arg1, arg2); LuaDLL.lua_pushboolean(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.StartsWith"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToLower(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string o = obj.ToLower(); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); System.Globalization.CultureInfo arg0 = (System.Globalization.CultureInfo)ToLua.CheckObject(L, 2); string o = obj.ToLower(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.ToLower"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToLowerInvariant(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string o = obj.ToLowerInvariant(); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToUpper(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string o = obj.ToUpper(); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); System.Globalization.CultureInfo arg0 = (System.Globalization.CultureInfo)ToLua.CheckObject(L, 2); string o = obj.ToUpper(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.ToUpper"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToUpperInvariant(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string o = obj.ToUpperInvariant(); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToString(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string o = obj.ToString(); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); System.IFormatProvider arg0 = (System.IFormatProvider)ToLua.CheckObject(L, 2); string o = obj.ToString(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.ToString"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Clone(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); object o = obj.Clone(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Insert(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); string arg1 = ToLua.CheckString(L, 3); string o = obj.Insert(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Replace(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); char arg1 = (char)LuaDLL.lua_tonumber(L, 3); string o = obj.Replace(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); string arg0 = ToLua.ToString(L, 2); string arg1 = ToLua.ToString(L, 3); string o = obj.Replace(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Replace"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Remove(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); string o = obj.Remove(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3) { System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); string o = obj.Remove(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Remove"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Format(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); object arg1 = ToLua.ToVarObject(L, 2); string o = System.String.Format(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.IFormatProvider arg0 = (System.IFormatProvider)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); object arg2 = ToLua.ToVarObject(L, 3); string o = System.String.Format(arg0, arg1, arg2); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); object arg1 = ToLua.ToVarObject(L, 2); object arg2 = ToLua.ToVarObject(L, 3); string o = System.String.Format(arg0, arg1, arg2); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { System.IFormatProvider arg0 = (System.IFormatProvider)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); object arg2 = ToLua.ToVarObject(L, 3); object arg3 = ToLua.ToVarObject(L, 4); string o = System.String.Format(arg0, arg1, arg2, arg3); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); object arg1 = ToLua.ToVarObject(L, 2); object arg2 = ToLua.ToVarObject(L, 3); object arg3 = ToLua.ToVarObject(L, 4); string o = System.String.Format(arg0, arg1, arg2, arg3); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 5 && TypeChecker.CheckTypes(L, 1)) { System.IFormatProvider arg0 = (System.IFormatProvider)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); object arg2 = ToLua.ToVarObject(L, 3); object arg3 = ToLua.ToVarObject(L, 4); object arg4 = ToLua.ToVarObject(L, 5); string o = System.String.Format(arg0, arg1, arg2, arg3, arg4); LuaDLL.lua_pushstring(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 3, count - 2)) { System.IFormatProvider arg0 = (System.IFormatProvider)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); object[] arg2 = ToLua.ToParamsObject(L, 3, count - 2); string o = System.String.Format(arg0, arg1, arg2); LuaDLL.lua_pushstring(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { string arg0 = ToLua.ToString(L, 1); object[] arg1 = ToLua.ToParamsObject(L, 2, count - 1); string o = System.String.Format(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Format"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Copy(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); string arg0 = ToLua.CheckString(L, 1); string o = System.String.Copy(arg0); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Concat(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1 && TypeChecker.CheckTypes>(L, 1)) { System.Collections.Generic.IEnumerable arg0 = (System.Collections.Generic.IEnumerable)ToLua.ToObject(L, 1); string o = System.String.Concat(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 1 && TypeChecker.CheckTypes(L, 1)) { object arg0 = ToLua.ToVarObject(L, 1); string o = System.String.Concat(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); string arg1 = ToLua.ToString(L, 2); string o = System.String.Concat(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { object arg0 = ToLua.ToVarObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2); string o = System.String.Concat(arg0, arg1); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); string arg1 = ToLua.ToString(L, 2); string arg2 = ToLua.ToString(L, 3); string o = System.String.Concat(arg0, arg1, arg2); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { object arg0 = ToLua.ToVarObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2); object arg2 = ToLua.ToVarObject(L, 3); string o = System.String.Concat(arg0, arg1, arg2); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); string arg1 = ToLua.ToString(L, 2); string arg2 = ToLua.ToString(L, 3); string arg3 = ToLua.ToString(L, 4); string o = System.String.Concat(arg0, arg1, arg2, arg3); LuaDLL.lua_pushstring(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { object arg0 = ToLua.ToVarObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2); object arg2 = ToLua.ToVarObject(L, 3); object arg3 = ToLua.ToVarObject(L, 4); string o = System.String.Concat(arg0, arg1, arg2, arg3); LuaDLL.lua_pushstring(L, o); return 1; } else if (TypeChecker.CheckParamsType(L, 1, count)) { string[] arg0 = ToLua.ToParamsString(L, 1, count); string o = System.String.Concat(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else if (TypeChecker.CheckParamsType(L, 1, count)) { object[] arg0 = ToLua.ToParamsObject(L, 1, count); string o = System.String.Concat(arg0); LuaDLL.lua_pushstring(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.String.Concat"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Intern(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); string arg0 = ToLua.CheckString(L, 1); string o = System.String.Intern(arg0); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsInterned(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); string arg0 = ToLua.CheckString(L, 1); string o = System.String.IsInterned(arg0); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); System.TypeCode o = obj.GetTypeCode(); LuaDLL.lua_pushinteger(L, (int)o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.String obj = (System.String)ToLua.CheckObject(L, 1, typeof(System.String)); System.Collections.IEnumerator o = obj.GetEnumerator(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Empty(IntPtr L) { try { LuaDLL.lua_pushstring(L, System.String.Empty); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Length(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.String obj = (System.String)o; int ret = obj.Length; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Length on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_StringWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 6380cf60ae81034418e4fe4dabc06bc2 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/System_TypeWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_TypeWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Type), typeof(System.Object)); L.RegFunction("GetType", GetType); L.RegFunction("MakePointerType", MakePointerType); L.RegFunction("MakeByRefType", MakeByRefType); L.RegFunction("MakeArrayType", MakeArrayType); L.RegFunction("GetTypeFromProgID", GetTypeFromProgID); L.RegFunction("GetTypeFromCLSID", GetTypeFromCLSID); L.RegFunction("GetTypeCode", GetTypeCode); L.RegFunction("InvokeMember", InvokeMember); L.RegFunction("GetTypeHandle", GetTypeHandle); L.RegFunction("GetArrayRank", GetArrayRank); L.RegFunction("GetInterface", GetInterface); L.RegFunction("GetInterfaces", GetInterfaces); L.RegFunction("FindInterfaces", FindInterfaces); L.RegFunction("GetNestedTypes", GetNestedTypes); L.RegFunction("GetNestedType", GetNestedType); L.RegFunction("GetDefaultMembers", GetDefaultMembers); L.RegFunction("FindMembers", FindMembers); L.RegFunction("GetGenericParameterConstraints", GetGenericParameterConstraints); L.RegFunction("MakeGenericType", MakeGenericType); L.RegFunction("GetElementType", GetElementType); L.RegFunction("GetGenericArguments", GetGenericArguments); L.RegFunction("GetGenericTypeDefinition", GetGenericTypeDefinition); L.RegFunction("GetEnumNames", GetEnumNames); L.RegFunction("GetEnumValues", GetEnumValues); L.RegFunction("GetEnumUnderlyingType", GetEnumUnderlyingType); L.RegFunction("IsEnumDefined", IsEnumDefined); L.RegFunction("GetEnumName", GetEnumName); L.RegFunction("IsSubclassOf", IsSubclassOf); L.RegFunction("IsInstanceOfType", IsInstanceOfType); L.RegFunction("IsAssignableFrom", IsAssignableFrom); L.RegFunction("IsEquivalentTo", IsEquivalentTo); L.RegFunction("ToString", ToString); L.RegFunction("GetTypeArray", GetTypeArray); L.RegFunction("Equals", Equals); L.RegFunction("GetHashCode", GetHashCode); L.RegFunction("GetInterfaceMap", GetInterfaceMap); L.RegFunction("ReflectionOnlyGetType", ReflectionOnlyGetType); L.RegFunction("GetTypeFromHandle", GetTypeFromHandle); L.RegFunction("__eq", op_Equality); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("FilterAttribute", get_FilterAttribute, null); L.RegVar("FilterName", get_FilterName, null); L.RegVar("FilterNameIgnoreCase", get_FilterNameIgnoreCase, null); L.RegVar("Missing", get_Missing, null); L.RegVar("Delimiter", get_Delimiter, null); L.RegVar("EmptyTypes", get_EmptyTypes, null); L.RegVar("MemberType", get_MemberType, null); L.RegFunction("getMemberType", get_MemberType); L.RegVar("DeclaringType", get_DeclaringType, null); L.RegFunction("getDeclaringType", get_DeclaringType); L.RegVar("DeclaringMethod", get_DeclaringMethod, null); L.RegFunction("getDeclaringMethod", get_DeclaringMethod); L.RegVar("ReflectedType", get_ReflectedType, null); L.RegFunction("getReflectedType", get_ReflectedType); L.RegVar("StructLayoutAttribute", get_StructLayoutAttribute, null); L.RegFunction("getStructLayoutAttribute", get_StructLayoutAttribute); L.RegVar("GUID", get_GUID, null); L.RegFunction("getGUID", get_GUID); L.RegVar("DefaultBinder", get_DefaultBinder, null); L.RegFunction("getDefaultBinder", get_DefaultBinder); L.RegVar("Module", get_Module, null); L.RegFunction("getModule", get_Module); L.RegVar("Assembly", get_Assembly, null); L.RegFunction("getAssembly", get_Assembly); L.RegVar("TypeHandle", get_TypeHandle, null); L.RegFunction("getTypeHandle", get_TypeHandle); L.RegVar("FullName", get_FullName, null); L.RegFunction("getFullName", get_FullName); L.RegVar("Namespace", get_Namespace, null); L.RegFunction("getNamespace", get_Namespace); L.RegVar("AssemblyQualifiedName", get_AssemblyQualifiedName, null); L.RegFunction("getAssemblyQualifiedName", get_AssemblyQualifiedName); L.RegVar("BaseType", get_BaseType, null); L.RegFunction("getBaseType", get_BaseType); L.RegVar("TypeInitializer", get_TypeInitializer, null); L.RegFunction("getTypeInitializer", get_TypeInitializer); L.RegVar("IsNested", get_IsNested, null); L.RegFunction("getIsNested", get_IsNested); L.RegVar("Attributes", get_Attributes, null); L.RegFunction("getAttributes", get_Attributes); L.RegVar("GenericParameterAttributes", get_GenericParameterAttributes, null); L.RegFunction("getGenericParameterAttributes", get_GenericParameterAttributes); L.RegVar("IsVisible", get_IsVisible, null); L.RegFunction("getIsVisible", get_IsVisible); L.RegVar("IsNotPublic", get_IsNotPublic, null); L.RegFunction("getIsNotPublic", get_IsNotPublic); L.RegVar("IsPublic", get_IsPublic, null); L.RegFunction("getIsPublic", get_IsPublic); L.RegVar("IsNestedPublic", get_IsNestedPublic, null); L.RegFunction("getIsNestedPublic", get_IsNestedPublic); L.RegVar("IsNestedPrivate", get_IsNestedPrivate, null); L.RegFunction("getIsNestedPrivate", get_IsNestedPrivate); L.RegVar("IsNestedFamily", get_IsNestedFamily, null); L.RegFunction("getIsNestedFamily", get_IsNestedFamily); L.RegVar("IsNestedAssembly", get_IsNestedAssembly, null); L.RegFunction("getIsNestedAssembly", get_IsNestedAssembly); L.RegVar("IsNestedFamANDAssem", get_IsNestedFamANDAssem, null); L.RegFunction("getIsNestedFamANDAssem", get_IsNestedFamANDAssem); L.RegVar("IsNestedFamORAssem", get_IsNestedFamORAssem, null); L.RegFunction("getIsNestedFamORAssem", get_IsNestedFamORAssem); L.RegVar("IsAutoLayout", get_IsAutoLayout, null); L.RegFunction("getIsAutoLayout", get_IsAutoLayout); L.RegVar("IsLayoutSequential", get_IsLayoutSequential, null); L.RegFunction("getIsLayoutSequential", get_IsLayoutSequential); L.RegVar("IsExplicitLayout", get_IsExplicitLayout, null); L.RegFunction("getIsExplicitLayout", get_IsExplicitLayout); L.RegVar("IsClass", get_IsClass, null); L.RegFunction("getIsClass", get_IsClass); L.RegVar("IsInterface", get_IsInterface, null); L.RegFunction("getIsInterface", get_IsInterface); L.RegVar("IsValueType", get_IsValueType, null); L.RegFunction("getIsValueType", get_IsValueType); L.RegVar("IsAbstract", get_IsAbstract, null); L.RegFunction("getIsAbstract", get_IsAbstract); L.RegVar("IsSealed", get_IsSealed, null); L.RegFunction("getIsSealed", get_IsSealed); L.RegVar("IsEnum", get_IsEnum, null); L.RegFunction("getIsEnum", get_IsEnum); L.RegVar("IsSpecialName", get_IsSpecialName, null); L.RegFunction("getIsSpecialName", get_IsSpecialName); L.RegVar("IsImport", get_IsImport, null); L.RegFunction("getIsImport", get_IsImport); L.RegVar("IsSerializable", get_IsSerializable, null); L.RegFunction("getIsSerializable", get_IsSerializable); L.RegVar("IsAnsiClass", get_IsAnsiClass, null); L.RegFunction("getIsAnsiClass", get_IsAnsiClass); L.RegVar("IsUnicodeClass", get_IsUnicodeClass, null); L.RegFunction("getIsUnicodeClass", get_IsUnicodeClass); L.RegVar("IsAutoClass", get_IsAutoClass, null); L.RegFunction("getIsAutoClass", get_IsAutoClass); L.RegVar("IsArray", get_IsArray, null); L.RegFunction("getIsArray", get_IsArray); L.RegVar("IsGenericType", get_IsGenericType, null); L.RegFunction("getIsGenericType", get_IsGenericType); L.RegVar("IsGenericTypeDefinition", get_IsGenericTypeDefinition, null); L.RegFunction("getIsGenericTypeDefinition", get_IsGenericTypeDefinition); L.RegVar("IsConstructedGenericType", get_IsConstructedGenericType, null); L.RegFunction("getIsConstructedGenericType", get_IsConstructedGenericType); L.RegVar("IsGenericParameter", get_IsGenericParameter, null); L.RegFunction("getIsGenericParameter", get_IsGenericParameter); L.RegVar("GenericParameterPosition", get_GenericParameterPosition, null); L.RegFunction("getGenericParameterPosition", get_GenericParameterPosition); L.RegVar("ContainsGenericParameters", get_ContainsGenericParameters, null); L.RegFunction("getContainsGenericParameters", get_ContainsGenericParameters); L.RegVar("IsByRef", get_IsByRef, null); L.RegFunction("getIsByRef", get_IsByRef); L.RegVar("IsPointer", get_IsPointer, null); L.RegFunction("getIsPointer", get_IsPointer); L.RegVar("IsPrimitive", get_IsPrimitive, null); L.RegFunction("getIsPrimitive", get_IsPrimitive); L.RegVar("IsCOMObject", get_IsCOMObject, null); L.RegFunction("getIsCOMObject", get_IsCOMObject); L.RegVar("HasElementType", get_HasElementType, null); L.RegFunction("getHasElementType", get_HasElementType); L.RegVar("IsContextful", get_IsContextful, null); L.RegFunction("getIsContextful", get_IsContextful); L.RegVar("IsMarshalByRef", get_IsMarshalByRef, null); L.RegFunction("getIsMarshalByRef", get_IsMarshalByRef); L.RegVar("GenericTypeArguments", get_GenericTypeArguments, null); L.RegFunction("getGenericTypeArguments", get_GenericTypeArguments); L.RegVar("IsSecurityCritical", get_IsSecurityCritical, null); L.RegFunction("getIsSecurityCritical", get_IsSecurityCritical); L.RegVar("IsSecuritySafeCritical", get_IsSecuritySafeCritical, null); L.RegFunction("getIsSecuritySafeCritical", get_IsSecuritySafeCritical); L.RegVar("IsSecurityTransparent", get_IsSecurityTransparent, null); L.RegFunction("getIsSecurityTransparent", get_IsSecurityTransparent); L.RegVar("UnderlyingSystemType", get_UnderlyingSystemType, null); L.RegFunction("getUnderlyingSystemType", get_UnderlyingSystemType); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetType(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1 && TypeChecker.CheckTypes(L, 1)) { System.Type obj = (System.Type)ToLua.ToObject(L, 1); System.Type o = obj.GetType(); ToLua.Push(L, o); return 1; } else if (count == 1 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); System.Type o = System.Type.GetType(arg0); ToLua.Push(L, o); return 1; } else if (count == 2) { string arg0 = ToLua.CheckString(L, 1); bool arg1 = LuaDLL.luaL_checkboolean(L, 2); System.Type o = System.Type.GetType(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { string arg0 = ToLua.CheckString(L, 1); bool arg1 = LuaDLL.lua_toboolean(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); System.Type o = System.Type.GetType(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes, System.Func>(L, 2)) { string arg0 = ToLua.CheckString(L, 1); System.Func arg1 = (System.Func)ToLua.ToObject(L, 2); System.Func arg2 = (System.Func)ToLua.ToObject(L, 3); System.Type o = System.Type.GetType(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else if (count == 4) { string arg0 = ToLua.CheckString(L, 1); System.Func arg1 = (System.Func)ToLua.CheckDelegate>(L, 2); System.Func arg2 = (System.Func)ToLua.CheckDelegate>(L, 3); bool arg3 = LuaDLL.luaL_checkboolean(L, 4); System.Type o = System.Type.GetType(arg0, arg1, arg2, arg3); ToLua.Push(L, o); return 1; } else if (count == 5) { string arg0 = ToLua.CheckString(L, 1); System.Func arg1 = (System.Func)ToLua.CheckDelegate>(L, 2); System.Func arg2 = (System.Func)ToLua.CheckDelegate>(L, 3); bool arg3 = LuaDLL.luaL_checkboolean(L, 4); bool arg4 = LuaDLL.luaL_checkboolean(L, 5); System.Type o = System.Type.GetType(arg0, arg1, arg2, arg3, arg4); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.GetType"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int MakePointerType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type o = obj.MakePointerType(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int MakeByRefType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type o = obj.MakeByRefType(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int MakeArrayType(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Type obj = ToLua.CheckMonoType(L, 1); System.Type o = obj.MakeArrayType(); ToLua.Push(L, o); return 1; } else if (count == 2) { System.Type obj = ToLua.CheckMonoType(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); System.Type o = obj.MakeArrayType(arg0); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.MakeArrayType"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeFromProgID(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { string arg0 = ToLua.CheckString(L, 1); System.Type o = System.Type.GetTypeFromProgID(arg0); ToLua.Push(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { string arg0 = ToLua.CheckString(L, 1); bool arg1 = LuaDLL.lua_toboolean(L, 2); System.Type o = System.Type.GetTypeFromProgID(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.ToString(L, 2); System.Type o = System.Type.GetTypeFromProgID(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3) { string arg0 = ToLua.CheckString(L, 1); string arg1 = ToLua.CheckString(L, 2); bool arg2 = LuaDLL.luaL_checkboolean(L, 3); System.Type o = System.Type.GetTypeFromProgID(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.GetTypeFromProgID"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeFromCLSID(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Guid arg0 = StackTraits.Check(L, 1); System.Type o = System.Type.GetTypeFromCLSID(arg0); ToLua.Push(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.Guid arg0 = StackTraits.Check(L, 1); bool arg1 = LuaDLL.lua_toboolean(L, 2); System.Type o = System.Type.GetTypeFromCLSID(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.Guid arg0 = StackTraits.Check(L, 1); string arg1 = ToLua.ToString(L, 2); System.Type o = System.Type.GetTypeFromCLSID(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 3) { System.Guid arg0 = StackTraits.Check(L, 1); string arg1 = ToLua.CheckString(L, 2); bool arg2 = LuaDLL.luaL_checkboolean(L, 3); System.Type o = System.Type.GetTypeFromCLSID(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.GetTypeFromCLSID"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 1); System.TypeCode o = System.Type.GetTypeCode(arg0); LuaDLL.lua_pushinteger(L, (int)o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int InvokeMember(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 6) { System.Type obj = ToLua.CheckMonoType(L, 1); string arg0 = ToLua.CheckString(L, 2); System.Reflection.BindingFlags arg1 = (System.Reflection.BindingFlags)LuaDLL.luaL_checknumber(L, 3); System.Reflection.Binder arg2 = (System.Reflection.Binder)ToLua.CheckObject(L, 4); object arg3 = ToLua.ToVarObject(L, 5); object[] arg4 = ToLua.CheckObjectArray(L, 6); object o = obj.InvokeMember(arg0, arg1, arg2, arg3, arg4); ToLua.Push(L, o); return 1; } else if (count == 7) { System.Type obj = ToLua.CheckMonoType(L, 1); string arg0 = ToLua.CheckString(L, 2); System.Reflection.BindingFlags arg1 = (System.Reflection.BindingFlags)LuaDLL.luaL_checknumber(L, 3); System.Reflection.Binder arg2 = (System.Reflection.Binder)ToLua.CheckObject(L, 4); object arg3 = ToLua.ToVarObject(L, 5); object[] arg4 = ToLua.CheckObjectArray(L, 6); System.Globalization.CultureInfo arg5 = (System.Globalization.CultureInfo)ToLua.CheckObject(L, 7); object o = obj.InvokeMember(arg0, arg1, arg2, arg3, arg4, arg5); ToLua.Push(L, o); return 1; } else if (count == 9) { System.Type obj = ToLua.CheckMonoType(L, 1); string arg0 = ToLua.CheckString(L, 2); System.Reflection.BindingFlags arg1 = (System.Reflection.BindingFlags)LuaDLL.luaL_checknumber(L, 3); System.Reflection.Binder arg2 = (System.Reflection.Binder)ToLua.CheckObject(L, 4); object arg3 = ToLua.ToVarObject(L, 5); object[] arg4 = ToLua.CheckObjectArray(L, 6); System.Reflection.ParameterModifier[] arg5 = ToLua.CheckStructArray(L, 7); System.Globalization.CultureInfo arg6 = (System.Globalization.CultureInfo)ToLua.CheckObject(L, 8); string[] arg7 = ToLua.CheckStringArray(L, 9); object o = obj.InvokeMember(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.InvokeMember"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeHandle(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object arg0 = ToLua.ToVarObject(L, 1); System.RuntimeTypeHandle o = System.Type.GetTypeHandle(arg0); ToLua.PushValue(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetArrayRank(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); int o = obj.GetArrayRank(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetInterface(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.Type obj = ToLua.CheckMonoType(L, 1); string arg0 = ToLua.CheckString(L, 2); System.Type o = obj.GetInterface(arg0); ToLua.Push(L, o); return 1; } else if (count == 3) { System.Type obj = ToLua.CheckMonoType(L, 1); string arg0 = ToLua.CheckString(L, 2); bool arg1 = LuaDLL.luaL_checkboolean(L, 3); System.Type o = obj.GetInterface(arg0, arg1); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.GetInterface"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetInterfaces(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type[] o = obj.GetInterfaces(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindInterfaces(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Type obj = ToLua.CheckMonoType(L, 1); System.Reflection.TypeFilter arg0 = (System.Reflection.TypeFilter)ToLua.CheckDelegate(L, 2); object arg1 = ToLua.ToVarObject(L, 3); System.Type[] o = obj.FindInterfaces(arg0, arg1); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetNestedTypes(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Type obj = ToLua.CheckMonoType(L, 1); System.Type[] o = obj.GetNestedTypes(); ToLua.Push(L, o); return 1; } else if (count == 2) { System.Type obj = ToLua.CheckMonoType(L, 1); System.Reflection.BindingFlags arg0 = (System.Reflection.BindingFlags)LuaDLL.luaL_checknumber(L, 2); System.Type[] o = obj.GetNestedTypes(arg0); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.GetNestedTypes"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetNestedType(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { System.Type obj = ToLua.CheckMonoType(L, 1); string arg0 = ToLua.CheckString(L, 2); System.Type o = obj.GetNestedType(arg0); ToLua.Push(L, o); return 1; } else if (count == 3) { System.Type obj = ToLua.CheckMonoType(L, 1); string arg0 = ToLua.CheckString(L, 2); System.Reflection.BindingFlags arg1 = (System.Reflection.BindingFlags)LuaDLL.luaL_checknumber(L, 3); System.Type o = obj.GetNestedType(arg0, arg1); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.GetNestedType"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetDefaultMembers(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Reflection.MemberInfo[] o = obj.GetDefaultMembers(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindMembers(IntPtr L) { try { ToLua.CheckArgsCount(L, 5); System.Type obj = ToLua.CheckMonoType(L, 1); System.Reflection.MemberTypes arg0 = (System.Reflection.MemberTypes)LuaDLL.luaL_checknumber(L, 2); System.Reflection.BindingFlags arg1 = (System.Reflection.BindingFlags)LuaDLL.luaL_checknumber(L, 3); System.Reflection.MemberFilter arg2 = (System.Reflection.MemberFilter)ToLua.CheckDelegate(L, 4); object arg3 = ToLua.ToVarObject(L, 5); System.Reflection.MemberInfo[] o = obj.FindMembers(arg0, arg1, arg2, arg3); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetGenericParameterConstraints(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type[] o = obj.GetGenericParameterConstraints(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int MakeGenericType(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type[] arg0 = ToLua.CheckParamsObject(L, 2, count - 1); System.Type o = obj.MakeGenericType(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetElementType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type o = obj.GetElementType(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetGenericArguments(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type[] o = obj.GetGenericArguments(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetGenericTypeDefinition(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type o = obj.GetGenericTypeDefinition(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumNames(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); string[] o = obj.GetEnumNames(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumValues(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Array o = obj.GetEnumValues(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumUnderlyingType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type o = obj.GetEnumUnderlyingType(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsEnumDefined(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type obj = ToLua.CheckMonoType(L, 1); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj.IsEnumDefined(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumName(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type obj = ToLua.CheckMonoType(L, 1); object arg0 = ToLua.ToVarObject(L, 2); string o = obj.GetEnumName(arg0); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsSubclassOf(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 2); bool o = obj.IsSubclassOf(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsInstanceOfType(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type obj = ToLua.CheckMonoType(L, 1); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj.IsInstanceOfType(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsAssignableFrom(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 2); bool o = obj.IsAssignableFrom(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsEquivalentTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 2); bool o = obj.IsEquivalentTo(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToString(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); string o = obj.ToString(); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeArray(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); object[] arg0 = ToLua.CheckObjectArray(L, 1); System.Type[] o = System.Type.GetTypeArray(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Equals(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.Type obj = ToLua.CheckMonoType(L, 1); System.Type arg0 = (System.Type)ToLua.ToObject(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { System.Type obj = ToLua.CheckMonoType(L, 1); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: System.Type.Equals"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Equality(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); System.Type arg1 = (System.Type)ToLua.ToObject(L, 2); bool o = arg0 == arg1; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetHashCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type obj = ToLua.CheckMonoType(L, 1); int o = obj.GetHashCode(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetInterfaceMap(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Type obj = ToLua.CheckMonoType(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 2); System.Reflection.InterfaceMapping o = obj.GetInterfaceMap(arg0); ToLua.PushValue(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ReflectionOnlyGetType(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); string arg0 = ToLua.CheckString(L, 1); bool arg1 = LuaDLL.luaL_checkboolean(L, 2); bool arg2 = LuaDLL.luaL_checkboolean(L, 3); System.Type o = System.Type.ReflectionOnlyGetType(arg0, arg1, arg2); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeFromHandle(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.RuntimeTypeHandle arg0 = StackTraits.Check(L, 1); System.Type o = System.Type.GetTypeFromHandle(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_FilterAttribute(IntPtr L) { try { ToLua.Push(L, System.Type.FilterAttribute); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_FilterName(IntPtr L) { try { ToLua.Push(L, System.Type.FilterName); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_FilterNameIgnoreCase(IntPtr L) { try { ToLua.Push(L, System.Type.FilterNameIgnoreCase); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Missing(IntPtr L) { try { ToLua.Push(L, System.Type.Missing); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Delimiter(IntPtr L) { try { LuaDLL.lua_pushnumber(L, System.Type.Delimiter); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_EmptyTypes(IntPtr L) { try { ToLua.Push(L, System.Type.EmptyTypes); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_MemberType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Reflection.MemberTypes ret = obj.MemberType; LuaDLL.lua_pushinteger(L, (int)ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index MemberType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_DeclaringType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Type ret = obj.DeclaringType; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index DeclaringType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_DeclaringMethod(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Reflection.MethodBase ret = obj.DeclaringMethod; ToLua.PushObject(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index DeclaringMethod on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_ReflectedType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Type ret = obj.ReflectedType; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index ReflectedType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_StructLayoutAttribute(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Runtime.InteropServices.StructLayoutAttribute ret = obj.StructLayoutAttribute; ToLua.PushSealed(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index StructLayoutAttribute on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_GUID(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Guid ret = obj.GUID; ToLua.PushValue(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index GUID on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_DefaultBinder(IntPtr L) { try { ToLua.PushObject(L, System.Type.DefaultBinder); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Module(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Reflection.Module ret = obj.Module; ToLua.PushObject(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Module on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Assembly(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Reflection.Assembly ret = obj.Assembly; ToLua.PushObject(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Assembly on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_TypeHandle(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.RuntimeTypeHandle ret = obj.TypeHandle; ToLua.PushValue(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index TypeHandle on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_FullName(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; string ret = obj.FullName; LuaDLL.lua_pushstring(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index FullName on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Namespace(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; string ret = obj.Namespace; LuaDLL.lua_pushstring(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Namespace on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_AssemblyQualifiedName(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; string ret = obj.AssemblyQualifiedName; LuaDLL.lua_pushstring(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index AssemblyQualifiedName on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_BaseType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Type ret = obj.BaseType; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index BaseType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_TypeInitializer(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Reflection.ConstructorInfo ret = obj.TypeInitializer; ToLua.PushObject(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index TypeInitializer on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNested(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNested; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNested on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Attributes(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Reflection.TypeAttributes ret = obj.Attributes; LuaDLL.lua_pushinteger(L, (int)ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Attributes on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_GenericParameterAttributes(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Reflection.GenericParameterAttributes ret = obj.GenericParameterAttributes; LuaDLL.lua_pushinteger(L, (int)ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index GenericParameterAttributes on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsVisible(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsVisible; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsVisible on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNotPublic(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNotPublic; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNotPublic on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsPublic(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsPublic; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsPublic on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNestedPublic(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNestedPublic; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNestedPublic on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNestedPrivate(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNestedPrivate; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNestedPrivate on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNestedFamily(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNestedFamily; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNestedFamily on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNestedAssembly(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNestedAssembly; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNestedAssembly on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNestedFamANDAssem(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNestedFamANDAssem; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNestedFamANDAssem on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsNestedFamORAssem(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsNestedFamORAssem; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsNestedFamORAssem on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsAutoLayout(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsAutoLayout; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsAutoLayout on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsLayoutSequential(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsLayoutSequential; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsLayoutSequential on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsExplicitLayout(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsExplicitLayout; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsExplicitLayout on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsClass(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsClass; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsClass on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsInterface(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsInterface; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsInterface on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsValueType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsValueType; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsValueType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsAbstract(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsAbstract; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsAbstract on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsSealed(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsSealed; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsSealed on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsEnum(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsEnum; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsEnum on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsSpecialName(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsSpecialName; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsSpecialName on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsImport(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsImport; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsImport on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsSerializable(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsSerializable; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsSerializable on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsAnsiClass(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsAnsiClass; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsAnsiClass on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsUnicodeClass(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsUnicodeClass; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsUnicodeClass on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsAutoClass(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsAutoClass; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsAutoClass on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsArray(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsArray; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsArray on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsGenericType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsGenericType; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsGenericType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsGenericTypeDefinition(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsGenericTypeDefinition; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsGenericTypeDefinition on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsConstructedGenericType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsConstructedGenericType; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsConstructedGenericType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsGenericParameter(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsGenericParameter; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsGenericParameter on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_GenericParameterPosition(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; int ret = obj.GenericParameterPosition; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index GenericParameterPosition on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_ContainsGenericParameters(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.ContainsGenericParameters; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index ContainsGenericParameters on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsByRef(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsByRef; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsByRef on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsPointer(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsPointer; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsPointer on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsPrimitive(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsPrimitive; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsPrimitive on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsCOMObject(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsCOMObject; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsCOMObject on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_HasElementType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.HasElementType; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index HasElementType on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsContextful(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsContextful; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsContextful on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsMarshalByRef(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsMarshalByRef; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsMarshalByRef on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_GenericTypeArguments(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Type[] ret = obj.GenericTypeArguments; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index GenericTypeArguments on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsSecurityCritical(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsSecurityCritical; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsSecurityCritical on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsSecuritySafeCritical(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsSecuritySafeCritical; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsSecuritySafeCritical on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_IsSecurityTransparent(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; bool ret = obj.IsSecurityTransparent; LuaDLL.lua_pushboolean(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index IsSecurityTransparent on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_UnderlyingSystemType(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Type obj = (System.Type)o; System.Type ret = obj.UnderlyingSystemType; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index UnderlyingSystemType on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/System_TypeWrap.cs.meta ================================================ fileFormatVersion: 2 guid: a713f1fe057cf7248b09e045a105933b MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType/UnityEngine_CoroutineWrap.cs ================================================ using System; using LuaInterface; public class UnityEngine_CoroutineWrap { public static void Register(LuaState L) { L.BeginClass(typeof(UnityEngine.Coroutine), null); L.RegFunction("__tostring", ToLua.op_ToString); L.EndClass(); } } ================================================ FILE: Assets/ToLua/BaseType/UnityEngine_CoroutineWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 0142bbe402aab764582bb960d6966d34 timeCreated: 1471422858 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/BaseType/UnityEngine_ObjectWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class UnityEngine_ObjectWrap { public static void Register(LuaState L) { L.BeginClass(typeof(UnityEngine.Object), typeof(System.Object)); L.RegFunction("GetInstanceID", GetInstanceID); L.RegFunction("GetHashCode", GetHashCode); L.RegFunction("Equals", Equals); L.RegFunction("FindObjectsOfType", FindObjectsOfType); L.RegFunction("DontDestroyOnLoad", DontDestroyOnLoad); L.RegFunction("FindObjectOfType", FindObjectOfType); L.RegFunction("ToString", ToString); L.RegFunction("Instantiate", Instantiate); L.RegFunction("DestroyImmediate", DestroyImmediate); L.RegFunction("Destroy", Destroy); L.RegFunction("New", _CreateUnityEngine_Object); L.RegFunction("__eq", op_Equality); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("name", get_name, set_name); L.RegFunction("getname", get_name); L.RegFunction("setname", set_name); L.RegVar("hideFlags", get_hideFlags, set_hideFlags); L.RegFunction("gethideFlags", get_hideFlags); L.RegFunction("sethideFlags", set_hideFlags); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateUnityEngine_Object(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 0) { UnityEngine.Object obj = new UnityEngine.Object(); ToLua.Push(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: UnityEngine.Object.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetInstanceID(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); UnityEngine.Object obj = (UnityEngine.Object)ToLua.CheckObject(L, 1); int o = obj.GetInstanceID(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetHashCode(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); UnityEngine.Object obj = (UnityEngine.Object)ToLua.CheckObject(L, 1); int o = obj.GetHashCode(); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Equals(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); UnityEngine.Object obj = (UnityEngine.Object)ToLua.CheckObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); bool o = obj != null ? obj.Equals(arg0) : arg0 == null; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindObjectsOfType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 1); UnityEngine.Object[] o = UnityEngine.Object.FindObjectsOfType(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int DontDestroyOnLoad(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Object.DontDestroyOnLoad(arg0); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindObjectOfType(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Type arg0 = ToLua.CheckMonoType(L, 1); UnityEngine.Object o = UnityEngine.Object.FindObjectOfType(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToString(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); UnityEngine.Object obj = (UnityEngine.Object)ToLua.CheckObject(L, 1); string o = obj.ToString(); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Equality(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.ToObject(L, 1); UnityEngine.Object arg1 = (UnityEngine.Object)ToLua.ToObject(L, 2); bool o = arg0 == arg1; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Instantiate(IntPtr L) { IntPtr L0 = LuaException.L; try { ++LuaException.InstantiateCount; LuaException.L = L; int count = LuaDLL.lua_gettop(L); if (count == 1) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #if UNITY_5_4_OR_NEWER else if (count == 2) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Transform arg1 = (UnityEngine.Transform)ToLua.CheckObject(L, 2); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #endif else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Vector3 arg1 = ToLua.ToVector3(L, 2); UnityEngine.Quaternion arg2 = ToLua.ToQuaternion(L, 3); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1, arg2); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #if UNITY_5_4_OR_NEWER else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Transform arg1 = (UnityEngine.Transform)ToLua.ToObject(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1, arg2); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } else if (count == 4) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Vector3 arg1 = ToLua.CheckVector3(L, 2); UnityEngine.Quaternion arg2 = ToLua.CheckQuaternion(L, 3); UnityEngine.Transform arg3 = (UnityEngine.Transform)ToLua.CheckObject(L, 4); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1, arg2, arg3); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #endif else { LuaException.L = L0; --LuaException.InstantiateCount; return LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.Object.Instantiate"); } } catch (Exception e) { LuaException.L = L0; --LuaException.InstantiateCount; return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int DestroyImmediate(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); ToLua.Destroy(L); UnityEngine.Object.DestroyImmediate(arg0); return 0; } else if (count == 2) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); bool arg1 = LuaDLL.luaL_checkboolean(L, 2); ToLua.Destroy(L); UnityEngine.Object.DestroyImmediate(arg0, arg1); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: Object.DestroyImmediate"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Destroy(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); ToLua.Destroy(L); UnityEngine.Object.Destroy(arg0); return 0; } else if (count == 2) { float arg1 = (float)LuaDLL.luaL_checknumber(L, 2); int udata = LuaDLL.tolua_rawnetobj(L, 1); ObjectTranslator translator = LuaState.GetTranslator(L); translator.DelayDestroy(udata, arg1); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: Object.Destroy"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_name(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); UnityEngine.Object obj = (UnityEngine.Object)o; string ret = obj.name; LuaDLL.lua_pushstring(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index name on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_hideFlags(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); UnityEngine.Object obj = (UnityEngine.Object)o; UnityEngine.HideFlags ret = obj.hideFlags; LuaDLL.lua_pushinteger(L, (int)ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index hideFlags on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_name(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); UnityEngine.Object obj = (UnityEngine.Object)o; string arg0 = ToLua.CheckString(L, 2); obj.name = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index name on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_hideFlags(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); UnityEngine.Object obj = (UnityEngine.Object)o; UnityEngine.HideFlags arg0 = (UnityEngine.HideFlags)LuaDLL.luaL_checknumber(L, 2); obj.hideFlags = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index hideFlags on a nil value"); } } } ================================================ FILE: Assets/ToLua/BaseType/UnityEngine_ObjectWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 66f068299d0233f409ae0011b24ae1ba MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/BaseType.meta ================================================ fileFormatVersion: 2 guid: 337508ffab1cff64bbf7476789c95d59 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Core/LuaAttributes.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; namespace LuaInterface { [AttributeUsage(AttributeTargets.Method)] public sealed class MonoPInvokeCallbackAttribute : Attribute { public MonoPInvokeCallbackAttribute(Type type) { } } public class NoToLuaAttribute : System.Attribute { public NoToLuaAttribute() { } } public class UseDefinedAttribute : System.Attribute { public UseDefinedAttribute() { } } public class OverrideDefinedAttribute: System.Attribute { public OverrideDefinedAttribute() { } } public sealed class LuaByteBufferAttribute : Attribute { public LuaByteBufferAttribute() { } } [AttributeUsage(AttributeTargets.Method)] public sealed class LuaRenameAttribute : Attribute { public string Name; public LuaRenameAttribute() { } } } ================================================ FILE: Assets/ToLua/Core/LuaAttributes.cs.meta ================================================ fileFormatVersion: 2 guid: 036fab5eb22f19e4bba933e194fb4756 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaBaseRef.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Runtime.CompilerServices; using UnityEngine; namespace LuaInterface { public abstract class LuaBaseRef : IDisposable { public string name = null; protected int reference = -1; protected LuaState luaState; protected ObjectTranslator translator = null; protected volatile bool beDisposed; protected int count = 0; public LuaBaseRef() { IsAlive = true; count = 1; } ~LuaBaseRef() { IsAlive = false; Dispose(false); } public virtual void Dispose() { --count; if (count > 0) { return; } IsAlive = false; Dispose(true); } public void AddRef() { ++count; } public virtual void Dispose(bool disposeManagedResources) { if (!beDisposed) { beDisposed = true; if (reference > 0 && luaState != null) { luaState.CollectRef(reference, name, !disposeManagedResources); } reference = -1; luaState = null; count = 0; } } //慎用 public void Dispose(int generation) { if (count > generation) { return; } Dispose(true); } public LuaState GetLuaState() { return luaState; } public void Push() { luaState.Push(this); } public override int GetHashCode() { return RuntimeHelpers.GetHashCode(this); } public virtual int GetReference() { return reference; } public override bool Equals(object o) { if (o == null) return reference <= 0; LuaBaseRef lr = o as LuaBaseRef; if (lr == null || lr.reference != reference) { return false; } return reference > 0; } static bool CompareRef(LuaBaseRef a, LuaBaseRef b) { if (System.Object.ReferenceEquals(a, b)) { return true; } object l = a; object r = b; if (l == null && r != null) { return b.reference <= 0; } if (l != null && r == null) { return a.reference <= 0; } if (a.reference != b.reference) { return false; } return a.reference > 0; } public static bool operator == (LuaBaseRef a, LuaBaseRef b) { return CompareRef(a, b); } public static bool operator != (LuaBaseRef a, LuaBaseRef b) { return !CompareRef(a, b); } public volatile bool IsAlive = true; } } ================================================ FILE: Assets/ToLua/Core/LuaBaseRef.cs.meta ================================================ fileFormatVersion: 2 guid: 39292548101f65b41be91c5d20f20812 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaBeatEvent.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using LuaInterface; namespace LuaInterface { public class LuaBeatEvent : IDisposable { protected LuaState luaState; protected bool beDisposed; LuaTable self = null; LuaFunction _add = null; LuaFunction _remove = null; //LuaFunction _call = null; public LuaBeatEvent(LuaTable table) { self = table; luaState = table.GetLuaState(); self.AddRef(); _add = self.GetLuaFunction("Add"); _remove = self.GetLuaFunction("Remove"); //_call = self.GetLuaFunction("__call"); } public void Dispose() { self.Dispose(); _add.Dispose(); _remove.Dispose(); //_call.Dispose(); Clear(); } void Clear() { //_call = null; _add = null; _remove = null; self = null; luaState = null; } public void Dispose(bool disposeManagedResources) { if (!beDisposed) { beDisposed = true; //if (_call != null) //{ // _call.Dispose(disposeManagedResources); // _call = null; //} if (_add != null) { _add.Dispose(disposeManagedResources); _add = null; } if (_remove != null) { _remove.Dispose(disposeManagedResources); _remove = null; } if (self != null) { self.Dispose(disposeManagedResources); } Clear(); } } public void Add(LuaFunction func, LuaTable obj) { if (func == null) { return; } _add.BeginPCall(); _add.Push(self); _add.Push(func); _add.Push(obj); _add.PCall(); _add.EndPCall(); } public void Remove(LuaFunction func, LuaTable obj) { if (func == null) { return; } _remove.BeginPCall(); _remove.Push(self); _remove.Push(func); _remove.Push(obj); _remove.PCall(); _remove.EndPCall(); } //public override int GetReference() //{ // return self.GetReference(); //} } } ================================================ FILE: Assets/ToLua/Core/LuaBeatEvent.cs.meta ================================================ fileFormatVersion: 2 guid: c7332596f22ac5446852c531d7148318 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaDLL.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Runtime.InteropServices; using System.Reflection; using System.Collections; using System.Text; using System.Security; namespace LuaInterface { public enum LuaTypes { LUA_TNONE = -1, LUA_TNIL = 0, LUA_TBOOLEAN = 1, LUA_TLIGHTUSERDATA = 2, LUA_TNUMBER = 3, LUA_TSTRING = 4, LUA_TTABLE = 5, LUA_TFUNCTION = 6, LUA_TUSERDATA = 7, LUA_TTHREAD = 8, } public enum LuaGCOptions { LUA_GCSTOP = 0, LUA_GCRESTART = 1, LUA_GCCOLLECT = 2, LUA_GCCOUNT = 3, LUA_GCCOUNTB = 4, LUA_GCSTEP = 5, LUA_GCSETPAUSE = 6, LUA_GCSETSTEPMUL = 7, } public enum LuaThreadStatus { LUA_YIELD = 1, LUA_ERRRUN = 2, LUA_ERRSYNTAX = 3, LUA_ERRMEM = 4, LUA_ERRERR = 5, } public enum LuaHookFlag { LUA_HOOKCALL = 0, LUA_HOOKRET = 1, LUA_HOOKLINE = 2, LUA_HOOKCOUNT = 3, LUA_HOOKTAILRET = 4, } public enum LuaMask { LUA_MASKCALL = 1, //1 << LUA_HOOKCALL LUA_MASKRET = 2, //(1 << LUA_HOOKRET) LUA_MASKLINE = 4,// (1 << LUA_HOOKLINE) LUA_MASKCOUNT = 8, // (1 << LUA_HOOKCOUNT) } public class LuaIndexes { public static int LUA_REGISTRYINDEX = -10000; public static int LUA_ENVIRONINDEX = -10001; public static int LUA_GLOBALSINDEX = -10002; } public class LuaRIDX { public int LUA_RIDX_MAINTHREAD = 1; public int LUA_RIDX_GLOBALS = 2; public int LUA_RIDX_PRELOAD = 25; public int LUA_RIDX_LOADED = 26; } public static class ToLuaFlags { public const int INDEX_ERROR = 1; //Index 失败提示error信息,false返回nil public const int USE_INT64 = 2; //是否luavm内部支持原生int64(目前用的vm都不支持, 默认false) } [StructLayout(LayoutKind.Sequential)] public struct Lua_Debug { public int eventcode; public IntPtr _name; /* (n) */ public IntPtr _namewhat; /* (n) `global', `local', `field', `method' */ public IntPtr _what; /* (S) `Lua', `C', `main', `tail' */ public IntPtr _source; /* (S) */ public int currentline; /* (l) */ public int nups; /* (u) number of upvalues */ public int linedefined; /* (S) */ public int lastlinedefined; /* (S) */ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] _short_src; public int i_ci; /* active function */ string tostring(IntPtr p) { if (p != IntPtr.Zero) { int len = LuaDLL.tolua_strlen(p); return LuaDLL.lua_ptrtostring(p, len); } return string.Empty; } public string namewhat { get { return tostring(_namewhat); } } public string name { get { return tostring(_name); } } public string what { get { return tostring(_what); } } public string source { get { return tostring(_source); } } int GetShortSrcLen(byte[] str) { int i = 0; for (; i < 128; i++) { if (str[i] == '\0') { return i; } } return i; } public string short_src { get { if (_short_src == null) { return string.Empty; } int count = GetShortSrcLen(_short_src); return Encoding.UTF8.GetString(_short_src, 0, count); } } } #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_WSA_10_0 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int LuaCSFunction(IntPtr luaState); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void LuaHookFunc(IntPtr L, ref Lua_Debug ar); #else public delegate int LuaCSFunction(IntPtr luaState); public delegate void LuaHookFunc(IntPtr L, ref Lua_Debug ar); #endif public class LuaDLL { public static string version = "1.0.7.386"; public static int LUA_MULTRET = -1; public static string[] LuaTypeName = { "none", "nil", "boolean", "lightuserdata", "number", "string", "table", "function", "userdata", "thread" }; #if !UNITY_EDITOR && UNITY_IPHONE const string LUADLL = "__Internal"; #else const string LUADLL = "tolua"; #endif /* ** third party library */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_sproto_core(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_protobuf_c(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_pb(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_ffi(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_bit(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_struct(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_lpeg(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_socket_core(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_mime_core(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_cjson(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaopen_cjson_safe(IntPtr L); /* ** pseudo-indices */ public static int lua_upvalueindex(int i) { return LuaIndexes.LUA_GLOBALSINDEX - i; } /* * state manipulation */ //[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] //public static extern IntPtr lua_newstate(LuaAlloc f, IntPtr ud); //luajit64位不能用这个函数 [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_close(IntPtr luaState); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] //[-0, +1, m] public static extern IntPtr lua_newthread(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr lua_atpanic(IntPtr luaState, IntPtr panic); /* * basic stack manipulation */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_gettop(IntPtr luaState); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_settop(IntPtr luaState, int top); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_pushvalue(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_remove(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_insert(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_replace(IntPtr luaState, int index); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_checkstack(IntPtr luaState, int extra); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_xmove(IntPtr from, IntPtr to, int n); /* * access functions (stack -> C) */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_isnumber(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_isstring(IntPtr luaState, int index); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_iscfunction(IntPtr luaState, int index); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_isuserdata(IntPtr luaState, int stackPos); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern LuaTypes lua_type(IntPtr luaState, int index); public static string lua_typename(IntPtr luaState, LuaTypes type) { int t = (int)type; return LuaTypeName[t + 1]; } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_equal(IntPtr luaState, int idx1, int idx2); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_rawequal(IntPtr luaState, int idx1, int idx2); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_lessthan(IntPtr luaState, int idx1, int idx2); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern double lua_tonumber(IntPtr luaState, int idx); public static int lua_tointeger(IntPtr luaState, int idx) { return tolua_tointeger(luaState, idx); } public static bool lua_toboolean(IntPtr luaState, int idx) { return tolua_toboolean(luaState, idx); } public static IntPtr lua_tolstring(IntPtr luaState, int index, out int strLen) //[-0, +0, m] { return tolua_tolstring(luaState, index, out strLen); } public static int lua_objlen(IntPtr luaState, int idx) { return tolua_objlen(luaState, idx); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr lua_tocfunction(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr lua_touserdata(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr lua_tothread(IntPtr L, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr lua_topointer(IntPtr L, int idx); /* * push functions (C -> stack) */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_pushnil(IntPtr luaState); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_pushnumber(IntPtr luaState, double number); public static void lua_pushinteger(IntPtr L, int n) { lua_pushnumber(L, n); } public static void lua_pushlstring(IntPtr luaState, byte[] str, int size) //[-0, +1, m] { if (size >= 0x7fffff00) { throw new LuaException("string length overflow"); } tolua_pushlstring(luaState, str, size); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_pushstring(IntPtr luaState, string str); //[-0, +1, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_pushcclosure(IntPtr luaState, IntPtr fn, int n); //[-n, +1, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_pushboolean(IntPtr luaState, int value); public static void lua_pushboolean(IntPtr luaState, bool value) { lua_pushboolean(luaState, value ? 1 : 0); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_pushlightuserdata(IntPtr luaState, IntPtr udata); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_pushthread(IntPtr L); /* * get functions (Lua -> stack) */ public static void lua_gettable(IntPtr L, int idx) { if (LuaDLL.tolua_gettable(L, idx) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } public static void lua_getfield(IntPtr L, int idx, string key) { if (LuaDLL.tolua_getfield(L, idx, key) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_rawget(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_rawgeti(IntPtr luaState, int idx, int n); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_createtable(IntPtr luaState, int narr, int nrec); //[-0, +1, m] public static IntPtr lua_newuserdata(IntPtr luaState, int size) //[-0, +1, m] { return tolua_newuserdata(luaState, size); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_getmetatable(IntPtr luaState, int objIndex); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_getfenv(IntPtr luaState, int idx); /* * set functions (stack -> Lua) */ public static void lua_settable(IntPtr L, int idx) { if (tolua_settable(L, idx) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } public static void lua_setfield(IntPtr L, int idx, string key) { if (tolua_setfield(L, idx, key) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_rawset(IntPtr luaState, int idx); //[-2, +0, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_rawseti(IntPtr luaState, int tableIndex, int index); //[-1, +0, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_setmetatable(IntPtr luaState, int objIndex); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_setfenv(IntPtr luaState, int stackPos); /* * `load' and `call' functions (load and run Lua code) */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_call(IntPtr luaState, int nArgs, int nResults); //[-(nargs+1), +nresults, e] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_cpcall(IntPtr L, IntPtr func, IntPtr ud); //[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] //public static extern int lua_load(IntPtr luaState, LuaChunkReader chunkReader, ref ReaderInfo data, string chunkName); //[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] //public static extern int lua_dump(IntPtr L, LuaWriter writer, IntPtr data); /* * coroutine functions */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_yield(IntPtr L, int nresults); //[-?, +?, e] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_resume(IntPtr L, int narg); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_status(IntPtr L); /* * garbage-collection function and options */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_gc(IntPtr luaState, LuaGCOptions what, int data); //[-0, +0, e] /* * miscellaneous functions */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_next(IntPtr luaState, int index); //[-1, +(2|0), e] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void lua_concat(IntPtr luaState, int n); //[-n, +1, e] /* ** =============================================================== ** some useful functions ** =============================================================== */ public static void lua_pop(IntPtr luaState, int amount) { LuaDLL.lua_settop(luaState, -(amount) - 1); } public static void lua_newtable(IntPtr luaState) { LuaDLL.lua_createtable(luaState, 0, 0); } public static void lua_register(IntPtr luaState, string name, LuaCSFunction func) { lua_pushcfunction(luaState, func); lua_setglobal(luaState, name); } public static void lua_pushcfunction(IntPtr luaState, LuaCSFunction func) { IntPtr fn = Marshal.GetFunctionPointerForDelegate(func); lua_pushcclosure(luaState, fn, 0); } public static bool lua_isfunction(IntPtr luaState, int n) { return lua_type(luaState, n) == LuaTypes.LUA_TFUNCTION; } public static bool lua_istable(IntPtr luaState, int n) { return lua_type(luaState, n) == LuaTypes.LUA_TTABLE; } public static bool lua_islightuserdata(IntPtr luaState, int n) { return lua_type(luaState, n) == LuaTypes.LUA_TLIGHTUSERDATA; } public static bool lua_isnil(IntPtr luaState, int n) { return (lua_type(luaState, n) == LuaTypes.LUA_TNIL); } public static bool lua_isboolean(IntPtr luaState, int n) { LuaTypes type = lua_type(luaState, n); return type == LuaTypes.LUA_TBOOLEAN || type == LuaTypes.LUA_TNIL; } public static bool lua_isthread(IntPtr luaState, int n) { return lua_type(luaState, n) == LuaTypes.LUA_TTHREAD; } public static bool lua_isnone(IntPtr luaState, int n) { return lua_type(luaState, n) == LuaTypes.LUA_TNONE; } public static bool lua_isnoneornil(IntPtr luaState, int n) { return lua_type(luaState, n) <= LuaTypes.LUA_TNIL; } public static void lua_setglobal(IntPtr luaState, string name) { lua_setfield(luaState, LuaIndexes.LUA_GLOBALSINDEX, name); } public static void lua_getglobal(IntPtr luaState, string name) { lua_getfield(luaState, LuaIndexes.LUA_GLOBALSINDEX, name); } public static string lua_ptrtostring(IntPtr str, int len) { string ss = Marshal.PtrToStringAnsi(str, len); if (ss == null) { byte[] buffer = new byte[len]; Marshal.Copy(str, buffer, 0, len); return Encoding.UTF8.GetString(buffer); } return ss; } public static string lua_tostring(IntPtr luaState, int index) { int len = 0; IntPtr str = tolua_tolstring(luaState, index, out len); if (str != IntPtr.Zero) { return lua_ptrtostring(str, len); } return null; } public static IntPtr lua_open() { return luaL_newstate(); } public static void lua_getregistry(IntPtr L) { lua_pushvalue(L, LuaIndexes.LUA_REGISTRYINDEX); } public static int lua_getgccount(IntPtr L) { return lua_gc(L, LuaGCOptions.LUA_GCCOUNT, 0); } /* ** ====================================================================== ** Debug API ** ======================================================================= */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_getstack(IntPtr L, int level, ref Lua_Debug ar); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_getinfo(IntPtr L, string what, ref Lua_Debug ar); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern string lua_getlocal(IntPtr L, ref Lua_Debug ar, int n); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern string lua_setlocal(IntPtr L, ref Lua_Debug ar, int n); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern string lua_getupvalue(IntPtr L, int funcindex, int n); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern string lua_setupvalue(IntPtr L, int funcindex, int n); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_sethook(IntPtr L, LuaHookFunc func, int mask, int count); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern LuaHookFunc lua_gethook(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_gethookmask(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int lua_gethookcount(IntPtr L); //lualib.h [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void luaL_openlibs(IntPtr luaState); //lauxlib.h public static int abs_index(IntPtr L, int i) { return (i > 0 || i <= LuaIndexes.LUA_REGISTRYINDEX) ? i : lua_gettop(L) + i + 1; } public static int luaL_getn(IntPtr luaState, int i) { return (int)tolua_getn(luaState, i); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaL_getmetafield(IntPtr luaState, int stackPos, string field); //[-0, +(0|1), m] public static int luaL_callmeta(IntPtr L, int stackPos, string field) //[-0, +(0|1), m] { stackPos = abs_index(L, stackPos); if (luaL_getmetafield(L, stackPos, field) == 0) /* no metafield? */ { return 0; } lua_pushvalue(L, stackPos); if (lua_pcall(L, 1, 1, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); lua_pop(L, 1); throw new LuaException(error); } return 1; } public static int luaL_argerror(IntPtr L, int narg, string extramsg) { if (tolua_argerror(L, narg, extramsg) != 0) { string error = LuaDLL.lua_tostring(L, -1); lua_pop(L, 1); throw new LuaException(error); } return 0; } public static int luaL_typerror(IntPtr L, int stackPos, string tname, string t2 = null) { if (t2 == null) { t2 = luaL_typename(L, stackPos); } string msg = string.Format("{0} expected, got {1}", tname, t2); return luaL_argerror(L, stackPos, msg); } public static string luaL_checklstring(IntPtr L, int numArg, out int len) { IntPtr str = tolua_tolstring(L, numArg, out len); if (str == IntPtr.Zero) { luaL_typerror(L, numArg, "string"); return null; } return lua_ptrtostring(str, len); } public static string luaL_optlstring(IntPtr L, int narg, string def, out int len) { if (lua_isnoneornil(L, narg)) { len = def != null ? def.Length : 0; return def; } return luaL_checklstring(L, narg, out len); } public static double luaL_checknumber(IntPtr L, int stackPos) { double d = lua_tonumber(L, stackPos); if (d == 0 && LuaDLL.lua_isnumber(L, stackPos) == 0) { luaL_typerror(L, stackPos, "number"); return 0; } return d; } public static double luaL_optnumber(IntPtr L, int idx, double def) { if (lua_isnoneornil(L, idx)) { return def; } return luaL_checknumber(L, idx); } public static int luaL_checkinteger(IntPtr L, int stackPos) { int d = tolua_tointeger(L, stackPos); if (d == 0 && lua_isnumber(L, stackPos) == 0) { luaL_typerror(L, stackPos, "number"); return 0; } return d; } public static int luaL_optinteger(IntPtr L, int idx, int def) { if (lua_isnoneornil(L, idx)) { return def; } return luaL_checkinteger(L, idx); } public static bool luaL_checkboolean(IntPtr luaState, int index) { if (lua_isboolean(luaState, index)) { return lua_toboolean(luaState, index); } luaL_typerror(luaState, index, "boolean"); return false; } public static void luaL_checkstack(IntPtr L, int space, string mes) { if (lua_checkstack(L, space) == 0) { throw new LuaException(string.Format("stack overflow {0}", mes)); } } public static void luaL_checktype(IntPtr L, int narg, LuaTypes t) { if (lua_type(L, narg) != t) { luaL_typerror(L, narg, lua_typename(L, t)); } } public static void luaL_checkany(IntPtr L, int narg) { if (lua_type(L, narg) == LuaTypes.LUA_TNONE) { luaL_argerror(L, narg, "value expected"); } } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaL_newmetatable(IntPtr luaState, string meta); //[-0, +1, m] public static IntPtr luaL_checkudata(IntPtr L, int ud, string tname) { IntPtr p = lua_touserdata(L, ud); if (p != IntPtr.Zero) { if (lua_getmetatable(L, ud) != 0) { lua_getfield(L, LuaIndexes.LUA_REGISTRYINDEX, tname); /* get correct metatable */ if (lua_rawequal(L, -1, -2) != 0) { /* does it have the correct mt? */ lua_pop(L, 2); /* remove both metatables */ return p; } } } luaL_typerror(L, ud, tname); /* else error */ return IntPtr.Zero; /* to avoid warnings */ } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void luaL_where(IntPtr luaState, int level); //[-0, +1, e] //[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] //public static extern int luaL_error(IntPtr luaState, string message); public static int luaL_throw(IntPtr L, string message) { tolua_pushtraceback(L); lua_pushstring(L, message); lua_pushnumber(L, 1); if (lua_pcall(L, 2, -1, 0) == 0) { message = lua_tostring(L, -1); } else { lua_pop(L, 1); } throw new LuaException(message, null, 2); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaL_ref(IntPtr luaState, int t); //[-1, +0, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void luaL_unref(IntPtr luaState, int registryIndex, int reference); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaL_loadfile(IntPtr luaState, string filename); //[-0, +1, e] public static int luaL_loadbuffer(IntPtr luaState, byte[] buff, int size, string name) { return tolua_loadbuffer(luaState, buff, size, name); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int luaL_loadstring(IntPtr luaState, string chunk); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr luaL_newstate(); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr luaL_gsub(IntPtr luaState, string str, string pattern, string replacement); //[-0, +1, e] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr luaL_findtable(IntPtr luaState, int idx, string fname, int szhint = 1); /* ** =============================================================== ** some useful functions ** =============================================================== */ public static string luaL_typename(IntPtr luaState, int stackPos) { LuaTypes type = LuaDLL.lua_type(luaState, stackPos); return lua_typename(luaState, type); } public static bool luaL_dofile(IntPtr luaState, string fileName) //[-0, +1, e] { int result = luaL_loadfile(luaState, fileName); if (result != 0) { return false; } return LuaDLL.lua_pcall(luaState, 0, LUA_MULTRET, 0) == 0; } public static bool luaL_dostring(IntPtr luaState, string chunk) { int result = LuaDLL.luaL_loadstring(luaState, chunk); if (result != 0) { return false; } return LuaDLL.lua_pcall(luaState, 0, LUA_MULTRET, 0) == 0; } public static void luaL_getmetatable(IntPtr luaState, string meta) { LuaDLL.lua_getfield(luaState, LuaIndexes.LUA_REGISTRYINDEX, meta); } /* compatibility with ref system */ public static int lua_ref(IntPtr luaState) { return LuaDLL.luaL_ref(luaState, LuaIndexes.LUA_REGISTRYINDEX); } public static void lua_getref(IntPtr luaState, int reference) { lua_rawgeti(luaState, LuaIndexes.LUA_REGISTRYINDEX, reference); } public static void lua_unref(IntPtr luaState, int reference) { luaL_unref(luaState, LuaIndexes.LUA_REGISTRYINDEX, reference); } /* ** ====================================================== ** tolua libs ** ======================================================= */ [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_openlibs(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_openint64(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_openlualibs(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tolua_tag(); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_newudata(IntPtr luaState, int val); //[-0, +0, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_rawnetobj(IntPtr luaState, int obj); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_pushudata(IntPtr L, int index); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_pushnewudata(IntPtr L, int metaRef, int index); //[-0, +0, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_beginpcall(IntPtr L, int reference); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushtraceback(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_getvec2(IntPtr luaState, int stackPos, out float x, out float y); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_getvec3(IntPtr luaState, int stackPos, out float x, out float y, out float z); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_getvec4(IntPtr luaState, int stackPos, out float x, out float y, out float z, out float w); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_getclr(IntPtr luaState, int stackPos, out float r, out float g, out float b, out float a); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_getquat(IntPtr luaState, int stackPos, out float x, out float y, out float z, out float w); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_getlayermask(IntPtr luaState, int stackPos); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushvec2(IntPtr luaState, float x, float y); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushvec3(IntPtr luaState, float x, float y, float z); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushvec4(IntPtr luaState, float x, float y, float z, float w); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushquat(IntPtr luaState, float x, float y, float z, float w); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushclr(IntPtr luaState, float r, float g, float b, float a); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushlayermask(IntPtr luaState, int mask); public static bool tolua_isint64(IntPtr luaState, int stackPos) { return lua_isnumber(luaState, stackPos) != 0; } public static long tolua_toint64(IntPtr luaState, int stackPos) { return (long)lua_tonumber(luaState, stackPos); } public static long tolua_checkint64(IntPtr L, int stackPos) { return (long)luaL_checknumber(L, stackPos); } public static void tolua_pushint64(IntPtr luaState, long n) { lua_pushnumber(luaState, n); } public static bool tolua_isuint64(IntPtr luaState, int stackPos) { return lua_isnumber(luaState, stackPos) != 0; } public static ulong tolua_touint64(IntPtr luaState, int stackPos) { return (ulong)lua_tonumber(luaState, stackPos); } public static ulong tolua_checkuint64(IntPtr L, int stackPos) { return (ulong)luaL_checknumber(L, stackPos); } public static void tolua_pushuint64(IntPtr luaState, ulong n) { lua_pushnumber(luaState, n); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_setindex(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_setnewindex(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int toluaL_ref(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void toluaL_unref(IntPtr L, int reference); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tolua_getmainstate(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_getvaluetype(IntPtr L, int stackPos); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_createtable(IntPtr L, string fullPath, int szhint = 0); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_pushluatable(IntPtr L, string fullPath); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_beginmodule(IntPtr L, string name); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_endmodule(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_beginpremodule(IntPtr L, string fullPath, int szhint = 0); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_endpremodule(IntPtr L, int reference); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_addpreload(IntPtr L, string path); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_beginclass(IntPtr L, string name, int baseMetaRef, int reference = -1); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_endclass(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_function(IntPtr L, string name, IntPtr fn); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tolua_tocbuffer(string name, int sz); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_freebuffer(IntPtr buffer); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_variable(IntPtr L, string name, IntPtr get, IntPtr set); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_constant(IntPtr L, string name, double val); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_beginenum(IntPtr L, string name); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_endenum(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_beginstaticclass(IntPtr L, string name); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_endstaticclass(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_require(IntPtr L, string fileName); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_getmetatableref(IntPtr L, int pos); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_setflag(int bit, [MarshalAs(UnmanagedType.I1)]bool flag); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_isvptrtable(IntPtr L, int index); public static int toluaL_exception(IntPtr L, Exception e) { LuaException.luaStack = new LuaException(e.Message, e, 2); return tolua_error(L, e.Message); } public static int toluaL_exception(IntPtr L, Exception e, object o, string msg) { if (o != null && !o.Equals(null)) { msg = e.Message; } LuaException.luaStack = new LuaException(msg, e, 2); return tolua_error(L, msg); } //适配函数 [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_loadbuffer(IntPtr luaState, byte[] buff, int size, string name); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool tolua_toboolean(IntPtr luaState, int index); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_tointeger(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tolua_tolstring(IntPtr luaState, int index, out int strLen); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushlstring(IntPtr luaState, byte[] str, int size); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_objlen(IntPtr luaState, int stackPos); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tolua_newuserdata(IntPtr luaState, int size); //[-0, +1, m] [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_argerror(IntPtr luaState, int narg, string extramsg); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_error(IntPtr L, string msg); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_getfield(IntPtr L, int idx, string key); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_setfield(IntPtr L, int idx, string key); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_gettable(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_settable(IntPtr luaState, int idx); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_getn(IntPtr luaState, int stackPos); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_strlen(IntPtr str); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushcfunction(IntPtr L, IntPtr fn); public static void tolua_pushcfunction(IntPtr luaState, LuaCSFunction func) { IntPtr fn = Marshal.GetFunctionPointerForDelegate(func); tolua_pushcfunction(luaState, fn); } public static string tolua_findtable(IntPtr L, int idx, string name, int size = 1) { int oldTop = lua_gettop(L); IntPtr p = LuaDLL.luaL_findtable(L, idx, name, size); if (p != IntPtr.Zero) { LuaDLL.lua_settop(L, oldTop); int len = LuaDLL.tolua_strlen(p); return LuaDLL.lua_ptrtostring(p, len); } return null; } public static IntPtr tolua_atpanic(IntPtr L, LuaCSFunction func) { IntPtr fn = Marshal.GetFunctionPointerForDelegate(func); return lua_atpanic(L, fn); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tolua_buffinit(IntPtr luaState); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_addlstring(IntPtr b, string str, int l); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_addstring(IntPtr b, string s); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_addchar(IntPtr b, byte s); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_pushresult(IntPtr b); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_update(IntPtr L, float deltaTime, float unscaledDelta); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_lateupdate(IntPtr L); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_fixedupdate(IntPtr L, float fixedTime); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern void tolua_regthis(IntPtr L, IntPtr get, IntPtr set); [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_where(IntPtr L, int level); public static void tolua_bindthis(IntPtr L, LuaCSFunction get, LuaCSFunction set) { IntPtr pGet = IntPtr.Zero; IntPtr pSet = IntPtr.Zero; if (get != null) { pGet = Marshal.GetFunctionPointerForDelegate(get); } if (set != null) { pSet = Marshal.GetFunctionPointerForDelegate(set); } tolua_regthis(L, pGet, pSet); } [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] public static extern int tolua_getclassref(IntPtr L, int pos); } } ================================================ FILE: Assets/ToLua/Core/LuaDLL.cs.meta ================================================ fileFormatVersion: 2 guid: d60cef534e986e849a829838fbeb74b5 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaEvent.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using LuaInterface; namespace LuaInterface { public class LuaEvent : IDisposable { protected LuaState luaState; protected bool beDisposed; LuaTable self = null; LuaFunction _add = null; LuaFunction _remove = null; //LuaFunction _call = null; public LuaEvent(LuaTable table) { self = table; luaState = table.GetLuaState(); self.AddRef(); _add = self.GetLuaFunction("Add"); _remove = self.GetLuaFunction("Remove"); //_call = self.GetLuaFunction("__call"); } public void Dispose() { self.Dispose(); _add.Dispose(); _remove.Dispose(); //_call.Dispose(); Clear(); } void Clear() { //_call = null; _add = null; _remove = null; self = null; luaState = null; } public void Dispose(bool disposeManagedResources) { if (!beDisposed) { beDisposed = true; //if (_call != null) //{ // _call.Dispose(disposeManagedResources); // _call = null; //} if (_add != null) { _add.Dispose(disposeManagedResources); _add = null; } if (_remove != null) { _remove.Dispose(disposeManagedResources); _remove = null; } if (self != null) { self.Dispose(disposeManagedResources); } Clear(); } } public void Add(LuaFunction func, LuaTable obj) { if (func == null) { return; } _add.BeginPCall(); _add.Push(self); _add.Push(func); _add.Push(obj); _add.PCall(); _add.EndPCall(); } public void Remove(LuaFunction func, LuaTable obj) { if (func == null) { return; } _remove.BeginPCall(); _remove.Push(self); _remove.Push(func); _remove.Push(obj); _remove.PCall(); _remove.EndPCall(); } //public override int GetReference() //{ // return self.GetReference(); //} } } ================================================ FILE: Assets/ToLua/Core/LuaEvent.cs.meta ================================================ fileFormatVersion: 2 guid: ce5b2d0ac4f71564c84ecc85556409a4 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaException.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Diagnostics; using System.Reflection; using System.Text; using UnityEngine; namespace LuaInterface { public class LuaException : Exception { public static Exception luaStack = null; public static string projectFolder = null; public static int InstantiateCount = 0; public static int SendMsgCount = 0; public static IntPtr L = IntPtr.Zero; public override string StackTrace { get { return _stack; } } protected string _stack = string.Empty; public LuaException(string msg, Exception e = null, int skip = 1) : base(msg) { if (e != null) { if (e is LuaException) { _stack = e.StackTrace; } else { StackTrace trace = new StackTrace(e, true); StringBuilder sb = new StringBuilder(); ExtractFormattedStackTrace(trace, sb); StackTrace self = new StackTrace(skip, true); ExtractFormattedStackTrace(self, sb, trace); _stack = sb.ToString(); } } else { StackTrace self = new StackTrace(skip, true); StringBuilder sb = new StringBuilder(); ExtractFormattedStackTrace(self, sb); _stack = sb.ToString(); } } public static Exception GetLastError() { Exception last = luaStack; luaStack = null; return last; } public static void ExtractFormattedStackTrace(StackTrace trace, StringBuilder sb, StackTrace skip = null) { int begin = 0; if (skip != null && skip.FrameCount > 0) { MethodBase m0 = skip.GetFrame(skip.FrameCount - 1).GetMethod(); for (int i = 0; i < trace.FrameCount; i++) { StackFrame frame = trace.GetFrame(i); MethodBase method = frame.GetMethod(); if (method == m0) { begin = i + 1; break; } } sb.AppendLineEx(); } for (int i = begin; i < trace.FrameCount; i++) { StackFrame frame = trace.GetFrame(i); MethodBase method = frame.GetMethod(); if (method == null || method.DeclaringType == null) { continue; } Type declaringType = method.DeclaringType; string str = declaringType.Namespace; if ( (InstantiateCount == 0 && declaringType == typeof(UnityEngine.Object) && method.Name == "Instantiate") //(method.Name == "Internal_CloneSingle" || (SendMsgCount == 0 && declaringType == typeof(GameObject) && method.Name == "SendMessage")) { break; } if ((str != null) && (str.Length != 0)) { sb.Append(str); sb.Append("."); } sb.Append(declaringType.Name); sb.Append(":"); sb.Append(method.Name); sb.Append("("); int index = 0; ParameterInfo[] parameters = method.GetParameters(); bool flag = true; while (index < parameters.Length) { if (!flag) { sb.Append(", "); } else { flag = false; } sb.Append(parameters[index].ParameterType.Name); index++; } sb.Append(")"); string fileName = frame.GetFileName(); if (fileName != null) { fileName = fileName.Replace('\\', '/'); sb.Append(" (at "); if (fileName.StartsWith(projectFolder)) { fileName = fileName.Substring(projectFolder.Length, fileName.Length - projectFolder.Length); } sb.Append(fileName); sb.Append(":"); sb.Append(frame.GetFileLineNumber().ToString()); sb.Append(")"); } if (i != trace.FrameCount - 1) { sb.Append("\n"); } } } public static void Init(IntPtr L0) { L = L0; Type type = typeof(StackTraceUtility); FieldInfo field = type.GetField("projectFolder", BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic); LuaException.projectFolder = (string)field.GetValue(null); projectFolder = projectFolder.Replace('\\', '/'); #if DEVELOPER Debugger.Log("projectFolder is {0}", projectFolder); #endif } } } ================================================ FILE: Assets/ToLua/Core/LuaException.cs.meta ================================================ fileFormatVersion: 2 guid: 1b37c8a2d4e86364c85c26a407d79af7 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaFileUtils.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System.Collections.Generic; using System.IO; using System.Collections; using System.Text; namespace LuaInterface { public class LuaFileUtils { public static LuaFileUtils Instance { get { if (instance == null) { instance = new LuaFileUtils(); } return instance; } protected set { instance = value; } } //beZip = false 在search path 中查找读取lua文件。否则从外部设置过来bundel文件中读取lua文件 public bool beZip = false; protected List searchPaths = new List(); protected Dictionary zipMap = new Dictionary(); protected static LuaFileUtils instance = null; public LuaFileUtils() { instance = this; } public virtual void Dispose() { if (instance != null) { instance = null; searchPaths.Clear(); foreach (KeyValuePair iter in zipMap) { iter.Value.Unload(true); } zipMap.Clear(); } } //格式: 路径/?.lua public bool AddSearchPath(string path, bool front = false) { int index = searchPaths.IndexOf(path); if (index >= 0) { return false; } if (front) { searchPaths.Insert(0, path); } else { searchPaths.Add(path); } return true; } public bool RemoveSearchPath(string path) { int index = searchPaths.IndexOf(path); if (index >= 0) { searchPaths.RemoveAt(index); return true; } return false; } public void AddSearchBundle(string name, AssetBundle bundle) { zipMap[name] = bundle; } public string FindFile(string fileName) { if (fileName == string.Empty) { return string.Empty; } if (Path.IsPathRooted(fileName)) { if (!fileName.EndsWith(".lua")) { fileName += ".lua"; } return fileName; } if (fileName.EndsWith(".lua")) { fileName = fileName.Substring(0, fileName.Length - 4); } string fullPath = null; for (int i = 0; i < searchPaths.Count; i++) { fullPath = searchPaths[i].Replace("?", fileName); if (File.Exists(fullPath)) { return fullPath; } } return null; } public virtual byte[] ReadFile(string fileName) { if (!beZip) { string path = FindFile(fileName); byte[] str = null; if (!string.IsNullOrEmpty(path) && File.Exists(path)) { #if !UNITY_WEBPLAYER str = File.ReadAllBytes(path); #else throw new LuaException("can't run in web platform, please switch to other platform"); #endif } return str; } else { return ReadZipFile(fileName); } } public virtual string FindFileError(string fileName) { if (Path.IsPathRooted(fileName)) { return fileName; } if (fileName.EndsWith(".lua")) { fileName = fileName.Substring(0, fileName.Length - 4); } using (CString.Block()) { CString sb = CString.Alloc(512); for (int i = 0; i < searchPaths.Count; i++) { sb.Append("\n\tno file '").Append(searchPaths[i]).Append('\''); } sb = sb.Replace("?", fileName); if (beZip) { int pos = fileName.LastIndexOf('/'); if (pos > 0) { int tmp = pos + 1; sb.Append("\n\tno file '").Append(fileName, tmp, fileName.Length - tmp).Append(".lua' in ").Append("lua_"); tmp = sb.Length; sb.Append(fileName, 0, pos).Replace('/', '_', tmp, pos).Append(".unity3d"); } else { sb.Append("\n\tno file '").Append(fileName).Append(".lua' in ").Append("lua.unity3d"); } } return sb.ToString(); } } byte[] ReadZipFile(string fileName) { AssetBundle zipFile = null; byte[] buffer = null; string zipName = null; using (CString.Block()) { CString sb = CString.Alloc(256); sb.Append("lua"); int pos = fileName.LastIndexOf('/'); if (pos > 0) { sb.Append("_"); sb.Append(fileName, 0, pos).ToLower().Replace('/', '_'); fileName = fileName.Substring(pos + 1); } if (!fileName.EndsWith(".lua")) { fileName += ".lua"; } #if UNITY_5 || UNITY_5_3_OR_NEWER fileName += ".bytes"; #endif zipName = sb.ToString(); zipMap.TryGetValue(zipName, out zipFile); } if (zipFile != null) { #if UNITY_4_6 || UNITY_4_7 TextAsset luaCode = zipFile.Load(fileName, typeof(TextAsset)) as TextAsset; #else TextAsset luaCode = zipFile.LoadAsset(fileName); #endif if (luaCode != null) { buffer = luaCode.bytes; Resources.UnloadAsset(luaCode); } } return buffer; } public static string GetOSDir() { return LuaConst.osDir; } } } ================================================ FILE: Assets/ToLua/Core/LuaFileUtils.cs.meta ================================================ fileFormatVersion: 2 guid: bc1dfae6a246cdf418b607701b2dfc7c MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaFunction.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using UnityEngine; namespace LuaInterface { public class LuaFunction : LuaBaseRef { protected struct FuncData { public int oldTop; public int stackPos; public FuncData(int top, int stack) { oldTop = top; stackPos = stack; } } protected int oldTop = -1; private int argCount = 0; private int stackPos = -1; private Stack stack = new Stack(); public LuaFunction(int reference, LuaState state) { this.reference = reference; this.luaState = state; } public override void Dispose() { #if UNITY_EDITOR if (oldTop != -1 && count <= 1) { Debugger.LogError("You must call EndPCall before calling Dispose"); } #endif base.Dispose(); } public T ToDelegate() where T : class { return DelegateTraits.Create(this) as T; } public virtual int BeginPCall() { if (luaState == null) { throw new LuaException("LuaFunction has been disposed"); } stack.Push(new FuncData(oldTop, stackPos)); oldTop = luaState.BeginPCall(reference); stackPos = -1; argCount = 0; return oldTop; } public void PCall() { #if UNITY_EDITOR if (oldTop == -1) { Debugger.LogError("You must call BeginPCall before calling PCall"); } #endif stackPos = oldTop + 1; try { luaState.PCall(argCount, oldTop); } catch (Exception e) { EndPCall(); throw e; } } public void EndPCall() { if (oldTop != -1) { luaState.EndPCall(oldTop); argCount = 0; FuncData data = stack.Pop(); oldTop = data.oldTop; stackPos = data.stackPos; } } public void Call() { BeginPCall(); PCall(); EndPCall(); } public void Call(T1 arg1) { BeginPCall(); PushGeneric(arg1); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2, T3 arg3) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PushGeneric(arg7); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PushGeneric(arg7); PushGeneric(arg8); PCall(); EndPCall(); } public void Call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PushGeneric(arg7); PushGeneric(arg8); PushGeneric(arg9); PCall(); EndPCall(); } public R1 Invoke() { BeginPCall(); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1) { BeginPCall(); PushGeneric(arg1); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2, T3 arg3) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PushGeneric(arg7); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PushGeneric(arg7); PushGeneric(arg8); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } public R1 Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { BeginPCall(); PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); PushGeneric(arg7); PushGeneric(arg8); PushGeneric(arg9); PCall(); R1 ret1 = CheckValue(); EndPCall(); return ret1; } //慎用, 有gc alloc [System.Obsolete("LuaFunction.LazyCall() is obsolete.Use LuaFunction.Invoke()")] public object[] LazyCall(params object[] args) { BeginPCall(); int count = args == null ? 0 : args.Length; if (!luaState.LuaCheckStack(count + 6)) { EndPCall(); throw new LuaException("stack overflow"); } PushArgs(args); PCall(); object[] objs = luaState.CheckObjects(oldTop); EndPCall(); return objs; } public void CheckStack(int args) { luaState.LuaCheckStack(args + 6); } public bool IsBegin() { return oldTop != -1; } public void Push(double num) { luaState.Push(num); ++argCount; } public void Push(int n) { luaState.Push(n); ++argCount; } public void PushLayerMask(LayerMask n) { luaState.PushLayerMask(n); ++argCount; } public void Push(uint un) { luaState.Push(un); ++argCount; } public void Push(long num) { luaState.Push(num); ++argCount; } public void Push(ulong un) { luaState.Push(un); ++argCount; } public void Push(bool b) { luaState.Push(b); ++argCount; } public void Push(string str) { luaState.Push(str); ++argCount; } public void Push(IntPtr ptr) { luaState.Push(ptr); ++argCount; } public void Push(LuaBaseRef lbr) { luaState.Push(lbr); ++argCount; } public void Push(object o) { luaState.PushVariant(o); ++argCount; } public void Push(UnityEngine.Object o) { luaState.Push(o); ++argCount; } public void Push(Type t) { luaState.Push(t); ++argCount; } public void Push(Enum e) { luaState.Push(e); ++argCount; } public void Push(Array array) { luaState.Push(array); ++argCount; } public void Push(Vector3 v3) { luaState.Push(v3); ++argCount; } public void Push(Vector2 v2) { luaState.Push(v2); ++argCount; } public void Push(Vector4 v4) { luaState.Push(v4); ++argCount; } public void Push(Quaternion quat) { luaState.Push(quat); ++argCount; } public void Push(Color clr) { luaState.Push(clr); ++argCount; } public void Push(Ray ray) { try { luaState.Push(ray); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void Push(Bounds bounds) { try { luaState.Push(bounds); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void Push(RaycastHit hit) { try { luaState.Push(hit); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void Push(Touch t) { try { luaState.Push(t); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void Push(LuaByteBuffer buffer) { try { luaState.Push(buffer); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void PushValue(T value) where T : struct { try { luaState.PushValue(value); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void PushObject(object o) { try { luaState.PushObject(o); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void PushSealed(T o) { try { luaState.PushSealed(o); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void PushGeneric(T t) { try { luaState.PushGeneric(t); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public void PushArgs(object[] args) { if (args == null) { return; } argCount += args.Length; luaState.PushArgs(args); } public void PushByteBuffer(byte[] buffer, int len = -1) { try { if (len == -1) { len = buffer.Length; } luaState.PushByteBuffer(buffer, len); ++argCount; } catch (Exception e) { EndPCall(); throw e; } } public double CheckNumber() { try { return luaState.LuaCheckNumber(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public bool CheckBoolean() { try { return luaState.LuaCheckBoolean(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public string CheckString() { try { return luaState.CheckString(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Vector3 CheckVector3() { try { return luaState.CheckVector3(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Quaternion CheckQuaternion() { try { return luaState.CheckQuaternion(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Vector2 CheckVector2() { try { return luaState.CheckVector2(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Vector4 CheckVector4() { try { return luaState.CheckVector4(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Color CheckColor() { try { return luaState.CheckColor(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Color32 CheckColor32() { try { return luaState.CheckColor32(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Ray CheckRay() { try { return luaState.CheckRay(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Bounds CheckBounds() { try { return luaState.CheckBounds(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public LayerMask CheckLayerMask() { try { return luaState.CheckLayerMask(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public long CheckLong() { try { return luaState.CheckLong(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public ulong CheckULong() { try { return luaState.CheckULong(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public Delegate CheckDelegate() { try { return luaState.CheckDelegate(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public object CheckVariant() { return luaState.ToVariant(stackPos++); } public char[] CheckCharBuffer() { try { return luaState.CheckCharBuffer(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public byte[] CheckByteBuffer() { try { return luaState.CheckByteBuffer(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public object CheckObject(Type t) { try { return luaState.CheckObject(stackPos++, t); } catch (Exception e) { EndPCall(); throw e; } } public LuaFunction CheckLuaFunction() { try { return luaState.CheckLuaFunction(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public LuaTable CheckLuaTable() { try { return luaState.CheckLuaTable(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public LuaThread CheckLuaThread() { try { return luaState.CheckLuaThread(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } public T CheckValue() { try { return luaState.CheckValue(stackPos++); } catch (Exception e) { EndPCall(); throw e; } } } } ================================================ FILE: Assets/ToLua/Core/LuaFunction.cs.meta ================================================ fileFormatVersion: 2 guid: 8f2e7f7664506cc45b1e1d375c066432 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaMatchType.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System; using System.Collections; namespace LuaInterface { public class LuaMatchType { public bool CheckNumber(IntPtr L, int pos) { return LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TNUMBER; } public bool CheckBool(IntPtr L, int pos) { return LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TBOOLEAN; } public bool CheckLong(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNUMBER: return true; case LuaTypes.LUA_TUSERDATA: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Int64; default: return false; } } public bool CheckULong(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNUMBER: return LuaDLL.lua_tonumber(L, pos) >= 0; case LuaTypes.LUA_TUSERDATA: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.UInt64; default: return false; } } public bool CheckNullNumber(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); return luaType == LuaTypes.LUA_TNUMBER || luaType == LuaTypes.LUA_TNIL; } public bool CheckNullBool(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); return luaType == LuaTypes.LUA_TBOOLEAN || luaType == LuaTypes.LUA_TNIL; } public bool CheckNullLong(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TNUMBER: return true; case LuaTypes.LUA_TUSERDATA: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Int64; default: return false; } } public bool CheckNullULong(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TNUMBER: return true; case LuaTypes.LUA_TUSERDATA: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.UInt64; default: return false; } } public bool CheckString(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TSTRING: return true; case LuaTypes.LUA_TUSERDATA: return CheckClassType(typeof(string), L, pos); default: return false; } } public bool CheckByteArray(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TSTRING: return true; case LuaTypes.LUA_TUSERDATA: return CheckClassType(typeof(byte[]), L, pos); default: return false; } } public bool CheckCharArray(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TSTRING: return true; case LuaTypes.LUA_TUSERDATA: return CheckClassType(typeof(char[]), L, pos); default: return false; } } public bool CheckArray(Type t, IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return true; case LuaTypes.LUA_TUSERDATA: return CheckClassType(t, L, pos); default: return false; } } public bool CheckBoolArray(IntPtr L, int pos) { return CheckArray(typeof(bool[]), L, pos); } public bool CheckSByteArray(IntPtr L, int pos) { return CheckArray(typeof(sbyte[]), L, pos); } public bool CheckInt16Array(IntPtr L, int pos) { return CheckArray(typeof(short[]), L, pos); } public bool CheckUInt16Array(IntPtr L, int pos) { return CheckArray(typeof(ushort[]), L, pos); } public bool CheckDecimalArray(IntPtr L, int pos) { return CheckArray(typeof(decimal[]), L, pos); } public bool CheckSingleArray(IntPtr L, int pos) { return CheckArray(typeof(float[]), L, pos); } public bool CheckDoubleArray(IntPtr L, int pos) { return CheckArray(typeof(double[]), L, pos); } public bool CheckInt32Array(IntPtr L, int pos) { return CheckArray(typeof(int[]), L, pos); } public bool CheckUInt32Array(IntPtr L, int pos) { return CheckArray(typeof(uint[]), L, pos); } public bool CheckInt64Array(IntPtr L, int pos) { return CheckArray(typeof(long[]), L, pos); } public bool CheckUInt64Array(IntPtr L, int pos) { return CheckArray(typeof(ulong[]), L, pos); } public bool CheckStringArray(IntPtr L, int pos) { return CheckArray(typeof(string[]), L, pos); } public bool CheckTypeArray(IntPtr L, int pos) { return CheckArray(typeof(Type[]), L, pos); } public bool CheckObjectArray(IntPtr L, int pos) { return CheckArray(typeof(object[]), L, pos); } bool CheckValueType(IntPtr L, int pos, int valueType, Type nt) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { int vt = LuaDLL.tolua_getvaluetype(L, pos); return vt == valueType; } return false; } public bool CheckVec3(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Vector3; } return false; } public bool CheckQuat(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Quaternion; } return false; } public bool CheckVec2(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Vector2; } return false; } public bool CheckColor(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Color; } return false; } public bool CheckColor32(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Color32; } return false; } public bool CheckVec4(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Vector4; } return false; } public bool CheckRay(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Ray; } return false; } public bool CheckBounds(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Bounds; } return false; } public bool CheckTouch(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Touch; } return false; } public bool CheckLayerMask(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.LayerMask; } return false; } public bool CheckRaycastHit(IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TTABLE) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.RaycastHit; } return false; } public bool CheckNullVec3(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Vector3; default: return false; } } public bool CheckNullQuat(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Quaternion; default: return false; } } public bool CheckNullVec2(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Vector2; default: return false; } } public bool CheckNullColor(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Color; default: return false; } } public bool CheckNullColor32(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Color32; default: return false; } } public bool CheckNullVec4(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Vector4; default: return false; } } public bool CheckNullRay(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Ray; default: return false; } } public bool CheckNullBounds(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Bounds; default: return false; } } public bool CheckNullTouch(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Touch; default: return false; } } public bool CheckNullLayerMask(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.LayerMask; default: return false; } } public bool CheckNullRaycastHit(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.RaycastHit; default: return false; } } public bool CheckVec3Array(IntPtr L, int pos) { return CheckArray(typeof(Vector3[]), L, pos); } public bool CheckQuatArray(IntPtr L, int pos) { return CheckArray(typeof(Quaternion[]), L, pos); } public bool CheckVec2Array(IntPtr L, int pos) { return CheckArray(typeof(Vector2[]), L, pos); } public bool CheckVec4Array(IntPtr L, int pos) { return CheckArray(typeof(Vector4[]), L, pos); } public bool CheckColorArray(IntPtr L, int pos) { return CheckArray(typeof(Color[]), L, pos); } public bool CheckColor32Array(IntPtr L, int pos) { return CheckArray(typeof(Color32[]), L, pos); } public bool CheckPtr(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); return luaType == LuaTypes.LUA_TLIGHTUSERDATA || luaType == LuaTypes.LUA_TNIL; } public bool CheckLuaFunc(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); return luaType == LuaTypes.LUA_TFUNCTION || luaType == LuaTypes.LUA_TNIL; } public bool CheckLuaTable(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); return luaType == LuaTypes.LUA_TTABLE || luaType == LuaTypes.LUA_TNIL; } public bool CheckLuaThread(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); return luaType == LuaTypes.LUA_TTHREAD || luaType == LuaTypes.LUA_TNIL; } public bool CheckLuaBaseRef(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch(luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TFUNCTION: return true; case LuaTypes.LUA_TTABLE: return true; case LuaTypes.LUA_TTHREAD: return true; default: return false; } } public bool CheckByteBuffer(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); return luaType == LuaTypes.LUA_TSTRING || luaType == LuaTypes.LUA_TNIL; } public bool CheckEventObject(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TUSERDATA: return CheckClassType(typeof(EventObject), L, pos); default: return false; } } public bool CheckEnumerator(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TUSERDATA: int udata = LuaDLL.tolua_rawnetobj(L, pos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); return obj == null ? true : obj is IEnumerator; } return false; case LuaTypes.LUA_TTABLE: return true; default: return false; } } //不存在派生类的类型 bool CheckFinalType(Type type, IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TUSERDATA: return CheckClassType(type, L, pos); default: return false; } } public bool CheckGameObject(IntPtr L, int pos) { return CheckFinalType(typeof(GameObject), L, pos); } public bool CheckTransform(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TUSERDATA: int udata = LuaDLL.tolua_rawnetobj(L, pos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); return obj == null ? true : obj is Transform; } return false; default: return false; } } static Type monoType = typeof(Type).GetType(); public bool CheckMonoType(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TUSERDATA: return CheckClassType(monoType, L, pos); default: return false; } } public bool CheckVariant(IntPtr L, int pos) { return true; } bool CheckClassType(Type t, IntPtr L, int pos) { int udata = LuaDLL.tolua_rawnetobj(L, pos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); return obj == null ? true : obj.GetType() == t; } return false; } } } ================================================ FILE: Assets/ToLua/Core/LuaMatchType.cs.meta ================================================ fileFormatVersion: 2 guid: 23fa92cf1685f2d4da97d54967a224ad timeCreated: 1494397554 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Core/LuaMethodCache.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Reflection; using System.Collections.Generic; namespace LuaInterface { public static class LuaMethodCache { public static Dictionary>> dict = new Dictionary>>(); static MethodInfo GetMethod(Type t, string name, Type[] ts) { Dictionary> map = null; List list = null; if (!dict.TryGetValue(t, out map)) { map = new Dictionary>(); dict.Add(t, map); } if (!map.TryGetValue(name, out list)) { list = new List(); MethodInfo[] mds = t.GetMethods(); for (int i = 0; i < mds.Length; i++) { if (mds[i].Name == name) { list.Add(mds[i]); } } map.Add(name, list); } if (list.Count == 1) { return list[0]; } for (int i = 0; i < list.Count; i++) { ParameterInfo[] pis = list[i].GetParameters(); bool flag = true; if (pis.Length == 0 && (ts == null || ts.Length == 0)) { return list[i]; } else if (pis.Length == ts.Length) { for (int j = 0; j < ts.Length; j++) { if (pis[j].ParameterType != ts[j]) { flag = false; break; } } if (flag) { return list[i]; } } } return null; } public static object CallSingleMethod(string name, object obj, params object[] args) { MethodInfo md = GetMethod(obj.GetType(), name, null); return md.Invoke(obj, args); } public static object CallMethod(string name, object obj, params object[] args) { Type[] ts = new Type[args.Length]; for (int i = 0; i < args.Length; i++) { ts[i] = args[i].GetType(); } MethodInfo md = GetMethod(obj.GetType(), name, ts); return md.Invoke(obj, args); } } } ================================================ FILE: Assets/ToLua/Core/LuaMethodCache.cs.meta ================================================ fileFormatVersion: 2 guid: 6d0c295670bdae343be5791ad4a0e9ae MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaMisc.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Reflection; using System.Text; using System.Runtime.CompilerServices; namespace LuaInterface { public class GCRef { public int reference; public string name = null; public GCRef(int reference, string name) { this.reference = reference; this.name = name; } } //让byte[] 压入成为lua string 而不是数组 userdata //也可以使用LuaByteBufferAttribute来标记byte[] public struct LuaByteBuffer { public LuaByteBuffer(IntPtr source, int len) : this() { buffer = new byte[len]; Length = len; Marshal.Copy(source, buffer, 0, len); } public LuaByteBuffer(byte[] buf) : this() { buffer = buf; Length = buf.Length; } public LuaByteBuffer(byte[] buf, int len) : this() { buffer = buf; Length = len; } public LuaByteBuffer(System.IO.MemoryStream stream) : this() { buffer = stream.GetBuffer(); Length = (int)stream.Length; } public static implicit operator LuaByteBuffer(System.IO.MemoryStream stream) { return new LuaByteBuffer(stream); } public byte[] buffer; public int Length { get; private set; } } public class LuaOut { } //public class LuaOutMetatable {} public class NullObject { } //泛型函数参数null代替 public struct nil { } public class LuaDelegate { public LuaFunction func = null; public LuaTable self = null; public MethodInfo method = null; public LuaDelegate(LuaFunction func) { this.func = func; } public LuaDelegate(LuaFunction func, LuaTable self) { this.func = func; this.self = self; } //如果count不是1,说明还有其他人引用,只能等待gc来处理 public virtual void Dispose() { method = null; if (func != null) { func.Dispose(1); func = null; } if (self != null) { self.Dispose(1); self = null; } } public override bool Equals(object o) { if (o == null) return func == null && self == null; LuaDelegate ld = o as LuaDelegate; if (ld == null || ld.func != func || ld.self != self) { return false; } return ld.func != null; } static bool CompareLuaDelegate(LuaDelegate a, LuaDelegate b) { if (System.Object.ReferenceEquals(a, b)) { return true; } object l = a; object r = b; if (l == null && r != null) { return b.func == null && b.self == null; } if (l != null && r == null) { return a.func == null && a.self == null; } if (a.func != b.func || a.self != b.self) { return false; } return a.func != null; } public static bool operator == (LuaDelegate a, LuaDelegate b) { return CompareLuaDelegate(a, b); } public static bool operator != (LuaDelegate a, LuaDelegate b) { return !CompareLuaDelegate(a, b); } public override int GetHashCode() { return RuntimeHelpers.GetHashCode(this); } } [NoToLuaAttribute] public static class LuaMisc { public static string GetArrayRank(Type t) { int count = t.GetArrayRank(); if (count == 1) { return "[]"; } using (CString.Block()) { CString sb = CString.Alloc(64); sb.Append('['); for (int i = 1; i < count; i++) { sb.Append(','); } sb.Append(']'); return sb.ToString(); } } public static string GetTypeName(Type t) { if (t.IsArray) { string str = GetTypeName(t.GetElementType()); str += GetArrayRank(t); return str; } else if (t.IsByRef) { t = t.GetElementType(); return GetTypeName(t); } else if (t.IsGenericType) { return GetGenericName(t); } else if (t == typeof(void)) { return "void"; } else { string name = GetPrimitiveStr(t); return name.Replace('+', '.'); } } public static string[] GetGenericName(Type[] types, int offset, int count) { string[] results = new string[count]; for (int i = 0; i < count; i++) { int pos = i + offset; if (types[pos].IsGenericType) { results[i] = GetGenericName(types[pos]); } else { results[i] = GetTypeName(types[pos]); } } return results; } static string CombineTypeStr(string space, string name) { if (string.IsNullOrEmpty(space)) { return name; } else { return space + "." + name; } } static string GetGenericName(Type t) { Type[] gArgs = t.GetGenericArguments(); string typeName = t.FullName ?? t.Name; int count = gArgs.Length; int pos = typeName.IndexOf("["); if (pos > 0) { typeName = typeName.Substring(0, pos); } string str = null; string name = null; int offset = 0; pos = typeName.IndexOf("+"); while (pos > 0) { str = typeName.Substring(0, pos); typeName = typeName.Substring(pos + 1); pos = str.IndexOf('`'); if (pos > 0) { count = (int)(str[pos + 1] - '0'); str = str.Substring(0, pos); str += "<" + string.Join(",", GetGenericName(gArgs, offset, count)) + ">"; offset += count; } name = CombineTypeStr(name, str); pos = typeName.IndexOf("+"); } str = typeName; if (offset < gArgs.Length) { pos = str.IndexOf('`'); count = (int)(str[pos + 1] - '0'); str = str.Substring(0, pos); str += "<" + string.Join(",", GetGenericName(gArgs, offset, count)) + ">"; } return CombineTypeStr(name, str); } public static Delegate GetEventHandler(object obj, Type t, string eventName) { FieldInfo eventField = t.GetField(eventName, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); return (Delegate)eventField.GetValue(obj); } public static string GetPrimitiveStr(Type t) { if (t == typeof(System.Single)) { return "float"; } else if (t == typeof(System.String)) { return "string"; } else if (t == typeof(System.Int32)) { return "int"; } else if (t == typeof(System.Double)) { return "double"; } else if (t == typeof(System.Boolean)) { return "bool"; } else if (t == typeof(System.UInt32)) { return "uint"; } else if (t == typeof(System.SByte)) { return "sbyte"; } else if (t == typeof(System.Byte)) { return "byte"; } else if (t == typeof(System.Int16)) { return "short"; } else if (t == typeof(System.UInt16)) { return "ushort"; } else if (t == typeof(System.Char)) { return "char"; } else if (t == typeof(System.Int64)) { return "long"; } else if (t == typeof(System.UInt64)) { return "ulong"; } else if (t == typeof(System.Decimal)) { return "decimal"; } else if (t == typeof(System.Object)) { return "object"; } else { return t.ToString(); } } public static double ToDouble(object obj) { Type t = obj.GetType(); if (t == typeof(double) || t == typeof(float)) { double d = Convert.ToDouble(obj); return d; } else if (t == typeof(int)) { int n = Convert.ToInt32(obj); return (double)n; } else if (t == typeof(uint)) { uint n = Convert.ToUInt32(obj); return (double)n; } else if (t == typeof(long)) { long n = Convert.ToInt64(obj); return (double)n; } else if (t == typeof(ulong)) { ulong n = Convert.ToUInt64(obj); return (double)n; } else if (t == typeof(byte)) { byte b = Convert.ToByte(obj); return (double)b; } else if (t == typeof(sbyte)) { sbyte b = Convert.ToSByte(obj); return (double)b; } else if (t == typeof(char)) { char c = Convert.ToChar(obj); return (double)c; } else if (t == typeof(short)) { Int16 n = Convert.ToInt16(obj); return (double)n; } else if (t == typeof(ushort)) { UInt16 n = Convert.ToUInt16(obj); return (double)n; } return 0; } //可产生导出文件的基类 public static Type GetExportBaseType(Type t) { Type baseType = t.BaseType; if (baseType == typeof(ValueType)) { return null; } if (t.IsAbstract && t.IsSealed) { return baseType == typeof(object) ? null : baseType; } return baseType; } } /*[NoToLuaAttribute] public struct LuaInteger64 { public long i64; public LuaInteger64(long i64) { this.i64 = i64; } public static implicit operator LuaInteger64(long i64) { return new LuaInteger64(i64); } public static implicit operator long(LuaInteger64 self) { return self.i64; } public ulong ToUInt64() { return (ulong)i64; } public override string ToString() { return Convert.ToString(i64); } }*/ public class TouchBits { public const int DeltaPosition = 1; public const int Position = 2; public const int RawPosition = 4; public const int ALL = 7; } public class RaycastBits { public const int Collider = 1; public const int Normal = 2; public const int Point = 4; public const int Rigidbody = 8; public const int Transform = 16; public const int ALL = 31; } public enum EventOp { None = 0, Add = 1, Sub = 2, } public class EventObject { [NoToLuaAttribute] public EventOp op = EventOp.None; [NoToLuaAttribute] public Delegate func = null; [NoToLuaAttribute] public Type type; [NoToLuaAttribute] public EventObject(Type t) { type = t; } public static EventObject operator +(EventObject a, Delegate b) { a.op = EventOp.Add; a.func = b; return a; } public static EventObject operator -(EventObject a, Delegate b) { a.op = EventOp.Sub; a.func = b; return a; } } } ================================================ FILE: Assets/ToLua/Core/LuaMisc.cs.meta ================================================ fileFormatVersion: 2 guid: 49b0c76b911a9d34bac07d4b3aa7f6de MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaStackOp.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System; using System.Runtime.InteropServices; using System.Collections; namespace LuaInterface { public class LuaStackOp { public sbyte ToSByte(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToSByte(ret); } public byte ToByte(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToByte(ret); } public short ToInt16(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToInt16(ret); } public ushort ToUInt16(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToUInt16(ret); } public char ToChar(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToChar(ret); } public int ToInt32(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToInt32(ret); } public uint ToUInt32(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToUInt32(ret); } public decimal ToDecimal(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToDecimal(ret); } public float ToFloat(IntPtr L, int stackPos) { double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToSingle(ret); } public LuaByteBuffer ToLuaByteBuffer(IntPtr L, int stackPos) { return new LuaByteBuffer(ToLua.ToByteBuffer(L, stackPos)); } public IEnumerator ToIter(IntPtr L, int stackPos) { return (IEnumerator)ToLua.ToObject(L, stackPos); } public Type ToType(IntPtr L, int stackPos) { return (Type)ToLua.ToObject(L, stackPos); } public EventObject ToEventObject(IntPtr L, int stackPos) { return (EventObject)ToLua.ToObject(L, stackPos); } public Transform ToTransform(IntPtr L, int stackPos) { return (Transform)ToLua.ToObject(L, stackPos); } public GameObject ToGameObject(IntPtr L, int stackPos) { return (GameObject)ToLua.ToObject(L, stackPos); } public object ToObject(IntPtr L, int stackPos) { return ToLua.ToObject(L, stackPos); } public sbyte CheckSByte(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToSByte(ret); } public byte CheckByte(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToByte(ret); } public short CheckInt16(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToInt16(ret); } public ushort CheckUInt16(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToUInt16(ret); } public char CheckChar(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToChar(ret); } public int CheckInt32(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToInt32(ret); } public uint CheckUInt32(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToUInt32(ret); } public decimal CheckDecimal(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToDecimal(ret); } public float CheckFloat(IntPtr L, int stackPos) { double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToSingle(ret); } public IntPtr CheckIntPtr(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch(luaType) { case LuaTypes.LUA_TNIL: return IntPtr.Zero; case LuaTypes.LUA_TLIGHTUSERDATA: return LuaDLL.lua_touserdata(L, stackPos); default: LuaDLL.luaL_typerror(L, stackPos, "IntPtr"); return IntPtr.Zero; } } public UIntPtr CheckUIntPtr(IntPtr L, int stackPos) { throw new LuaException("NYI"); } public LuaByteBuffer CheckLuaByteBuffer(IntPtr L, int stackPos) { return new LuaByteBuffer(ToLua.CheckByteBuffer(L, stackPos)); } public EventObject CheckEventObject(IntPtr L, int stackPos) { return (EventObject)ToLua.CheckObject(L, stackPos, typeof(EventObject)); } public Transform CheckTransform(IntPtr L, int stackPos) { return (Transform)ToLua.CheckObject(L, stackPos, typeof(Transform)); } public GameObject CheckGameObject(IntPtr L, int stackPos) { return (GameObject)ToLua.CheckObject(L, stackPos, typeof(GameObject)); } public void Push(IntPtr L, sbyte n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, byte n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, short n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, ushort n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, char n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, int n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, uint n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, decimal n) { LuaDLL.lua_pushnumber(L, (double)n); } public void Push(IntPtr L, float n) { LuaDLL.lua_pushnumber(L, n); } public void Push(IntPtr L, UIntPtr p) { throw new LuaException("NYI"); } public void Push(IntPtr L, Delegate ev) { ToLua.Push(L, ev); } public void Push(IntPtr L, object obj) { ToLua.Push(L, obj); } public void Push(IntPtr L, GameObject o) { if (o == null) { LuaDLL.lua_pushnil(L); } else { int reference = TypeTraits.GetLuaReference(L); if (reference <= 0) { reference = ToLua.LoadPreType(L, typeof(GameObject)); } ToLua.PushUserData(L, o, reference); } } public void Push(IntPtr L, Transform o) { if (o == null) { LuaDLL.lua_pushnil(L); } else { Type type = o.GetType(); int reference = -1; if (type == typeof(Transform)) { reference = TypeTraits.GetLuaReference(L); } else { reference = LuaStatic.GetMetaReference(L, type); } if (reference <= 0) { reference = ToLua.LoadPreType(L, type); } ToLua.PushUserData(L, o, reference); } } #region Nullable public Nullable ToNullSByte(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToSByte(ret); } public Nullable ToNullByte(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToByte(ret); } public Nullable ToNullInt16(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToInt16(ret); } public Nullable ToNullUInt16(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToUInt16(ret); } public Nullable ToNullChar(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToChar(ret); } public Nullable ToNullInt32(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToInt32(ret); } public Nullable ToNullUInt32(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToUInt32(ret); } public Nullable ToNullDecimal(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToDecimal(ret); } public Nullable ToNullFloat(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.lua_tonumber(L, stackPos); return Convert.ToSingle(ret); } public Nullable ToNullNumber(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.lua_tonumber(L, stackPos); } public Nullable ToNullBool(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.lua_toboolean(L, stackPos); } public Nullable ToNullInt64(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.tolua_toint64(L, stackPos); } public Nullable ToNullUInt64(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.tolua_touint64(L, stackPos); } public sbyte[] ToSByteArray(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public short[] ToInt16Array(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public ushort[] ToUInt16Array(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public decimal[] ToDecimalArray(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public float[] ToFloatArray(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public double[] ToDoubleArray(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public int[] ToInt32Array(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public uint[] ToUInt32Array(IntPtr L, int stackPos) { return ToLua.ToNumberArray(L, stackPos); } public long[] ToInt64Array(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public ulong[] ToUInt64Array(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public Nullable ToNullVec3(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } float x = 0, y = 0, z = 0; LuaDLL.tolua_getvec3(L, stackPos, out x, out y, out z); return new Vector3(x, y, z); } public Nullable ToNullQuat(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } float x, y, z, w; LuaDLL.tolua_getquat(L, stackPos, out x, out y, out z, out w); return new Quaternion(x, y, z, w); } public Nullable ToNullVec2(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } float x, y; LuaDLL.tolua_getvec2(L, stackPos, out x, out y); return new Vector2(x, y); } public Nullable ToNullColor(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } float r, g, b, a; LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color(r, g, b, a); } public Nullable ToNullColor32(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } float r, g, b, a; LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color32((byte)r, (byte)g, (byte)b, (byte)a); } public Nullable ToNullVec4(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } float x, y, z, w; LuaDLL.tolua_getvec4(L, stackPos, out x, out y, out z, out w); return new Vector4(x, y, z, w); } public Nullable ToNullRay(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.ToRay(L, stackPos); } public Nullable ToNullBounds(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.ToBounds(L, stackPos); } public Nullable ToNullLayerMask(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.tolua_getlayermask(L, stackPos); } public Vector3[] ToVec3Array(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public Quaternion[] ToQuatArray(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public Vector2[] ToVec2Array(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public Color[] ToColorArray(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public Color32[] ToColor32Array(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public Vector4[] ToVec4Array(IntPtr L, int stackPos) { return ToLua.ToStructArray(L, stackPos); } public Type[] ToTypeArray(IntPtr L, int stackPos) { return ToLua.ToObjectArray(L, stackPos); } public Nullable CheckNullSByte(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToSByte(ret); } public Nullable CheckNullByte(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToByte(ret); } public Nullable CheckNullInt16(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToInt16(ret); } public Nullable CheckNullUInt16(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToUInt16(ret); } public Nullable CheckNullChar(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToChar(ret); } public Nullable CheckNullInt32(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToInt32(ret); } public Nullable CheckNullUInt32(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToUInt32(ret); } public Nullable CheckNullDecimal(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToDecimal(ret); } public Nullable CheckNullFloat(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } double ret = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ToSingle(ret); } public Nullable CheckNullNumber(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.luaL_checknumber(L, stackPos); } public Nullable CheckNullBool(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.luaL_checkboolean(L, stackPos); } public Nullable CheckNullInt64(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.tolua_checkint64(L, stackPos); } public Nullable CheckNullUInt64(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return LuaDLL.tolua_checkuint64(L, stackPos); } public sbyte[] CheckSByteArray(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public short[] CheckInt16Array(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public ushort[] CheckUInt16Array(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public decimal[] CheckDecimalArray(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public float[] CheckFloatArray(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public double[] CheckDoubleArray(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public int[] CheckInt32Array(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public uint[] CheckUInt32Array(IntPtr L, int stackPos) { return ToLua.CheckNumberArray(L, stackPos); } public long[] CheckInt64Array(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public ulong[] CheckUInt64Array(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public Nullable CheckNullVec3(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckVector3(L, stackPos); } public Nullable CheckNullQuat(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckQuaternion(L, stackPos); } public Nullable CheckNullVec2(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckVector2(L, stackPos); } public Nullable CheckNullColor(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckColor(L, stackPos); } public Nullable CheckNullColor32(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckColor32(L, stackPos); } public Nullable CheckNullVec4(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckVector4(L, stackPos); } public Nullable CheckNullRay(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckRay(L, stackPos); } public Nullable CheckNullBounds(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckBounds(L, stackPos); } public Nullable CheckNullLayerMask(IntPtr L, int stackPos) { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return ToLua.CheckLayerMask(L, stackPos); } public Vector3[] CheckVec3Array(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public Quaternion[] CheckQuatArray(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public Vector2[] CheckVec2Array(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public Color[] CheckColorArray(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public Color32[] CheckColor32Array(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public Vector4[] CheckVec4Array(IntPtr L, int stackPos) { return ToLua.CheckStructArray(L, stackPos); } public Type[] CheckTypeArray(IntPtr L, int stackPos) { return ToLua.CheckObjectArray(L, stackPos); } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, Convert.ToDouble(n.Value)); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushnumber(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_pushboolean(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.tolua_pushint64(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.tolua_pushuint64(L, n.Value); } } public void Push(IntPtr L, Nullable v3) { if (v3 == null) { LuaDLL.lua_pushnil(L); return; } else { Vector3 v = v3.Value; LuaDLL.tolua_pushvec3(L, v.x, v.y, v.z); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { Quaternion q = n.Value; LuaDLL.tolua_pushquat(L, q.x, q.y, q.z, q.w); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { Vector2 v2 = n.Value; LuaDLL.tolua_pushvec2(L, v2.x, v2.y); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { Color clr = n.Value; LuaDLL.tolua_pushclr(L, clr.r, clr.g, clr.b, clr.a); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { Color32 clr = n.Value; LuaDLL.tolua_pushclr(L, clr.r, clr.g, clr.b, clr.a); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { Vector4 v4 = n.Value; LuaDLL.tolua_pushvec4(L, v4.x, v4.y, v4.z, v4.w); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { ToLua.Push(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { ToLua.Push(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.tolua_pushlayermask(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { ToLua.Push(L, n.Value); } } public void Push(IntPtr L, Nullable n) { if (n == null) { LuaDLL.lua_pushnil(L); } else { ToLua.Push(L, n.Value); } } #endregion } } ================================================ FILE: Assets/ToLua/Core/LuaStackOp.cs.meta ================================================ fileFormatVersion: 2 guid: 57935fe3acd7c654599f70b62465e1d0 timeCreated: 1495076837 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Core/LuaState.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define MISS_WARNING using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Text; using UnityEngine; namespace LuaInterface { public class LuaState : LuaStatePtr, IDisposable { public ObjectTranslator translator = new ObjectTranslator(); public LuaReflection reflection = new LuaReflection(); public int ArrayMetatable { get; private set; } public int DelegateMetatable { get; private set; } public int TypeMetatable { get; private set; } public int EnumMetatable { get; private set; } public int IterMetatable { get; private set; } public int EventMetatable { get; private set; } //function ref public int PackBounds { get; private set; } public int UnpackBounds { get; private set; } public int PackRay { get; private set; } public int UnpackRay { get; private set; } public int PackRaycastHit { get; private set; } public int PackTouch { get; private set; } public bool LogGC { get { return beLogGC; } set { beLogGC = value; translator.LogGC = value; } } public Action OnDestroy = delegate { }; Dictionary funcMap = new Dictionary(); Dictionary funcRefMap = new Dictionary(); Dictionary delegateMap = new Dictionary(); List gcList = new List(); List subList = new List(); Dictionary metaMap = new Dictionary(); Dictionary enumMap = new Dictionary(); Dictionary preLoadMap = new Dictionary(); Dictionary typeMap = new Dictionary(); HashSet genericSet = new HashSet(); HashSet moduleSet = null; private static LuaState mainState = null; private static LuaState injectionState = null; private static Dictionary stateMap = new Dictionary(); private int beginCount = 0; private bool beLogGC = false; private bool bInjectionInited = false; #if UNITY_EDITOR private bool beStart = false; #endif #if MISS_WARNING HashSet missSet = new HashSet(); #endif public LuaState() { if (mainState == null) { mainState = this; // MULTI_STATE Not Support injectionState = mainState; } float time = Time.realtimeSinceStartup; InitTypeTraits(); InitStackTraits(); L = LuaNewState(); LuaException.Init(L); stateMap.Add(L, this); OpenToLuaLibs(); ToLua.OpenLibs(L); OpenBaseLibs(); LuaSetTop(0); InitLuaPath(); Debugger.Log("Init lua state cost: {0}", Time.realtimeSinceStartup - time); } void OpenBaseLibs() { BeginModule(null); BeginModule("System"); System_ObjectWrap.Register(this); System_NullObjectWrap.Register(this); System_StringWrap.Register(this); System_DelegateWrap.Register(this); System_EnumWrap.Register(this); System_ArrayWrap.Register(this); System_TypeWrap.Register(this); BeginModule("Collections"); System_Collections_IEnumeratorWrap.Register(this); BeginModule("ObjectModel"); System_Collections_ObjectModel_ReadOnlyCollectionWrap.Register(this); EndModule();//ObjectModel BeginModule("Generic"); System_Collections_Generic_ListWrap.Register(this); System_Collections_Generic_DictionaryWrap.Register(this); System_Collections_Generic_KeyValuePairWrap.Register(this); BeginModule("Dictionary"); System_Collections_Generic_Dictionary_KeyCollectionWrap.Register(this); System_Collections_Generic_Dictionary_ValueCollectionWrap.Register(this); EndModule();//Dictionary EndModule();//Generic EndModule();//Collections EndModule();//end System BeginModule("LuaInterface"); LuaInterface_LuaOutWrap.Register(this); LuaInterface_EventObjectWrap.Register(this); EndModule();//end LuaInterface BeginModule("UnityEngine"); UnityEngine_ObjectWrap.Register(this); UnityEngine_CoroutineWrap.Register(this); EndModule(); //end UnityEngine EndModule(); //end global LuaUnityLibs.OpenLibs(L); LuaReflection.OpenLibs(L); ArrayMetatable = metaMap[typeof(System.Array)]; TypeMetatable = metaMap[typeof(System.Type)]; DelegateMetatable = metaMap[typeof(System.Delegate)]; EnumMetatable = metaMap[typeof(System.Enum)]; IterMetatable = metaMap[typeof(IEnumerator)]; EventMetatable = metaMap[typeof(EventObject)]; } void InitLuaPath() { InitPackagePath(); if (!LuaFileUtils.Instance.beZip) { #if UNITY_EDITOR if (!Directory.Exists(LuaConst.luaDir)) { string msg = string.Format("luaDir path not exists: {0}, configer it in LuaConst.cs", LuaConst.luaDir); throw new LuaException(msg); } if (!Directory.Exists(LuaConst.toluaDir)) { string msg = string.Format("toluaDir path not exists: {0}, configer it in LuaConst.cs", LuaConst.toluaDir); throw new LuaException(msg); } AddSearchPath(LuaConst.toluaDir); AddSearchPath(LuaConst.luaDir); #endif if (LuaFileUtils.Instance.GetType() == typeof(LuaFileUtils)) { AddSearchPath(LuaConst.luaResDir); } } } void OpenBaseLuaLibs() { DoFile("tolua.lua"); //tolua table名字已经存在了,不能用require LuaUnityLibs.OpenLuaLibs(L); } public void Start() { #if UNITY_EDITOR beStart = true; #endif Debugger.Log("LuaState start"); OpenBaseLuaLibs(); #if ENABLE_LUA_INJECTION Push(LuaDLL.tolua_tag()); LuaSetGlobal("tolua_tag"); #if UNITY_EDITOR if (UnityEditor.EditorPrefs.GetInt(Application.dataPath + "InjectStatus") == 1) { #endif DoFile("System/Injection/LuaInjectionStation.lua"); bInjectionInited = true; #if UNITY_EDITOR } #endif #endif PackBounds = GetFuncRef("Bounds.New"); UnpackBounds = GetFuncRef("Bounds.Get"); PackRay = GetFuncRef("Ray.New"); UnpackRay = GetFuncRef("Ray.Get"); PackRaycastHit = GetFuncRef("RaycastHit.New"); PackTouch = GetFuncRef("Touch.New"); } public int OpenLibs(LuaCSFunction open) { int ret = open(L); return ret; } public void BeginPreLoad() { LuaGetGlobal("package"); LuaGetField(-1, "preload"); moduleSet = new HashSet(); } public void EndPreLoad() { LuaPop(2); moduleSet = null; } public void AddPreLoad(string name, LuaCSFunction func, Type type) { if (!preLoadMap.ContainsKey(type)) { LuaDLL.tolua_pushcfunction(L, func); LuaSetField(-2, name); preLoadMap[type] = func; string module = type.Namespace; if (!string.IsNullOrEmpty(module) && !moduleSet.Contains(module)) { LuaDLL.tolua_addpreload(L, module); moduleSet.Add(module); } } } //慎用,需要自己保证不会重复Add相同的name,并且上面函数没有使用过这个name public void AddPreLoad(string name, LuaCSFunction func) { LuaDLL.tolua_pushcfunction(L, func); LuaSetField(-2, name); } public int BeginPreModule(string name) { int top = LuaGetTop(); if (string.IsNullOrEmpty(name)) { LuaDLL.lua_pushvalue(L, LuaIndexes.LUA_GLOBALSINDEX); ++beginCount; return top; } else if (LuaDLL.tolua_beginpremodule(L, name)) { ++beginCount; return top; } throw new LuaException(string.Format("create table {0} fail", name)); } public void EndPreModule(int reference) { --beginCount; LuaDLL.tolua_endpremodule(L, reference); } public void EndPreModule(IntPtr L, int reference) { --beginCount; LuaDLL.tolua_endpremodule(L, reference); } public void BindPreModule(Type t, LuaCSFunction func) { preLoadMap[t] = func; } public LuaCSFunction GetPreModule(Type t) { LuaCSFunction func = null; preLoadMap.TryGetValue(t, out func); return func; } public bool BeginModule(string name) { #if UNITY_EDITOR if (name != null) { LuaTypes type = LuaType(-1); if (type != LuaTypes.LUA_TTABLE) { throw new LuaException("open global module first"); } } #endif if (LuaDLL.tolua_beginmodule(L, name)) { ++beginCount; return true; } LuaSetTop(0); throw new LuaException(string.Format("create table {0} fail", name)); } public void EndModule() { --beginCount; LuaDLL.tolua_endmodule(L); } void BindTypeRef(int reference, Type t) { metaMap.Add(t, reference); typeMap.Add(reference, t); if (t.IsGenericTypeDefinition) { genericSet.Add(t); } } public Type GetClassType(int reference) { Type t = null; typeMap.TryGetValue(reference, out t); return t; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] public static int Collect(IntPtr L) { int udata = LuaDLL.tolua_rawnetobj(L, 1); if (udata != -1) { ObjectTranslator translator = GetTranslator(L); translator.RemoveObject(udata); } return 0; } public static bool GetInjectInitState(int index) { if (injectionState != null && injectionState.bInjectionInited) { return true; } return false; } string GetToLuaTypeName(Type t) { if (t.IsGenericType) { string str = t.Name; int pos = str.IndexOf('`'); if (pos > 0) { str = str.Substring(0, pos); } return str; } return t.Name; } public int BeginClass(Type t, Type baseType, string name = null) { if (beginCount == 0) { throw new LuaException("must call BeginModule first"); } int baseMetaRef = 0; int reference = 0; if (name == null) { name = GetToLuaTypeName(t); } if (baseType != null && !metaMap.TryGetValue(baseType, out baseMetaRef)) { LuaCreateTable(); baseMetaRef = LuaRef(LuaIndexes.LUA_REGISTRYINDEX); BindTypeRef(baseMetaRef, baseType); } if (metaMap.TryGetValue(t, out reference)) { LuaDLL.tolua_beginclass(L, name, baseMetaRef, reference); RegFunction("__gc", Collect); RegConstant("__name__", t.FullName); } else { reference = LuaDLL.tolua_beginclass(L, name, baseMetaRef); RegFunction("__gc", Collect); RegConstant("__name__", t.FullName); BindTypeRef(reference, t); } return reference; } public void EndClass() { LuaDLL.tolua_endclass(L); } public int BeginEnum(Type t) { if (beginCount == 0) { throw new LuaException("must call BeginModule first"); } int reference = LuaDLL.tolua_beginenum(L, t.Name); RegFunction("__gc", Collect); BindTypeRef(reference, t); return reference; } public void EndEnum() { LuaDLL.tolua_endenum(L); } public void BeginStaticLibs(string name) { if (beginCount == 0) { throw new LuaException("must call BeginModule first"); } LuaDLL.tolua_beginstaticclass(L, name); } public void EndStaticLibs() { LuaDLL.tolua_endstaticclass(L); } public void RegFunction(string name, LuaCSFunction func) { IntPtr fn = Marshal.GetFunctionPointerForDelegate(func); LuaDLL.tolua_function(L, name, fn); } public void RegVar(string name, LuaCSFunction get, LuaCSFunction set) { IntPtr fget = IntPtr.Zero; IntPtr fset = IntPtr.Zero; if (get != null) { fget = Marshal.GetFunctionPointerForDelegate(get); } if (set != null) { fset = Marshal.GetFunctionPointerForDelegate(set); } LuaDLL.tolua_variable(L, name, fget, fset); } public void RegConstant(string name, double d) { LuaDLL.tolua_constant(L, name, d); } public void RegConstant(string name, ValueType value) { LuaDLL.tolua_constant(L, name, (int)value); } public void RegConstant(string name, bool flag) { LuaDLL.lua_pushstring(L, name); LuaDLL.lua_pushboolean(L, flag); LuaDLL.lua_rawset(L, -3); } public void RegConstant(string name, string s) { LuaDLL.lua_pushstring(L, name); LuaDLL.lua_pushstring(L, s); LuaDLL.lua_rawset(L, -3); } int GetFuncRef(string name) { if (PushLuaFunction(name, false)) { return LuaRef(LuaIndexes.LUA_REGISTRYINDEX); } throw new LuaException("get lua function reference failed: " + name); } public static LuaState Get(IntPtr ptr) { #if !MULTI_STATE return mainState; #else if (mainState != null && mainState.L == ptr) { return mainState; } LuaState state = null; if (stateMap.TryGetValue(ptr, out state)) { return state; } else { return Get(LuaDLL.tolua_getmainstate(ptr)); } #endif } public static ObjectTranslator GetTranslator(IntPtr ptr) { #if !MULTI_STATE return mainState.translator; #else if (mainState != null && mainState.L == ptr) { return mainState.translator; } return Get(ptr).translator; #endif } public static LuaReflection GetReflection(IntPtr ptr) { #if !MULTI_STATE return mainState.reflection; #else if (mainState != null && mainState.L == ptr) { return mainState.reflection; } return Get(ptr).reflection; #endif } public void DoString(string chunk, string chunkName = "LuaState.cs") { #if UNITY_EDITOR if (!beStart) { throw new LuaException("you must call Start() first to initialize LuaState"); } #endif byte[] buffer = Encoding.UTF8.GetBytes(chunk); LuaLoadBuffer(buffer, chunkName); } public T DoString(string chunk, string chunkName = "LuaState.cs") { byte[] buffer = Encoding.UTF8.GetBytes(chunk); return LuaLoadBuffer(buffer, chunkName); } byte[] LoadFileBuffer(string fileName) { #if UNITY_EDITOR if (!beStart) { throw new LuaException("you must call Start() first to initialize LuaState"); } #endif byte[] buffer = LuaFileUtils.Instance.ReadFile(fileName); if (buffer == null) { string error = string.Format("cannot open {0}: No such file or directory", fileName); error += LuaFileUtils.Instance.FindFileError(fileName); throw new LuaException(error); } return buffer; } string LuaChunkName(string name) { if (LuaConst.openLuaDebugger) { name = LuaFileUtils.Instance.FindFile(name); } return "@" + name; } public void DoFile(string fileName) { byte[] buffer = LoadFileBuffer(fileName); fileName = LuaChunkName(fileName); LuaLoadBuffer(buffer, fileName); } public T DoFile(string fileName) { byte[] buffer = LoadFileBuffer(fileName); fileName = LuaChunkName(fileName); return LuaLoadBuffer(buffer, fileName); } //注意fileName与lua文件中require一致。 public void Require(string fileName) { int top = LuaGetTop(); int ret = LuaRequire(fileName); if (ret != 0) { string err = LuaToString(-1); LuaSetTop(top); throw new LuaException(err, LuaException.GetLastError()); } LuaSetTop(top); } public T Require(string fileName) { int top = LuaGetTop(); int ret = LuaRequire(fileName); if (ret != 0) { string err = LuaToString(-1); LuaSetTop(top); throw new LuaException(err, LuaException.GetLastError()); } T o = CheckValue(-1); LuaSetTop(top); return o; } public void InitPackagePath() { LuaGetGlobal("package"); LuaGetField(-1, "path"); string current = LuaToString(-1); string[] paths = current.Split(';'); for (int i = 0; i < paths.Length; i++) { if (!string.IsNullOrEmpty(paths[i])) { string path = paths[i].Replace('\\', '/'); LuaFileUtils.Instance.AddSearchPath(path); } } LuaPushString(""); LuaSetField(-3, "path"); LuaPop(2); } string ToPackagePath(string path) { using (CString.Block()) { CString sb = CString.Alloc(256); sb.Append(path); sb.Replace('\\', '/'); if (sb.Length > 0 && sb[sb.Length - 1] != '/') { sb.Append('/'); } sb.Append("?.lua"); return sb.ToString(); } } public void AddSearchPath(string fullPath) { if (!Path.IsPathRooted(fullPath)) { throw new LuaException(fullPath + " is not a full path"); } fullPath = ToPackagePath(fullPath); LuaFileUtils.Instance.AddSearchPath(fullPath); } public void RemoveSeachPath(string fullPath) { if (!Path.IsPathRooted(fullPath)) { throw new LuaException(fullPath + " is not a full path"); } fullPath = ToPackagePath(fullPath); LuaFileUtils.Instance.RemoveSearchPath(fullPath); } public int BeginPCall(int reference) { return LuaDLL.tolua_beginpcall(L, reference); } public void PCall(int args, int oldTop) { if (LuaDLL.lua_pcall(L, args, LuaDLL.LUA_MULTRET, oldTop) != 0) { string error = LuaToString(-1); throw new LuaException(error, LuaException.GetLastError()); } } public void EndPCall(int oldTop) { LuaDLL.lua_settop(L, oldTop - 1); } public void PushArgs(object[] args) { for (int i = 0; i < args.Length; i++) { PushVariant(args[i]); } } void CheckNull(LuaBaseRef lbr, string fmt, object arg0) { if (lbr == null) { string error = string.Format(fmt, arg0); throw new LuaException(error, null, 2); } } //压入一个存在的或不存在的table, 但不增加引用计数 bool PushLuaTable(string fullPath, bool checkMap = true) { if (checkMap) { WeakReference weak = null; if (funcMap.TryGetValue(fullPath, out weak)) { if (weak.IsAlive) { LuaTable table = weak.Target as LuaTable; CheckNull(table, "{0} not a lua table", fullPath); Push(table); return true; } else { funcMap.Remove(fullPath); } } } if (!LuaDLL.tolua_pushluatable(L, fullPath)) { return false; } return true; } bool PushLuaFunction(string fullPath, bool checkMap = true) { if (checkMap) { WeakReference weak = null; if (funcMap.TryGetValue(fullPath, out weak)) { if (weak.IsAlive) { LuaFunction func = weak.Target as LuaFunction; CheckNull(func, "{0} not a lua function", fullPath); if (func.IsAlive) { func.AddRef(); return true; } } funcMap.Remove(fullPath); } } int oldTop = LuaDLL.lua_gettop(L); int pos = fullPath.LastIndexOf('.'); if (pos > 0) { string tableName = fullPath.Substring(0, pos); if (PushLuaTable(tableName, checkMap)) { string funcName = fullPath.Substring(pos + 1); LuaDLL.lua_pushstring(L, funcName); LuaDLL.lua_rawget(L, -2); LuaTypes type = LuaDLL.lua_type(L, -1); if (type == LuaTypes.LUA_TFUNCTION) { LuaDLL.lua_insert(L, oldTop + 1); LuaDLL.lua_settop(L, oldTop + 1); return true; } } LuaDLL.lua_settop(L, oldTop); return false; } else { LuaDLL.lua_getglobal(L, fullPath); LuaTypes type = LuaDLL.lua_type(L, -1); if (type != LuaTypes.LUA_TFUNCTION) { LuaDLL.lua_settop(L, oldTop); return false; } } return true; } void RemoveFromGCList(int reference) { lock (gcList) { for (int i = 0; i < gcList.Count; i++) { if (gcList[i].reference == reference) { gcList.RemoveAt(i); break; } } } } public LuaFunction GetFunction(string name, bool beLogMiss = true) { WeakReference weak = null; if (funcMap.TryGetValue(name, out weak)) { if (weak.IsAlive) { LuaFunction func = weak.Target as LuaFunction; CheckNull(func, "{0} not a lua function", name); if (func.IsAlive) { func.AddRef(); RemoveFromGCList(func.GetReference()); return func; } } funcMap.Remove(name); } if (PushLuaFunction(name, false)) { int reference = ToLuaRef(); if (funcRefMap.TryGetValue(reference, out weak)) { if (weak.IsAlive) { LuaFunction func = weak.Target as LuaFunction; CheckNull(func, "{0} not a lua function", name); if (func.IsAlive) { funcMap.Add(name, weak); func.AddRef(); RemoveFromGCList(reference); return func; } } funcRefMap.Remove(reference); delegateMap.Remove(reference); } LuaFunction fun = new LuaFunction(reference, this); fun.name = name; funcMap.Add(name, new WeakReference(fun)); funcRefMap.Add(reference, new WeakReference(fun)); RemoveFromGCList(reference); if (LogGC) Debugger.Log("Alloc LuaFunction name {0}, id {1}", name, reference); return fun; } if (beLogMiss) { Debugger.Log("Lua function {0} not exists", name); } return null; } LuaBaseRef TryGetLuaRef(int reference) { WeakReference weak = null; if (funcRefMap.TryGetValue(reference, out weak)) { if (weak.IsAlive) { LuaBaseRef luaRef = (LuaBaseRef)weak.Target; if (luaRef.IsAlive) { luaRef.AddRef(); return luaRef; } } funcRefMap.Remove(reference); } return null; } public LuaFunction GetFunction(int reference) { LuaFunction func = TryGetLuaRef(reference) as LuaFunction; if (func == null) { func = new LuaFunction(reference, this); funcRefMap.Add(reference, new WeakReference(func)); if (LogGC) Debugger.Log("Alloc LuaFunction name , id {0}", reference); } RemoveFromGCList(reference); return func; } public LuaTable GetTable(string fullPath, bool beLogMiss = true) { WeakReference weak = null; if (funcMap.TryGetValue(fullPath, out weak)) { if (weak.IsAlive) { LuaTable table = weak.Target as LuaTable; CheckNull(table, "{0} not a lua table", fullPath); if (table.IsAlive) { table.AddRef(); RemoveFromGCList(table.GetReference()); return table; } } funcMap.Remove(fullPath); } if (PushLuaTable(fullPath, false)) { int reference = ToLuaRef(); LuaTable table = null; if (funcRefMap.TryGetValue(reference, out weak)) { if (weak.IsAlive) { table = weak.Target as LuaTable; CheckNull(table, "{0} not a lua table", fullPath); if (table.IsAlive) { funcMap.Add(fullPath, weak); table.AddRef(); RemoveFromGCList(reference); return table; } } funcRefMap.Remove(reference); } table = new LuaTable(reference, this); table.name = fullPath; funcMap.Add(fullPath, new WeakReference(table)); funcRefMap.Add(reference, new WeakReference(table)); if (LogGC) Debugger.Log("Alloc LuaTable name {0}, id {1}", fullPath, reference); RemoveFromGCList(reference); return table; } if (beLogMiss) { Debugger.LogWarning("Lua table {0} not exists", fullPath); } return null; } public LuaTable GetTable(int reference) { LuaTable table = TryGetLuaRef(reference) as LuaTable; if (table == null) { table = new LuaTable(reference, this); funcRefMap.Add(reference, new WeakReference(table)); } RemoveFromGCList(reference); return table; } public LuaThread GetLuaThread(int reference) { LuaThread thread = TryGetLuaRef(reference) as LuaThread; if (thread == null) { thread = new LuaThread(reference, this); funcRefMap.Add(reference, new WeakReference(thread)); } RemoveFromGCList(reference); return thread; } public LuaDelegate GetLuaDelegate(LuaFunction func) { WeakReference weak = null; int reference = func.GetReference(); delegateMap.TryGetValue(reference, out weak); if (weak != null) { if (weak.IsAlive) { return weak.Target as LuaDelegate; } delegateMap.Remove(reference); } return null; } public LuaDelegate GetLuaDelegate(LuaFunction func, LuaTable self) { WeakReference weak = null; long high = func.GetReference(); long low = self == null ? 0 : self.GetReference(); low = low >= 0 ? low : 0; long key = high << 32 | low; delegateMap.TryGetValue(key, out weak); if (weak != null) { if (weak.IsAlive) { return weak.Target as LuaDelegate; } delegateMap.Remove(key); } return null; } public void AddLuaDelegate(LuaDelegate target, LuaFunction func) { int key = func.GetReference(); if (key > 0) { delegateMap[key] = new WeakReference(target); } } public void AddLuaDelegate(LuaDelegate target, LuaFunction func, LuaTable self) { long high = func.GetReference(); long low = self == null ? 0 : self.GetReference(); low = low >= 0 ? low : 0; long key = high << 32 | low; if (key > 0) { delegateMap[key] = new WeakReference(target); } } public bool CheckTop() { int n = LuaGetTop(); if (n != 0) { Debugger.LogWarning("Lua stack top is {0}", n); return false; } return true; } public void Push(bool b) { LuaDLL.lua_pushboolean(L, b); } public void Push(double d) { LuaDLL.lua_pushnumber(L, d); } public void Push(uint un) { LuaDLL.lua_pushnumber(L, un); } public void Push(int n) { LuaDLL.lua_pushinteger(L, n); } public void Push(short s) { LuaDLL.lua_pushnumber(L, s); } public void Push(ushort us) { LuaDLL.lua_pushnumber(L, us); } public void Push(long l) { LuaDLL.tolua_pushint64(L, l); } public void Push(ulong ul) { LuaDLL.tolua_pushuint64(L, ul); } public void Push(string str) { LuaDLL.lua_pushstring(L, str); } public void Push(IntPtr p) { LuaDLL.lua_pushlightuserdata(L, p); } public void Push(Vector3 v3) { LuaDLL.tolua_pushvec3(L, v3.x, v3.y, v3.z); } public void Push(Vector2 v2) { LuaDLL.tolua_pushvec2(L, v2.x, v2.y); } public void Push(Vector4 v4) { LuaDLL.tolua_pushvec4(L, v4.x, v4.y, v4.z, v4.w); } public void Push(Color clr) { LuaDLL.tolua_pushclr(L, clr.r, clr.g, clr.b, clr.a); } public void Push(Color32 clr) { LuaDLL.tolua_pushclr(L, clr.r, clr.g, clr.b, clr.a); } public void Push(Quaternion q) { LuaDLL.tolua_pushquat(L, q.x, q.y, q.z, q.w); } public void Push(Ray ray) { ToLua.Push(L, ray); } public void Push(Bounds bound) { ToLua.Push(L, bound); } public void Push(RaycastHit hit) { ToLua.Push(L, hit); } public void Push(Touch touch) { ToLua.Push(L, touch); } public void PushLayerMask(LayerMask mask) { LuaDLL.tolua_pushlayermask(L, mask.value); } public void Push(LuaByteBuffer bb) { LuaDLL.lua_pushlstring(L, bb.buffer, bb.Length); } public void PushByteBuffer(byte[] buffer) { LuaDLL.lua_pushlstring(L, buffer, buffer.Length); } public void PushByteBuffer(byte[] buffer, int len) { LuaDLL.lua_pushlstring(L, buffer, len); } public void Push(LuaBaseRef lbr) { if (lbr == null) { LuaPushNil(); } else { LuaGetRef(lbr.GetReference()); } } void PushUserData(object o, int reference) { int index; if (translator.Getudata(o, out index)) { if (LuaDLL.tolua_pushudata(L, index)) { return; } translator.Destroyudata(index); } index = translator.AddObject(o); LuaDLL.tolua_pushnewudata(L, reference, index); } public void Push(Array array) { if (array == null) { LuaPushNil(); } else { PushUserData(array, ArrayMetatable); } } public void Push(Type t) { if (t == null) { LuaPushNil(); } else { PushUserData(t, TypeMetatable); } } public void Push(Delegate ev) { if (ev == null) { LuaPushNil(); } else { PushUserData(ev, DelegateMetatable); } } public object GetEnumObj(Enum e) { object o = null; if (!enumMap.TryGetValue(e, out o)) { o = e; enumMap.Add(e, o); } return o; } public void Push(Enum e) { ToLua.Push(L, e); } public void Push(IEnumerator iter) { ToLua.Push(L, iter); } public void Push(UnityEngine.Object obj) { ToLua.Push(L, obj); } public void Push(UnityEngine.TrackedReference tracker) { ToLua.Push(L, tracker); } public void PushVariant(object obj) { ToLua.Push(L, obj); } public void PushObject(object obj) { ToLua.PushObject(L, obj); } public void PushSealed(T o) { ToLua.PushSealed(L, o); } public void PushValue(T v) where T : struct { StackTraits.Push(L, v); } public void PushGeneric(T o) { StackTraits.Push(L, o); } Vector3 ToVector3(int stackPos) { float x, y, z; stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.tolua_getvec3(L, stackPos, out x, out y, out z); return new Vector3(x, y, z); } public Vector3 CheckVector3(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Vector3) { LuaTypeError(stackPos, "Vector3", LuaValueTypeName.Get(type)); return Vector3.zero; } float x, y, z; stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.tolua_getvec3(L, stackPos, out x, out y, out z); return new Vector3(x, y, z); } public Quaternion CheckQuaternion(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Quaternion) { LuaTypeError(stackPos, "Quaternion", LuaValueTypeName.Get(type)); return Quaternion.identity; } float x, y, z, w; stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.tolua_getquat(L, stackPos, out x, out y, out z, out w); return new Quaternion(x, y, z, w); } public Vector2 CheckVector2(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Vector2) { LuaTypeError(stackPos, "Vector2", LuaValueTypeName.Get(type)); return Vector2.zero; } float x, y; stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.tolua_getvec2(L, stackPos, out x, out y); return new Vector2(x, y); } public Vector4 CheckVector4(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Vector4) { LuaTypeError(stackPos, "Vector4", LuaValueTypeName.Get(type)); return Vector4.zero; } float x, y, z, w; stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.tolua_getvec4(L, stackPos, out x, out y, out z, out w); return new Vector4(x, y, z, w); } public Color CheckColor(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Color) { LuaTypeError(stackPos, "Color", LuaValueTypeName.Get(type)); return Color.black; } float r, g, b, a; stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color(r, g, b, a); } public Color32 CheckColor32(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Color32) { LuaTypeError(stackPos, "Color32", LuaValueTypeName.Get(type)); return new Color32(); } float r, g, b, a; stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color32((byte)r, (byte)g, (byte)b, (byte)a); } public Ray CheckRay(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Ray) { LuaTypeError(stackPos, "Ray", LuaValueTypeName.Get(type)); return new Ray(); } stackPos = LuaDLL.abs_index(L, stackPos); int oldTop = BeginPCall(UnpackRay); LuaPushValue(stackPos); try { PCall(1, oldTop); Vector3 origin = ToVector3(oldTop + 1); Vector3 dir = ToVector3(oldTop + 2); EndPCall(oldTop); return new Ray(origin, dir); } catch(Exception e) { EndPCall(oldTop); throw e; } } public Bounds CheckBounds(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Bounds) { LuaTypeError(stackPos, "Bounds", LuaValueTypeName.Get(type)); return new Bounds(); } stackPos = LuaDLL.abs_index(L, stackPos); int oldTop = BeginPCall(UnpackBounds); LuaPushValue(stackPos); try { PCall(1, oldTop); Vector3 center = ToVector3(oldTop + 1); Vector3 size = ToVector3(oldTop + 2); EndPCall(oldTop); return new Bounds(center, size); } catch(Exception e) { EndPCall(oldTop); throw e; } } public LayerMask CheckLayerMask(int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.LayerMask) { LuaTypeError(stackPos, "LayerMask", LuaValueTypeName.Get(type)); return 0; } stackPos = LuaDLL.abs_index(L, stackPos); return LuaDLL.tolua_getlayermask(L, stackPos); } public long CheckLong(int stackPos) { stackPos = LuaDLL.abs_index(L, stackPos); return LuaDLL.tolua_checkint64(L, stackPos); } public ulong CheckULong(int stackPos) { stackPos = LuaDLL.abs_index(L, stackPos); return LuaDLL.tolua_checkuint64(L, stackPos); } public string CheckString(int stackPos) { return ToLua.CheckString(L, stackPos); } public Delegate CheckDelegate(int stackPos) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { object obj = translator.GetObject(udata); if (obj != null) { if (obj is Delegate) { return (Delegate)obj; } LuaTypeError(stackPos, "Delegate", obj.GetType().FullName); } return null; } else if (LuaDLL.lua_isnil(L,stackPos)) { return null; } LuaTypeError(stackPos, "Delegate"); return null; } public char[] CheckCharBuffer(int stackPos) { return ToLua.CheckCharBuffer(L, stackPos); } public byte[] CheckByteBuffer(int stackPos) { return ToLua.CheckByteBuffer(L, stackPos); } public T[] CheckNumberArray(int stackPos) where T : struct { return ToLua.CheckNumberArray(L, stackPos); } public object CheckObject(int stackPos, Type type) { return ToLua.CheckObject(L, stackPos, type); } public object CheckVarObject(int stackPos, Type type) { return ToLua.CheckVarObject(L, stackPos, type); } public object[] CheckObjects(int oldTop) { int newTop = LuaGetTop(); if (oldTop == newTop) { return null; } else { List returnValues = new List(); for (int i = oldTop + 1; i <= newTop; i++) { returnValues.Add(ToVariant(i)); } return returnValues.ToArray(); } } public LuaFunction CheckLuaFunction(int stackPos) { return ToLua.CheckLuaFunction(L, stackPos); } public LuaTable CheckLuaTable(int stackPos) { return ToLua.CheckLuaTable(L, stackPos); } public LuaThread CheckLuaThread(int stackPos) { return ToLua.CheckLuaThread(L, stackPos); } //从堆栈读取一个值类型 public T CheckValue(int stackPos) { return StackTraits.Check(L, stackPos); } public object ToVariant(int stackPos) { return ToLua.ToVarObject(L, stackPos); } public void CollectRef(int reference, string name, bool isGCThread = false) { if (!isGCThread) { Collect(reference, name, false); } else { lock (gcList) { gcList.Add(new GCRef(reference, name)); } } } //在委托调用中减掉一个LuaFunction, 此lua函数在委托中还会执行一次, 所以必须延迟删除,委托值类型表现之一 public void DelayDispose(LuaBaseRef br) { if (br != null) { subList.Add(br); } } public int Collect() { int count = gcList.Count; if (count > 0) { lock (gcList) { for (int i = 0; i < gcList.Count; i++) { int reference = gcList[i].reference; string name = gcList[i].name; Collect(reference, name, true); } gcList.Clear(); return count; } } for (int i = 0; i < subList.Count; i++) { subList[i].Dispose(); } subList.Clear(); translator.Collect(); return 0; } public void StepCollect() { translator.StepCollect(); } public void RefreshDelegateMap() { List list = new List(); var iter = delegateMap.GetEnumerator(); while (iter.MoveNext()) { if (!iter.Current.Value.IsAlive) { list.Add(iter.Current.Key); } } for (int i = 0; i < list.Count; i++) { delegateMap.Remove(list[i]); } } public object this[string fullPath] { get { int oldTop = LuaGetTop(); int pos = fullPath.LastIndexOf('.'); object obj = null; if (pos > 0) { string tableName = fullPath.Substring(0, pos); if (PushLuaTable(tableName)) { string name = fullPath.Substring(pos + 1); LuaPushString(name); LuaRawGet(-2); obj = ToVariant(-1); } else { LuaSetTop(oldTop); return null; } } else { LuaGetGlobal(fullPath); obj = ToVariant(-1); } LuaSetTop(oldTop); return obj; } set { int oldTop = LuaGetTop(); int pos = fullPath.LastIndexOf('.'); if (pos > 0) { string tableName = fullPath.Substring(0, pos); IntPtr p = LuaFindTable(LuaIndexes.LUA_GLOBALSINDEX, tableName); if (p == IntPtr.Zero) { string name = fullPath.Substring(pos + 1); LuaPushString(name); PushVariant(value); LuaSetTable(-3); } else { LuaSetTop(oldTop); int len = LuaDLL.tolua_strlen(p); string str = LuaDLL.lua_ptrtostring(p, len); throw new LuaException(string.Format("{0} not a Lua table", str)); } } else { PushVariant(value); LuaSetGlobal(fullPath); } LuaSetTop(oldTop); } } public void NewTable(string fullPath) { string[] path = fullPath.Split(new char[] { '.' }); int oldTop = LuaDLL.lua_gettop(L); if (path.Length == 1) { LuaDLL.lua_newtable(L); LuaDLL.lua_setglobal(L, fullPath); } else { LuaDLL.lua_getglobal(L, path[0]); for (int i = 1; i < path.Length - 1; i++) { LuaDLL.lua_pushstring(L, path[i]); LuaDLL.lua_gettable(L, -2); } LuaDLL.lua_pushstring(L, path[path.Length - 1]); LuaDLL.lua_newtable(L); LuaDLL.lua_settable(L, -3); } LuaDLL.lua_settop(L, oldTop); } public LuaTable NewTable(int narr = 0, int nrec = 0) { int oldTop = LuaDLL.lua_gettop(L); LuaDLL.lua_createtable(L, 0, 0); LuaTable table = ToLua.ToLuaTable(L, oldTop + 1); LuaDLL.lua_settop(L, oldTop); return table; } //慎用 public void ReLoad(string moduleFileName) { LuaGetGlobal("package"); LuaGetField(-1, "loaded"); LuaPushString(moduleFileName); LuaGetTable(-2); if (!LuaIsNil(-1)) { LuaPushString(moduleFileName); LuaPushNil(); LuaSetTable(-4); } LuaPop(3); string require = string.Format("require '{0}'", moduleFileName); DoString(require, "ReLoad"); } public int GetMetaReference(Type t) { int reference = -1; metaMap.TryGetValue(t, out reference); return reference; } public int GetMissMetaReference(Type t) { int reference = -1; Type type = GetBaseType(t); while (type != null) { if (metaMap.TryGetValue(type, out reference)) { #if MISS_WARNING if (!missSet.Contains(t)) { missSet.Add(t); Debugger.LogWarning("Type {0} not wrap to lua, push as {1}, the warning is only raised once", LuaMisc.GetTypeName(t), LuaMisc.GetTypeName(type)); } #endif return reference; } type = GetBaseType(type); } if (reference <= 0) { type = typeof(object); reference = LuaStatic.GetMetaReference(L, type); } #if MISS_WARNING if (!missSet.Contains(t)) { missSet.Add(t); Debugger.LogWarning("Type {0} not wrap to lua, push as {1}, the warning is only raised once", LuaMisc.GetTypeName(t), LuaMisc.GetTypeName(type)); } #endif return reference; } Type GetBaseType(Type t) { if (t.IsGenericType) { return GetSpecialGenericType(t); } return LuaMisc.GetExportBaseType(t); } Type GetSpecialGenericType(Type t) { Type generic = t.GetGenericTypeDefinition(); if (genericSet.Contains(generic)) { return t == generic ? t.BaseType : generic; } return t.BaseType; } void CloseBaseRef() { LuaUnRef(PackBounds); LuaUnRef(UnpackBounds); LuaUnRef(PackRay); LuaUnRef(UnpackRay); LuaUnRef(PackRaycastHit); LuaUnRef(PackTouch); } public void Dispose() { if (IntPtr.Zero != L) { Collect(); foreach (KeyValuePair kv in metaMap) { LuaUnRef(kv.Value); } List list = new List(); foreach (KeyValuePair kv in funcRefMap) { if (kv.Value.IsAlive) { list.Add((LuaBaseRef)kv.Value.Target); } } for (int i = 0; i < list.Count; i++) { list[i].Dispose(true); } CloseBaseRef(); delegateMap.Clear(); funcRefMap.Clear(); funcMap.Clear(); metaMap.Clear(); typeMap.Clear(); enumMap.Clear(); preLoadMap.Clear(); genericSet.Clear(); LuaDLL.lua_close(L); translator.Dispose(); stateMap.Remove(L); translator = null; L = IntPtr.Zero; #if MISS_WARNING missSet.Clear(); #endif OnDestroy(); Debugger.Log("LuaState destroy"); } if (mainState == this) { mainState = null; } if (injectionState == this) { injectionState = null; LuaInjectionStation.Clear(); } #if UNITY_EDITOR beStart = false; #endif LuaFileUtils.Instance.Dispose(); System.GC.SuppressFinalize(this); } //public virtual void Dispose(bool dispose) //{ //} public override int GetHashCode() { return RuntimeHelpers.GetHashCode(this); } public override bool Equals(object o) { if (o == null) return L == IntPtr.Zero; LuaState state = o as LuaState; if (state == null || state.L != L) { return false; } return L != IntPtr.Zero; } public static bool operator == (LuaState a, LuaState b) { if (System.Object.ReferenceEquals(a, b)) { return true; } object l = a; object r = b; if (l == null && r != null) { return b.L == IntPtr.Zero; } if (l != null && r == null) { return a.L == IntPtr.Zero; } if (a.L != b.L) { return false; } return a.L != IntPtr.Zero; } public static bool operator != (LuaState a, LuaState b) { return !(a == b); } public void PrintTable(string name) { LuaTable table = GetTable(name); LuaDictTable dict = table.ToDictTable(); table.Dispose(); var iter2 = dict.GetEnumerator(); while (iter2.MoveNext()) { Debugger.Log("map item, k,v is {0}:{1}", iter2.Current.Key, iter2.Current.Value); } iter2.Dispose(); dict.Dispose(); } protected void Collect(int reference, string name, bool beThread) { if (beThread) { WeakReference weak = null; if (name != null) { funcMap.TryGetValue(name, out weak); if (weak != null && !weak.IsAlive) { funcMap.Remove(name); weak = null; } } funcRefMap.TryGetValue(reference, out weak); if (weak != null && !weak.IsAlive) { ToLuaUnRef(reference); funcRefMap.Remove(reference); delegateMap.Remove(reference); if (LogGC) { string str = name == null ? "null" : name; Debugger.Log("collect lua reference name {0}, id {1} in thread", str, reference); } } } else { if (name != null) { WeakReference weak = null; funcMap.TryGetValue(name, out weak); if (weak != null && weak.IsAlive) { LuaBaseRef lbr = (LuaBaseRef)weak.Target; if (reference == lbr.GetReference()) { funcMap.Remove(name); } } } ToLuaUnRef(reference); funcRefMap.Remove(reference); delegateMap.Remove(reference); if (LogGC) { string str = name == null ? "null" : name; Debugger.Log("collect lua reference name {0}, id {1} in main", str, reference); } } } protected void LuaLoadBuffer(byte[] buffer, string chunkName) { LuaDLL.tolua_pushtraceback(L); int oldTop = LuaGetTop(); if (LuaLoadBuffer(buffer, buffer.Length, chunkName) == 0) { if (LuaPCall(0, LuaDLL.LUA_MULTRET, oldTop) == 0) { LuaSetTop(oldTop - 1); return; } } string err = LuaToString(-1); LuaSetTop(oldTop - 1); throw new LuaException(err, LuaException.GetLastError()); } protected T LuaLoadBuffer(byte[] buffer, string chunkName) { LuaDLL.tolua_pushtraceback(L); int oldTop = LuaGetTop(); if (LuaLoadBuffer(buffer, buffer.Length, chunkName) == 0) { if (LuaPCall(0, LuaDLL.LUA_MULTRET, oldTop) == 0) { T result = CheckValue(oldTop + 1); LuaSetTop(oldTop - 1); return result; } } string err = LuaToString(-1); LuaSetTop(oldTop - 1); throw new LuaException(err, LuaException.GetLastError()); } public bool BeginCall(string name, int top, bool beLogMiss) { LuaDLL.tolua_pushtraceback(L); if (PushLuaFunction(name, false)) { return true; } else { LuaDLL.lua_settop(L, top); if (beLogMiss) { Debugger.Log("Lua function {0} not exists", name); } return false; } } public void Call(int nArgs, int errfunc, int top) { if (LuaDLL.lua_pcall(L, nArgs, LuaDLL.LUA_MULTRET, errfunc) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error, LuaException.GetLastError()); } } public void Call(string name, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { Call(0, top + 1, top); LuaDLL.lua_settop(L, top); } } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public void Call(string name, T arg1, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); Call(1, top + 1, top); LuaDLL.lua_settop(L, top); } } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); Call(2, top + 1, top); LuaDLL.lua_settop(L, top); } } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); Call(3, top + 1, top); LuaDLL.lua_settop(L, top); } } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); Call(4, top + 1, top); LuaDLL.lua_settop(L, top); } } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); Call(5, top + 1, top); LuaDLL.lua_settop(L, top); } } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); Call(6, top + 1, top); LuaDLL.lua_settop(L, top); } } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public R1 Invoke(string name, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { Call(0, top + 1, top); R1 ret1 = CheckValue(top + 2); LuaDLL.lua_settop(L, top); return ret1; } return default(R1); } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public R1 Invoke(string name, T1 arg1, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); Call(1, top + 1, top); R1 ret1 = CheckValue(top + 2); LuaDLL.lua_settop(L, top); return ret1; } return default(R1); } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); Call(2, top + 1, top); R1 ret1 = CheckValue(top + 2); LuaDLL.lua_settop(L, top); return ret1; } return default(R1); } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); Call(3, top + 1, top); R1 ret1 = CheckValue(top + 2); LuaDLL.lua_settop(L, top); return ret1; } return default(R1); } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); Call(4, top + 1, top); R1 ret1 = CheckValue(top + 2); LuaDLL.lua_settop(L, top); return ret1; } return default(R1); } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); Call(5, top + 1, top); R1 ret1 = CheckValue(top + 2); LuaDLL.lua_settop(L, top); return ret1; } return default(R1); } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, bool beLogMiss) { int top = LuaDLL.lua_gettop(L); try { if (BeginCall(name, top, beLogMiss)) { PushGeneric(arg1); PushGeneric(arg2); PushGeneric(arg3); PushGeneric(arg4); PushGeneric(arg5); PushGeneric(arg6); Call(6, top + 1, top); R1 ret1 = CheckValue(top + 2); LuaDLL.lua_settop(L, top); return ret1; } return default(R1); } catch (Exception e) { LuaDLL.lua_settop(L, top); throw e; } } void InitTypeTraits() { LuaMatchType _ck = new LuaMatchType(); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckNumber); TypeTraits.Init(_ck.CheckBool); TypeTraits.Init(_ck.CheckLong); TypeTraits.Init(_ck.CheckULong); TypeTraits.Init(_ck.CheckString); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullNumber); TypeTraits>.Init(_ck.CheckNullBool); TypeTraits>.Init(_ck.CheckNullLong); TypeTraits>.Init(_ck.CheckNullULong); TypeTraits.Init(_ck.CheckByteArray); TypeTraits.Init(_ck.CheckCharArray); TypeTraits.Init(_ck.CheckBoolArray); TypeTraits.Init(_ck.CheckSByteArray); TypeTraits.Init(_ck.CheckInt16Array); TypeTraits.Init(_ck.CheckUInt16Array); TypeTraits.Init(_ck.CheckDecimalArray); TypeTraits.Init(_ck.CheckSingleArray); TypeTraits.Init(_ck.CheckDoubleArray); TypeTraits.Init(_ck.CheckInt32Array); TypeTraits.Init(_ck.CheckUInt32Array); TypeTraits.Init(_ck.CheckInt64Array); TypeTraits.Init(_ck.CheckUInt64Array); TypeTraits.Init(_ck.CheckStringArray); TypeTraits.Init(_ck.CheckVec3); TypeTraits.Init(_ck.CheckQuat); TypeTraits.Init(_ck.CheckVec2); TypeTraits.Init(_ck.CheckColor); TypeTraits.Init(_ck.CheckColor32); TypeTraits.Init(_ck.CheckVec4); TypeTraits.Init(_ck.CheckRay); TypeTraits.Init(_ck.CheckBounds); TypeTraits.Init(_ck.CheckTouch); TypeTraits.Init(_ck.CheckLayerMask); TypeTraits.Init(_ck.CheckRaycastHit); TypeTraits>.Init(_ck.CheckNullVec3); TypeTraits>.Init(_ck.CheckNullQuat); TypeTraits>.Init(_ck.CheckNullVec2); TypeTraits>.Init(_ck.CheckNullColor); TypeTraits>.Init(_ck.CheckNullColor32); TypeTraits>.Init(_ck.CheckNullVec4); TypeTraits>.Init(_ck.CheckNullRay); TypeTraits>.Init(_ck.CheckNullBounds); TypeTraits>.Init(_ck.CheckNullTouch); TypeTraits>.Init(_ck.CheckNullLayerMask); TypeTraits>.Init(_ck.CheckNullRaycastHit); TypeTraits.Init(_ck.CheckVec3Array); TypeTraits.Init(_ck.CheckQuatArray); TypeTraits.Init(_ck.CheckVec2Array); TypeTraits.Init(_ck.CheckColorArray); TypeTraits.Init(_ck.CheckColor32Array); TypeTraits.Init(_ck.CheckVec4Array); TypeTraits.Init(_ck.CheckPtr); TypeTraits.Init(_ck.CheckPtr); TypeTraits.Init(_ck.CheckLuaFunc); TypeTraits.Init(_ck.CheckLuaTable); TypeTraits.Init(_ck.CheckLuaThread); TypeTraits.Init(_ck.CheckLuaBaseRef); TypeTraits.Init(_ck.CheckByteBuffer); TypeTraits.Init(_ck.CheckEventObject); TypeTraits.Init(_ck.CheckEnumerator); TypeTraits.Init(_ck.CheckMonoType); TypeTraits.Init(_ck.CheckGameObject); TypeTraits.Init(_ck.CheckTransform); TypeTraits.Init(_ck.CheckTypeArray); TypeTraits.Init(_ck.CheckVariant); TypeTraits.Init(_ck.CheckObjectArray); } void InitStackTraits() { LuaStackOp op = new LuaStackOp(); StackTraits.Init(op.Push, op.CheckSByte, op.ToSByte); StackTraits.Init(op.Push, op.CheckByte, op.ToByte); StackTraits.Init(op.Push, op.CheckInt16, op.ToInt16); StackTraits.Init(op.Push, op.CheckUInt16, op.ToUInt16); StackTraits.Init(op.Push, op.CheckChar, op.ToChar); StackTraits.Init(op.Push, op.CheckInt32, op.ToInt32); StackTraits.Init(op.Push, op.CheckUInt32, op.ToUInt32); StackTraits.Init(op.Push, op.CheckDecimal, op.ToDecimal); StackTraits.Init(op.Push, op.CheckFloat, op.ToFloat); StackTraits.Init(LuaDLL.lua_pushnumber, LuaDLL.luaL_checknumber, LuaDLL.lua_tonumber); StackTraits.Init(LuaDLL.lua_pushboolean, LuaDLL.luaL_checkboolean, LuaDLL.lua_toboolean); StackTraits.Init(LuaDLL.tolua_pushint64, LuaDLL.tolua_checkint64, LuaDLL.tolua_toint64); StackTraits.Init(LuaDLL.tolua_pushuint64, LuaDLL.tolua_checkuint64, LuaDLL.tolua_touint64); StackTraits.Init(LuaDLL.lua_pushstring, ToLua.CheckString, ToLua.ToString); StackTraits>.Init(op.Push, op.CheckNullSByte, op.ToNullSByte); StackTraits>.Init(op.Push, op.CheckNullByte, op.ToNullByte); StackTraits>.Init(op.Push, op.CheckNullInt16, op.ToNullInt16); StackTraits>.Init(op.Push, op.CheckNullUInt16, op.ToNullUInt16); StackTraits>.Init(op.Push, op.CheckNullChar, op.ToNullChar); StackTraits>.Init(op.Push, op.CheckNullInt32, op.ToNullInt32); StackTraits>.Init(op.Push, op.CheckNullUInt32, op.ToNullUInt32); StackTraits>.Init(op.Push, op.CheckNullDecimal, op.ToNullDecimal); StackTraits>.Init(op.Push, op.CheckNullFloat, op.ToNullFloat); StackTraits>.Init(op.Push, op.CheckNullNumber, op.ToNullNumber); StackTraits>.Init(op.Push, op.CheckNullBool, op.ToNullBool); StackTraits>.Init(op.Push, op.CheckNullInt64, op.ToNullInt64); StackTraits>.Init(op.Push, op.CheckNullUInt64, op.ToNullUInt64); StackTraits.Init(ToLua.Push, ToLua.CheckByteBuffer, ToLua.ToByteBuffer); StackTraits.Init(ToLua.Push, ToLua.CheckCharBuffer, ToLua.ToCharBuffer); StackTraits.Init(ToLua.Push, ToLua.CheckBoolArray, ToLua.ToBoolArray); StackTraits.Init(ToLua.Push, op.CheckSByteArray, op.ToSByteArray); StackTraits.Init(ToLua.Push, op.CheckInt16Array, op.ToInt16Array); StackTraits.Init(ToLua.Push, op.CheckUInt16Array, op.ToUInt16Array); StackTraits.Init(ToLua.Push, op.CheckDecimalArray, op.ToDecimalArray); StackTraits.Init(ToLua.Push, op.CheckFloatArray, op.ToFloatArray); StackTraits.Init(ToLua.Push, op.CheckDoubleArray, op.ToDoubleArray); StackTraits.Init(ToLua.Push, op.CheckInt32Array, op.ToInt32Array); StackTraits.Init(ToLua.Push, op.CheckUInt32Array, op.ToUInt32Array); StackTraits.Init(ToLua.Push, op.CheckInt64Array, op.ToInt64Array); StackTraits.Init(ToLua.Push, op.CheckUInt64Array, op.ToUInt64Array); StackTraits.Init(ToLua.Push, ToLua.CheckStringArray, ToLua.ToStringArray); StackTraits.Init(ToLua.Push, ToLua.CheckVector3, ToLua.ToVector3); StackTraits.Init(ToLua.Push, ToLua.CheckQuaternion, ToLua.ToQuaternion); StackTraits.Init(ToLua.Push, ToLua.CheckVector2, ToLua.ToVector2); StackTraits.Init(ToLua.Push, ToLua.CheckColor, ToLua.ToColor); StackTraits.Init(ToLua.Push, ToLua.CheckColor32, ToLua.ToColor32); StackTraits.Init(ToLua.Push, ToLua.CheckVector4, ToLua.ToVector4); StackTraits.Init(ToLua.Push, ToLua.CheckRay, ToLua.ToRay); StackTraits.Init(ToLua.Push, null, null); StackTraits.Init(ToLua.Push, ToLua.CheckBounds, ToLua.ToBounds); StackTraits.Init(ToLua.PushLayerMask, ToLua.CheckLayerMask, ToLua.ToLayerMask); StackTraits.Init(ToLua.Push, null, null); StackTraits>.Init(op.Push, op.CheckNullVec3, op.ToNullVec3); StackTraits>.Init(op.Push, op.CheckNullQuat, op.ToNullQuat); StackTraits>.Init(op.Push, op.CheckNullVec2, op.ToNullVec2); StackTraits>.Init(op.Push, op.CheckNullColor, op.ToNullColor); StackTraits>.Init(op.Push, op.CheckNullColor32, op.ToNullColor32); StackTraits>.Init(op.Push, op.CheckNullVec4, op.ToNullVec4); StackTraits>.Init(op.Push, op.CheckNullRay, op.ToNullRay); StackTraits>.Init(op.Push, null, null); StackTraits>.Init(op.Push, op.CheckNullBounds, op.ToNullBounds); StackTraits>.Init(op.Push, op.CheckNullLayerMask, op.ToNullLayerMask); StackTraits>.Init(op.Push, null, null); StackTraits.Init(ToLua.Push, op.CheckVec3Array, op.ToVec3Array); StackTraits.Init(ToLua.Push, op.CheckQuatArray, op.ToQuatArray); StackTraits.Init(ToLua.Push, op.CheckVec2Array, op.ToVec2Array); StackTraits.Init(ToLua.Push, op.CheckColorArray, op.ToColorArray); StackTraits.Init(ToLua.Push, op.CheckColor32Array, op.ToColor32Array); StackTraits.Init(ToLua.Push, op.CheckVec4Array, op.ToVec4Array); StackTraits.Init(op.Push, op.CheckUIntPtr, op.CheckUIntPtr); //"NYI" StackTraits.Init(LuaDLL.lua_pushlightuserdata, ToLua.CheckIntPtr, ToLua.CheckIntPtr); StackTraits.Init(ToLua.Push, ToLua.CheckLuaFunction, ToLua.ToLuaFunction); StackTraits.Init(ToLua.Push, ToLua.CheckLuaTable, ToLua.ToLuaTable); StackTraits.Init(ToLua.Push, ToLua.CheckLuaThread, ToLua.ToLuaThread); StackTraits.Init(ToLua.Push, ToLua.CheckLuaBaseRef, ToLua.CheckLuaBaseRef); StackTraits.Init(ToLua.Push, op.CheckLuaByteBuffer, op.ToLuaByteBuffer); StackTraits.Init(ToLua.Push, op.CheckEventObject, op.ToEventObject); StackTraits.Init(ToLua.Push, ToLua.CheckIter, op.ToIter); StackTraits.Init(ToLua.Push, ToLua.CheckMonoType, op.ToType); StackTraits.Init(ToLua.Push, op.CheckTypeArray, op.ToTypeArray); StackTraits.Init(op.Push, op.CheckGameObject, op.ToGameObject); StackTraits.Init(op.Push, op.CheckTransform, op.ToTransform); StackTraits.Init(ToLua.Push, ToLua.ToVarObject, ToLua.ToVarObject); StackTraits.Init(ToLua.Push, ToLua.CheckObjectArray, ToLua.ToObjectArray); StackTraits.Init(ToLua.Push, null, null); } } } ================================================ FILE: Assets/ToLua/Core/LuaState.cs.meta ================================================ fileFormatVersion: 2 guid: 358b86bdf79858e46b17d8700238c397 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaStatePtr.cs ================================================ using UnityEngine; using System; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace LuaInterface { public class LuaStatePtr { protected IntPtr L; string jit = @" function Euler(x, y, z) x = x * 0.0087266462599716 y = y * 0.0087266462599716 z = z * 0.0087266462599716 local sinX = math.sin(x) local cosX = math.cos(x) local sinY = math.sin(y) local cosY = math.cos(y) local sinZ = math.sin(z) local cosZ = math.cos(z) local w = cosY * cosX * cosZ + sinY * sinX * sinZ x = cosY* sinX * cosZ + sinY* cosX * sinZ y = sinY * cosX * cosZ - cosY * sinX * sinZ z = cosY* cosX * sinZ - sinY* sinX * cosZ return {x = x, y = y, z= z, w = w} end function Slerp(q1, q2, t) local x1, y1, z1, w1 = q1.x, q1.y, q1.z, q1.w local x2,y2,z2,w2 = q2.x, q2.y, q2.z, q2.w local dot = x1* x2 + y1* y2 + z1* z2 + w1* w2 if dot< 0 then dot = -dot x2, y2, z2, w2 = -x2, -y2, -z2, -w2 end if dot< 0.95 then local sin = math.sin local angle = math.acos(dot) local invSinAngle = 1 / sin(angle) local t1 = sin((1 - t) * angle) * invSinAngle local t2 = sin(t * angle) * invSinAngle return {x = x1* t1 + x2* t2, y = y1 * t1 + y2 * t2, z = z1 * t1 + z2 * t2, w = w1 * t1 + w2 * t2} else x1 = x1 + t* (x2 - x1) y1 = y1 + t* (y2 - y1) z1 = z1 + t* (z2 - z1) w1 = w1 + t* (w2 - w1) dot = x1* x1 + y1* y1 + z1* z1 + w1* w1 return {x = x1 / dot, y = y1 / dot, z = z1 / dot, w = w1 / dot} end end if jit then if jit.status() then for i=1,10000 do local q1 = Euler(i, i, i) Slerp({ x = 0, y = 0, z = 0, w = 1}, q1, 0.5) end end end"; public int LuaUpValueIndex(int i) { return LuaIndexes.LUA_GLOBALSINDEX - i; } public IntPtr LuaNewState() { return LuaDLL.luaL_newstate(); } public void LuaOpenJit() { #if UNITY_ANDROID //某些机型如三星arm64在jit on模式下会崩溃,临时关闭这里 if (IntPtr.Size == 8) { LuaDLL.luaL_dostring(L, "jit.off()"); } else if (!LuaDLL.luaL_dostring(L, jit)) { string str = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, 0); throw new Exception(str); } #endif } public void LuaClose() { LuaDLL.lua_close(L); L = IntPtr.Zero; } public IntPtr LuaNewThread() { return LuaDLL.lua_newthread(L); } public IntPtr LuaAtPanic(IntPtr panic) { return LuaDLL.lua_atpanic(L, panic); } public int LuaGetTop() { return LuaDLL.lua_gettop(L); } public void LuaSetTop(int newTop) { LuaDLL.lua_settop(L, newTop); } public void LuaPushValue(int idx) { LuaDLL.lua_pushvalue(L, idx); } public void LuaRemove(int index) { LuaDLL.lua_remove(L, index); } public void LuaInsert(int idx) { LuaDLL.lua_insert(L, idx); } public void LuaReplace(int idx) { LuaDLL.lua_replace(L, idx); } public bool LuaCheckStack(int args) { return LuaDLL.lua_checkstack(L, args) != 0; } public void LuaXMove(IntPtr to, int n) { LuaDLL.lua_xmove(L, to, n); } public bool LuaIsNumber(int idx) { return LuaDLL.lua_isnumber(L, idx) != 0; } public bool LuaIsString(int index) { return LuaDLL.lua_isstring(L, index) != 0; } public bool LuaIsCFunction(int index) { return LuaDLL.lua_iscfunction(L, index) != 0; } public bool LuaIsUserData(int index) { return LuaDLL.lua_isuserdata(L, index) != 0; } public bool LuaIsNil(int n) { return LuaDLL.lua_isnil(L, n); } public LuaTypes LuaType(int index) { return LuaDLL.lua_type(L, index); } public string LuaTypeName(LuaTypes type) { return LuaDLL.lua_typename(L, type); } public string LuaTypeName(int idx) { return LuaDLL.luaL_typename(L, idx); } public bool LuaEqual(int idx1, int idx2) { return LuaDLL.lua_equal(L, idx1, idx2) != 0; } public bool LuaRawEqual(int idx1, int idx2) { return LuaDLL.lua_rawequal(L, idx1, idx2) != 0; } public bool LuaLessThan(int idx1, int idx2) { return LuaDLL.lua_lessthan(L, idx1, idx2) != 0; } public double LuaToNumber(int idx) { return LuaDLL.lua_tonumber(L, idx); } public int LuaToInteger(int idx) { return LuaDLL.lua_tointeger(L, idx); } public bool LuaToBoolean(int idx) { return LuaDLL.lua_toboolean(L, idx); } public string LuaToString(int index) { string s = LuaDLL.lua_tostring(L, index); if (s == null) { // 可能抛出一个table作为error参数,调用tostring获取其字符串 LuaDLL.lua_getglobal(L, "tostring"); LuaDLL.lua_pushvalue(L, index - 1); LuaDLL.lua_pcall(L, 1, 1, 0); s = LuaDLL.lua_tostring(L, -1); } return s; } public IntPtr LuaToLString(int index, out int len) { return LuaDLL.tolua_tolstring(L, index, out len); } public IntPtr LuaToCFunction(int idx) { return LuaDLL.lua_tocfunction(L, idx); } public IntPtr LuaToUserData(int idx) { return LuaDLL.lua_touserdata(L, idx); } public IntPtr LuaToThread(int idx) { return LuaDLL.lua_tothread(L, idx); } public IntPtr LuaToPointer(int idx) { return LuaDLL.lua_topointer(L, idx); } public int LuaObjLen(int index) { return LuaDLL.tolua_objlen(L, index); } public void LuaPushNil() { LuaDLL.lua_pushnil(L); } public void LuaPushNumber(double number) { LuaDLL.lua_pushnumber(L, number); } public void LuaPushInteger(int n) { LuaDLL.lua_pushnumber(L, n); } public void LuaPushLString(byte[] str, int size) { LuaDLL.lua_pushlstring(L, str, size); } public void LuaPushString(string str) { LuaDLL.lua_pushstring(L, str); } public void LuaPushCClosure(IntPtr fn, int n) { LuaDLL.lua_pushcclosure(L, fn, n); } public void LuaPushBoolean(bool value) { LuaDLL.lua_pushboolean(L, value ? 1 : 0); } public void LuaPushLightUserData(IntPtr udata) { LuaDLL.lua_pushlightuserdata(L, udata); } public int LuaPushThread() { return LuaDLL.lua_pushthread(L); } public void LuaGetTable(int idx) { LuaDLL.lua_gettable(L, idx); } public void LuaGetField(int index, string key) { LuaDLL.lua_getfield(L, index, key); } public void LuaRawGet(int idx) { LuaDLL.lua_rawget(L, idx); } public void LuaRawGetI(int tableIndex, int index) { LuaDLL.lua_rawgeti(L, tableIndex, index); } public void LuaCreateTable(int narr = 0, int nec = 0) { LuaDLL.lua_createtable(L, narr, nec); } public IntPtr LuaNewUserData(int size) { return LuaDLL.tolua_newuserdata(L, size); } public int LuaGetMetaTable(int idx) { return LuaDLL.lua_getmetatable(L, idx); } public void LuaGetEnv(int idx) { LuaDLL.lua_getfenv(L, idx); } public void LuaSetTable(int idx) { LuaDLL.lua_settable(L, idx); } public void LuaSetField(int idx, string key) { LuaDLL.lua_setfield(L, idx, key); } public void LuaRawSet(int idx) { LuaDLL.lua_rawset(L, idx); } public void LuaRawSetI(int tableIndex, int index) { LuaDLL.lua_rawseti(L, tableIndex, index); } public void LuaSetMetaTable(int objIndex) { LuaDLL.lua_setmetatable(L, objIndex); } public void LuaSetEnv(int idx) { LuaDLL.lua_setfenv(L, idx); } public void LuaCall(int nArgs, int nResults) { LuaDLL.lua_call(L, nArgs, nResults); } public int LuaPCall(int nArgs, int nResults, int errfunc) { return LuaDLL.lua_pcall(L, nArgs, nResults, errfunc); } public int LuaYield(int nresults) { return LuaDLL.lua_yield(L, nresults); } public int LuaResume(int narg) { return LuaDLL.lua_resume(L, narg); } public int LuaStatus() { return LuaDLL.lua_status(L); } public int LuaGC(LuaGCOptions what, int data = 0) { return LuaDLL.lua_gc(L, what, data); } public bool LuaNext(int index) { return LuaDLL.lua_next(L, index) != 0; } public void LuaConcat(int n) { LuaDLL.lua_concat(L, n); } public void LuaPop(int amount) { LuaDLL.lua_pop(L, amount); } public void LuaNewTable() { LuaDLL.lua_createtable(L, 0 , 0); } public void LuaPushFunction(LuaCSFunction func) { IntPtr fn = Marshal.GetFunctionPointerForDelegate(func); LuaDLL.lua_pushcclosure(L, fn, 0); } public bool lua_isfunction(int n) { return LuaDLL.lua_type(L, n) == LuaTypes.LUA_TFUNCTION; } public bool lua_istable(int n) { return LuaDLL.lua_type(L, n) == LuaTypes.LUA_TTABLE; } public bool lua_islightuserdata(int n) { return LuaDLL.lua_type(L, n) == LuaTypes.LUA_TLIGHTUSERDATA; } public bool lua_isnil(int n) { return LuaDLL.lua_type(L, n) == LuaTypes.LUA_TNIL; } public bool lua_isboolean(int n) { LuaTypes type = LuaDLL.lua_type(L, n); return type == LuaTypes.LUA_TBOOLEAN || type == LuaTypes.LUA_TNIL; } public bool lua_isthread(int n) { return LuaDLL.lua_type(L, n) == LuaTypes.LUA_TTHREAD; } public bool lua_isnone(int n) { return LuaDLL.lua_type(L, n) == LuaTypes.LUA_TNONE; } public bool lua_isnoneornil(int n) { return LuaDLL.lua_type(L, n) <= LuaTypes.LUA_TNIL; } public void LuaRawGlobal(string name) { LuaDLL.lua_pushstring(L, name); LuaDLL.lua_rawget(L, LuaIndexes.LUA_GLOBALSINDEX); } public void LuaSetGlobal(string name) { LuaDLL.lua_setglobal(L, name); } public void LuaGetGlobal(string name) { LuaDLL.lua_getglobal(L, name); } public void LuaOpenLibs() { LuaDLL.luaL_openlibs(L); } public int AbsIndex(int i) { return (i > 0 || i <= LuaIndexes.LUA_REGISTRYINDEX) ? i : LuaDLL.lua_gettop(L) + i + 1; } public int LuaGetN(int i) { return LuaDLL.luaL_getn(L, i); } public double LuaCheckNumber(int stackPos) { return LuaDLL.luaL_checknumber(L, stackPos); } public int LuaCheckInteger(int idx) { return LuaDLL.luaL_checkinteger(L, idx); } public bool LuaCheckBoolean(int stackPos) { return LuaDLL.luaL_checkboolean(L, stackPos); } public string LuaCheckLString(int numArg, out int len) { return LuaDLL.luaL_checklstring(L, numArg, out len); } public int LuaLoadBuffer(byte[] buff, int size, string name) { return LuaDLL.luaL_loadbuffer(L, buff, size, name); } public IntPtr LuaFindTable(int idx, string fname, int szhint = 1) { return LuaDLL.luaL_findtable(L, idx, fname, szhint); } public int LuaTypeError(int stackPos, string tname, string t2 = null) { return LuaDLL.luaL_typerror(L, stackPos, tname, t2); } public bool LuaDoString(string chunk, string chunkName = "@LuaStatePtr.cs") { byte[] buffer = Encoding.UTF8.GetBytes(chunk); int status = LuaDLL.luaL_loadbuffer(L, buffer, buffer.Length, chunkName); if (status != 0) { return false; } return LuaDLL.lua_pcall(L, 0, LuaDLL.LUA_MULTRET, 0) == 0; //return LuaDLL.luaL_dostring(L, chunk); } public bool LuaDoFile(string fileName) { int top = LuaGetTop(); if (LuaDLL.luaL_dofile(L, fileName)) { return true; } string err = LuaToString(-1); LuaSetTop(top); throw new LuaException(err, LuaException.GetLastError()); } public void LuaGetMetaTable(string meta) { LuaDLL.luaL_getmetatable(L, meta); } public int LuaRef(int t) { return LuaDLL.luaL_ref(L, t); } public void LuaGetRef(int reference) { LuaDLL.lua_getref(L, reference); } public void LuaUnRef(int reference) { LuaDLL.lua_unref(L, reference); } public int LuaRequire(string fileName) { #if UNITY_EDITOR string str = Path.GetExtension(fileName); if (str == ".lua") { throw new LuaException("Require not need file extension: " + str); } #endif return LuaDLL.tolua_require(L, fileName); } //适合Awake OnSendMsg使用 public void ThrowLuaException(Exception e) { if (LuaException.InstantiateCount > 0 || LuaException.SendMsgCount > 0) { LuaDLL.toluaL_exception(LuaException.L, e); } else { throw e; } } public int ToLuaRef() { return LuaDLL.toluaL_ref(L); } public int LuaUpdate(float delta, float unscaled) { return LuaDLL.tolua_update(L, delta, unscaled); } public int LuaLateUpdate() { return LuaDLL.tolua_lateupdate(L); } public int LuaFixedUpdate(float fixedTime) { return LuaDLL.tolua_fixedupdate(L, fixedTime); } public void OpenToLuaLibs() { LuaDLL.tolua_openlibs(L); LuaOpenJit(); } public void ToLuaPushTraceback() { LuaDLL.tolua_pushtraceback(L); } public void ToLuaUnRef(int reference) { LuaDLL.toluaL_unref(L, reference); } public int LuaGetStack(int level, ref Lua_Debug ar) { return LuaDLL.lua_getstack(L, level, ref ar); } public int LuaGetInfo(string what, ref Lua_Debug ar) { return LuaDLL.lua_getinfo(L, what, ref ar); } public string LuaGetLocal(ref Lua_Debug ar, int n) { return LuaDLL.lua_getlocal(L, ref ar, n); } public string LuaSetLocal(ref Lua_Debug ar, int n) { return LuaDLL.lua_setlocal(L, ref ar, n); } public string LuaGetUpvalue(int funcindex, int n) { return LuaDLL.lua_getupvalue(L, funcindex, n); } public string LuaSetUpvalue(int funcindex, int n) { return LuaDLL.lua_setupvalue(L, funcindex, n); } public int LuaSetHook(LuaHookFunc func, int mask, int count) { return LuaDLL.lua_sethook(L, func, mask, count); } public LuaHookFunc LuaGetHook() { return LuaDLL.lua_gethook(L); } public int LuaGetHookMask() { return LuaDLL.lua_gethookmask(L); } public int LuaGetHookCount() { return LuaDLL.lua_gethookcount(L); } } } ================================================ FILE: Assets/ToLua/Core/LuaStatePtr.cs.meta ================================================ fileFormatVersion: 2 guid: e68c435592e3d3b47a315497b6150aae timeCreated: 1515060461 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Core/LuaStatic.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.IO; using System.Text; namespace LuaInterface { public static class LuaStatic { public static int GetMetaReference(IntPtr L, Type t) { LuaState state = LuaState.Get(L); return state.GetMetaReference(t); } public static int GetMissMetaReference(IntPtr L, Type t) { LuaState state = LuaState.Get(L); return state.GetMissMetaReference(t); } public static Type GetClassType(IntPtr L, int reference) { LuaState state = LuaState.Get(L); return state.GetClassType(reference); } public static LuaFunction GetFunction(IntPtr L, int reference) { LuaState state = LuaState.Get(L); return state.GetFunction(reference); } public static LuaTable GetTable(IntPtr L, int reference) { LuaState state = LuaState.Get(L); return state.GetTable(reference); } public static LuaThread GetLuaThread(IntPtr L, int reference) { LuaState state = LuaState.Get(L); return state.GetLuaThread(reference); } public static void GetUnpackRayRef(IntPtr L) { LuaState state = LuaState.Get(L); LuaDLL.lua_getref(L, state.UnpackRay); } public static void GetUnpackBounds(IntPtr L) { LuaState state = LuaState.Get(L); LuaDLL.lua_getref(L, state.UnpackBounds); } public static void GetPackRay(IntPtr L) { LuaState state = LuaState.Get(L); LuaDLL.lua_getref(L, state.PackRay); } public static void GetPackRaycastHit(IntPtr L) { LuaState state = LuaState.Get(L); LuaDLL.lua_getref(L, state.PackRaycastHit); } public static void GetPackTouch(IntPtr L) { LuaState state = LuaState.Get(L); LuaDLL.lua_getref(L, state.PackTouch); } public static void GetPackBounds(IntPtr L) { LuaState state = LuaState.Get(L); LuaDLL.lua_getref(L, state.PackBounds); } public static int GetArrayMetatable(IntPtr L) { LuaState state = LuaState.Get(L); return state.ArrayMetatable; } public static int GetTypeMetatable(IntPtr L) { LuaState state = LuaState.Get(L); return state.TypeMetatable; } public static int GetDelegateMetatable(IntPtr L) { LuaState state = LuaState.Get(L); return state.DelegateMetatable; } public static int GetEventMetatable(IntPtr L) { LuaState state = LuaState.Get(L); return state.EventMetatable; } public static int GetIterMetatable(IntPtr L) { LuaState state = LuaState.Get(L); return state.IterMetatable; } public static int GetEnumObject(IntPtr L, System.Enum e, out object obj) { LuaState state = LuaState.Get(L); obj = state.GetEnumObj(e); return state.EnumMetatable; } public static LuaCSFunction GetPreModule(IntPtr L, Type t) { LuaState state = LuaState.Get(L); return state.GetPreModule(t); } } } ================================================ FILE: Assets/ToLua/Core/LuaStatic.cs.meta ================================================ fileFormatVersion: 2 guid: e7f8fdc4e97256748b422edf401c641d MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaTable.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections; using System.Collections.Generic; namespace LuaInterface { public class LuaTable : LuaBaseRef { public LuaTable(int reference, LuaState state) { this.reference = reference; this.luaState = state; } public object this[string key] { get { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.Push(key); luaState.LuaGetTable(top + 1); object ret = luaState.ToVariant(top + 2); luaState.LuaSetTop(top); return ret; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } set { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.Push(key); luaState.PushVariant(value); luaState.LuaSetTable(top + 1); luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } } public object this[int key] { get { int oldTop = luaState.LuaGetTop(); try { luaState.Push(this); luaState.LuaRawGetI(oldTop + 1, key); object obj = luaState.ToVariant(oldTop + 2); luaState.LuaSetTop(oldTop); return obj; } catch (Exception e) { luaState.LuaSetTop(oldTop); throw e; } } set { int oldTop = luaState.LuaGetTop(); try { luaState.Push(this); luaState.PushVariant(value); luaState.LuaRawSetI(oldTop + 1, key); luaState.LuaSetTop(oldTop); } catch (Exception e) { luaState.LuaSetTop(oldTop); throw e; } } } public int Length { get { luaState.Push(this); int n = luaState.LuaObjLen(-1); luaState.LuaPop(1); return n; } } public T RawGetIndex(int index) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.LuaRawGetI(top + 1, index); T ret = luaState.CheckValue(top + 2); luaState.LuaSetTop(top); return ret; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void RawSetIndex(int index, T value) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.PushGeneric(value); luaState.LuaRawSetI(top + 1, index); luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public V RawGet(K key) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.PushGeneric(key); luaState.LuaRawGet(top + 1); V ret = luaState.CheckValue(top + 2); luaState.LuaSetTop(top); return ret; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void RawSet(K key, V arg) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.PushGeneric(key); luaState.PushGeneric(arg); luaState.LuaRawSet(top + 1); luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public T GetTable(string key) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.Push(key); luaState.LuaGetTable(top + 1); T ret = luaState.CheckValue(top + 2); luaState.LuaSetTop(top); return ret; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void SetTable(string key, T arg) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.Push(key); luaState.PushGeneric(arg); luaState.LuaSetTable(top + 1); luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public LuaFunction RawGetLuaFunction(string key) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.Push(key); luaState.LuaRawGet(top + 1); LuaFunction func = luaState.CheckLuaFunction(top + 2); luaState.LuaSetTop(top); #if UNITY_EDITOR if (func != null) { func.name = name + "." + key; } #endif return func; } catch(Exception e) { luaState.LuaSetTop(top); throw e; } } public LuaFunction GetLuaFunction(string key) { int top = luaState.LuaGetTop(); try { luaState.Push(this); luaState.Push(key); luaState.LuaGetTable(top + 1); LuaFunction func = luaState.CheckLuaFunction(top + 2); luaState.LuaSetTop(top); #if UNITY_EDITOR if (func != null) { func.name = name + "." + key; } #endif return func; } catch(Exception e) { luaState.LuaSetTop(top); throw e; } } bool BeginCall(string name, int top) { luaState.Push(this); luaState.ToLuaPushTraceback(); luaState.Push(name); luaState.LuaGetTable(top + 1); return luaState.LuaType(top + 3) == LuaTypes.LUA_TFUNCTION; } public void Call(string name) { int top = luaState.LuaGetTop(); try { if (BeginCall(name, top)) { luaState.Call(0, top + 2, top); } luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void Call(string name, T1 arg1) { int top = luaState.LuaGetTop(); try { if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.Call(1, top + 2, top); } luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void Call(string name, T1 arg1, T2 arg2) { int top = luaState.LuaGetTop(); try { if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.Call(2, top + 2, top); } luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3) { int top = luaState.LuaGetTop(); try { if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.Call(3, top + 2, top); } luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { int top = luaState.LuaGetTop(); try { if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.PushGeneric(arg4); luaState.Call(4, top + 2, top); } luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { int top = luaState.LuaGetTop(); try { if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.PushGeneric(arg4); luaState.PushGeneric(arg5); luaState.Call(5, top + 2, top); } luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public void Call(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { int top = luaState.LuaGetTop(); try { if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.PushGeneric(arg4); luaState.PushGeneric(arg5); luaState.PushGeneric(arg6); luaState.Call(6, top + 2, top); } luaState.LuaSetTop(top); } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public R1 Invoke(string name) { int top = luaState.LuaGetTop(); try { R1 ret1 = default(R1); if (BeginCall(name, top)) { luaState.Call(0, top + 2, top); ret1 = luaState.CheckValue(top + 3); } luaState.LuaSetTop(top); return ret1; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public R1 Invoke(string name, T1 arg1) { int top = luaState.LuaGetTop(); try { R1 ret1 = default(R1); if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.Call(1, top + 2, top); ret1 = luaState.CheckValue(top + 3); } luaState.LuaSetTop(top); return ret1; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2) { int top = luaState.LuaGetTop(); try { R1 ret1 = default(R1); if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.Call(2, top + 2, top); ret1 = luaState.CheckValue(top + 3); } luaState.LuaSetTop(top); return ret1; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3) { int top = luaState.LuaGetTop(); try { R1 ret1 = default(R1); if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.Call(3, top + 2, top); ret1 = luaState.CheckValue(top + 3); } luaState.LuaSetTop(top); return ret1; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { int top = luaState.LuaGetTop(); try { R1 ret1 = default(R1); if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.PushGeneric(arg4); luaState.Call(4, top + 2, top); ret1 = luaState.CheckValue(top + 3); } luaState.LuaSetTop(top); return ret1; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { int top = luaState.LuaGetTop(); try { R1 ret1 = default(R1); if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.PushGeneric(arg4); luaState.PushGeneric(arg5); luaState.Call(5, top + 2, top); ret1 = luaState.CheckValue(top + 3); } luaState.LuaSetTop(top); return ret1; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public R1 Invoke(string name, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { int top = luaState.LuaGetTop(); try { R1 ret1 = default(R1); if (BeginCall(name, top)) { luaState.PushGeneric(arg1); luaState.PushGeneric(arg2); luaState.PushGeneric(arg3); luaState.PushGeneric(arg4); luaState.PushGeneric(arg5); luaState.PushGeneric(arg6); luaState.Call(6, top + 2, top); ret1 = luaState.CheckValue(top + 3); } luaState.LuaSetTop(top); return ret1; } catch (Exception e) { luaState.LuaSetTop(top); throw e; } } public string GetStringField(string name) { int oldTop = luaState.LuaGetTop(); try { luaState.Push(this); luaState.LuaGetField(oldTop + 1, name); string str = luaState.CheckString(-1); luaState.LuaSetTop(oldTop); return str; } catch(LuaException e) { luaState.LuaSetTop(oldTop); throw e; } } public void AddTable(string name) { int oldTop = luaState.LuaGetTop(); try { luaState.Push(this); luaState.Push(name); luaState.LuaCreateTable(); luaState.LuaRawSet(oldTop + 1); luaState.LuaSetTop(oldTop); } catch (Exception e) { luaState.LuaSetTop(oldTop); throw e; } } public object[] ToArray() { int oldTop = luaState.LuaGetTop(); try { luaState.Push(this); int len = luaState.LuaObjLen(-1); List list = new List(len + 1); int index = 1; object obj = null; while(index <= len) { luaState.LuaRawGetI(-1, index++); obj = luaState.ToVariant(-1); luaState.LuaPop(1); list.Add(obj); } luaState.LuaSetTop(oldTop); return list.ToArray(); } catch (Exception e) { luaState.LuaSetTop(oldTop); throw e; } } public override string ToString() { luaState.Push(this); IntPtr p = luaState.LuaToPointer(-1); luaState.LuaPop(1); return string.Format("table:0x{0}", p.ToString("X")); } public LuaArrayTable ToArrayTable() { return new LuaArrayTable(this); } public LuaDictTable ToDictTable() { return new LuaDictTable(this); } public LuaDictTable ToDictTable() { return new LuaDictTable(this); } public LuaTable GetMetaTable() { int oldTop = luaState.LuaGetTop(); try { LuaTable t = null; luaState.Push(this); if (luaState.LuaGetMetaTable(-1) != 0) { t = luaState.CheckLuaTable(-1); } luaState.LuaSetTop(oldTop); return t; } catch (Exception e) { luaState.LuaSetTop(oldTop); throw e; } } } public class LuaArrayTable : IDisposable, IEnumerable { private LuaTable table = null; private LuaState state = null; public LuaArrayTable(LuaTable table) { table.AddRef(); this.table = table; this.state = table.GetLuaState(); } public void Dispose() { if (table != null) { table.Dispose(); table = null; } } public int Length { get { return table.Length; } } public object this[int key] { get { return table[key]; } set { table[key] = value; } } public void ForEach(Action action) { using (var iter = this.GetEnumerator()) { while (iter.MoveNext()) { action(iter.Current); } } } public IEnumerator GetEnumerator() { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } class Enumerator : IEnumerator { LuaState state; int index = 1; object current = null; int top = -1; public Enumerator(LuaArrayTable list) { state = list.state; top = state.LuaGetTop(); state.Push(list.table); } public object Current { get { return current; } } public bool MoveNext() { state.LuaRawGetI(-1, index); current = state.ToVariant(-1); state.LuaPop(1); ++index; return current == null ? false : true; } public void Reset() { index = 1; current = null; } public void Dispose() { if (state != null) { state.LuaSetTop(top); state = null; } } } } public class LuaDictTable : IDisposable, IEnumerable { LuaTable table; LuaState state; public LuaDictTable(LuaTable table) { table.AddRef(); this.table = table; this.state = table.GetLuaState() ; } public void Dispose() { if (table != null) { table.Dispose(); table = null; } } public object this[string key] { get { return table[key]; } set { table[key] = value; } } public Hashtable ToHashtable() { Hashtable hash = new Hashtable(); var iter = GetEnumerator(); while (iter.MoveNext()) { hash.Add(iter.Current.Key, iter.Current.Value); } iter.Dispose(); return hash; } public IEnumerator GetEnumerator() { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } class Enumerator : IEnumerator { LuaState state; DictionaryEntry current = new DictionaryEntry(); int top = -1; public Enumerator(LuaDictTable list) { state = list.state; top = state.LuaGetTop(); state.Push(list.table); state.LuaPushNil(); } public DictionaryEntry Current { get { return current; } } object IEnumerator.Current { get { return Current; } } public bool MoveNext() { if (state.LuaNext(-2)) { current = new DictionaryEntry(); current.Key = state.ToVariant(-2); current.Value = state.ToVariant(-1); state.LuaPop(1); return true; } else { current = new DictionaryEntry(); return false; } } public void Reset() { current = new DictionaryEntry(); } public void Dispose() { if (state != null) { state.LuaSetTop(top); state = null; } } } } public struct LuaDictEntry { public LuaDictEntry(K key, V value) : this() { Key = key; Value = value; } public K Key { get; set; } public V Value { get; set; } } public class LuaDictTable : IDisposable, IEnumerable> { LuaTable table; LuaState state; public LuaDictTable(LuaTable table) { table.AddRef(); this.table = table; this.state = table.GetLuaState(); } public void Dispose() { if (table != null) { table.Dispose(); table = null; } } public V this[K key] { get { return table.RawGet(key); } set { table.RawSet(key, value); } } public Dictionary ToDictionary() { Dictionary dict = new Dictionary(); var iter = GetEnumerator(); while (iter.MoveNext()) { dict.Add(iter.Current.Key, iter.Current.Value); } iter.Dispose(); return dict; } public IEnumerator> GetEnumerator() { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } class Enumerator : IEnumerator> { LuaState state; LuaDictEntry current = new LuaDictEntry(); int top = -1; public Enumerator(LuaDictTable list) { state = list.state; top = state.LuaGetTop(); state.Push(list.table); state.LuaPushNil(); } public LuaDictEntry Current { get { return current; } } object IEnumerator.Current { get { return Current; } } public bool MoveNext() { if (state.LuaNext(-2)) { current = new LuaDictEntry(); current.Key = state.CheckValue(-2); current.Value = state.CheckValue(-1); state.LuaPop(1); return true; } else { current = new LuaDictEntry(); return false; } } public void Reset() { current = new LuaDictEntry(); } public void Dispose() { if (state != null) { state.LuaSetTop(top); state = null; } } } } } ================================================ FILE: Assets/ToLua/Core/LuaTable.cs.meta ================================================ fileFormatVersion: 2 guid: b68fd1e3004ea4a4a879bf6fbda73510 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaThread.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; namespace LuaInterface { public class LuaThread : LuaBaseRef { public LuaThread(int reference, LuaState state) { this.luaState = state; this.reference = reference; } protected int Resume(IntPtr L, int nArgs) { int ret = LuaDLL.lua_resume(L, nArgs); if (ret > (int)LuaThreadStatus.LUA_YIELD) { string error = null; int top = LuaDLL.lua_gettop(L); LuaDLL.tolua_pushtraceback(L); LuaDLL.lua_pushthread(L); LuaDLL.lua_pushvalue(L, top); if (LuaDLL.lua_pcall(L, 2, -1, 0) != 0) { LuaDLL.lua_settop(L, top); } error = LuaDLL.lua_tostring(L, -1); luaState.LuaSetTop(0); throw new LuaException(error); } return ret; } public int Resume() { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); int ret = Resume(L, 0); if (ret == 0) { Dispose(); } return ret; } public int Resume(T1 arg1) { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); StackTraits.Push(L, arg1); int ret = Resume(L, 1); if (ret == 0) { Dispose(); } return ret; } public int Resume(T1 arg1, T2 arg2) { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); StackTraits.Push(L, arg1); StackTraits.Push(L, arg2); int ret = Resume(L, 2); if (ret == 0) { Dispose(); } return ret; } public int Resume(T1 arg1, T2 arg2, T3 arg3) { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); StackTraits.Push(L, arg1); StackTraits.Push(L, arg2); StackTraits.Push(L, arg3); int ret = Resume(L, 3); if (ret == 0) { Dispose(); } return ret; } public int Resume(out R1 ret1) { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); int ret = Resume(L, 0); if (ret == 0) { ret1 = default(R1); Dispose(); } else { int top = LuaDLL.lua_gettop(L); ret1 = StackTraits.Check(L, top); } return ret; } public int Resume(T1 arg1, out R1 ret1) { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); StackTraits.Push(L, arg1); int ret = Resume(L, 1); if (ret == 0) { ret1 = default(R1); Dispose(); } else { int top = LuaDLL.lua_gettop(L); ret1 = StackTraits.Check(L, top); } return ret; } public int Resume(T1 arg1, T2 arg2, out R1 ret1) { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); StackTraits.Push(L, arg1); StackTraits.Push(L, arg2); int ret = Resume(L, 2); if (ret == 0) { ret1 = default(R1); Dispose(); } else { int top = LuaDLL.lua_gettop(L); ret1 = StackTraits.Check(L, top); } return ret; } public int Resume(T1 arg1, T2 arg2, T3 arg3, out R1 ret1) { luaState.Push(this); IntPtr L = luaState.LuaToThread(-1); luaState.LuaPop(1); StackTraits.Push(L, arg1); StackTraits.Push(L, arg2); StackTraits.Push(L, arg3); int ret = Resume(L, 3); if (ret == 0) { ret1 = default(R1); Dispose(); } else { int top = LuaDLL.lua_gettop(L); ret1 = StackTraits.Check(L, top); } return ret; } } } ================================================ FILE: Assets/ToLua/Core/LuaThread.cs.meta ================================================ fileFormatVersion: 2 guid: c80e713269311db4689148e01949206a MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaUnityLibs.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Runtime.InteropServices; using UnityEngine; namespace LuaInterface { public sealed class LuaUnityLibs { public static void OpenLibs(IntPtr L) { InitMathf(L); InitLayer(L); } public static void OpenLuaLibs(IntPtr L) { if (LuaDLL.tolua_openlualibs(L) != 0) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error); } SetOutMethods(L, "Vector3", GetOutVector3); SetOutMethods(L, "Vector2", GetOutVector2); SetOutMethods(L, "Vector4", GetOutVector4); SetOutMethods(L, "Color", GetOutColor); SetOutMethods(L, "Color32", GetOutColor32); SetOutMethods(L, "Quaternion", GetOutQuaternion); SetOutMethods(L, "Ray", GetOutRay); SetOutMethods(L, "Bounds", GetOutBounds); SetOutMethods(L, "Touch", GetOutTouch); SetOutMethods(L, "RaycastHit", GetOutRaycastHit); SetOutMethods(L, "LayerMask", GetOutLayerMask); } static void InitMathf(IntPtr L) { LuaDLL.lua_getglobal(L, "Mathf"); LuaDLL.lua_pushstring(L, "PerlinNoise"); LuaDLL.tolua_pushcfunction(L, PerlinNoise); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pop(L, 1); } static void InitLayer(IntPtr L) { LuaDLL.tolua_createtable(L, "Layer"); for (int i = 0; i < 32; i++) { string str = LayerMask.LayerToName(i); if (!string.IsNullOrEmpty(str)) { LuaDLL.lua_pushstring(L, str); LuaDLL.lua_pushinteger(L, i); LuaDLL.lua_rawset(L, -3); } } LuaDLL.lua_pop(L, 1); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int PerlinNoise(IntPtr L) { try { float x = (float)LuaDLL.luaL_checknumber(L, 1); float y = (float)LuaDLL.luaL_checknumber(L, 2); float ret = Mathf.PerlinNoise(x, y); LuaDLL.lua_pushnumber(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } static void SetOutMethods(IntPtr L, string table, LuaCSFunction getOutFunc = null) { LuaDLL.lua_getglobal(L, table); IntPtr get = Marshal.GetFunctionPointerForDelegate(getOutFunc); LuaDLL.tolua_variable(L, "out", get, IntPtr.Zero); LuaDLL.lua_pop(L, 1); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutVector3(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutVector2(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutVector4(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutColor(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutColor32(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutQuaternion(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutRay(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutBounds(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutRaycastHit(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutTouch(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetOutLayerMask(IntPtr L) { ToLua.PushOut(L, new LuaOut()); return 1; } } } ================================================ FILE: Assets/ToLua/Core/LuaUnityLibs.cs.meta ================================================ fileFormatVersion: 2 guid: 6f293d0bd6470a044a8688cd9a61b433 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/LuaValueType.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; namespace LuaInterface { public partial struct LuaValueType { public const int None = 0; public const int Vector3 = 1; public const int Quaternion = 2; public const int Vector2 = 3; public const int Color = 4; public const int Vector4 = 5; public const int Ray = 6; public const int Bounds = 7; public const int Touch = 8; public const int LayerMask = 9; public const int RaycastHit = 10; public const int Int64 = 11; public const int UInt64 = 12; public const int Color32 = 13; public const int Max = 64; private int type; public LuaValueType(int value) { type = value; } public static implicit operator int(LuaValueType mask) { return mask.type; } public static implicit operator LuaValueType(int intVal) { return new LuaValueType(intVal); } public override string ToString() { return LuaValueTypeName.Get(type); } } public static class LuaValueTypeName { public static string[] names = new string[LuaValueType.Max]; static LuaValueTypeName() { names[LuaValueType.None] = "None"; names[LuaValueType.Vector3] = "Vector3"; names[LuaValueType.Quaternion] = "Quaternion"; names[LuaValueType.Vector2] = "Vector2"; names[LuaValueType.Color] = "Color"; names[LuaValueType.Color32] = "Color32"; names[LuaValueType.Vector4] = "Vector4"; names[LuaValueType.Ray] = "Ray"; names[LuaValueType.Bounds] = "Bounds"; names[LuaValueType.Touch] = "Touch"; names[LuaValueType.LayerMask] = "LayerMask"; names[LuaValueType.RaycastHit] = "RaycastHit"; } static public string Get(int type) { if (type >= 0 && type < LuaValueType.Max) { return names[type]; } return "UnKnownType:" + ConstStringTable.GetNumIntern(type); } } } ================================================ FILE: Assets/ToLua/Core/LuaValueType.cs.meta ================================================ fileFormatVersion: 2 guid: caa2d85e8d1314547a78624e7fec25a3 timeCreated: 1494919728 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Core/ObjectPool.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; namespace LuaInterface { public class LuaObjectPool { class PoolNode { public int index; public object obj; public PoolNode(int index, object obj) { this.index = index; this.obj = obj; } } private List list; //同lua_ref策略,0作为一个回收链表头,不使用这个位置 private PoolNode head = null; private int count = 0; private int collectStep = 2; private int collectedIndex = -1; public LuaObjectPool() { list = new List(1024); head = new PoolNode(0, null); list.Add(head); list.Add(new PoolNode(1, null)); count = list.Count; } public object this[int i] { get { if (i > 0 && i < count) { return list[i].obj; } return null; } } public void Clear() { list.Clear(); head = null; count = 0; } public int Add(object obj) { int pos = -1; if (head.index != 0) { pos = head.index; list[pos].obj = obj; head.index = list[pos].index; } else { pos = list.Count; list.Add(new PoolNode(pos, obj)); count = pos + 1; } return pos; } public object TryGetValue(int index) { if (index > 0 && index < count) { return list[index].obj; } return null; } public object Remove(int pos) { if (pos > 0 && pos < count) { object o = list[pos].obj; list[pos].obj = null; list[pos].index = head.index; head.index = pos; return o; } return null; } public object Destroy(int pos) { if (pos > 0 && pos < count) { object o = list[pos].obj; list[pos].obj = null; return o; } return null; } public void StepCollect(Action collectListener) { ++collectedIndex; for (int i = 0; i < collectStep; ++i) { collectedIndex += i; if (collectedIndex >= count) { collectedIndex = -1; return; } var node = list[collectedIndex]; object o = node.obj; if (o != null && o.Equals(null)) { node.obj = null; if (collectListener != null) { collectListener(o, collectedIndex); } } } } public object Replace(int pos, object o) { if (pos > 0 && pos < count) { object obj = list[pos].obj; list[pos].obj = o; return obj; } return null; } } } ================================================ FILE: Assets/ToLua/Core/ObjectPool.cs.meta ================================================ fileFormatVersion: 2 guid: 375ac727a60642f4e9db9303e4025911 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/ObjectTranslator.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using UnityEngine; namespace LuaInterface { public class ObjectTranslator { private class DelayGC { public DelayGC(int id, UnityEngine.Object obj, float time) { this.id = id; this.time = time; this.obj = obj; } public int id; public UnityEngine.Object obj; public float time; } private class CompareObject : IEqualityComparer { public new bool Equals(object x, object y) { return object.ReferenceEquals(x, y); } public int GetHashCode(object obj) { return RuntimeHelpers.GetHashCode(obj); } } public bool LogGC { get; set; } public readonly Dictionary objectsBackMap = new Dictionary(257, new CompareObject()); public readonly LuaObjectPool objects = new LuaObjectPool(); private List gcList = new List(); private Action removeInvalidObject; #if !MULTI_STATE private static ObjectTranslator _translator = null; #endif public ObjectTranslator() { LogGC = false; #if !MULTI_STATE _translator = this; #endif removeInvalidObject = RemoveObject; } public int AddObject(object obj) { int index = objects.Add(obj); if (!TypeChecker.IsValueType(obj.GetType())) { objectsBackMap[obj] = index; } return index; } public static ObjectTranslator Get(IntPtr L) { #if !MULTI_STATE return _translator; #else return LuaState.GetTranslator(L); #endif } //fixed 枚举唯一性问题(对象唯一,没有实现__eq操作符) void RemoveObject(object o, int udata) { int index = -1; if (objectsBackMap.TryGetValue(o, out index) && index == udata) { objectsBackMap.Remove(o); } } //lua gc一个对象(lua 库不再引用,但不代表c#没使用) public void RemoveObject(int udata) { //只有lua gc才能移除 object o = objects.Remove(udata); if (o != null) { if (!TypeChecker.IsValueType(o.GetType())) { RemoveObject(o, udata); } if (LogGC) { Debugger.Log("gc object {0}, id {1}", o, udata); } } } public object GetObject(int udata) { return objects.TryGetValue(udata); } //预删除,但不移除一个lua对象(移除id只能由gc完成) public void Destroy(int udata) { object o = objects.Destroy(udata); if (o != null) { if (!TypeChecker.IsValueType(o.GetType())) { RemoveObject(o, udata); } if (LogGC) { Debugger.Log("destroy object {0}, id {1}", o, udata); } } } //Unity Object 延迟删除 public void DelayDestroy(int id, float time) { UnityEngine.Object obj = (UnityEngine.Object)GetObject(id); if (obj != null) { gcList.Add(new DelayGC(id, obj, time)); } } public bool Getudata(object o, out int index) { index = -1; return objectsBackMap.TryGetValue(o, out index); } public void Destroyudata(int udata) { objects.Destroy(udata); } public void SetBack(int index, object o) { objects.Replace(index, o); } bool RemoveFromGCList(int id) { int index = gcList.FindIndex((p) => { return p.id == id; }); if (index >= 0) { gcList.RemoveAt(index); return true; } return false; } //延迟删除处理 void DestroyUnityObject(int udata, UnityEngine.Object obj) { object o = objects.TryGetValue(udata); if (object.ReferenceEquals(o, obj)) { RemoveObject(o, udata); //一定不能Remove, 因为GC还可能再来一次 objects.Destroy(udata); if (LogGC) { Debugger.Log("destroy object {0}, id {1}", o, udata); } } UnityEngine.Object.Destroy(obj); } public void Collect() { if (gcList.Count == 0) { return; } float delta = Time.deltaTime; for (int i = gcList.Count - 1; i >= 0; i--) { float time = gcList[i].time - delta; if (time <= 0) { DestroyUnityObject(gcList[i].id, gcList[i].obj); gcList.RemoveAt(i); } else { gcList[i].time = time; } } } public void StepCollect() { objects.StepCollect(removeInvalidObject); } public void Dispose() { objectsBackMap.Clear(); objects.Clear(); #if !MULTI_STATE _translator = null; #endif } } } ================================================ FILE: Assets/ToLua/Core/ObjectTranslator.cs.meta ================================================ fileFormatVersion: 2 guid: 607902915586ecd43b863b154c1337ad MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/ToLua.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System; using System.Diagnostics; using System.IO; using System.Collections.Generic; using System.Collections; using System.Runtime.InteropServices; using System.Text; #if UNITY_EDITOR using UnityEditor; using UnityEditor.Callbacks; using System.Reflection; #endif namespace LuaInterface { public static class ToLua { public delegate object LuaTableToVar(IntPtr L, int pos); public delegate void LuaPushVarObject(IntPtr L, object o); static Type monoType = typeof(Type).GetType(); static public LuaTableToVar[] ToVarMap = new LuaTableToVar[LuaValueType.Max]; static public Dictionary VarPushMap = new Dictionary(); #if UNITY_EDITOR static int _instanceID = -1; static int _line = 203; private static object consoleWindow; private static object logListView; private static FieldInfo logListViewCurrentRow; private static MethodInfo LogEntriesGetEntry; private static MethodInfo StartGettingEntries; private static MethodInfo EndGettingEntries; private static object logEntry; private static FieldInfo logEntryCondition; #endif static ToLua() { ToVarMap[LuaValueType.Vector3] = ToObjectVec3; ToVarMap[LuaValueType.Quaternion] = ToObjectQuat; ToVarMap[LuaValueType.Vector2] = ToObjectVec2; ToVarMap[LuaValueType.Color] = ToObjectColor; ToVarMap[LuaValueType.Color32] = ToObjectColor32; ToVarMap[LuaValueType.Vector4] = ToObjectVec4; ToVarMap[LuaValueType.Ray] = ToObjectRay; ToVarMap[LuaValueType.LayerMask] = ToObjectLayerMask; ToVarMap[LuaValueType.Bounds] = ToObjectBounds; } public static void OpenLibs(IntPtr L) { AddLuaLoader(L); LuaDLL.tolua_atpanic(L, Panic); LuaDLL.tolua_pushcfunction(L, Print); LuaDLL.lua_setglobal(L, "print"); LuaDLL.tolua_pushcfunction(L, DoFile); LuaDLL.lua_setglobal(L, "dofile"); LuaDLL.tolua_pushcfunction(L, LoadFile); LuaDLL.lua_setglobal(L, "loadfile"); LuaDLL.lua_getglobal(L, "tolua"); LuaDLL.lua_pushstring(L, "isnull"); LuaDLL.lua_pushcfunction(L, IsNull); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "typeof"); LuaDLL.lua_pushcfunction(L, GetClassType); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "tolstring"); LuaDLL.tolua_pushcfunction(L, BufferToString); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "toarray"); LuaDLL.tolua_pushcfunction(L, TableToArray); LuaDLL.lua_rawset(L, -3); //手动模拟gc //LuaDLL.lua_pushstring(L, "collect"); //LuaDLL.lua_pushcfunction(L, Collect); //LuaDLL.lua_rawset(L, -3); int meta = LuaStatic.GetMetaReference(L, typeof(NullObject)); LuaDLL.lua_pushstring(L, "null"); LuaDLL.tolua_pushnewudata(L, meta, 1); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pop(L, 1); LuaDLL.tolua_pushudata(L, 1); LuaDLL.lua_setfield(L, LuaIndexes.LUA_GLOBALSINDEX, "null"); #if UNITY_EDITOR GetToLuaInstanceID(); GetConsoleWindowListView(); #endif } /*--------------------------------对于tolua扩展函数------------------------------------------*/ #region TOLUA_EXTEND_FUNCTIONS static void AddLuaLoader(IntPtr L) { LuaDLL.lua_getglobal(L, "package"); LuaDLL.lua_getfield(L, -1, "loaders"); LuaDLL.tolua_pushcfunction(L, Loader); for (int i = LuaDLL.lua_objlen(L, -2) + 1; i > 2; i--) { LuaDLL.lua_rawgeti(L, -2, i - 1); LuaDLL.lua_rawseti(L, -3, i); } LuaDLL.lua_rawseti(L, -2, 2); LuaDLL.lua_pop(L, 2); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Panic(IntPtr L) { string reason = String.Format("PANIC: unprotected error in call to Lua API ({0})", LuaDLL.lua_tostring(L, -1)); throw new LuaException(reason); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Print(IntPtr L) { try { int n = LuaDLL.lua_gettop(L); using (CString.Block()) { CString sb = CString.Alloc(256); #if UNITY_EDITOR int line = LuaDLL.tolua_where(L, 1); string filename = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, n); int offset = filename[0] == '@' ? 1 : 0; if (!filename.Contains(".")) { sb.Append('[').Append(filename, offset, filename.Length - offset).Append(".lua:").Append(line).Append("]:"); } else { sb.Append('[').Append(filename, offset, filename.Length - offset).Append(':').Append(line).Append("]:"); } #endif for (int i = 1; i <= n; i++) { if (i > 1) sb.Append(" "); if (LuaDLL.lua_isstring(L, i) == 1) { sb.Append(LuaDLL.lua_tostring(L, i)); } else if (LuaDLL.lua_isnil(L, i)) { sb.Append("nil"); } else if (LuaDLL.lua_isboolean(L, i)) { sb.Append(LuaDLL.lua_toboolean(L, i) ? "true" : "false"); } else { IntPtr p = LuaDLL.lua_topointer(L, i); if (p == IntPtr.Zero) { sb.Append("nil"); } else { sb.Append(LuaDLL.luaL_typename(L, i)).Append(":0x").Append(p.ToString("X")); } } } Debugger.Log(sb.ToString()); //203行与_line一致 } return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Loader(IntPtr L) { try { string fileName = LuaDLL.lua_tostring(L, 1); fileName = fileName.Replace(".", "/"); byte[] buffer = LuaFileUtils.Instance.ReadFile(fileName); if (buffer == null) { string error = LuaFileUtils.Instance.FindFileError(fileName); LuaDLL.lua_pushstring(L, error); return 1; } if (LuaConst.openLuaDebugger) { fileName = LuaFileUtils.Instance.FindFile(fileName); } if (LuaDLL.luaL_loadbuffer(L, buffer, buffer.Length, "@"+ fileName) != 0) { string err = LuaDLL.lua_tostring(L, -1); throw new LuaException(err, LuaException.GetLastError()); } return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] public static int DoFile(IntPtr L) { try { string fileName = LuaDLL.lua_tostring(L, 1); int n = LuaDLL.lua_gettop(L); byte[] buffer = LuaFileUtils.Instance.ReadFile(fileName); if (buffer == null) { string error = string.Format("cannot open {0}: No such file or directory", fileName); error += LuaFileUtils.Instance.FindFileError(fileName); throw new LuaException(error); } if (LuaDLL.luaL_loadbuffer(L, buffer, buffer.Length, fileName) == 0) { if (LuaDLL.lua_pcall(L, 0, LuaDLL.LUA_MULTRET, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error, LuaException.GetLastError()); } } else { string err = LuaDLL.lua_tostring(L, -1); throw new LuaException(err, LuaException.GetLastError()); } return LuaDLL.lua_gettop(L) - n; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] public static int LoadFile(IntPtr L) { try { string fileName = LuaDLL.lua_tostring(L, 1); byte[] buffer = LuaFileUtils.Instance.ReadFile(fileName); if (buffer == null) { string error = string.Format("cannot open {0}: No such file or directory", fileName); error += LuaFileUtils.Instance.FindFileError(fileName); throw new LuaException(error); } if (LuaDLL.luaL_loadbuffer(L, buffer, buffer.Length, fileName) == 0) { return 1; } LuaDLL.lua_pushnil(L); LuaDLL.lua_insert(L, -2); /* put before error message */ return 2; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IsNull(IntPtr L) { LuaTypes t = LuaDLL.lua_type(L, 1); if (t == LuaTypes.LUA_TNIL) { LuaDLL.lua_pushboolean(L, true); } else { object o = ToLua.ToObject(L, -1); if (o == null || o.Equals(null)) { LuaDLL.lua_pushboolean(L, true); } else { LuaDLL.lua_pushboolean(L, false); } } return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int BufferToString(IntPtr L) { try { object o = CheckObject(L, 1); if (o is byte[]) { byte[] buff = (byte[])o; LuaDLL.lua_pushlstring(L, buff, buff.Length); } else if (o is char[]) { byte[] buff = System.Text.Encoding.UTF8.GetBytes((char[])o); LuaDLL.lua_pushlstring(L, buff, buff.Length); } else if (o is string) { LuaDLL.lua_pushstring(L, (string)o); } else { LuaDLL.luaL_typerror(L, 1, "byte[] or char[]"); } return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetClassType(IntPtr L) { int reference = LuaDLL.tolua_getmetatableref(L, 1); if (reference > 0) { Type t = LuaStatic.GetClassType(L, reference); Push(L, t); } else { int ret = LuaDLL.tolua_getvaluetype(L, -1); if (ret != LuaValueType.None) { Type t = TypeChecker.LuaValueTypeMap[ret]; Push(L, t); } else { Debugger.LogError("type not register to lua"); LuaDLL.lua_pushnil(L); } } return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TableToArray(IntPtr L) { try { object[] objs = ToLua.CheckObjectArray(L, 1); Type t = ToLua.CheckMonoType(L, 2); Array ret = System.Array.CreateInstance(t, objs.Length); for (int i = 0; i < objs.Length; i++) { ret.SetValue(objs[i], i); } ToLua.Push(L, ret); return 1; } catch(LuaException e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] public static int op_ToString(IntPtr L) { object obj = ToLua.ToObject(L, 1); if (obj != null) { LuaDLL.lua_pushstring(L, obj.ToString()); } else { LuaDLL.lua_pushnil(L); } return 1; } #if UNITY_EDITOR private static bool GetConsoleWindowListView() { if (logListView == null) { Assembly unityEditorAssembly = Assembly.GetAssembly(typeof(EditorWindow)); Type consoleWindowType = unityEditorAssembly.GetType("UnityEditor.ConsoleWindow"); FieldInfo fieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic); consoleWindow = fieldInfo.GetValue(null); if (consoleWindow == null) { logListView = null; return false; } FieldInfo listViewFieldInfo = consoleWindowType.GetField("m_ListView", BindingFlags.Instance | BindingFlags.NonPublic); logListView = listViewFieldInfo.GetValue(consoleWindow); logListViewCurrentRow = listViewFieldInfo.FieldType.GetField("row", BindingFlags.Instance | BindingFlags.Public); #if UNITY_2017_1_OR_NEWER Type logEntriesType = unityEditorAssembly.GetType("UnityEditor.LogEntries"); LogEntriesGetEntry = logEntriesType.GetMethod("GetEntryInternal", BindingFlags.Static | BindingFlags.Public); Type logEntryType = unityEditorAssembly.GetType("UnityEditor.LogEntry"); #else Type logEntriesType = unityEditorAssembly.GetType("UnityEditorInternal.LogEntries"); LogEntriesGetEntry = logEntriesType.GetMethod("GetEntryInternal", BindingFlags.Static | BindingFlags.Public); Type logEntryType = unityEditorAssembly.GetType("UnityEditorInternal.LogEntry"); #endif logEntryCondition = logEntryType.GetField("condition", BindingFlags.Instance | BindingFlags.Public); StartGettingEntries = logEntriesType.GetMethod("StartGettingEntries", BindingFlags.Static | BindingFlags.Public); EndGettingEntries = logEntriesType.GetMethod("EndGettingEntries", BindingFlags.Static | BindingFlags.Public); logEntry = Activator.CreateInstance(logEntryType); } return true; } private static string GetListViewRowCount(ref int line) { #if UNITY_2017_1_OR_NEWER object rows = StartGettingEntries.Invoke(null, null); #endif int row = (int)logListViewCurrentRow.GetValue(logListView); LogEntriesGetEntry.Invoke(null, new object[] { row, logEntry }); string condition = logEntryCondition.GetValue(logEntry) as string; #if UNITY_2017_1_OR_NEWER EndGettingEntries.Invoke(null, null); #endif condition = condition.Substring(0, condition.IndexOf('\n')); int index = condition.IndexOf(".lua:"); if (index >= 0) { int start = condition.IndexOf("["); int end = condition.IndexOf("]:"); string _line = condition.Substring(index + 5, end - index - 5); Int32.TryParse(_line, out line); return condition.Substring(start + 1, index + 3 - start); } index = condition.IndexOf(".cs:"); if (index >= 0) { int start = condition.IndexOf("["); int end = condition.IndexOf("]:"); string _line = condition.Substring(index + 4, end - index - 4); Int32.TryParse(_line, out line); return condition.Substring(start + 1, index + 2 - start); } return null; } static void GetToLuaInstanceID() { if (_instanceID == -1) { int start = LuaConst.toluaDir.IndexOf("Assets"); int end = LuaConst.toluaDir.LastIndexOf("/Lua"); string dir = LuaConst.toluaDir.Substring(start, end - start); dir += "/Core/ToLua.cs"; _instanceID = AssetDatabase.LoadAssetAtPath(dir, typeof(MonoScript)).GetInstanceID();//"Assets/ToLua/Core/ToLua.cs" } } [OnOpenAssetAttribute(0)] public static bool OnOpenAsset(int instanceID, int line) { GetToLuaInstanceID(); if (!GetConsoleWindowListView() || (object)EditorWindow.focusedWindow != consoleWindow) { return false; } if (instanceID == _instanceID && line == _line) { string fileName = GetListViewRowCount(ref line); if (fileName == null) { return false; } if (fileName.EndsWith(".cs")) { string filter = fileName.Substring(0, fileName.Length - 3); filter += " t:MonoScript"; string[] searchPaths = AssetDatabase.FindAssets(filter); for (int i = 0; i < searchPaths.Length; i++) { string path = AssetDatabase.GUIDToAssetPath(searchPaths[i]); if (path.EndsWith(fileName)) { UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(path, typeof(MonoScript)); AssetDatabase.OpenAsset(obj, line); return true; } } } else { string filter = fileName.Substring(0, fileName.Length - 4); int index = filter.IndexOf("/"); if (index > 0) { filter = filter.Substring(index + 1); } string[] searchPaths = AssetDatabase.FindAssets(filter); for (int i = 0; i < searchPaths.Length; i++) { string path = AssetDatabase.GUIDToAssetPath(searchPaths[i]); if (path.EndsWith(fileName) || path.EndsWith(fileName + ".bytes")) { UnityEngine.Object obj = AssetDatabase.LoadMainAssetAtPath(path); #if !UNITY_2017_1_OR_NEWER EditorApplication.delayCall += () => { AssetDatabase.OpenAsset(obj, line); }; #else AssetDatabase.OpenAsset(obj, line); #endif return true; } } } } return false; } #endif #endregion /*-------------------------------------------------------------------------------------------*/ public static string ToString(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TSTRING: return LuaDLL.lua_tostring(L, stackPos); case LuaTypes.LUA_TUSERDATA: return (string)ToObject(L, stackPos); default: return null; } } public static object ToObject(IntPtr L, int stackPos) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); return translator.GetObject(udata); } return null; } public static LuaFunction ToLuaFunction(IntPtr L, int stackPos) { LuaTypes type = LuaDLL.lua_type(L, stackPos); if (type == LuaTypes.LUA_TNIL) { return null; } stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int reference = LuaDLL.toluaL_ref(L); return LuaStatic.GetFunction(L, reference); } public static LuaTable ToLuaTable(IntPtr L, int stackPos) { LuaTypes type = LuaDLL.lua_type(L, stackPos); if (type == LuaTypes.LUA_TNIL) { return null; } stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int reference = LuaDLL.toluaL_ref(L); return LuaStatic.GetTable(L, reference); } public static LuaThread ToLuaThread(IntPtr L, int stackPos) { LuaTypes type = LuaDLL.lua_type(L, stackPos); if (type == LuaTypes.LUA_TNIL) { return null; } stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int reference = LuaDLL.toluaL_ref(L); return LuaStatic.GetLuaThread(L, reference); } public static Vector3 ToVector3(IntPtr L, int stackPos) { float x = 0, y = 0, z = 0; LuaDLL.tolua_getvec3(L, stackPos, out x, out y, out z); return new Vector3(x, y, z); } public static Vector4 ToVector4(IntPtr L, int stackPos) { float x, y, z, w; LuaDLL.tolua_getvec4(L, stackPos, out x, out y, out z, out w); return new Vector4(x, y, z, w); } public static Vector2 ToVector2(IntPtr L, int stackPos) { float x, y; LuaDLL.tolua_getvec2(L, stackPos, out x, out y); return new Vector2(x, y); } public static Quaternion ToQuaternion(IntPtr L, int stackPos) { float x, y, z, w; LuaDLL.tolua_getquat(L, stackPos, out x, out y, out z, out w); return new Quaternion(x, y, z, w); } public static Color ToColor(IntPtr L, int stackPos) { float r, g, b, a; LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color(r, g, b, a); } public static Color32 ToColor32(IntPtr L, int stackPos) { float r, g, b, a; LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color32((byte)r, (byte)g, (byte)b, (byte)a); } public static Ray ToRay(IntPtr L, int stackPos) { int top = LuaDLL.lua_gettop(L); LuaStatic.GetUnpackRayRef(L); stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); if (LuaDLL.lua_pcall(L, 1, 6, 0) == 0) { float ox = (float)LuaDLL.lua_tonumber(L, top + 1); float oy = (float)LuaDLL.lua_tonumber(L, top + 2); float oz = (float)LuaDLL.lua_tonumber(L, top + 3); float dx = (float)LuaDLL.lua_tonumber(L, top + 4); float dy = (float)LuaDLL.lua_tonumber(L, top + 5); float dz = (float)LuaDLL.lua_tonumber(L, top + 6); LuaDLL.lua_settop(L, top); return new Ray(new Vector3(ox, oy, oz), new Vector3(dx, dy, dz)); } else { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, top); throw new LuaException(error); } } public static Bounds ToBounds(IntPtr L, int stackPos) { int top = LuaDLL.lua_gettop(L); LuaStatic.GetUnpackBounds(L); stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); if (LuaDLL.lua_pcall(L, 1, 2, 0) == 0) { Vector3 center = ToVector3(L, top + 1); Vector3 size = ToVector3(L, top + 2); LuaDLL.lua_settop(L, top); return new Bounds(center, size); } else { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, top); throw new LuaException(error); } } public static LayerMask ToLayerMask(IntPtr L, int stackPos) { return LuaDLL.tolua_getlayermask(L, stackPos); } public static object ToVarObject(IntPtr L, int stackPos) { LuaTypes type = LuaDLL.lua_type(L, stackPos); switch (type) { case LuaTypes.LUA_TNUMBER: return LuaDLL.lua_tonumber(L, stackPos); case LuaTypes.LUA_TSTRING: return LuaDLL.lua_tostring(L, stackPos); case LuaTypes.LUA_TUSERDATA: switch(LuaDLL.tolua_getvaluetype(L, stackPos)) { case LuaValueType.Int64: return LuaDLL.tolua_toint64(L, stackPos); case LuaValueType.UInt64: return LuaDLL.tolua_touint64(L, stackPos); default: return ToObject(L, stackPos); } case LuaTypes.LUA_TBOOLEAN: return LuaDLL.lua_toboolean(L, stackPos); case LuaTypes.LUA_TFUNCTION: return ToLuaFunction(L, stackPos); case LuaTypes.LUA_TTABLE: return ToVarTable(L, stackPos); case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TLIGHTUSERDATA: return LuaDLL.lua_touserdata(L, stackPos); case LuaTypes.LUA_TTHREAD: return ToLuaThread(L, stackPos); default: return null; } } //for Generic Array and List, 转换double为指定type在存入object public static object ToVarObject(IntPtr L, int stackPos, Type t) { LuaTypes type = LuaDLL.lua_type(L, stackPos); if (type == LuaTypes.LUA_TNUMBER) { object o = LuaDLL.lua_tonumber(L, stackPos); o = Convert.ChangeType(o, t); return o; } return ToVarObject(L, stackPos); } public static object ToVarTable(IntPtr L, int stackPos) { stackPos = LuaDLL.abs_index(L, stackPos); int ret = LuaDLL.tolua_getvaluetype(L, stackPos); LuaTableToVar _ToObject = ToVarMap[ret]; if (_ToObject != null) { return _ToObject(L, stackPos); } else { LuaDLL.lua_pushvalue(L, stackPos); int reference = LuaDLL.toluaL_ref(L); return LuaStatic.GetTable(L, reference); } } public static Nullable ToNullable(IntPtr L, int stackPos) where T : struct { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return StackTraits.To(L, stackPos); } static object ToObjectVec3(IntPtr L, int stackPos) { return ToVector3(L, stackPos); } static object ToObjectQuat(IntPtr L, int stackPos) { return ToQuaternion(L, stackPos); } static object ToObjectColor(IntPtr L, int stackPos) { return ToColor(L, stackPos); } static object ToObjectColor32(IntPtr L, int stackPos) { return ToColor32(L, stackPos); } static object ToObjectVec4(IntPtr L, int stackPos) { return ToVector4(L, stackPos); } static object ToObjectVec2(IntPtr L, int stackPos) { return ToVector2(L, stackPos); } static object ToObjectRay(IntPtr L, int stackPos) { return ToRay(L, stackPos); } static object ToObjectLayerMask(IntPtr L, int stackPos) { return ToLayerMask(L, stackPos); } static object ToObjectBounds(IntPtr L, int stackPos) { return ToBounds(L, stackPos); } public static IEnumerator ToIEnumerator(IntPtr L, int stackPos) { var luaTable = ToLuaTable(L, stackPos); if (luaTable != null) { return CSharpLua.LuaIEnumerator.Create(luaTable); } return (IEnumerator)ToObject(L, 2); } public static LuaFunction CheckLuaFunction(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TFUNCTION: stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int reference = LuaDLL.toluaL_ref(L); return LuaStatic.GetFunction(L, reference); default: LuaDLL.luaL_typerror(L, stackPos, "function"); return null; } } public static LuaTable CheckLuaTable(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int reference = LuaDLL.toluaL_ref(L); return LuaStatic.GetTable(L, reference); default: LuaDLL.luaL_typerror(L, stackPos, "table"); return null; } } public static LuaThread CheckLuaThread(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTHREAD: stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int reference = LuaDLL.toluaL_ref(L); return LuaStatic.GetLuaThread(L, reference); default: LuaDLL.luaL_typerror(L, stackPos, "thread"); return null; } } public static LuaBaseRef CheckLuaBaseRef(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TFUNCTION: stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int ref1 = LuaDLL.toluaL_ref(L); return LuaStatic.GetFunction(L, ref1); case LuaTypes.LUA_TTABLE: stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int ref2 = LuaDLL.toluaL_ref(L); return LuaStatic.GetTable(L, ref2); case LuaTypes.LUA_TTHREAD: stackPos = LuaDLL.abs_index(L, stackPos); LuaDLL.lua_pushvalue(L, stackPos); int ref3 = LuaDLL.toluaL_ref(L); return LuaStatic.GetLuaThread(L, ref3); default: LuaDLL.luaL_typerror(L, stackPos, "function or table or thread"); return null; } } public static string CheckString(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TNUMBER: return LuaDLL.lua_tostring(L, stackPos); case LuaTypes.LUA_TSTRING: return LuaDLL.lua_tostring(L, stackPos); case LuaTypes.LUA_TUSERDATA: int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); if (obj != null) { if (obj is string) { return (string)obj; } LuaDLL.luaL_argerror(L, stackPos, string.Format("string expected, got {0}", obj.GetType().FullName)); } return null; } break; } LuaDLL.luaL_typerror(L, stackPos, "string"); return null; } public static IntPtr CheckIntPtr(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return IntPtr.Zero; case LuaTypes.LUA_TLIGHTUSERDATA: return LuaDLL.lua_touserdata(L, stackPos); default: LuaDLL.luaL_typerror(L, stackPos, "IntPtr"); return IntPtr.Zero; } } static public Type CheckMonoType(IntPtr L, int stackPos) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); if (obj != null) { if (obj is Type) { return (Type)obj; } LuaDLL.luaL_argerror(L, stackPos, string.Format("Type expected, got {0}", obj.GetType().FullName)); } return null; } else if (LuaDLL.lua_isnil(L, stackPos)) { return null; } LuaDLL.luaL_typerror(L, stackPos, "Type"); return null; } public static IEnumerator CheckIter(IntPtr L, int stackPos) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); if (obj != null) { if (obj is IEnumerator) { return (IEnumerator)obj; } LuaDLL.luaL_argerror(L, stackPos, string.Format("Type expected, got {0}", obj.GetType().FullName)); } return null; } else if (LuaDLL.lua_isnil(L, stackPos)) { return null; } else { var luaTable = ToLuaTable(L, stackPos); if (luaTable != null) { return CSharpLua.LuaIEnumerator.Create(luaTable); } } LuaDLL.luaL_typerror(L, stackPos, "Type"); return null; } public static object CheckObject(IntPtr L, int stackPos) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); return translator.GetObject(udata); } else if (LuaDLL.lua_isnil(L, stackPos)) { return null; } LuaDLL.luaL_typerror(L, stackPos, "object"); return null; } public static object CheckObject(IntPtr L, int stackPos, Type type) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); if (obj != null) { Type objType = obj.GetType(); if (type == objType || type.IsAssignableFrom(objType)) { return obj; } LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got {1}", LuaMisc.GetTypeName(type), LuaMisc.GetTypeName(objType))); } return null; } else if (LuaDLL.lua_isnil(L, stackPos)) { return null; } LuaDLL.luaL_typerror(L, stackPos, LuaMisc.GetTypeName(type)); return null; } public static object CheckObject(IntPtr L, int stackPos) where T : class { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); if (obj != null) { if (obj is T) { return obj; } Type objType = obj.GetType(); LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got {1}", TypeTraits.GetTypeName(), objType.FullName)); } return null; } else if (LuaDLL.lua_isnil(L, stackPos)) { return null; } LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return null; } static public Vector3 CheckVector3(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Vector3) { LuaDLL.luaL_typerror(L, stackPos, "Vector3", LuaValueTypeName.Get(type)); return Vector3.zero; } float x, y, z; LuaDLL.tolua_getvec3(L, stackPos, out x, out y, out z); return new Vector3(x, y, z); } static public Quaternion CheckQuaternion(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Quaternion) { LuaDLL.luaL_typerror(L, stackPos, "Quaternion", LuaValueTypeName.Get(type)); return Quaternion.identity; } float x, y, z, w; LuaDLL.tolua_getquat(L, stackPos, out x, out y, out z, out w); return new Quaternion(x, y, z, w); } static public Vector2 CheckVector2(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Vector2) { LuaDLL.luaL_typerror(L, stackPos, "Vector2", LuaValueTypeName.Get(type)); return Vector2.zero; } float x, y; LuaDLL.tolua_getvec2(L, stackPos, out x, out y); return new Vector2(x, y); } static public Vector4 CheckVector4(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Vector4) { LuaDLL.luaL_typerror(L, stackPos, "Vector4", LuaValueTypeName.Get(type)); return Vector4.zero; } float x, y, z, w; LuaDLL.tolua_getvec4(L, stackPos, out x, out y, out z, out w); return new Vector4(x, y, z, w); } static public Color CheckColor(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Color) { LuaDLL.luaL_typerror(L, stackPos, "Color", LuaValueTypeName.Get(type)); return Color.black; } float r, g, b, a; LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color(r, g, b, a); } static public Color32 CheckColor32(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Color32) { LuaDLL.luaL_typerror(L, stackPos, "Color32", LuaValueTypeName.Get(type)); return new Color32(); } float r, g, b, a; LuaDLL.tolua_getclr(L, stackPos, out r, out g, out b, out a); return new Color32((byte)r, (byte)g, (byte)b, (byte)a); } static public Ray CheckRay(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Ray) { LuaDLL.luaL_typerror(L, stackPos, "Ray", LuaValueTypeName.Get(type)); return new Ray(); } return ToRay(L, stackPos); } static public Bounds CheckBounds(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.Bounds) { LuaDLL.luaL_typerror(L, stackPos, "Bounds", LuaValueTypeName.Get(type)); return new Bounds(); } return ToBounds(L, stackPos); } static public LayerMask CheckLayerMask(IntPtr L, int stackPos) { int type = LuaDLL.tolua_getvaluetype(L, stackPos); if (type != LuaValueType.LayerMask) { LuaDLL.luaL_typerror(L, stackPos, "LayerMask", LuaValueTypeName.Get(type)); return 0; } return LuaDLL.tolua_getlayermask(L, stackPos); } public static T CheckValue(IntPtr L, int stackPos) where T : struct { return StackTraits.Check(L, stackPos); } public static Nullable CheckNullable(IntPtr L, int stackPos) where T : struct { if (LuaDLL.lua_type(L, stackPos) == LuaTypes.LUA_TNIL) { return null; } return StackTraits.Check(L, stackPos); } public static object CheckVarObject(IntPtr L, int stackPos, Type t) { bool beValue = TypeChecker.IsValueType(t); LuaTypes luaType = LuaDLL.lua_type(L, stackPos); if (!beValue && luaType == LuaTypes.LUA_TNIL) { return null; } TypeCode code = Type.GetTypeCode(t); switch (code) { case TypeCode.Boolean: { return LuaDLL.luaL_checkboolean(L, stackPos); } case TypeCode.Char: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: { double d = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ChangeType(d, t); } case TypeCode.String: { return CheckString(L, stackPos); } } if (beValue) { if (TypeChecker.IsNullable(t)) { if (luaType == LuaTypes.LUA_TNIL) { return null; } Type[] ts = t.GetGenericArguments(); t = ts[0]; } if (t == typeof(bool)) { return LuaDLL.luaL_checkboolean(L, stackPos); } else if (t == typeof(long)) { return LuaDLL.tolua_checkint64(L, stackPos); } else if (t == typeof(ulong)) { return LuaDLL.tolua_checkuint64(L, stackPos); } else if (t.IsPrimitive) { double d = LuaDLL.luaL_checknumber(L, stackPos); return Convert.ChangeType(d, t); } else if (t == typeof(LuaByteBuffer)) { int len = 0; IntPtr source = LuaDLL.tolua_tolstring(L, stackPos, out len); return new LuaByteBuffer(source, len); } else if (t == typeof(Vector3)) { return CheckVector3(L, stackPos); } else if (t == typeof(Quaternion)) { return CheckQuaternion(L, stackPos); } else if (t == typeof(Vector2)) { return CheckVector2(L, stackPos); } else if (t == typeof(Vector4)) { return CheckVector4(L, stackPos); } else if (t == typeof(Color)) { return CheckColor(L, stackPos); } else if (t == typeof(Color32)) { return CheckColor32(L, stackPos); } else if (t == typeof(Ray)) { return CheckRay(L, stackPos); } else if (t == typeof(Bounds)) { return CheckBounds(L, stackPos); } else if (t == typeof(LayerMask)) { return CheckLayerMask(L, stackPos); } else { if (luaType == LuaTypes.LUA_TTABLE) { object o = ToVarTable(L, stackPos); if (o.GetType() != t) { LuaDLL.luaL_typerror(L, stackPos, LuaMisc.GetTypeName(t)); } return o; } else { return CheckObject(L, stackPos, t); } } } else { if (t.IsEnum) { return ToLua.CheckObject(L, stackPos, t); } else if (t == typeof(string)) { return CheckString(L, stackPos); } else { return CheckObject(L, stackPos, t); } } } public static UnityEngine.Object CheckUnityObject(IntPtr L, int stackPos, Type type) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); object obj = null; if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); obj = translator.GetObject(udata); if (obj != null) { UnityEngine.Object uObj = (UnityEngine.Object)obj; if (uObj == null) { LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got nil", type.FullName)); return null; } Type objType = uObj.GetType(); if (type == objType || objType.IsSubclassOf(type)) { return uObj; } LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got {1}", type.FullName, objType.FullName)); } //传递了tolua.null过来 return null; } else if (LuaDLL.lua_isnil(L, stackPos)) { return null; } LuaDLL.luaL_typerror(L, stackPos, type.FullName); return null; } public static UnityEngine.TrackedReference CheckTrackedReference(IntPtr L, int stackPos, Type type) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); object obj = null; if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); obj = translator.GetObject(udata); if (obj != null) { UnityEngine.TrackedReference uObj = (UnityEngine.TrackedReference)obj; if (uObj == null) { LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got nil", type.FullName)); return null; } Type objType = uObj.GetType(); if (type == objType || objType.IsSubclassOf(type)) { return uObj; } LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got {1}", type.FullName, objType.FullName)); } return null; } else if (LuaDLL.lua_isnil(L, stackPos)) { return null; } LuaDLL.luaL_typerror(L, stackPos, type.FullName); return null; } //必须检测类型 public static object[] CheckObjectArray(IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); object[] list = new object[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); list[i - 1] = ToVarObject(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (object[])CheckObject(L, stackPos, typeof(object[])); default: LuaDLL.luaL_typerror(L, stackPos, "object[] or table"); return null; } } public static T[] CheckObjectArray(IntPtr L, int stackPos) where T : class { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch(luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); T[] list = new T[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, typeof(T[]).FullName); return list; } list[i - 1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (T[])CheckObject(L, stackPos, typeof(T[])); default: LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return null; } } public static T[] CheckStructArray(IntPtr L, int stackPos) where T : struct { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); T[] list = new T[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, typeof(T[]).FullName); return list; } list[i-1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (T[])CheckObject(L, stackPos, typeof(T[])); default: LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return null; } } public static char[] CheckCharBuffer(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TSTRING: string str = LuaDLL.lua_tostring(L, stackPos); return str.ToCharArray(); ; case LuaTypes.LUA_TUSERDATA: return (char[])CheckObject(L, stackPos, typeof(char[])); default: LuaDLL.luaL_typerror(L, stackPos, "string or char[]"); return null; } } public static byte[] CheckByteBuffer(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TSTRING: int len; IntPtr source = LuaDLL.lua_tolstring(L, stackPos, out len); byte[] buffer = new byte[len]; Marshal.Copy(source, buffer, 0, len); return buffer; case LuaTypes.LUA_TUSERDATA: return (byte[])CheckObject(L, stackPos, typeof(byte[])); default: LuaDLL.luaL_typerror(L, stackPos, "string or byte[]"); return null; } } public static T[] CheckNumberArray(IntPtr L, int stackPos) where T : struct { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch(luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); T[] list = new T[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return list; } list[i - 1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (T[])CheckObject(L, stackPos, typeof(T[])); default: LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return null; } } public static bool[] CheckBoolArray(IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch(luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); bool[] list = new bool[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (LuaDLL.lua_type(L, pos) != LuaTypes.LUA_TBOOLEAN) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, "bool[]"); return list; } list[i - 1] = LuaDLL.lua_toboolean(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (bool[])CheckObject(L, stackPos, typeof(bool[])); default: LuaDLL.luaL_typerror(L, stackPos, "bool[]"); return null; } } public static string[] CheckStringArray(IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch(luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); string[] list = new string[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, "string[]"); return list; } list[i - 1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (string[])CheckObject(L, stackPos, typeof(string[])); default: LuaDLL.luaL_typerror(L, stackPos, "string[]"); return null; } } public static object CheckGenericObject(IntPtr L, int stackPos, Type type, out Type ArgType) { object obj = ToLua.ToObject(L, 1); Type t = obj.GetType(); ArgType = null; if (t.IsGenericType && t.GetGenericTypeDefinition() == type) { Type[] ts = t.GetGenericArguments(); ArgType = ts[0]; return obj; } LuaDLL.luaL_argerror(L, stackPos, LuaMisc.GetTypeName(type)); return null; } public static object CheckGenericObject(IntPtr L, int stackPos, Type type, out Type t1, out Type t2) { object obj = ToLua.ToObject(L, 1); Type t = obj.GetType(); t1 = null; t2 = null; if (t.IsGenericType && t.GetGenericTypeDefinition() == type) { Type[] ts = t.GetGenericArguments(); t1 = ts[0]; t2 = ts[1]; return obj; } LuaDLL.luaL_argerror(L, stackPos, LuaMisc.GetTypeName(type)); return null; } public static object CheckGenericObject(IntPtr L, int stackPos, Type type) { object obj = ToLua.ToObject(L, 1); Type t = obj.GetType(); if (t.IsGenericType && t.GetGenericTypeDefinition() == type) { return obj; } LuaDLL.luaL_argerror(L, stackPos, LuaMisc.GetTypeName(type)); return null; } public static object[] ToParamsObject(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } object[] list = new object[count]; int pos = 0; while (pos < count) { list[pos++] = ToVarObject(L, stackPos++); } return list; } public static T[] ToParamsObject(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } T[] list = new T[count]; int pos = 0; while (pos < count) { list[pos++] = StackTraits.To(L, stackPos++); } return list; } public static string[] ToParamsString(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } string[] list = new string[count]; int pos = 0; while (pos < count) { list[pos++] = ToString(L, stackPos++); } return list; } public static T[] ToParamsNumber(IntPtr L, int stackPos, int count) where T : struct { if (count <= 0) { return null; } T[] list = new T[count]; int pos = 0; while (pos < count) { list[pos++] = StackTraits.To(L, stackPos++); } return list; } public static char[] ToParamsChar(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } char[] list = new char[count]; int pos = 0; while (pos < count) { list[pos++] = (char)LuaDLL.lua_tointeger(L, stackPos++); } return list; } public static bool[] CheckParamsBool(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } bool[] list = new bool[count]; int pos = 0; while (pos < count) { list[pos++] = LuaDLL.luaL_checkboolean(L, stackPos++); } return list; } public static T[] CheckParamsNumber(IntPtr L, int stackPos, int count) where T : struct { if (count <= 0) { return null; } T[] list = new T[count]; int pos = 0; while (pos < count) { list[pos++] = StackTraits.Check(L, stackPos++); } return list; } public static char[] CheckParamsChar(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } char[] list = new char[count]; int pos = 0; while (pos < count) { list[pos++] = (char)LuaDLL.luaL_checkinteger(L, stackPos++); } return list; } public static string[] CheckParamsString(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } string[] list = new string[count]; int pos = 0; while (pos < count) { list[pos++] = CheckString(L, stackPos++); } return list; } public static T[] CheckParamsObject(IntPtr L, int stackPos, int count) { if (count <= 0) { return null; } T[] list = new T[count]; int pos = 0; while (pos < count) { list[pos++] = StackTraits.Check(L, stackPos++); } return list; } static public char[] ToCharBuffer(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TSTRING: string str = LuaDLL.lua_tostring(L, stackPos); return str.ToCharArray(); case LuaTypes.LUA_TUSERDATA: return (char[])ToObject(L, stackPos); default: return null; } } static public byte[] ToByteBuffer(IntPtr L, int stackPos) { LuaTypes luaType = LuaDLL.lua_type(L, stackPos); switch (luaType) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TSTRING: int len; IntPtr source = LuaDLL.lua_tolstring(L, stackPos, out len); byte[] buffer = new byte[len]; Marshal.Copy(source, buffer, 0, len); return buffer; case LuaTypes.LUA_TUSERDATA: return (byte[])ToObject(L, stackPos); default: return null; } } public static T[] ToNumberArray(IntPtr L, int stackPos) where T : struct { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); T[] list = new T[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return list; } list[i - 1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (T[])ToObject(L, stackPos); default: return null; } } public static bool[] ToBoolArray(IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); bool[] list = new bool[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (LuaDLL.lua_type(L, pos) != LuaTypes.LUA_TBOOLEAN) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, "bool[]"); return list; } list[i - 1] = LuaDLL.lua_toboolean(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (bool[])ToObject(L, stackPos); default: return null; } } public static string[] ToStringArray(IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch(luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); string[] list = new string[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, "string[]"); return list; } list[i - 1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (string[])ToObject(L, stackPos); default: return null; } } public static object[] ToObjectArray(IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch(luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); object[] list = new object[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); list[i - 1] = ToVarObject(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (object[])ToObject(L, stackPos); default: return null; } } public static T[] ToObjectArray(IntPtr L, int stackPos) where T : class { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); T[] list = new T[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, typeof(T[]).FullName); return list; } list[i - 1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (T[])ToObject(L, stackPos); default: return null; } } public static T[] ToStructArray(IntPtr L, int stackPos) where T : struct { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TTABLE: int len = LuaDLL.lua_objlen(L, stackPos); T[] list = new T[len]; int pos = LuaDLL.lua_gettop(L) + 1; for (int i = 1; i <= len; i++) { LuaDLL.lua_rawgeti(L, stackPos, i); if (!TypeTraits.Check(L, pos)) { LuaDLL.lua_pop(L, 1); LuaDLL.luaL_typerror(L, stackPos, typeof(T[]).FullName); return list; } list[i - 1] = StackTraits.To(L, pos); LuaDLL.lua_pop(L, 1); } return list; case LuaTypes.LUA_TUSERDATA: return (T[])ToObject(L, stackPos); default: return null; } } public static void Push(IntPtr L, Vector3 v3) { LuaDLL.tolua_pushvec3(L, v3.x, v3.y, v3.z); } public static void Push(IntPtr L, Vector2 v2) { LuaDLL.tolua_pushvec2(L, v2.x, v2.y); } public static void Push(IntPtr L, Vector4 v4) { LuaDLL.tolua_pushvec4(L, v4.x, v4.y, v4.z, v4.w); } public static void Push(IntPtr L, Quaternion q) { LuaDLL.tolua_pushquat(L, q.x, q.y, q.z, q.w); } public static void Push(IntPtr L, Color clr) { LuaDLL.tolua_pushclr(L, clr.r, clr.g, clr.b, clr.a); } public static void Push(IntPtr L, Color32 clr) { LuaDLL.tolua_pushclr(L, clr.r, clr.g, clr.b, clr.a); } public static void Push(IntPtr L, Ray ray) { LuaStatic.GetPackRay(L); Push(L, ray.direction); Push(L, ray.origin); if (LuaDLL.lua_pcall(L, 2, 1, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } public static void Push(IntPtr L, Bounds bound) { LuaStatic.GetPackBounds(L); Push(L, bound.center); Push(L, bound.size); if (LuaDLL.lua_pcall(L, 2, 1, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } public static void Push(IntPtr L, RaycastHit hit) { LuaStatic.GetPackRaycastHit(L); Push(L, hit.collider); LuaDLL.lua_pushnumber(L, hit.distance); Push(L, hit.normal); Push(L, hit.point); Push(L, hit.rigidbody); Push(L, hit.transform); if (LuaDLL.lua_pcall(L, 6, 1, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } public static void Push(IntPtr L, RaycastHit hit, int flag) { LuaStatic.GetPackRaycastHit(L); if ((flag & RaycastBits.Collider) != 0) { Push(L, hit.collider); } else { LuaDLL.lua_pushnil(L); } LuaDLL.lua_pushnumber(L, hit.distance); if ((flag & RaycastBits.Normal) != 0) { Push(L, hit.normal); } else { LuaDLL.lua_pushnil(L); } if ((flag & RaycastBits.Point) != 0) { Push(L, hit.point); } else { LuaDLL.lua_pushnil(L); } if ((flag & RaycastBits.Rigidbody) != 0) { Push(L, hit.rigidbody); } else { LuaDLL.lua_pushnil(L); } if ((flag & RaycastBits.Transform) != 0) { Push(L, hit.transform); } else { LuaDLL.lua_pushnil(L); } if (LuaDLL.lua_pcall(L, 6, 1, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } public static void Push(IntPtr L, Touch t) { Push(L, t, TouchBits.ALL); } public static void Push(IntPtr L, Touch t, int flag) { LuaStatic.GetPackTouch(L); LuaDLL.lua_pushinteger(L, t.fingerId); if ((flag & TouchBits.Position) != 0) { Push(L, t.position); } else { LuaDLL.lua_pushnil(L); } if ((flag & TouchBits.RawPosition) != 0) { Push(L, t.rawPosition); } else { LuaDLL.lua_pushnil(L); } if ((flag & TouchBits.DeltaPosition) != 0) { Push(L, t.deltaPosition); } else { LuaDLL.lua_pushnil(L); } LuaDLL.lua_pushnumber(L, t.deltaTime); LuaDLL.lua_pushinteger(L, t.tapCount); LuaDLL.lua_pushinteger(L, (int)t.phase); if (LuaDLL.lua_pcall(L, 7, -1, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); throw new LuaException(error); } } public static void PushLayerMask(IntPtr L, LayerMask l) { LuaDLL.tolua_pushlayermask(L, l.value); } public static void Push(IntPtr L, LuaByteBuffer bb) { LuaDLL.lua_pushlstring(L, bb.buffer, bb.buffer.Length); } public static void PushByteBuffer(IntPtr L, byte[] buffer) { LuaDLL.tolua_pushlstring(L, buffer, buffer.Length); } public static void Push(IntPtr L, Array array) { if (array == null) { LuaDLL.lua_pushnil(L); } else { int arrayMetaTable = LuaStatic.GetArrayMetatable(L); PushUserData(L, array, arrayMetaTable); } } public static void Push(IntPtr L, LuaBaseRef lbr) { if (lbr == null) { LuaDLL.lua_pushnil(L); } else { LuaDLL.lua_getref(L, lbr.GetReference()); } } public static void Push(IntPtr L, Type t) { if (t == null) { LuaDLL.lua_pushnil(L); } else { int typeMetatable = LuaStatic.GetTypeMetatable(L); PushUserData(L, t, typeMetatable); } } public static void Push(IntPtr L, Delegate ev) { if (ev == null) { LuaDLL.lua_pushnil(L); } else { int delegateMetatable = LuaStatic.GetDelegateMetatable(L); PushUserData(L, ev, delegateMetatable); } } public static void Push(IntPtr L, EventObject ev) { if (ev == null) { LuaDLL.lua_pushnil(L); } else { int eventMetatable = LuaStatic.GetEventMetatable(L); PushUserData(L, ev, eventMetatable); } } public static void Push(IntPtr L, IEnumerator iter) { if (iter == null) { LuaDLL.lua_pushnil(L); } else { var luaIEnumerator = iter as CSharpLua.LuaIEnumerator; if (luaIEnumerator != null) { luaIEnumerator.Push(L); } else { int reference = LuaStatic.GetMetaReference(L, iter.GetType()); if (reference > 0) { PushUserData(L, iter, reference); } else { int iterMetatable = LuaStatic.GetIterMetatable(L); PushUserData(L, iter, iterMetatable); } } } } public static void Push(IntPtr L, System.Enum e) { LuaDLL.lua_pushinteger(L, (int)(ValueType)e); } //基础类型获取需要一个函数 public static void PushOut(IntPtr L, LuaOut lo) { ObjectTranslator translator = ObjectTranslator.Get(L); int index = translator.AddObject(lo); LuaDLL.tolua_pushnewudata(L, LuaIndexes.LUA_REGISTRYINDEX, index); } public static void PushStruct(IntPtr L, object o) { if (o == null || o.Equals(null)) { LuaDLL.lua_pushnil(L); return; } if (o is Enum) { ToLua.Push(L, (Enum)o); return; } Type type = o.GetType(); int reference = LuaStatic.GetMetaReference(L, type); if (reference <= 0) { reference = LoadPreType(L, type); } ObjectTranslator translator = ObjectTranslator.Get(L); int index = translator.AddObject(o); LuaDLL.tolua_pushnewudata(L, reference, index); } public static void PushValue(IntPtr L, T v) where T : struct { StackTraits.Push(L, v); } public static void PusNullable(IntPtr L, Nullable v) where T : struct { if (v == null) { LuaDLL.lua_pushnil(L); return; } StackTraits.Push(L, v.Value); } public static void PushUserData(IntPtr L, object o, int reference) { int index; ObjectTranslator translator = ObjectTranslator.Get(L); if (translator.Getudata(o, out index)) { if (LuaDLL.tolua_pushudata(L, index)) { return; } translator.Destroyudata(index); } index = translator.AddObject(o); LuaDLL.tolua_pushnewudata(L, reference, index); } static int LuaPCall(IntPtr L, LuaCSFunction func) { int top = LuaDLL.lua_gettop(L); LuaDLL.tolua_pushcfunction(L, func); if (LuaDLL.lua_pcall(L, 0, -1, 0) != 0) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, top); throw new LuaException(error, LuaException.GetLastError()); } int reference = LuaDLL.tolua_getclassref(L, -1); LuaDLL.lua_settop(L, top); return reference; } public static int LoadPreType(IntPtr L, Type type) { LuaCSFunction LuaOpenLib = LuaStatic.GetPreModule(L, type); int reference = -1; if (LuaOpenLib != null) { #if UNITY_EDITOR Debugger.LogWarning("register PreLoad type {0} to lua", LuaMisc.GetTypeName(type)); #endif reference = LuaPCall(L, LuaOpenLib); } else { //类型未Wrap reference = LuaStatic.GetMissMetaReference(L, type); } return reference; } //o 不为 null static void PushUserObject(IntPtr L, object o) { Type type = o.GetType(); int reference = LuaStatic.GetMetaReference(L, type); if (reference <= 0) { reference = LoadPreType(L, type); } PushUserData(L, o, reference); } public static void Push(IntPtr L, UnityEngine.Object obj) { if (obj == null) { LuaDLL.lua_pushnil(L); } else { PushUserObject(L, obj); } } public static void Push(IntPtr L, UnityEngine.TrackedReference obj) { if (obj == null) { LuaDLL.lua_pushnil(L); } else { PushUserObject(L, obj); } } public static void PushSealed(IntPtr L, T o) { if (o == null || o.Equals(null)) { LuaDLL.lua_pushnil(L); } else { int reference = TypeTraits.GetLuaReference(L); if (reference <= 0) { reference = LoadPreType(L, o.GetType()); } ToLua.PushUserData(L, o, reference); } } public static void PushObject(IntPtr L, object o) { if (o == null || o.Equals(null)) { LuaDLL.lua_pushnil(L); } else { if (o is Enum) { ToLua.Push(L, (Enum)o); } else { PushUserObject(L, o); } } } /*static void PushNull(IntPtr L) { LuaDLL.tolua_pushudata(L, 1); }*/ public static void Push(IntPtr L, nil obj) { LuaDLL.lua_pushnil(L); } //PushVarObject public static void Push(IntPtr L, object obj) { if (obj == null || obj.Equals(null)) { LuaDLL.lua_pushnil(L); return; } Type t = obj.GetType(); TypeCode code = Type.GetTypeCode(t); switch (code) { case TypeCode.Boolean: { bool b = (bool)obj; LuaDLL.lua_pushboolean(L, b); return; } case TypeCode.Char: { char ch = (char)obj; LuaDLL.lua_pushnumber(L, ch); return; } case TypeCode.SByte: { LuaDLL.lua_pushnumber(L, (sbyte)obj); return; } case TypeCode.Byte: { LuaDLL.lua_pushnumber(L, (byte)obj); return; } case TypeCode.Int16: { LuaDLL.lua_pushnumber(L, (Int16)obj); return; } case TypeCode.UInt16: { LuaDLL.lua_pushnumber(L, (UInt16)obj); return; } case TypeCode.Int32: { LuaDLL.lua_pushnumber(L, (Int32)obj); return; } case TypeCode.UInt32: { LuaDLL.lua_pushnumber(L, (UInt32)obj); return; } case TypeCode.Int64: { LuaDLL.lua_pushnumber(L, (Int64)obj); return; } case TypeCode.UInt64: { LuaDLL.lua_pushnumber(L, (UInt64)obj); return; } case TypeCode.Single: { LuaDLL.lua_pushnumber(L, (Single)obj); return; ; } case TypeCode.Double: { LuaDLL.lua_pushnumber(L, (double)obj); return; } case TypeCode.String: { LuaDLL.lua_pushstring(L, (string)obj); return; } } if (t.IsValueType) { if (TypeChecker.IsNullable(t)) { Type[] ts = t.GetGenericArguments(); t = ts[0]; } if (t == typeof(bool)) { bool b = (bool)obj; LuaDLL.lua_pushboolean(L, b); } else if (obj is Enum) { Push(L, (System.Enum)obj); } else if (t == typeof(long)) { LuaDLL.tolua_pushint64(L, (long)obj); } else if (t == typeof(ulong)) { LuaDLL.tolua_pushuint64(L, (ulong)obj); } else if (t.IsPrimitive) { double d = LuaMisc.ToDouble(obj); LuaDLL.lua_pushnumber(L, d); } else if (t == typeof(LuaByteBuffer)) { LuaByteBuffer lbb = (LuaByteBuffer)obj; LuaDLL.lua_pushlstring(L, lbb.buffer, lbb.buffer.Length); } else if (t == typeof(Vector3)) { Push(L, (Vector3)obj); } else if (t == typeof(Quaternion)) { Push(L, (Quaternion)obj); } else if (t == typeof(Vector2)) { Push(L, (Vector2)obj); } else if (t == typeof(Vector4)) { Push(L, (Vector4)obj); } else if (t == typeof(Color)) { Push(L, (Color)obj); } else if (t == typeof(Color32)) { Push(L, (Color32)obj); } else if (t == typeof(RaycastHit)) { Push(L, (RaycastHit)obj); } else if (t == typeof(Touch)) { Push(L, (Touch)obj); } else if (t == typeof(Ray)) { Push(L, (Ray)obj); } else if (t == typeof(Bounds)) { Push(L, (Bounds)obj); } else if (t == typeof(LayerMask)) { PushLayerMask(L, (LayerMask)obj); } else { LuaPushVarObject _Push = null; if (VarPushMap.TryGetValue(t, out _Push)) { _Push(L, obj); } else { PushStruct(L, obj); } } } else { if (t.IsArray) { Push(L, (Array)obj); } else if(t == typeof(string)) { LuaDLL.lua_pushstring(L, (string)obj); } else if (obj is LuaBaseRef) { Push(L, (LuaBaseRef)obj); } else if (obj is UnityEngine.Object) { Push(L, (UnityEngine.Object)obj); } else if (obj is UnityEngine.TrackedReference) { Push(L, (UnityEngine.TrackedReference)obj); } else if (obj is Delegate) { Push(L, (Delegate)obj); } else if (obj is IEnumerator) { Push(L, (IEnumerator)obj); } else if (t == typeof(EventObject)) { Push(L, (EventObject)obj); } else if (t == monoType) { Push(L, (Type)obj); } else { PushObject(L, obj); } } } public static void SetBack(IntPtr L, int stackPos, object o) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); ObjectTranslator translator = ObjectTranslator.Get(L); if (udata != -1) { translator.SetBack(udata, o); } } public static int Destroy(IntPtr L) { int udata = LuaDLL.tolua_rawnetobj(L, 1); ObjectTranslator translator = ObjectTranslator.Get(L); translator.Destroy(udata); return 0; } public static void CheckArgsCount(IntPtr L, string method, int count) { int c = LuaDLL.lua_gettop(L); if (c != count) { throw new LuaException(string.Format("no overload for method '{0}' takes '{1}' arguments", method, c)); } } public static void CheckArgsCount(IntPtr L, int count) { int c = LuaDLL.lua_gettop(L); if (c != count) { throw new LuaException(string.Format("no overload for method takes '{0}' arguments", c)); } } public static Delegate CheckDelegate(Type t, IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TFUNCTION: case LuaTypes.LUA_TTABLE: LuaFunction func = ToLua.ToLuaFunction(L, stackPos); return DelegateFactory.CreateDelegate(t, func); case LuaTypes.LUA_TUSERDATA: return (Delegate)ToLua.CheckObject(L, stackPos, t); default: LuaDLL.luaL_typerror(L, stackPos, LuaMisc.GetTypeName(t)); return null; } } public static Delegate CheckDelegate(IntPtr L, int stackPos) { LuaTypes luatype = LuaDLL.lua_type(L, stackPos); switch (luatype) { case LuaTypes.LUA_TNIL: return null; case LuaTypes.LUA_TFUNCTION: case LuaTypes.LUA_TTABLE: LuaFunction func = ToLua.ToLuaFunction(L, stackPos); return DelegateTraits.Create(func); case LuaTypes.LUA_TUSERDATA: return (Delegate)ToLua.CheckObject(L, stackPos, typeof(T)); default: LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return null; } } } } ================================================ FILE: Assets/ToLua/Core/ToLua.cs.meta ================================================ fileFormatVersion: 2 guid: 8558028e53ff5d946b0ef857634815da MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/TypeChecker.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System; using System.Collections.Generic; namespace LuaInterface { public static class TypeChecker { public static Type[] LuaValueTypeMap = new Type[LuaValueType.Max]; static TypeChecker() { LuaValueTypeMap[LuaValueType.None] = null; LuaValueTypeMap[LuaValueType.Vector3] = typeof(Vector3); LuaValueTypeMap[LuaValueType.Quaternion] = typeof(Quaternion); LuaValueTypeMap[LuaValueType.Vector2] = typeof(Vector2); LuaValueTypeMap[LuaValueType.Color] = typeof(Color); LuaValueTypeMap[LuaValueType.Color32] = typeof(Color32); LuaValueTypeMap[LuaValueType.Vector4] = typeof(Vector4); LuaValueTypeMap[LuaValueType.Ray] = typeof(Ray); LuaValueTypeMap[LuaValueType.Bounds] = typeof(Bounds); LuaValueTypeMap[LuaValueType.Touch] = typeof(Touch); LuaValueTypeMap[LuaValueType.LayerMask] = typeof(LayerMask); LuaValueTypeMap[LuaValueType.RaycastHit] = typeof(RaycastHit); LuaValueTypeMap[LuaValueType.Int64] = typeof(long); LuaValueTypeMap[LuaValueType.UInt64] = typeof(ulong); } public static bool IsValueType(Type t) { return !t.IsEnum && t.IsValueType; } public static bool CheckTypes(IntPtr L, int begin, Type type0) { return CheckType(L, type0, begin); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2, Type type3) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2) && CheckType(L, type3, begin + 3); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2, Type type3, Type type4) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2) && CheckType(L, type3, begin + 3) && CheckType(L, type4, begin + 4); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2, Type type3, Type type4, Type type5) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2) && CheckType(L, type3, begin + 3) && CheckType(L, type4, begin + 4) && CheckType(L, type5, begin + 5); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2, Type type3, Type type4, Type type5, Type type6) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2) && CheckType(L, type3, begin + 3) && CheckType(L, type4, begin + 4) && CheckType(L, type5, begin + 5) && CheckType(L, type6, begin + 6); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2) && CheckType(L, type3, begin + 3) && CheckType(L, type4, begin + 4) && CheckType(L, type5, begin + 5) && CheckType(L, type6, begin + 6) && CheckType(L, type7, begin + 7); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7, Type type8) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2) && CheckType(L, type3, begin + 3) && CheckType(L, type4, begin + 4) && CheckType(L, type5, begin + 5) && CheckType(L, type6, begin + 6) && CheckType(L, type7, begin + 7) && CheckType(L, type8, begin + 8); } public static bool CheckTypes(IntPtr L, int begin, Type type0, Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7, Type type8, Type type9) { return CheckType(L, type0, begin) && CheckType(L, type1, begin + 1) && CheckType(L, type2, begin + 2) && CheckType(L, type3, begin + 3) && CheckType(L, type4, begin + 4) && CheckType(L, type5, begin + 5) && CheckType(L, type6, begin + 6) && CheckType(L, type7, begin + 7) && CheckType(L, type8, begin + 8) && CheckType(L, type9, begin + 9); } public static bool CheckTypes(IntPtr L, int begin, params Type[] types) { for (int i = 0; i < types.Length; i++) { if (!CheckType(L, types[i], i + begin)) { return false; } } return true; } public static bool CheckParamsType(IntPtr L, Type t, int begin, int count) { if (t == typeof(object)) { return true; } for (int i = 0; i < count; i++) { if (!CheckType(L, t, i + begin)) { return false; } } return true; } static bool IsNilType(Type t) { if (!t.IsValueType) { return true; } if (IsNullable(t)) { return true; } return false; } public static bool IsNullable(Type t) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) { return true; } return false; } public static Type GetNullableType(Type t) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) { Type[] ts = t.GetGenericArguments(); t = ts[0]; } return t; } public static bool CheckType(IntPtr L, Type type, int pos) { //默认都可以转 object if (type == typeof(object)) { return true; } Type t = GetNullableType(type); LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNUMBER: return IsNumberType(t); case LuaTypes.LUA_TSTRING: return t == typeof(string) || t == typeof(byte[]) || t == typeof(char[]) || t == typeof(LuaByteBuffer); case LuaTypes.LUA_TUSERDATA: return IsMatchUserData(L, t, pos); case LuaTypes.LUA_TBOOLEAN: return t == typeof(bool); case LuaTypes.LUA_TFUNCTION: return t == typeof(LuaFunction); case LuaTypes.LUA_TTABLE: return IsUserTable(t, L, pos); case LuaTypes.LUA_TLIGHTUSERDATA: return t == typeof(IntPtr) || t == typeof(UIntPtr); case LuaTypes.LUA_TNIL: return IsNilType(type); default: break; } throw new LuaException("undefined type to check" + LuaDLL.luaL_typename(L, pos)); } static Type monoType = typeof(Type).GetType(); public static T ChangeType(object temp, Type type) { var tempType = temp.GetType(); if (tempType == monoType || type.IsAssignableFrom(tempType)) { return (T)temp; } else { return (T)Convert.ChangeType(temp, type); } } public static object ChangeType(object temp, Type type) { var tempType = temp.GetType(); if (tempType == monoType) { return (Type)temp; } else if (type.IsAssignableFrom(tempType)) { return temp; } else { return Convert.ChangeType(temp, type); } } static bool IsMatchUserData(IntPtr L, Type t, int pos) { if (t == typeof(long)) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Int64; } else if (t == typeof(ulong)) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.UInt64; } object obj = null; int udata = LuaDLL.tolua_rawnetobj(L, pos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); obj = translator.GetObject(udata); if (obj != null) { Type objType = obj.GetType(); if (t == objType || t.IsAssignableFrom(objType)) { return true; } } else { return !t.IsValueType; } } return false; } public static bool IsNumberType(Type t) { if (t.IsPrimitive) { if (t == typeof(bool) || t == typeof(IntPtr) || t == typeof(UIntPtr)) { return false; } return true; } return false; } public static bool IsUserTable(Type t, IntPtr L, int pos) { int type = LuaDLL.tolua_getvaluetype(L, pos); if (type != LuaValueType.None) { return t == LuaValueTypeMap[type]; } if (t.IsArray) { if (t.GetElementType().IsArray || t.GetArrayRank() > 1) { return false; } return true; } else if (t == typeof(LuaTable)) { return true; } else if (LuaDLL.tolua_isvptrtable(L, pos)) { return IsMatchUserData(L, t, pos); } return false; } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4) && TypeTraits.Check(L, pos + 5); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4) && TypeTraits.Check(L, pos + 5) && TypeTraits.Check(L, pos + 6); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4) && TypeTraits.Check(L, pos + 5) && TypeTraits.Check(L, pos + 6) && TypeTraits.Check(L, pos + 7); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4) && TypeTraits.Check(L, pos + 5) && TypeTraits.Check(L, pos + 6) && TypeTraits.Check(L, pos + 7) && TypeTraits.Check(L, pos + 8); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4) && TypeTraits.Check(L, pos + 5) && TypeTraits.Check(L, pos + 6) && TypeTraits.Check(L, pos + 7) && TypeTraits.Check(L, pos + 8) && TypeTraits.Check(L, pos + 9); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4) && TypeTraits.Check(L, pos + 5) && TypeTraits.Check(L, pos + 6) && TypeTraits.Check(L, pos + 7) && TypeTraits.Check(L, pos + 8) && TypeTraits.Check(L, pos + 9) && TypeTraits.Check(L, pos + 10); } public static bool CheckTypes(IntPtr L, int pos) { return TypeTraits.Check(L, pos) && TypeTraits.Check(L, pos + 1) && TypeTraits.Check(L, pos + 2) && TypeTraits.Check(L, pos + 3) && TypeTraits.Check(L, pos + 4) && TypeTraits.Check(L, pos + 5) && TypeTraits.Check(L, pos + 6) && TypeTraits.Check(L, pos + 7) && TypeTraits.Check(L, pos + 8) && TypeTraits.Check(L, pos + 9) && TypeTraits.Check(L, pos + 10) && TypeTraits.Check(L, pos + 11); } public static bool CheckParamsType(IntPtr L, int begin, int count) { if (typeof(T) == typeof(object)) { return true; } for (int i = 0; i < count; i++) { if (!TypeTraits.Check(L, i + begin)) { return false; } } return true; } static public bool CheckDelegateType(Type type, IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TUSERDATA: int udata = LuaDLL.tolua_rawnetobj(L, pos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); return obj == null ? true : type == obj.GetType(); } return false; default: return false; } } static public bool CheckEnumType(Type type, IntPtr L, int pos) { if (LuaDLL.lua_type(L, pos) == LuaTypes.LUA_TUSERDATA) { int udata = LuaDLL.tolua_rawnetobj(L, pos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); return obj == null ? false : type == obj.GetType(); } } return false; } } } ================================================ FILE: Assets/ToLua/Core/TypeChecker.cs.meta ================================================ fileFormatVersion: 2 guid: b2c5d493c1805784994fefe7b22da126 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Core/TypeTraits.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System; using System.Collections; namespace LuaInterface { public static class TypeTraits { static public Func Check = DefaultCheck; static public Type type = typeof(T); static public bool IsValueType = type.IsValueType; static public bool IsArray = type.IsArray; static string typeName = string.Empty; static int nilType = -1; static int metaref = -1; static public void Init(Func check) { if (check != null) { Check = check; } } static public string GetTypeName() { if (typeName == string.Empty) { typeName = LuaMisc.GetTypeName(type); } return typeName; } static public int GetLuaReference(IntPtr L) { #if MULTI_STATE return LuaStatic.GetMetaReference(L, type); #else if (metaref > 0) { return metaref; } metaref = LuaStatic.GetMetaReference(L, type); if (metaref > 0) { LuaState.Get(L).OnDestroy += () => { metaref = -1; }; } return metaref; #endif } static bool DefaultCheck(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return IsNilType(); case LuaTypes.LUA_TUSERDATA: return IsUserData(L, pos); case LuaTypes.LUA_TTABLE: return IsUserTable(L, pos); default: return false; } } static bool IsNilType() { if (nilType != -1) { return nilType != 0; } if (!IsValueType) { nilType = 1; return true; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { nilType = 1; return true; } nilType = 0; return false; } static bool IsUserData(IntPtr L, int pos) { object obj = null; int udata = LuaDLL.tolua_rawnetobj(L, pos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); obj = translator.GetObject(udata); if (obj != null) { return obj is T; } else { return !IsValueType; } } return false; } static bool IsUserTable(IntPtr L, int pos) { if (type == typeof(LuaTable)) { return true; } else if (type.IsArray) { if (type.GetElementType().IsArray || type.GetArrayRank() > 1) { return false; } return true; } else if (LuaDLL.tolua_isvptrtable(L, pos)) { return IsUserData(L, pos); } return false; } } public static class DelegateTraits { static DelegateFactory.DelegateCreate _Create = null; static public void Init(DelegateFactory.DelegateCreate func) { _Create = func; } static public Delegate Create(LuaFunction func) { #if UNITY_EDITOR if (_Create == null) { throw new LuaException(string.Format("Delegate {0} not register", TypeTraits.GetTypeName())); } #endif if (func != null) { LuaState state = func.GetLuaState(); LuaDelegate target = state.GetLuaDelegate(func); if (target != null) { return Delegate.CreateDelegate(typeof(T), target, target.method); } else { Delegate d = _Create(func, null, false); target = d.Target as LuaDelegate; state.AddLuaDelegate(target, func); return d; } } return _Create(null, null, false); } static public Delegate Create(LuaFunction func, LuaTable self) { #if UNITY_EDITOR if (_Create == null) { throw new LuaException(string.Format("Delegate {0} not register", TypeTraits.GetTypeName())); } #endif if (func != null) { LuaState state = func.GetLuaState(); LuaDelegate target = state.GetLuaDelegate(func, self); if (target != null) { return Delegate.CreateDelegate(typeof(T), target, target.method); } else { Delegate d = _Create(func, self, true); target = d.Target as LuaDelegate; state.AddLuaDelegate(target, func, self); return d; } } return _Create(null, null, true); } } public static class StackTraits { static public Action Push = SelectPush(); static public Func Check = DefaultCheck; static public Func To = DefaultTo; static public void Init(Action push, Func check, Func to) { if (push != null) { Push = push; } if (to != null) { To = to; } if (check != null) { Check = check; } } static Action SelectPush() { if (TypeTraits.IsValueType) { return PushValue; } else if (TypeTraits.IsArray) { return PushArray; } else { return PushObject; } } static void PushValue(IntPtr L, T o) { ToLua.PushStruct(L, o); } static void PushObject(IntPtr L, T o) { ToLua.PushObject(L, o); } static void PushArray(IntPtr L, T array) { if (array == null) { LuaDLL.lua_pushnil(L); } else { int arrayMetaTable = LuaStatic.GetArrayMetatable(L); ToLua.PushUserData(L, array, arrayMetaTable); } } static T DefaultTo(IntPtr L, int pos) { return (T)ToLua.ToObject(L, pos); } static T DefaultCheck(IntPtr L, int stackPos) { int udata = LuaDLL.tolua_rawnetobj(L, stackPos); if (udata != -1) { ObjectTranslator translator = ObjectTranslator.Get(L); object obj = translator.GetObject(udata); if (obj != null) { if (obj is T) { return (T)obj; } LuaDLL.luaL_argerror(L, stackPos, string.Format("{0} expected, got {1}", TypeTraits.GetTypeName(), obj.GetType().FullName)); } if (!TypeTraits.IsValueType) { return default(T); } } else if (LuaDLL.lua_isnil(L, stackPos) && !TypeTraits.IsValueType) { return default(T); } LuaDLL.luaL_typerror(L, stackPos, TypeTraits.GetTypeName()); return default(T); } } } ================================================ FILE: Assets/ToLua/Core/TypeTraits.cs.meta ================================================ fileFormatVersion: 2 guid: 82858b365ef4145429c2f3227be8c845 timeCreated: 1494572166 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Core.meta ================================================ fileFormatVersion: 2 guid: 7714c4ebcd6e6474da6ec5df53bca350 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_EventObject.cs ================================================ using System; using LuaInterface; public class ToLua_LuaInterface_EventObject { [NoToLuaAttribute] public static string op_AdditionDefined = @" try { EventObject arg0 = (EventObject)ToLua.CheckObject(L, 1, typeof(EventObject)); arg0.func = ToLua.CheckDelegate(arg0.type, L, 2); arg0.op = EventOp.Add; ToLua.Push(L, arg0); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [NoToLuaAttribute] public static string op_SubtractionDefined = @" try { EventObject arg0 = (EventObject)ToLua.CheckObject(L, 1, typeof(EventObject)); arg0.func = ToLua.CheckDelegate(arg0.type, L, 2); arg0.op = EventOp.Sub; ToLua.Push(L, arg0); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public static ToLua_LuaInterface_EventObject operator +(ToLua_LuaInterface_EventObject a, ToLua_LuaInterface_EventObject b) { return null; } [UseDefinedAttribute] public static ToLua_LuaInterface_EventObject operator -(ToLua_LuaInterface_EventObject a, ToLua_LuaInterface_EventObject b) { return null; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_EventObject.cs.meta ================================================ fileFormatVersion: 2 guid: 6a98ce054e1b9e848a9ed23974b72436 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaConstructor.cs ================================================ using System; using LuaInterface; public class ToLua_LuaInterface_LuaConstructor { public static string CallDefined = @" try { LuaConstructor obj = (LuaConstructor)ToLua.CheckObject(L, 1, typeof(LuaConstructor)); return obj.Call(L); } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string DestroyDefined = @" try { ToLua.CheckArgsCount(L, 1); LuaConstructor obj = (LuaConstructor)ToLua.CheckObject(L, 1, typeof(LuaConstructor)); obj.Destroy(); ToLua.Destroy(L); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public void Destroy() { } [UseDefinedAttribute] public int Call(IntPtr L) { return 0; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaConstructor.cs.meta ================================================ fileFormatVersion: 2 guid: 24ae6f8094d27814db58bed92723e5eb MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaField.cs ================================================ using System; using LuaInterface; public class ToLua_LuaInterface_LuaField { public static string GetDefined = @" try { LuaField obj = (LuaField)ToLua.CheckObject(L, 1, typeof(LuaField)); return obj.Get(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string SetDefined = @" try { LuaField obj = (LuaField)ToLua.CheckObject(L, 1, typeof(LuaField)); return obj.Set(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public int Set(IntPtr L) { return 0; } [UseDefinedAttribute] public int Get(IntPtr L) { return 0; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaField.cs.meta ================================================ fileFormatVersion: 2 guid: f6b190ca703de424fafa500033a782a3 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaMethod.cs ================================================ using System; using LuaInterface; public class ToLua_LuaInterface_LuaMethod { public static string CallDefined = @" try { LuaMethod obj = (LuaMethod)ToLua.CheckObject(L, 1, typeof(LuaMethod)); return obj.Call(L); } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string DestroyDefined = @" try { ToLua.CheckArgsCount(L, 1); LuaMethod obj = (LuaMethod)ToLua.CheckObject(L, 1, typeof(LuaMethod)); obj.Destroy(); ToLua.Destroy(L); return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public int Call(IntPtr L) { return 0; } [UseDefinedAttribute] public void Destroy() { } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaMethod.cs.meta ================================================ fileFormatVersion: 2 guid: 6eac87eec04d6e547ac028d69e0eeb71 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaProperty.cs ================================================ using System; using LuaInterface; public class ToLua_LuaInterface_LuaProperty { public static string GetDefined = @" try { LuaProperty obj = (LuaProperty)ToLua.CheckObject(L, 1, typeof(LuaProperty)); return obj.Get(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string SetDefined = @" try { LuaProperty obj = (LuaProperty)ToLua.CheckObject(L, 1, typeof(LuaProperty)); return obj.Set(L); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public int Set(IntPtr L) { return 0; } [UseDefinedAttribute] public int Get(IntPtr L) { return 0; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_LuaInterface_LuaProperty.cs.meta ================================================ fileFormatVersion: 2 guid: e00a567610c97754bbae9672db75a1f2 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Delegate.cs ================================================ using System; using LuaInterface; public class ToLua_System_Delegate { public static string AdditionNameSpace = "System.Collections.Generic"; [NoToLuaAttribute] public static string op_AdditionDefined = @" try { LuaTypes type = LuaDLL.lua_type(L, 1); switch (type) { case LuaTypes.LUA_TFUNCTION: Delegate arg0 = ToLua.ToObject(L, 2) as Delegate; LuaFunction func = ToLua.ToLuaFunction(L, 1); Type t = arg0.GetType(); Delegate arg1 = DelegateFactory.CreateDelegate(t, func); Delegate arg2 = Delegate.Combine(arg0, arg1); ToLua.Push(L, arg2); return 1; case LuaTypes.LUA_TNIL: LuaDLL.lua_pushvalue(L, 2); return 1; case LuaTypes.LUA_TUSERDATA: Delegate a0 = ToLua.ToObject(L, 1) as Delegate; Delegate a1 = ToLua.CheckDelegate(a0.GetType(), L, 2); Delegate ret = Delegate.Combine(a0, a1); ToLua.Push(L, ret); return 1; default: LuaDLL.luaL_typerror(L, 1, ""Delegate""); return 0; } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [NoToLuaAttribute] public static string op_SubtractionDefined = @" try { Delegate arg0 = (Delegate)ToLua.CheckObject(L, 1); LuaTypes type = LuaDLL.lua_type(L, 2); if (type == LuaTypes.LUA_TFUNCTION) { LuaState state = LuaState.Get(L); LuaFunction func = ToLua.ToLuaFunction(L, 2); Delegate[] ds = arg0.GetInvocationList(); for (int i = 0; i < ds.Length; i++) { LuaDelegate ld = ds[i].Target as LuaDelegate; if (ld != null && ld.func == func && ld.self == null) { arg0 = Delegate.Remove(arg0, ds[i]); state.DelayDispose(ld.func); break; } } func.Dispose(); ToLua.Push(L, arg0); return 1; } else { Delegate arg1 = (Delegate)ToLua.CheckObject(L, 2); arg0 = DelegateFactory.RemoveDelegate(arg0, arg1); ToLua.Push(L, arg0); return 1; } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static bool operator ==(ToLua_System_Delegate lhs, ToLua_System_Delegate rhs) { return false; } public static bool operator !=(ToLua_System_Delegate lhs, ToLua_System_Delegate rhs) { return false; } [UseDefinedAttribute] public static ToLua_System_Delegate operator +(ToLua_System_Delegate a, ToLua_System_Delegate b) { return null; } [UseDefinedAttribute] public static ToLua_System_Delegate operator -(ToLua_System_Delegate a, ToLua_System_Delegate b) { return null; } public override bool Equals(object other) { return false; } public override int GetHashCode() { return 0; } public static string DestroyDefined = @" Delegate arg0 = (Delegate)ToLua.CheckObject(L, 1); Delegate[] ds = arg0.GetInvocationList(); for (int i = 0; i < ds.Length; i++) { LuaDelegate ld = ds[i].Target as LuaDelegate; if (ld != null) { ld.Dispose(); } } return 0;"; [UseDefinedAttribute] public static void Destroy(object obj) { } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Delegate.cs.meta ================================================ fileFormatVersion: 2 guid: 6f0591686bc09e74e9a4fe2ad4e9fdb2 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Enum.cs ================================================ using System; using LuaInterface; public class ToLua_System_Enum { public static string ToIntDefined = @" try { object arg0 = ToLua.CheckObject(L, 1); int ret = Convert.ToInt32(arg0); LuaDLL.lua_pushinteger(L, ret); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string ParseDefined = @" try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); object o = System.Enum.Parse(arg0, arg1); ToLua.Push(L, (Enum)o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); string arg1 = ToLua.ToString(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); object o = System.Enum.Parse(arg0, arg1, arg2); ToLua.Push(L, (Enum)o); return 1; } else { return LuaDLL.luaL_throw(L, ""invalid arguments to method: System.Enum.Parse""); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string ToObjectDefined = @" try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); object o = System.Enum.ToObject(arg0, arg1); ToLua.Push(L, (Enum)o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { System.Type arg0 = (System.Type)ToLua.ToObject(L, 1); object arg1 = ToLua.ToVarObject(L, 2); object o = System.Enum.ToObject(arg0, arg1); ToLua.Push(L, (Enum)o); return 1; } else { return LuaDLL.luaL_throw(L, ""invalid arguments to method: System.Enum.ToObject""); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public static void ToInt(System.Enum obj) { } [UseDefinedAttribute] public static object ToObject(Type enumType, int value) { return null; } [UseDefinedAttribute] public static object Parse(Type enumType, string value) { return null; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Enum.cs.meta ================================================ fileFormatVersion: 2 guid: ff4fa54c22d6f7c428ef9aa02f6c10d4 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Object.cs ================================================ using System; using LuaInterface; public class ToLua_System_Object { public static string DestroyDefined = "\t\treturn ToLua.Destroy(L);"; [UseDefinedAttribute] public static void Destroy(object obj) { } public static bool op_Equality(Object x, Object y) { return false; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Object.cs.meta ================================================ fileFormatVersion: 2 guid: afb4e6913f506df4c9eb98f70781a578 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_String.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; public class ToLua_System_String { [NoToLuaAttribute] public static string ToLua_System_StringDefined = @" try { LuaTypes luatype = LuaDLL.lua_type(L, 1); if (luatype == LuaTypes.LUA_TSTRING) { string arg0 = LuaDLL.lua_tostring(L, 1); ToLua.PushSealed(L, arg0); return 1; } else { return LuaDLL.luaL_throw(L, ""invalid arguments to string's ctor method""); } } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public ToLua_System_String() { } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_String.cs.meta ================================================ fileFormatVersion: 2 guid: 7cc775dacb56ec34587e28d9e3f68417 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Type.cs ================================================ using System; using System.Reflection; using LuaInterface; public class ToLua_System_Type { [NoToLuaAttribute] public EventInfo GetEvent(string name) { return null; } [NoToLuaAttribute] public EventInfo GetEvent(string name, BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public EventInfo[] GetEvents() { return null; } [NoToLuaAttribute] public EventInfo[] GetEvents(BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public MethodInfo GetMethod(string name) { return null; } [NoToLuaAttribute] public MethodInfo GetMethod(string name, Type[] types) { return null; } [NoToLuaAttribute] public MethodInfo GetMethod(string name, BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers) { return null; } [NoToLuaAttribute] public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { return null; } [NoToLuaAttribute] public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { return null; } [NoToLuaAttribute] public MethodInfo[] GetMethods() { return null; } [NoToLuaAttribute] public MethodInfo[] GetMethods(BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public PropertyInfo[] GetProperties() { return null; } [NoToLuaAttribute] public PropertyInfo[] GetProperties(BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public PropertyInfo GetProperty(string name) { return null; } [NoToLuaAttribute] public PropertyInfo GetProperty(string name, Type[] types) { return null; } [NoToLuaAttribute] public PropertyInfo GetProperty(string name, Type returnType) { return null; } [NoToLuaAttribute] public PropertyInfo GetProperty(string name, BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public PropertyInfo GetProperty(string name, Type returnType, Type[] types) { return null; } [NoToLuaAttribute] public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers) { return null; } [NoToLuaAttribute] public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { return null; } [NoToLuaAttribute] public FieldInfo GetField(string name) { return null; } [NoToLuaAttribute] public FieldInfo GetField(string name, BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public FieldInfo[] GetFields() { return null; } [NoToLuaAttribute] public FieldInfo[] GetFields(BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public ConstructorInfo GetConstructor(Type[] types) { return null; } [NoToLuaAttribute] public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { return null; } [NoToLuaAttribute] public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { return null; } [NoToLuaAttribute] public ConstructorInfo[] GetConstructors() { return null; } [NoToLuaAttribute] public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public MemberInfo[] GetMember(string name) { return null; } [NoToLuaAttribute] public MemberInfo[] GetMember(string name, BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { return null; } [NoToLuaAttribute] public MemberInfo[] GetMembers() { return null; } [NoToLuaAttribute] public MemberInfo[] GetMembers(BindingFlags bindingAttr) { return null; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_System_Type.cs.meta ================================================ fileFormatVersion: 2 guid: a67e5f490d5d4cd4f8754c921a414d9a MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_GameObject.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System; public class ToLua_UnityEngine_GameObject { public static string SendMessageDefined = @" IntPtr L0 = LuaException.L; try { ++LuaException.SendMsgCount; LuaException.L = L; int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); obj.SendMessage(arg0); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); UnityEngine.SendMessageOptions arg1 = (UnityEngine.SendMessageOptions)ToLua.ToObject(L, 3); obj.SendMessage(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); object arg1 = ToLua.ToVarObject(L, 3); obj.SendMessage(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); object arg1 = ToLua.ToVarObject(L, 3); UnityEngine.SendMessageOptions arg2 = (UnityEngine.SendMessageOptions)ToLua.ToObject(L, 4); obj.SendMessage(arg0, arg1, arg2); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else { --LuaException.SendMsgCount; LuaException.L = L0; return LuaDLL.luaL_throw(L, ""invalid arguments to method: UnityEngine.GameObject.SendMessage""); } } catch(Exception e) { --LuaException.SendMsgCount; LuaException.L = L0; return LuaDLL.toluaL_exception(L, e); }"; public static string SendMessageUpwardsDefined = @" IntPtr L0 = LuaException.L; try { ++LuaException.SendMsgCount; LuaException.L = L; int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); obj.SendMessageUpwards(arg0); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); UnityEngine.SendMessageOptions arg1 = (UnityEngine.SendMessageOptions)ToLua.ToObject(L, 3); obj.SendMessageUpwards(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); object arg1 = ToLua.ToVarObject(L, 3); obj.SendMessageUpwards(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); object arg1 = ToLua.ToVarObject(L, 3); UnityEngine.SendMessageOptions arg2 = (UnityEngine.SendMessageOptions)ToLua.ToObject(L, 4); obj.SendMessageUpwards(arg0, arg1, arg2); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else { --LuaException.SendMsgCount; LuaException.L = L0; return LuaDLL.luaL_throw(L, ""invalid arguments to method: UnityEngine.GameObject.SendMessageUpwards""); } } catch (Exception e) { --LuaException.SendMsgCount; LuaException.L = L0; return LuaDLL.toluaL_exception(L, e); }"; public static string BroadcastMessageDefined = @" IntPtr L0 = LuaException.L; try { ++LuaException.SendMsgCount; LuaException.L = L; int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); obj.BroadcastMessage(arg0); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); UnityEngine.SendMessageOptions arg1 = (UnityEngine.SendMessageOptions)ToLua.ToObject(L, 3); obj.BroadcastMessage(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); object arg1 = ToLua.ToVarObject(L, 3); obj.BroadcastMessage(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else if (count == 4 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); string arg0 = ToLua.ToString(L, 2); object arg1 = ToLua.ToVarObject(L, 3); UnityEngine.SendMessageOptions arg2 = (UnityEngine.SendMessageOptions)ToLua.ToObject(L, 4); obj.BroadcastMessage(arg0, arg1, arg2); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } --LuaException.SendMsgCount; LuaException.L = L0; return 0; } else { --LuaException.SendMsgCount; LuaException.L = L0; return LuaDLL.luaL_throw(L, ""invalid arguments to method: UnityEngine.GameObject.BroadcastMessage""); } } catch (Exception e) { --LuaException.SendMsgCount; LuaException.L = L0; return LuaDLL.toluaL_exception(L, e); }"; public static string AddComponentDefined = @" IntPtr L0 = LuaException.L; try { ++LuaException.InstantiateCount; LuaException.L = L; ToLua.CheckArgsCount(L, 2); UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); System.Type arg0 = ToLua.CheckMonoType(L, 2); UnityEngine.Component o = obj.AddComponent(arg0); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } ToLua.Push(L, o); LuaException.L = L0; --LuaException.InstantiateCount; return 1; } catch (Exception e) { LuaException.L = L0; --LuaException.InstantiateCount; return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public void SendMessage(string methodName) { } [UseDefinedAttribute] public void SendMessageUpwards(string methodName) { } [UseDefinedAttribute] public void BroadcastMessage(string methodName) { } [UseDefinedAttribute] public void AddComponent(Type t) { } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_GameObject.cs.meta ================================================ fileFormatVersion: 2 guid: 1ed77ac31b521ad4bae3fe7e8b84cab4 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_Input.cs ================================================ using UnityEngine; using LuaInterface; public class ToLua_UnityEngine_Input { public static string GetTouchDefined = @" try { int arg0 = (int)LuaDLL.luaL_checknumber(L, 1); int arg1 = LuaDLL.luaL_optinteger(L, 2, TouchBits.ALL); UnityEngine.Touch o = UnityEngine.Input.GetTouch(arg0); ToLua.Push(L, o, arg1); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public static Touch GetTouch(int index, int flag) { return new Touch(); } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_Input.cs.meta ================================================ fileFormatVersion: 2 guid: 3cee476932ca9a04da9cff77f92e1894 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_Object.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; public class ToLua_UnityEngine_Object { public static string DestroyDefined = @" try { int count = LuaDLL.lua_gettop(L); if (count == 1) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); ToLua.Destroy(L); UnityEngine.Object.Destroy(arg0); return 0; } else if (count == 2) { float arg1 = (float)LuaDLL.luaL_checknumber(L, 2); int udata = LuaDLL.tolua_rawnetobj(L, 1); ObjectTranslator translator = LuaState.GetTranslator(L); translator.DelayDestroy(udata, arg1); return 0; } else { return LuaDLL.luaL_throw(L, ""invalid arguments to method: Object.Destroy""); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string DestroyImmediateDefined = @" try { int count = LuaDLL.lua_gettop(L); if (count == 1) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); ToLua.Destroy(L); UnityEngine.Object.DestroyImmediate(arg0); return 0; } else if (count == 2) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); bool arg1 = LuaDLL.luaL_checkboolean(L, 2); ToLua.Destroy(L); UnityEngine.Object.DestroyImmediate(arg0, arg1); return 0; } else { return LuaDLL.luaL_throw(L, ""invalid arguments to method: Object.DestroyImmediate""); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); }"; public static string InstantiateDefined = @" IntPtr L0 = LuaException.L; try { ++LuaException.InstantiateCount; LuaException.L = L; int count = LuaDLL.lua_gettop(L); if (count == 1) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #if UNITY_5_4_OR_NEWER else if (count == 2) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Transform arg1 = (UnityEngine.Transform)ToLua.CheckObject(L, 2); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #endif else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Vector3 arg1 = ToLua.ToVector3(L, 2); UnityEngine.Quaternion arg2 = ToLua.ToQuaternion(L, 3); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1, arg2); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #if UNITY_5_4_OR_NEWER else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Transform arg1 = (UnityEngine.Transform)ToLua.ToObject(L, 2); bool arg2 = LuaDLL.lua_toboolean(L, 3); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1, arg2); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } else if (count == 4) { UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.CheckObject(L, 1); UnityEngine.Vector3 arg1 = ToLua.CheckVector3(L, 2); UnityEngine.Quaternion arg2 = ToLua.CheckQuaternion(L, 3); UnityEngine.Transform arg3 = (UnityEngine.Transform)ToLua.CheckObject(L, 4); UnityEngine.Object o = UnityEngine.Object.Instantiate(arg0, arg1, arg2, arg3); if (LuaDLL.lua_toboolean(L, LuaDLL.lua_upvalueindex(1))) { string error = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_pop(L, 1); throw new LuaException(error, LuaException.GetLastError()); } else { ToLua.Push(L, o); } LuaException.L = L0; --LuaException.InstantiateCount; return 1; } #endif else { LuaException.L = L0; --LuaException.InstantiateCount; return LuaDLL.luaL_throw(L, ""invalid arguments to method: UnityEngine.Object.Instantiate""); } } catch (Exception e) { LuaException.L = L0; --LuaException.InstantiateCount; return LuaDLL.toluaL_exception(L, e); }"; [UseDefinedAttribute] public static void Destroy(Object obj) { } [UseDefinedAttribute] public static void DestroyImmediate(Object obj) { } [NoToLuaAttribute] public static void DestroyObject(Object obj) { } [NoToLuaAttribute] public static void DestroyObject(Object obj, float t) { } [UseDefinedAttribute] public static void Instantiate(Object original) { } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_Object.cs.meta ================================================ fileFormatVersion: 2 guid: ed2a77b78fd7258438b2b5a9e881d7c2 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_RectTransform.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; public class ToLua_UnityEngine_RectTransform { public static string GetLocalCornersDefined = @" if (count == 1) { UnityEngine.RectTransform obj = (UnityEngine.RectTransform)ToLua.CheckObject(L, 1, typeof(UnityEngine.RectTransform)); UnityEngine.Vector3[] arg0 = new UnityEngine.Vector3[4]; obj.GetLocalCorners(arg0); ToLua.Push(L, arg0); return 1; }"; public static string GetWorldCornersDefined = @" if (count == 1) { UnityEngine.RectTransform obj = (UnityEngine.RectTransform)ToLua.CheckObject(L, 1, typeof(UnityEngine.RectTransform)); UnityEngine.Vector3[] arg0 = new UnityEngine.Vector3[4]; obj.GetWorldCorners(arg0); ToLua.Push(L, arg0); return 1; }"; [OverrideDefinedAttribute] public Vector3[] GetLocalCorners() { return null; } [OverrideDefinedAttribute] public Vector3[] GetWorldCorners() { return null; } } ================================================ FILE: Assets/ToLua/Editor/Extend/ToLua_UnityEngine_RectTransform.cs.meta ================================================ fileFormatVersion: 2 guid: 2479ef1b120013c478a5f7148251be9e timeCreated: 1501832587 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Editor/Extend.meta ================================================ fileFormatVersion: 2 guid: bdd2718c24fc3014d96c208f87886fe3 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Editor/ToLuaExport.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System; using System.Collections; using System.Text; using System.Reflection; using System.Collections.Generic; using LuaInterface; using Object = UnityEngine.Object; using System.IO; using System.Text.RegularExpressions; using System.Runtime.CompilerServices; public enum MetaOp { None = 0, Add = 1, Sub = 2, Mul = 4, Div = 8, Eq = 16, Neg = 32, ToStr = 64, ALL = Add | Sub | Mul | Div | Eq | Neg | ToStr, } public enum ObjAmbig { None = 0, U3dObj = 1, NetObj = 2, All = 3 } public class DelegateType { public string name; public Type type; public string abr = null; public string strType = ""; public DelegateType(Type t) { type = t; strType = ToLuaExport.GetTypeStr(t); name = ToLuaExport.ConvertToLibSign(strType); } public DelegateType SetAbrName(string str) { abr = str; return this; } } public static class ToLuaExport { public static string className = string.Empty; public static Type type = null; public static Type baseType = null; public static bool isStaticClass = true; static HashSet usingList = new HashSet(); static MetaOp op = MetaOp.None; static StringBuilder sb = null; static List<_MethodBase> methods = new List<_MethodBase>(); static Dictionary nameCounter = new Dictionary(); static FieldInfo[] fields = null; static PropertyInfo[] props = null; static List propList = new List(); //非静态属性 static List allProps = new List(); static EventInfo[] events = null; static List eventList = new List(); static List<_MethodBase> ctorList = new List<_MethodBase>(); static List ctorExtList = new List(); static List<_MethodBase> getItems = new List<_MethodBase>(); //特殊属性 static List<_MethodBase> setItems = new List<_MethodBase>(); static BindingFlags binding = BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase; static ObjAmbig ambig = ObjAmbig.NetObj; //wrapClaaName + "Wrap" = 导出文件名,导出类名 public static string wrapClassName = ""; public static string libClassName = ""; public static string extendName = ""; public static Type extendType = null; public static HashSet eventSet = new HashSet(); public static List extendList = new List(); public static List memberFilter = new List { "String.Chars", "Directory.SetAccessControl", "File.GetAccessControl", "File.SetAccessControl", //UnityEngine "AnimationClip.averageDuration", "AnimationClip.averageAngularSpeed", "AnimationClip.averageSpeed", "AnimationClip.apparentSpeed", "AnimationClip.isLooping", "AnimationClip.isAnimatorMotion", "AnimationClip.isHumanMotion", "AnimatorOverrideController.PerformOverrideClipListCleanup", "AnimatorControllerParameter.name", "Caching.SetNoBackupFlag", "Caching.ResetNoBackupFlag", "Light.areaSize", "Light.lightmappingMode", "Light.lightmapBakeType", "Light.shadowAngle", "Light.shadowRadius", "Light.SetLightDirty", "Security.GetChainOfTrustValue", "Texture2D.alphaIsTransparency", "WWW.movie", "WWW.GetMovieTexture", "WebCamTexture.MarkNonReadable", "WebCamTexture.isReadable", "Graphic.OnRebuildRequested", "Text.OnRebuildRequested", "Resources.LoadAssetAtPath", "Application.ExternalEval", "Handheld.SetActivityIndicatorStyle", "CanvasRenderer.OnRequestRebuild", "CanvasRenderer.onRequestRebuild", "Terrain.bakeLightProbesForTrees", "MonoBehaviour.runInEditMode", "TextureFormat.DXT1Crunched", "TextureFormat.DXT5Crunched", "Texture.imageContentsHash", "QualitySettings.streamingMipmapsMaxLevelReduction", "QualitySettings.streamingMipmapsRenderersPerFrame", //NGUI "UIInput.ProcessEvent", "UIWidget.showHandlesWithMoveTool", "UIWidget.showHandles", "Input.IsJoystickPreconfigured", "UIDrawCall.isActive", "Dictionary.TryAdd", "KeyValuePair.Deconstruct", "ParticleSystem.SetJob", "ParticleSystem.subEmitters", /*2019.09 ios编译出错,也可能是unity版本问题*/ "Type.IsSZArray" }; class _MethodBase { public bool IsStatic { get { return method.IsStatic; } } public bool IsConstructor { get { return method.IsConstructor; } } public string Name { get { return method.Name; } } public MethodBase Method { get { return method; } } public bool IsGenericMethod { get { return method.IsGenericMethod; } } MethodBase method; ParameterInfo[] args; public _MethodBase(MethodBase m, int argCount = -1) { method = m; ParameterInfo[] infos = m.GetParameters(); argCount = argCount != -1 ? argCount : infos.Length; args = new ParameterInfo[argCount]; Array.Copy(infos, args, argCount); } public ParameterInfo[] GetParameters() { return args; } public int GetParamsCount() { int c = method.IsStatic ? 0 : 1; return args.Length + c; } public int GetEqualParamsCount(_MethodBase b) { int count = 0; List list1 = new List(); List list2 = new List(); if (!IsStatic) { list1.Add(type); } if (!b.IsStatic) { list2.Add(type); } for (int i = 0; i < args.Length; i++) { list1.Add(GetParameterType(args[i])); } ParameterInfo[] p = b.args; for (int i = 0; i < p.Length; i++) { list2.Add(GetParameterType(p[i])); } for (int i = 0; i < list1.Count; i++) { if (list1[i] != list2[i]) { break; } ++count; } return count; } public string GenParamTypes(int offset = 0) { StringBuilder sb = new StringBuilder(); List list = new List(); if (!method.IsStatic) { list.Add(type); } for (int i = 0; i < args.Length; i++) { if (IsParams(args[i])) { continue; } if (args[i].ParameterType.IsByRef && (args[i].Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { Type genericClass = typeof(LuaOut<>); Type t = genericClass.MakeGenericType(args[i].ParameterType.GetElementType()); list.Add(t); } else { list.Add(GetGenericBaseType(method, args[i].ParameterType)); } } for (int i = offset; i < list.Count - 1; i++) { sb.Append(GetTypeOf(list[i], ", ")); } if (list.Count > 0) { sb.Append(GetTypeOf(list[list.Count - 1], "")); } return sb.ToString(); } public bool HasSetIndex() { if (method.Name == "set_Item") { return true; } object[] attrs = type.GetCustomAttributes(true); for (int i = 0; i < attrs.Length; i++) { if (attrs[i] is DefaultMemberAttribute) { return method.Name == "set_ItemOf"; } } return false; } public bool HasGetIndex() { if (method.Name == "get_Item") { return true; } object[] attrs = type.GetCustomAttributes(true); for (int i = 0; i < attrs.Length; i++) { if (attrs[i] is DefaultMemberAttribute) { return method.Name == "get_ItemOf"; } } return false; } public Type GetReturnType() { MethodInfo m = method as MethodInfo; if (m != null) { return m.ReturnType; } return null; } public string GetTotalName() { string[] ss = new string[args.Length]; for (int i = 0; i < args.Length; i++) { ss[i] = GetTypeStr(args[i].GetType()); } if (!ToLuaExport.IsGenericMethod(method)) { return Name + "(" + string.Join(",", ss) + ")"; } else { Type[] gts = method.GetGenericArguments(); string[] ts = new string[gts.Length]; for (int i = 0; i < gts.Length; i++) { ts[i] = GetTypeStr(gts[i]); } return Name + "<" + string.Join(",", ts) + ">" + "(" + string.Join(",", ss) + ")"; } } public bool BeExtend = false; public int ProcessParams(int tab, bool beConstruct, int checkTypePos) { ParameterInfo[] paramInfos = args; if (BeExtend) { ParameterInfo[] pt = new ParameterInfo[paramInfos.Length - 1]; Array.Copy(paramInfos, 1, pt, 0, pt.Length); paramInfos = pt; } int count = paramInfos.Length; string head = string.Empty; PropertyInfo pi = null; int methodType = GetMethodType(method, out pi); int offset = ((method.IsStatic && !BeExtend) || beConstruct) ? 1 : 2; if (method.Name == "op_Equality") { checkTypePos = -1; } for (int i = 0; i < tab; i++) { head += "\t"; } if ((!method.IsStatic && !beConstruct) || BeExtend) { if (checkTypePos > 0) { CheckObject(head, type, className, 1); } else { if (method.Name == "Equals") { if (!type.IsValueType && checkTypePos > 0) { CheckObject(head, type, className, 1); } else { sb.AppendFormat("{0}{1} obj = ({1})ToLua.ToObject(L, 1);\r\n", head, className); } } else if (checkTypePos > 0)// && methodType == 0) { CheckObject(head, type, className, 1); } else { ToObject(head, type, className, 1); } } } StringBuilder sbArgs = new StringBuilder(); List refList = new List(); List refTypes = new List(); checkTypePos = checkTypePos - offset + 1; for (int j = 0; j < count; j++) { ParameterInfo param = paramInfos[j]; string arg = "arg" + j; bool beOutArg = param.ParameterType.IsByRef && ((param.Attributes & ParameterAttributes.Out) != ParameterAttributes.None); bool beParams = IsParams(param); Type t = GetGenericBaseType(method, param.ParameterType); ProcessArg(t, head, arg, offset + j, j >= checkTypePos, beParams, beOutArg); } for (int j = 0; j < count; j++) { ParameterInfo param = paramInfos[j]; if (!param.ParameterType.IsByRef) { sbArgs.Append("arg"); } else { if ((param.Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { sbArgs.Append("out arg"); } else { sbArgs.Append("ref arg"); } refList.Add("arg" + j); refTypes.Add(GetRefBaseType(param.ParameterType)); } sbArgs.Append(j); if (j != count - 1) { sbArgs.Append(", "); } } if (beConstruct) { sb.AppendFormat("{2}{0} obj = new {0}({1});\r\n", className, sbArgs.ToString(), head); string str = GetPushFunction(type); sb.AppendFormat("{0}ToLua.{1}(L, obj);\r\n", head, str); for (int i = 0; i < refList.Count; i++) { GenPushStr(refTypes[i], refList[i], head); } return refList.Count + 1; } string obj = (method.IsStatic && !BeExtend) ? className : "obj"; Type retType = GetReturnType(); if (retType == typeof(void)) { if (HasSetIndex()) { if (methodType == 2) { string str = sbArgs.ToString(); string[] ss = str.Split(','); str = string.Join(",", ss, 0, ss.Length - 1); sb.AppendFormat("{0}{1}[{2}] ={3};\r\n", head, obj, str, ss[ss.Length - 1]); } else if (methodType == 1) { sb.AppendFormat("{0}{1}.Item = arg0;\r\n", head, obj, pi.Name); } else { sb.AppendFormat("{0}{1}.{2}({3});\r\n", head, obj, method.Name, sbArgs.ToString()); } } else if (methodType == 1) { sb.AppendFormat("{0}{1}.{2} = arg0;\r\n", head, obj, pi.Name); } else { sb.AppendFormat("{3}{0}.{1}({2});\r\n", obj, method.Name, sbArgs.ToString(), head); } } else { Type genericType = GetGenericBaseType(method, retType); string ret = GetTypeStr(genericType); if (method.Name.StartsWith("op_")) { CallOpFunction(method.Name, tab, ret); } else if (HasGetIndex()) { if (methodType == 2) { sb.AppendFormat("{0}{1} o = {2}[{3}];\r\n", head, ret, obj, sbArgs.ToString()); } else if (methodType == 1) { sb.AppendFormat("{0}{1} o = {2}.Item;\r\n", head, ret, obj); } else { sb.AppendFormat("{0}{1} o = {2}.{3}({4});\r\n", head, ret, obj, method.Name, sbArgs.ToString()); } } else if (method.Name == "Equals") { if (type.IsValueType || method.GetParameters().Length > 1) { sb.AppendFormat("{0}{1} o = obj.Equals({2});\r\n", head, ret, sbArgs.ToString()); } else { sb.AppendFormat("{0}{1} o = obj != null ? obj.Equals({2}) : arg0 == null;\r\n", head, ret, sbArgs.ToString()); } } else if (methodType == 1) { sb.AppendFormat("{0}{1} o = {2}.{3};\r\n", head, ret, obj, pi.Name); } else { sb.AppendFormat("{0}{1} o = {2}.{3}({4});\r\n", head, ret, obj, method.Name, sbArgs.ToString()); } bool isbuffer = IsByteBuffer(); GenPushStr(retType, "o", head, isbuffer); } for (int i = 0; i < refList.Count; i++) { if (refTypes[i] == typeof(RaycastHit) && method.Name == "Raycast" && (type == typeof(Physics) || type == typeof(Collider))) { sb.AppendFormat("{0}if (o) ToLua.Push(L, {1}); else LuaDLL.lua_pushnil(L);\r\n", head, refList[i]); } else { GenPushStr(refTypes[i], refList[i], head); } } if (!method.IsStatic && type.IsValueType && method.Name != "ToString") { sb.Append(head + "ToLua.SetBack(L, 1, obj);\r\n"); } return refList.Count; } bool IsByteBuffer() { object[] attrs = method.GetCustomAttributes(true); for (int j = 0; j < attrs.Length; j++) { Type t = attrs[j].GetType(); if (t == typeof(LuaByteBufferAttribute)) { return true; } } return false; } } public static List memberInfoFilter = new List { //可精确查找一个函数 //Type.GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers); }; public static bool IsMemberFilter(MemberInfo mi) { if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); if (genericType == typeof(Dictionary<,>) && mi.Name == "Remove") { MethodBase mb = (MethodBase)mi; return mb.GetParameters().Length == 2; } if (genericType == typeof(Dictionary<,>) || genericType == typeof(KeyValuePair<,>)) { string str = genericType.Name; str = str.Substring(0, str.IndexOf("`")); return memberFilter.Contains(str + "." + mi.Name); } } return memberInfoFilter.Contains(mi) || memberFilter.Contains(type.Name + "." + mi.Name); } public static bool IsMemberFilter(Type t) { string name = LuaMisc.GetTypeName(t); return memberInfoFilter.Contains(t) || memberFilter.Find((p) => { return name.Contains(p); }) != null; } static ToLuaExport() { Debugger.useLog = true; } public static void Clear() { className = null; type = null; baseType = null; isStaticClass = false; usingList.Clear(); op = MetaOp.None; sb = new StringBuilder(); fields = null; props = null; methods.Clear(); allProps.Clear(); propList.Clear(); eventList.Clear(); ctorList.Clear(); ctorExtList.Clear(); ambig = ObjAmbig.NetObj; wrapClassName = ""; libClassName = ""; extendName = ""; eventSet.Clear(); extendType = null; nameCounter.Clear(); events = null; getItems.Clear(); setItems.Clear(); } private static MetaOp GetOp(string name) { if (name == "op_Addition") { return MetaOp.Add; } else if (name == "op_Subtraction") { return MetaOp.Sub; } else if (name == "op_Equality") { return MetaOp.Eq; } else if (name == "op_Multiply") { return MetaOp.Mul; } else if (name == "op_Division") { return MetaOp.Div; } else if (name == "op_UnaryNegation") { return MetaOp.Neg; } else if (name == "ToString" && !isStaticClass) { return MetaOp.ToStr; } return MetaOp.None; } //操作符函数无法通过继承metatable实现 static void GenBaseOpFunction(List<_MethodBase> list) { Type baseType = type.BaseType; while (baseType != null) { if (allTypes.IndexOf(baseType) >= 0) { MethodInfo[] methods = baseType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase); for (int i = 0; i < methods.Length; i++) { MetaOp baseOp = GetOp(methods[i].Name); if (baseOp != MetaOp.None && (op & baseOp) == 0) { if (baseOp != MetaOp.ToStr) { list.Add(new _MethodBase(methods[i])); } op |= baseOp; } } } baseType = baseType.BaseType; } } public static void Generate(string dir) { #if !EXPORT_INTERFACE Type iterType = typeof(System.Collections.IEnumerator); if (type.IsInterface && type != iterType) { return; } #endif //Debugger.Log("Begin Generate lua Wrap for class {0}", className); sb = new StringBuilder(); usingList.Add("System"); if (wrapClassName == "") { wrapClassName = className; } if (type.IsEnum) { BeginCodeGen(); GenEnum(); EndCodeGen(dir); return; } InitMethods(); InitPropertyList(); InitCtorList(); BeginCodeGen(); GenRegisterFunction(); GenConstructFunction(); GenItemPropertyFunction(); GenFunctions(); //GenToStringFunction(); GenIndexFunc(); GenNewIndexFunc(); GenOutFunction(); GenEventFunctions(); if (type.IsValueType && !type.IsEnum) { GenCSharpLuaValueTypeDefault(); GenCSharpLuaValueTypeClone(); } EndCodeGen(dir); } //记录所有的导出类型 public static List allTypes = new List(); static bool BeDropMethodType(MethodInfo md) { Type t = md.DeclaringType; if (t == type) { return true; } return allTypes.IndexOf(t) < 0; } //是否为委托类型,没处理废弃 public static bool IsDelegateType(Type t) { if (!typeof(System.MulticastDelegate).IsAssignableFrom(t) || t == typeof(System.MulticastDelegate)) { return false; } if (IsMemberFilter(t)) { return false; } return true; } static void BeginCodeGen() { sb.AppendFormat("public class {0}Wrap\r\n", wrapClassName); sb.AppendLineEx("{"); } static void EndCodeGen(string dir) { sb.AppendLineEx("}\r\n"); SaveFile(dir + wrapClassName + "Wrap.cs"); } static void InitMethods() { bool flag = false; if (baseType != null || isStaticClass) { binding |= BindingFlags.DeclaredOnly; flag = true; } List<_MethodBase> list = new List<_MethodBase>(); MethodInfo[] infos = type.GetMethods(BindingFlags.Instance | binding); for (int i = 0; i < infos.Length; i++) { list.Add(new _MethodBase(infos[i])); } for (int i = list.Count - 1; i >= 0; --i) { //去掉操作符函数 if (list[i].Name.StartsWith("op_") || list[i].Name.StartsWith("add_") || list[i].Name.StartsWith("remove_")) { if (!IsNeedOp(list[i].Name)) { list.RemoveAt(i); } continue; } //扔掉 unity3d 废弃的函数 if (IsObsolete(list[i].Method)) { list.RemoveAt(i); } } PropertyInfo[] ps = type.GetProperties(); for (int i = 0; i < ps.Length; i++) { if (IsObsolete(ps[i])) { list.RemoveAll((p) => { return p.Method == ps[i].GetGetMethod() || p.Method == ps[i].GetSetMethod(); }); } else { MethodInfo md = ps[i].GetGetMethod(); if (md != null) { int index = list.FindIndex((m) => { return m.Method == md; }); if (index >= 0) { if (md.GetParameters().Length == 0) { list.RemoveAt(index); } else if (list[index].HasGetIndex()) { getItems.Add(list[index]); } } } md = ps[i].GetSetMethod(); if (md != null) { int index = list.FindIndex((m) => { return m.Method == md; }); if (index >= 0) { if (md.GetParameters().Length == 1) { list.RemoveAt(index); } else if (list[index].HasSetIndex()) { setItems.Add(list[index]); } } } } } if (flag && !isStaticClass) { List baseList = new List(type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.IgnoreCase)); for (int i = baseList.Count - 1; i >= 0; i--) { if (BeDropMethodType(baseList[i])) { baseList.RemoveAt(i); } } HashSet addList = new HashSet(); for (int i = 0; i < list.Count; i++) { List mds = baseList.FindAll((p) => { return p.Name == list[i].Name; }); for (int j = 0; j < mds.Count; j++) { addList.Add(mds[j]); baseList.Remove(mds[j]); } } foreach(var iter in addList) { list.Add(new _MethodBase(iter)); } } for (int i = 0; i < list.Count; i++) { GetDelegateTypeFromMethodParams(list[i]); } ProcessExtends(list); GenBaseOpFunction(list); for (int i = 0; i < list.Count; i++) { int count = GetDefalutParamCount(list[i].Method); int length = list[i].GetParameters().Length; for (int j = 0; j < count + 1; j++) { _MethodBase r = new _MethodBase(list[i].Method, length - j); r.BeExtend = list[i].BeExtend; methods.Add(r); } } } static void InitPropertyList() { props = type.GetProperties(BindingFlags.GetProperty | BindingFlags.SetProperty | BindingFlags.Instance | binding); propList.AddRange(type.GetProperties(BindingFlags.GetProperty | BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)); fields = type.GetFields(BindingFlags.GetField | BindingFlags.SetField | BindingFlags.Instance | binding); events = type.GetEvents(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static); eventList.AddRange(type.GetEvents(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)); List fieldList = new List(); fieldList.AddRange(fields); for (int i = fieldList.Count - 1; i >= 0; i--) { if (IsObsolete(fieldList[i])) { fieldList.RemoveAt(i); } else if (IsDelegateType(fieldList[i].FieldType)) { eventSet.Add(fieldList[i].FieldType); } } fields = fieldList.ToArray(); List piList = new List(); piList.AddRange(props); for (int i = piList.Count - 1; i >= 0; i--) { if (IsObsolete(piList[i])) { piList.RemoveAt(i); } else if (piList[i].Name == "Item" && IsItemThis(piList[i])) { piList.RemoveAt(i); } else if(piList[i].GetGetMethod() != null && HasGetIndex(piList[i].GetGetMethod())) { piList.RemoveAt(i); } else if (piList[i].GetSetMethod() != null && HasSetIndex(piList[i].GetSetMethod())) { piList.RemoveAt(i); } else if (IsDelegateType(piList[i].PropertyType)) { eventSet.Add(piList[i].PropertyType); } } props = piList.ToArray(); for (int i = propList.Count - 1; i >= 0; i--) { if (IsObsolete(propList[i])) { propList.RemoveAt(i); } } allProps.AddRange(props); allProps.AddRange(propList); List evList = new List(); evList.AddRange(events); for (int i = evList.Count - 1; i >= 0; i--) { if (IsObsolete(evList[i])) { evList.RemoveAt(i); } else if (IsDelegateType(evList[i].EventHandlerType)) { eventSet.Add(evList[i].EventHandlerType); } } events = evList.ToArray(); for (int i = eventList.Count - 1; i >= 0; i--) { if (IsObsolete(eventList[i])) { eventList.RemoveAt(i); } } } static void SaveFile(string file) { using (StreamWriter textWriter = new StreamWriter(file, false, Encoding.UTF8)) { StringBuilder usb = new StringBuilder(); usb.AppendLineEx("//this source code was auto-generated by tolua#, do not modify it"); foreach (string str in usingList) { usb.AppendFormat("using {0};\r\n", str); } usb.AppendLineEx("using LuaInterface;"); if (ambig == ObjAmbig.All) { usb.AppendLineEx("using Object = UnityEngine.Object;"); } usb.AppendLineEx(); textWriter.Write(usb.ToString()); textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } } static string GetMethodName(MethodBase md) { if (md.Name.StartsWith("op_")) { return md.Name; } object[] attrs = md.GetCustomAttributes(true); for (int i = 0; i < attrs.Length; i++) { if (attrs[i] is LuaRenameAttribute) { LuaRenameAttribute attr = attrs[i] as LuaRenameAttribute; return attr.Name; } } return md.Name; } static bool HasGetIndex(MemberInfo md) { if (md.Name == "get_Item") { return true; } object[] attrs = type.GetCustomAttributes(true); for (int i = 0; i < attrs.Length; i++) { if (attrs[i] is DefaultMemberAttribute) { return md.Name == "get_ItemOf"; } } return false; } static bool HasSetIndex(MemberInfo md) { if (md.Name == "set_Item") { return true; } object[] attrs = type.GetCustomAttributes(true); for (int i = 0; i < attrs.Length; i++) { if (attrs[i] is DefaultMemberAttribute) { return md.Name == "set_ItemOf"; } } return false; } static bool IsThisArray(MethodBase md, int count) { ParameterInfo[] pis = md.GetParameters(); if (pis.Length != count) { return false; } if (pis[0].ParameterType == typeof(int)) { return true; } return false; } static void GenRegisterFuncItems() { //bool isList = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>); //注册库函数 for (int i = 0; i < methods.Count; i++) { _MethodBase m = methods[i]; int count = 1; if (IsGenericMethod(m.Method)) { continue; } string name = GetMethodName(m.Method); if (!nameCounter.TryGetValue(name, out count)) { if (name == "get_Item" && IsThisArray(m.Method, 1)) { sb.AppendFormat("\t\tL.RegFunction(\"{0}\", get_Item);\r\n", ".geti"); sb.AppendFormat("\t\tL.RegFunction(\"{0}\", get_Item);\r\n", "get"); } else if (name == "set_Item" && IsThisArray(m.Method, 2)) { sb.AppendFormat("\t\tL.RegFunction(\"{0}\", set_Item);\r\n", ".seti"); sb.AppendFormat("\t\tL.RegFunction(\"{0}\", get_Item);\r\n", "set"); } if (!name.StartsWith("op_")) { sb.AppendFormat("\t\tL.RegFunction(\"{0}\", {1});\r\n", name, name == "Register" ? "_Register" : name); if (m.Method.IsSpecialName) { GenCSharpLuaGetOrSet(m, name); } } nameCounter[name] = 1; } else { nameCounter[name] = count + 1; } } if (ctorList.Count > 0 || type.IsValueType || ctorExtList.Count > 0) { sb.AppendFormat("\t\tL.RegFunction(\"New\", _Create{0});\r\n", wrapClassName); } if (getItems.Count > 0 || setItems.Count > 0) { sb.AppendLineEx("\t\tL.RegVar(\"this\", _this, null);"); } } static void GenRegisterOpItems() { if ((op & MetaOp.Add) != 0) { sb.AppendLineEx("\t\tL.RegFunction(\"__add\", op_Addition);"); } if ((op & MetaOp.Sub) != 0) { sb.AppendLineEx("\t\tL.RegFunction(\"__sub\", op_Subtraction);"); } if ((op & MetaOp.Mul) != 0) { sb.AppendLineEx("\t\tL.RegFunction(\"__mul\", op_Multiply);"); } if ((op & MetaOp.Div) != 0) { sb.AppendLineEx("\t\tL.RegFunction(\"__div\", op_Division);"); } if ((op & MetaOp.Eq) != 0) { sb.AppendLineEx("\t\tL.RegFunction(\"__eq\", op_Equality);"); } if ((op & MetaOp.Neg) != 0) { sb.AppendLineEx("\t\tL.RegFunction(\"__unm\", op_UnaryNegation);"); } if ((op & MetaOp.ToStr) != 0) { sb.AppendLineEx("\t\tL.RegFunction(\"__tostring\", ToLua.op_ToString);"); } } static bool IsItemThis(PropertyInfo info) { MethodInfo md = info.GetGetMethod(); if (md != null) { return md.GetParameters().Length != 0; } md = info.GetSetMethod(); if (md != null) { return md.GetParameters().Length != 1; } return true; } static void GenRegisterVariables() { if (fields.Length == 0 && props.Length == 0 && events.Length == 0 && isStaticClass && baseType == null) { return; } for (int i = 0; i < fields.Length; i++) { if (fields[i].IsLiteral || fields[i].IsPrivate || fields[i].IsInitOnly) { if (fields[i].IsLiteral && fields[i].FieldType.IsPrimitive && !fields[i].FieldType.IsEnum) { double d = Convert.ToDouble(fields[i].GetValue(null)); sb.AppendFormat("\t\tL.RegConstant(\"{0}\", {1});\r\n", fields[i].Name, d); } else { sb.AppendFormat("\t\tL.RegVar(\"{0}\", get_{0}, null);\r\n", fields[i].Name); } } else { sb.AppendFormat("\t\tL.RegVar(\"{0}\", get_{0}, set_{0});\r\n", fields[i].Name); } } for (int i = 0; i < props.Length; i++) { if (props[i].CanRead && props[i].CanWrite && props[i].GetSetMethod(true).IsPublic) { _MethodBase md = methods.Find((p) => { return p.Name == "get_" + props[i].Name; }); string get = md == null ? "get" : "_get"; md = methods.Find((p) => { return p.Name == "set_" + props[i].Name; }); string set = md == null ? "set" : "_set"; sb.AppendFormat("\t\tL.RegVar(\"{0}\", {1}_{0}, {2}_{0});\r\n", props[i].Name, get, set); sb.AppendFormat("\t\tL.RegFunction(\"get{0}\", {1}_{0});\r\n", props[i].Name, get); if(props[i].GetSetMethod().IsStatic) sb.AppendFormat("\t\tL.RegFunction(\"set{0}\", {1}_{0}ter);\r\n", props[i].Name, set); else sb.AppendFormat("\t\tL.RegFunction(\"set{0}\", {1}_{0});\r\n", props[i].Name, set); } else if (props[i].CanRead) { _MethodBase md = methods.Find((p) => { return p.Name == "get_" + props[i].Name; }); sb.AppendFormat("\t\tL.RegVar(\"{0}\", {1}_{0}, null);\r\n", props[i].Name, md == null ? "get" : "_get"); sb.AppendFormat("\t\tL.RegFunction(\"get{0}\", {1}_{0});\r\n", props[i].Name, md == null ? "get" : "_get"); } else if (props[i].CanWrite) { _MethodBase md = methods.Find((p) => { return p.Name == "set_" + props[i].Name; }); sb.AppendFormat("\t\tL.RegVar(\"{0}\", null, {1}_{0});\r\n", props[i].Name, md == null ? "set" : "_set"); if (props[i].GetSetMethod().IsStatic) sb.AppendFormat("\t\tL.RegFunction(\"set{0}\", {1}_{0}ter);\r\n", props[i].Name, md == null ? "set" : "_set"); else sb.AppendFormat("\t\tL.RegFunction(\"set{0}\", {1}_{0});\r\n", props[i].Name, md == null ? "set" : "_set"); } } for (int i = 0; i < events.Length; i++) { sb.AppendFormat("\t\tL.RegVar(\"{0}\", get_{0}, set_{0});\r\n", events[i].Name); sb.AppendFormat("\t\tL.RegFunction(\"add{0}\", add{0});\r\n", events[i].Name); sb.AppendFormat("\t\tL.RegFunction(\"remove{0}\", remove{0});\r\n", events[i].Name); } } static void GenRegisterEventTypes() { List list = new List(); foreach (Type t in eventSet) { string funcName = null; string space = GetNameSpace(t, out funcName); if (space != className) { list.Add(t); continue; } funcName = ConvertToLibSign(funcName); int index = Array.FindIndex(CustomSettings.customDelegateList, (p) => { return p.type == t; }); string abr = null; if (index >= 0) abr = CustomSettings.customDelegateList[index].abr; abr = abr == null ? funcName : abr; funcName = ConvertToLibSign(space) + "_" + funcName; sb.AppendFormat("\t\tL.RegFunction(\"{0}\", {1});\r\n", abr, funcName); } for (int i = 0; i < list.Count; i++) { eventSet.Remove(list[i]); } } static void GenRegisterFunction() { sb.AppendLineEx("\tpublic static void Register(LuaState L)"); sb.AppendLineEx("\t{"); if (isStaticClass) { sb.AppendFormat("\t\tL.BeginStaticLibs(\"{0}\");\r\n", libClassName); } else if (!type.IsGenericType) { if (baseType == null) { sb.AppendFormat("\t\tL.BeginClass(typeof({0}), null);\r\n", className); } else { sb.AppendFormat("\t\tL.BeginClass(typeof({0}), typeof({1}));\r\n", className, GetBaseTypeStr(baseType)); } } else { if (baseType == null) { sb.AppendFormat("\t\tL.BeginClass(typeof({0}), null, \"{1}\");\r\n", className, libClassName); } else { sb.AppendFormat("\t\tL.BeginClass(typeof({0}), typeof({1}), \"{2}\");\r\n", className, GetBaseTypeStr(baseType), libClassName); } } GenRegisterFuncItems(); GenRegisterOpItems(); GenRegisterVariables(); GenRegisterEventTypes(); //注册事件类型 if (type.IsValueType && !type.IsEnum) { sb.Append("\t\tL.RegFunction(\"default\", __default__);\r\n"); sb.Append("\t\tL.RegFunction(\"__clone__\", __clone__);\r\n"); } if (!isStaticClass) { if (CustomSettings.outList.IndexOf(type) >= 0) { sb.AppendLineEx("\t\tL.RegVar(\"out\", get_out, null);"); } sb.AppendFormat("\t\tL.EndClass();\r\n"); } else { sb.AppendFormat("\t\tL.EndStaticLibs();\r\n"); } sb.AppendLineEx("\t}"); } static bool IsParams(ParameterInfo param) { return param.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; } static void GenFunction(_MethodBase m) { string name = GetMethodName(m.Method); sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int {0}(IntPtr L)\r\n", name == "Register" ? "_Register" : name); sb.AppendLineEx("\t{"); if (HasAttribute(m.Method, typeof(UseDefinedAttribute))) { FieldInfo field = extendType.GetField(name + "Defined"); string strfun = field.GetValue(null) as string; sb.AppendLineEx(strfun); sb.AppendLineEx("\t}"); return; } ParameterInfo[] paramInfos = m.GetParameters(); int offset = m.IsStatic ? 0 : 1; bool haveParams = HasOptionalParam(paramInfos); int rc = m.GetReturnType() == typeof(void) ? 0 : 1; BeginTry(); if (!haveParams) { int count = paramInfos.Length + offset; if (m.Name == "op_UnaryNegation") count = 2; sb.AppendFormat("\t\t\tToLua.CheckArgsCount(L, {0});\r\n", count); } else { sb.AppendLineEx("\t\t\tint count = LuaDLL.lua_gettop(L);"); } rc += m.ProcessParams(3, false, int.MaxValue); sb.AppendFormat("\t\t\treturn {0};\r\n", rc); EndTry(); sb.AppendLineEx("\t}"); } //没有未知类型的模版类型List 返回false, List返回true static bool IsGenericConstraintType(Type t) { if (!t.IsGenericType) { return t.IsGenericParameter || t == typeof(System.ValueType); } Type[] types = t.GetGenericArguments(); for (int i = 0; i < types.Length; i++) { Type t1 = types[i]; if (t1.IsGenericParameter || t1 == typeof(System.ValueType)) { return true; } if (IsGenericConstraintType(t1)) { return true; } } return false; } static bool IsGenericConstraints(Type[] constraints) { for (int i = 0; i < constraints.Length; i++) { if (!IsGenericConstraintType(constraints[i])) { return false; } } return true; } static bool IsGenericMethod(MethodBase md) { if (md.IsGenericMethod) { Type[] gts = md.GetGenericArguments(); List list = new List(md.GetParameters()); for (int i = 0; i < gts.Length; i++) { Type[] ts = gts[i].GetGenericParameterConstraints(); if (ts == null || ts.Length == 0 || IsGenericConstraints(ts)) { return true; } ParameterInfo p = list.Find((iter) => { return iter.ParameterType == gts[i]; }); if (p == null) { return true; } list.RemoveAll((iter) => { return iter.ParameterType == gts[i]; }); } for (int i = 0; i < list.Count; i++) { Type t = list[i].ParameterType; if (IsGenericConstraintType(t)) { return true; } } } return false; } static void GenFunctions() { HashSet set = new HashSet(); for (int i = 0; i < methods.Count; i++) { _MethodBase m = methods[i]; if (IsGenericMethod(m.Method)) { Debugger.Log("Generic Method {0}.{1} cannot be export to lua", LuaMisc.GetTypeName(type), m.GetTotalName()); continue; } string name = GetMethodName(m.Method); if (nameCounter[name] > 1) { if (!set.Contains(name)) { _MethodBase mi = GenOverrideFunc(name); if (mi == null) { set.Add(name); continue; } else { m = mi; //非重载函数,或者折叠之后只有一个函数 } } else { continue; } } set.Add(name); GenFunction(m); } } static bool IsSealedType(Type t) { if (t.IsSealed || CustomSettings.sealedList.Contains(t)) { return true; } if (t.IsGenericType && (t.GetGenericTypeDefinition() == typeof(List<>) || t.GetGenericTypeDefinition() == typeof(Dictionary<,>))) { return true; } return false; } static bool IsIEnumerator(Type t) { if (t == typeof(IEnumerator) || t == typeof(CharEnumerator)) return true; if (typeof(IEnumerator).IsAssignableFrom(t)) { if (t.IsGenericType) { Type gt = t.GetGenericTypeDefinition(); if (gt == typeof(List<>.Enumerator) || gt == typeof(Dictionary<,>.Enumerator)) { return true; } } } return false; } static string GetPushFunction(Type t, bool isByteBuffer = false) { if (t.IsEnum || t.IsPrimitive || t == typeof(string) || t == typeof(LuaTable) || t == typeof(LuaCSFunction) || t == typeof(LuaThread) || t == typeof(LuaFunction) || t == typeof(Type) || t == typeof(IntPtr) || typeof(Delegate).IsAssignableFrom(t) || t == typeof(LuaByteBuffer) // || t == typeof(LuaInteger64) || t == typeof(Vector3) || t == typeof(Vector2) || t == typeof(Vector4) || t == typeof(Quaternion) || t == typeof(Color) || t == typeof(RaycastHit) || t == typeof(Ray) || t == typeof(Touch) || t == typeof(Bounds) || t == typeof(object)) { return "Push"; } else if (t.IsArray || t == typeof(System.Array)) { return "Push"; } else if (IsIEnumerator(t)) { return "Push"; } else if (t == typeof(LayerMask)) { return "PushLayerMask"; } else if (typeof(UnityEngine.Object).IsAssignableFrom(t) || typeof(UnityEngine.TrackedReference).IsAssignableFrom(t)) { return IsSealedType(t) ? "PushSealed" : "Push"; } else if (t.IsValueType) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) { return "PusNullable"; } return "PushValue"; } else if (IsSealedType(t)) { return "PushSealed"; } return "PushObject"; } static void DefaultConstruct() { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int _Create{0}(IntPtr L)\r\n", wrapClassName); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\t{0} obj = new {0}();\r\n", className); GenPushStr(type, "obj", "\t\t"); sb.AppendLineEx("\t\treturn 1;"); sb.AppendLineEx("\t}"); } static string GetCountStr(int count) { if (count != 0) { return string.Format("count - {0}", count); } return "count"; } static void GenOutFunction() { if (isStaticClass || CustomSettings.outList.IndexOf(type) < 0) { return; } sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendLineEx("\tstatic int get_out(IntPtr L)"); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\tToLua.PushOut<{0}>(L, new LuaOut<{0}>());\r\n", className); sb.AppendLineEx("\t\treturn 1;"); sb.AppendLineEx("\t}"); } static int GetDefalutParamCount(MethodBase md) { int count = 0; ParameterInfo[] infos = md.GetParameters(); for (int i = 0; i < infos.Length; i++) { if (!(infos[i].DefaultValue is DBNull)) { ++count; } } return count; } static void InitCtorList() { if (isStaticClass || type.IsAbstract || typeof(MonoBehaviour).IsAssignableFrom(type)) { return; } ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Instance | binding); if (extendType != null) { ConstructorInfo[] ctorExtends = extendType.GetConstructors(BindingFlags.Instance | binding); if (HasAttribute(ctorExtends[0], typeof(UseDefinedAttribute))) { ctorExtList.AddRange(ctorExtends); } } if (constructors.Length == 0) { return; } bool isGenericType = type.IsGenericType; Type genericType = isGenericType ? type.GetGenericTypeDefinition() : null; Type dictType = typeof(Dictionary<,>); for (int i = 0; i < constructors.Length; i++) { if (IsObsolete(constructors[i])) { continue; } int count = GetDefalutParamCount(constructors[i]); int length = constructors[i].GetParameters().Length; if (genericType == dictType && length >= 1) { Type pt = constructors[i].GetParameters()[0].ParameterType; if (pt.IsGenericType && pt.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IEnumerable<>)) { continue; } } for (int j = 0; j < count + 1; j++) { _MethodBase r = new _MethodBase(constructors[i], length - j); int index = ctorList.FindIndex((p) => { return CompareMethod(p, r) >= 0; }); if (index >= 0) { if (CompareMethod(ctorList[index], r) == 2) { ctorList.RemoveAt(index); ctorList.Add(r); } } else { ctorList.Add(r); } } } } static void GenConstructFunction() { if (ctorExtList.Count > 0) { if (HasAttribute(ctorExtList[0], typeof(UseDefinedAttribute))) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int _Create{0}(IntPtr L)\r\n", wrapClassName); sb.AppendLineEx("\t{"); FieldInfo field = extendType.GetField(extendName + "Defined"); string strfun = field.GetValue(null) as string; sb.AppendLineEx(strfun); sb.AppendLineEx("\t}"); return; } } if (ctorList.Count == 0) { if (type.IsValueType) { DefaultConstruct(); } return; } ctorList.Sort(Compare); int[] checkTypeMap = CheckCheckTypePos(ctorList); sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int _Create{0}(IntPtr L)\r\n", wrapClassName); sb.AppendLineEx("\t{"); BeginTry(); sb.AppendLineEx("\t\t\tint count = LuaDLL.lua_gettop(L);"); sb.AppendLineEx(); _MethodBase md = ctorList[0]; bool hasEmptyCon = ctorList[0].GetParameters().Length == 0 ? true : false; //处理重载构造函数 if (HasOptionalParam(md.GetParameters())) { ParameterInfo[] paramInfos = md.GetParameters(); ParameterInfo param = paramInfos[paramInfos.Length - 1]; string str = GetTypeStr(param.ParameterType.GetElementType()); if (paramInfos.Length > 1) { string strParams = md.GenParamTypes(1); sb.AppendFormat("\t\t\tif (TypeChecker.CheckTypes<{0}>(L, 1) && TypeChecker.CheckParamsType<{1}>(L, {2}, {3}))\r\n", strParams, str, paramInfos.Length, GetCountStr(paramInfos.Length - 1)); } else { sb.AppendFormat("\t\t\tif (TypeChecker.CheckParamsType<{0}>(L, {1}, {2}))\r\n", str, paramInfos.Length, GetCountStr(paramInfos.Length - 1)); } } else { ParameterInfo[] paramInfos = md.GetParameters(); if (ctorList.Count == 1 || paramInfos.Length == 0 || paramInfos.Length + 1 <= checkTypeMap[0]) { sb.AppendFormat("\t\t\tif (count == {0})\r\n", paramInfos.Length); } else { string strParams = md.GenParamTypes(checkTypeMap[0]); sb.AppendFormat("\t\t\tif (count == {0} && TypeChecker.CheckTypes<{1}>(L, {2}))\r\n", paramInfos.Length, strParams, checkTypeMap[0]); } } sb.AppendLineEx("\t\t\t{"); int rc = md.ProcessParams(4, true, checkTypeMap[0] - 1); sb.AppendFormat("\t\t\t\treturn {0};\r\n", rc); sb.AppendLineEx("\t\t\t}"); for (int i = 1; i < ctorList.Count; i++) { hasEmptyCon = ctorList[i].GetParameters().Length == 0 ? true : hasEmptyCon; md = ctorList[i]; ParameterInfo[] paramInfos = md.GetParameters(); if (!HasOptionalParam(md.GetParameters())) { string strParams = md.GenParamTypes(checkTypeMap[i]); if (paramInfos.Length + 1 > checkTypeMap[i]) { sb.AppendFormat("\t\t\telse if (count == {0} && TypeChecker.CheckTypes<{1}>(L, {2}))\r\n", paramInfos.Length, strParams, checkTypeMap[i]); } else { sb.AppendFormat("\t\t\telse if (count == {0})\r\n", paramInfos.Length); } } else { ParameterInfo param = paramInfos[paramInfos.Length - 1]; string str = GetTypeStr(param.ParameterType.GetElementType()); if (paramInfos.Length > 1) { string strParams = md.GenParamTypes(1); sb.AppendFormat("\t\t\telse if (TypeChecker.CheckTypes<{0}>(L, 1) && TypeChecker.CheckParamsType<{1}>(L, {2}, {3}))\r\n", strParams, str, paramInfos.Length, GetCountStr(paramInfos.Length - 1)); } else { sb.AppendFormat("\t\t\telse if (TypeChecker.CheckParamsType<{0}>(L, {1}, {2}))\r\n", str, paramInfos.Length, GetCountStr(paramInfos.Length - 1)); } } sb.AppendLineEx("\t\t\t{"); rc = md.ProcessParams(4, true, checkTypeMap[i] - 1); sb.AppendFormat("\t\t\t\treturn {0};\r\n", rc); sb.AppendLineEx("\t\t\t}"); } if (type.IsValueType && !hasEmptyCon) { sb.AppendLineEx("\t\t\telse if (count == 0)"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\t{0} obj = new {0}();\r\n", className); GenPushStr(type, "obj", "\t\t\t\t"); sb.AppendLineEx("\t\t\t\treturn 1;"); sb.AppendLineEx("\t\t\t}"); } sb.AppendLineEx("\t\t\telse"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\treturn LuaDLL.luaL_throw(L, \"invalid arguments to ctor method: {0}.New\");\r\n", className); sb.AppendLineEx("\t\t\t}"); EndTry(); sb.AppendLineEx("\t}"); } //this[] 非静态函数 static void GenItemPropertyFunction() { int flag = 0; if (getItems.Count > 0) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendLineEx("\tstatic int _get_this(IntPtr L)"); sb.AppendLineEx("\t{"); BeginTry(); if (getItems.Count == 1) { _MethodBase m = getItems[0]; int count = m.GetParameters().Length + 1; sb.AppendFormat("\t\t\tToLua.CheckArgsCount(L, {0});\r\n", count); m.ProcessParams(3, false, int.MaxValue); sb.AppendLineEx("\t\t\treturn 1;\r\n"); } else { getItems.Sort(Compare); int[] checkTypeMap = CheckCheckTypePos(getItems); sb.AppendLineEx("\t\t\tint count = LuaDLL.lua_gettop(L);"); sb.AppendLineEx(); for (int i = 0; i < getItems.Count; i++) { GenOverrideFuncBody(getItems[i], i == 0, checkTypeMap[i]); } sb.AppendLineEx("\t\t\telse"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\treturn LuaDLL.luaL_throw(L, \"invalid arguments to operator method: {0}.this\");\r\n", className); sb.AppendLineEx("\t\t\t}"); } EndTry(); sb.AppendLineEx("\t}"); flag |= 1; } if (setItems.Count > 0) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendLineEx("\tstatic int _set_this(IntPtr L)"); sb.AppendLineEx("\t{"); BeginTry(); if (setItems.Count == 1) { _MethodBase m = setItems[0]; int count = m.GetParameters().Length + 1; sb.AppendFormat("\t\t\tToLua.CheckArgsCount(L, {0});\r\n", count); m.ProcessParams(3, false, int.MaxValue); sb.AppendLineEx("\t\t\treturn 0;\r\n"); } else { setItems.Sort(Compare); int[] checkTypeMap = CheckCheckTypePos(setItems); sb.AppendLineEx("\t\t\tint count = LuaDLL.lua_gettop(L);"); sb.AppendLineEx(); for (int i = 0; i < setItems.Count; i++) { GenOverrideFuncBody(setItems[i], i == 0, checkTypeMap[i]); } sb.AppendLineEx("\t\t\telse"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\treturn LuaDLL.luaL_throw(L, \"invalid arguments to operator method: {0}.this\");\r\n", className); sb.AppendLineEx("\t\t\t}"); } EndTry(); sb.AppendLineEx("\t}"); flag |= 2; } if (flag != 0) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendLineEx("\tstatic int _this(IntPtr L)"); sb.AppendLineEx("\t{"); BeginTry(); sb.AppendLineEx("\t\t\tLuaDLL.lua_pushvalue(L, 1);"); sb.AppendFormat("\t\t\tLuaDLL.tolua_bindthis(L, {0}, {1});\r\n", (flag & 1) == 1 ? "_get_this" : "null", (flag & 2) == 2 ? "_set_this" : "null"); sb.AppendLineEx("\t\t\treturn 1;"); EndTry(); sb.AppendLineEx("\t}"); } } static int GetOptionalParamPos(ParameterInfo[] infos) { for (int i = 0; i < infos.Length; i++) { if (IsParams(infos[i])) { return i; } } return -1; } static bool Is64bit(Type t) { return t == typeof(long) || t == typeof(ulong); } static int Compare(_MethodBase lhs, _MethodBase rhs) { int off1 = lhs.IsStatic ? 0 : 1; int off2 = rhs.IsStatic ? 0 : 1; ParameterInfo[] lp = lhs.GetParameters(); ParameterInfo[] rp = rhs.GetParameters(); int pos1 = GetOptionalParamPos(lp); int pos2 = GetOptionalParamPos(rp); if (pos1 >= 0 && pos2 < 0) { return 1; } else if (pos1 < 0 && pos2 >= 0) { return -1; } else if (pos1 >= 0 && pos2 >= 0) { pos1 += off1; pos2 += off2; if (pos1 != pos2) { return pos1 > pos2 ? -1 : 1; } else { pos1 -= off1; pos2 -= off2; if (lp[pos1].ParameterType.GetElementType() == typeof(object) && rp[pos2].ParameterType.GetElementType() != typeof(object)) { return 1; } else if (lp[pos1].ParameterType.GetElementType() != typeof(object) && rp[pos2].ParameterType.GetElementType() == typeof(object)) { return -1; } } } int c1 = off1 + lp.Length; int c2 = off2 + rp.Length; if (c1 > c2) { return 1; } else if (c1 == c2) { List list1 = new List(lp); List list2 = new List(rp); if (list1.Count > list2.Count) { if (list1[0].ParameterType == typeof(object)) { return 1; } else if (list1[0].ParameterType.IsPrimitive) { return -1; } list1.RemoveAt(0); } else if (list2.Count > list1.Count) { if (list2[0].ParameterType == typeof(object)) { return -1; } else if (list2[0].ParameterType.IsPrimitive) { return 1; } list2.RemoveAt(0); } for (int i = 0; i < list1.Count; i++) { if (list1[i].ParameterType == typeof(object) && list2[i].ParameterType != typeof(object)) { return 1; } else if (list1[i].ParameterType != typeof(object) && list2[i].ParameterType == typeof(object)) { return -1; } else if (list1[i].ParameterType.IsPrimitive && !list2[i].ParameterType.IsPrimitive) { return -1; } else if (!list1[i].ParameterType.IsPrimitive && list2[i].ParameterType.IsPrimitive) { return 1; } else if (list1[i].ParameterType.IsPrimitive && list2[i].ParameterType.IsPrimitive) { if (Is64bit(list1[i].ParameterType) && !Is64bit(list2[i].ParameterType)) { return 1; } else if (!Is64bit(list1[i].ParameterType) && Is64bit(list2[i].ParameterType)) { return -1; } else if (Is64bit(list1[i].ParameterType) && Is64bit(list2[i].ParameterType) && list1[i].ParameterType != list2[i].ParameterType) { if (list1[i].ParameterType == typeof(ulong)) { return 1; } return -1; } } } return 0; } else { return -1; } } static bool HasOptionalParam(ParameterInfo[] infos) { for (int i = 0; i < infos.Length; i++) { if (IsParams(infos[i])) { return true; } } return false; } static void CheckObject(string head, Type type, string className, int pos) { if (type == typeof(object)) { sb.AppendFormat("{0}object obj = ToLua.CheckObject(L, {1});\r\n", head, pos); } else if (type == typeof(Type)) { sb.AppendFormat("{0}{1} obj = ToLua.CheckMonoType(L, {2});\r\n", head, className, pos); } else if (IsIEnumerator(type)) { sb.AppendFormat("{0}{1} obj = ToLua.CheckIter(L, {2});\r\n", head, className, pos); } else { if (IsSealedType(type)) { sb.AppendFormat("{0}{1} obj = ({1})ToLua.CheckObject(L, {2}, typeof({1}));\r\n", head, className, pos); } else { sb.AppendFormat("{0}{1} obj = ({1})ToLua.CheckObject<{1}>(L, {2});\r\n", head, className, pos); } } } static void ToObject(string head, Type type, string className, int pos) { if (type == typeof(object)) { sb.AppendFormat("{0}object obj = ToLua.ToObject(L, {1});\r\n", head, pos); } else { sb.AppendFormat("{0}{1} obj = ({1})ToLua.ToObject(L, {2});\r\n", head, className, pos); } } static void BeginTry() { sb.AppendLineEx("\t\ttry"); sb.AppendLineEx("\t\t{"); } static void EndTry() { sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t\tcatch (Exception e)"); sb.AppendLineEx("\t\t{"); sb.AppendLineEx("\t\t\treturn LuaDLL.toluaL_exception(L, e);"); sb.AppendLineEx("\t\t}"); } static Type GetRefBaseType(Type argType) { if (argType.IsByRef) { return argType.GetElementType(); } return argType; } static void ProcessArg(Type varType, string head, string arg, int stackPos, bool beCheckTypes = false, bool beParams = false, bool beOutArg = false) { varType = GetRefBaseType(varType); string str = GetTypeStr(varType); string checkStr = beCheckTypes ? "To" : "Check"; if (beOutArg) { if (varType.IsValueType) { sb.AppendFormat("{0}{1} {2};\r\n", head, str, arg); } else { sb.AppendFormat("{0}{1} {2} = null;\r\n", head, str, arg); } } else if (varType == typeof(bool)) { string chkstr = beCheckTypes ? "lua_toboolean" : "luaL_checkboolean"; sb.AppendFormat("{0}bool {1} = LuaDLL.{2}(L, {3});\r\n", head, arg, chkstr, stackPos); } else if (varType == typeof(string)) { sb.AppendFormat("{0}string {1} = ToLua.{2}String(L, {3});\r\n", head, arg, checkStr, stackPos); } else if (varType == typeof(IntPtr)) { sb.AppendFormat("{0}{1} {2} = ToLua.CheckIntPtr(L, {3});\r\n", head, str, arg, stackPos); } else if (varType == typeof(long)) { string chkstr = beCheckTypes ? "tolua_toint64" : "tolua_checkint64"; sb.AppendFormat("{0}{1} {2} = LuaDLL.{3}(L, {4});\r\n", head, str, arg, chkstr, stackPos); } else if (varType == typeof(ulong)) { string chkstr = beCheckTypes ? "tolua_touint64" : "tolua_checkuint64"; sb.AppendFormat("{0}{1} {2} = LuaDLL.{3}(L, {4});\r\n", head, str, arg, chkstr, stackPos); } else if (varType.IsPrimitive || IsNumberEnum(varType)) { string chkstr = beCheckTypes ? "lua_tonumber" : "luaL_checknumber"; sb.AppendFormat("{0}{1} {2} = ({1})LuaDLL.{3}(L, {4});\r\n", head, str, arg, chkstr, stackPos); } else if (varType == typeof(LuaFunction)) { sb.AppendFormat("{0}LuaFunction {1} = ToLua.{2}LuaFunction(L, {3});\r\n", head, arg, checkStr, stackPos); } else if (varType.IsSubclassOf(typeof(System.MulticastDelegate))) { if (beCheckTypes) { sb.AppendFormat("{0}{1} {2} = ({1})ToLua.ToObject(L, {3});\r\n", head, str, arg, stackPos); } else { sb.AppendFormat("{0}{1} {2} = ({1})ToLua.CheckDelegate<{1}>(L, {3});\r\n", head, str, arg, stackPos); } } else if (varType == typeof(LuaTable)) { sb.AppendFormat("{0}LuaTable {1} = ToLua.{2}LuaTable(L, {3});\r\n", head, arg, checkStr, stackPos); } else if (varType == typeof(Vector2)) { sb.AppendFormat("{0}UnityEngine.Vector2 {1} = ToLua.ToVector2(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(Vector3)) { sb.AppendFormat("{0}UnityEngine.Vector3 {1} = ToLua.ToVector3(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(Vector4)) { sb.AppendFormat("{0}UnityEngine.Vector4 {1} = ToLua.ToVector4(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(Quaternion)) { sb.AppendFormat("{0}UnityEngine.Quaternion {1} = ToLua.ToQuaternion(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(Color)) { sb.AppendFormat("{0}UnityEngine.Color {1} = ToLua.ToColor(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(Ray)) { sb.AppendFormat("{0}UnityEngine.Ray {1} = ToLua.ToRay(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(Bounds)) { sb.AppendFormat("{0}UnityEngine.Bounds {1} = ToLua.ToBounds(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(LayerMask)) { sb.AppendFormat("{0}UnityEngine.LayerMask {1} = ToLua.ToLayerMask(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(object)) { sb.AppendFormat("{0}object {1} = ToLua.ToVarObject(L, {2});\r\n", head, arg, stackPos); } else if (varType == typeof(LuaByteBuffer)) { sb.AppendFormat("{0}LuaByteBuffer {1} = new LuaByteBuffer(ToLua.CheckByteBuffer(L, {2}));\r\n", head, arg, stackPos); } else if (varType == typeof(Type)) { if (beCheckTypes) { sb.AppendFormat("{0}System.Type {1} = (System.Type)ToLua.ToObject(L, {2});\r\n", head, arg, stackPos); } else { sb.AppendFormat("{0}System.Type {1} = ToLua.CheckMonoType(L, {2});\r\n", head, arg, stackPos); } } else if (IsIEnumerator(varType)) { if (beCheckTypes) { sb.AppendFormat("{0}System.Collections.IEnumerator {1} = ToLua.ToIEnumerator(L, {2});\r\n", head, arg, stackPos); } else { sb.AppendFormat("{0}System.Collections.IEnumerator {1} = ToLua.CheckIter(L, {2});\r\n", head, arg, stackPos); } } else if (varType.IsArray && varType.GetArrayRank() == 1) { Type et = varType.GetElementType(); string atstr = GetTypeStr(et); string fname; bool flag = false; //是否模版函数 bool isObject = false; if (et.IsPrimitive) { if (beParams) { if (et == typeof(bool)) { fname = beCheckTypes ? "ToParamsBool" : "CheckParamsBool"; } else if (et == typeof(char)) { //char用的多些,特殊处理一下减少gcalloc fname = beCheckTypes ? "ToParamsChar" : "CheckParamsChar"; } else { flag = true; fname = beCheckTypes ? "ToParamsNumber" : "CheckParamsNumber"; } } else if(et == typeof(char)) { fname = "CheckCharBuffer"; } else if (et == typeof(byte)) { fname = "CheckByteBuffer"; } else if (et == typeof(bool)) { fname = "CheckBoolArray"; } else { fname = beCheckTypes ? "ToNumberArray" : "CheckNumberArray"; flag = true; } } else if (et == typeof(string)) { if (beParams) { fname = beCheckTypes ? "ToParamsString" : "CheckParamsString"; } else { fname = beCheckTypes ? "ToStringArray" : "CheckStringArray"; } } else //if (et == typeof(object)) { flag = true; if (et == typeof(object)) { isObject = true; flag = false; } if (beParams) { fname = (isObject || beCheckTypes) ? "ToParamsObject" : "CheckParamsObject"; } else { if (et.IsValueType) { fname = beCheckTypes ? "ToStructArray" : "CheckStructArray"; } else { fname = beCheckTypes ? "ToObjectArray" : "CheckObjectArray"; } } if (et == typeof(UnityEngine.Object)) { ambig |= ObjAmbig.U3dObj; } } if (flag) { if (beParams) { if (!isObject) { sb.AppendFormat("{0}{1}[] {2} = ToLua.{3}<{1}>(L, {4}, {5});\r\n", head, atstr, arg, fname, stackPos, GetCountStr(stackPos - 1)); } else { sb.AppendFormat("{0}object[] {1} = ToLua.{2}(L, {3}, {4});\r\n", head, arg, fname, stackPos, GetCountStr(stackPos - 1)); } } else { sb.AppendFormat("{0}{1}[] {2} = ToLua.{3}<{1}>(L, {4});\r\n", head, atstr, arg, fname, stackPos); } } else { if (beParams) { sb.AppendFormat("{0}{1}[] {2} = ToLua.{3}(L, {4}, {5});\r\n", head, atstr, arg, fname, stackPos, GetCountStr(stackPos - 1)); } else { sb.AppendFormat("{0}{1}[] {2} = ToLua.{3}(L, {4});\r\n", head, atstr, arg, fname, stackPos); } } } else if (varType.IsGenericType && varType.GetGenericTypeDefinition() == typeof(Nullable<>)) { Type t = TypeChecker.GetNullableType(varType); if (beCheckTypes) { sb.AppendFormat("{0}{1} {2} = ToLua.ToNullable<{3}>(L, {4});\r\n", head, str, arg, GetTypeStr(t), stackPos); } else { sb.AppendFormat("{0}{1} {2} = ToLua.CheckNullable<{3}>(L, {4});\r\n", head, str, arg, GetTypeStr(t), stackPos); } } else if (varType.IsValueType && !varType.IsEnum) { string func = beCheckTypes ? "To" : "Check"; sb.AppendFormat("{0}{1} {2} = StackTraits<{1}>.{3}(L, {4});\r\n", head, str, arg, func, stackPos); } else //从object派生但不是object { if (beCheckTypes) { sb.AppendFormat("{0}{1} {2} = ({1})ToLua.ToObject(L, {3});\r\n", head, str, arg, stackPos); } //else if (varType == typeof(UnityEngine.TrackedReference) || typeof(UnityEngine.TrackedReference).IsAssignableFrom(varType)) //{ // sb.AppendFormat("{3}{0} {1} = ({0})ToLua.CheckTrackedReference(L, {2}, typeof({0}));\r\n", str, arg, stackPos, head); //} //else if (typeof(UnityEngine.Object).IsAssignableFrom(varType)) //{ // sb.AppendFormat("{3}{0} {1} = ({0})ToLua.CheckUnityObject(L, {2}, typeof({0}));\r\n", str, arg, stackPos, head); //} else { if (IsSealedType(varType)) { sb.AppendFormat("{0}{1} {2} = ({1})ToLua.CheckObject(L, {3}, typeof({1}));\r\n", head, str, arg, stackPos); } else { sb.AppendFormat("{0}{1} {2} = ({1})ToLua.CheckObject<{1}>(L, {3});\r\n", head, str, arg, stackPos); } } } } static int GetMethodType(MethodBase md, out PropertyInfo pi) { pi = null; if (!md.IsSpecialName) { return 0; } int methodType = 0; int pos = allProps.FindIndex((p) => { return p.GetGetMethod() == md || p.GetSetMethod() == md; }); if (pos >= 0) { methodType = 1; pi = allProps[pos]; if (md == pi.GetGetMethod()) { if (md.GetParameters().Length > 0) { methodType = 2; } } else if (md == pi.GetSetMethod()) { if (md.GetParameters().Length > 1) { methodType = 2; } } } return methodType; } static Type GetGenericBaseType(MethodBase md, Type t) { if (!md.IsGenericMethod) { return t; } List list = new List(md.GetGenericArguments()); if (list.Contains(t)) { return t.BaseType; } return t; } static bool IsNumberEnum(Type t) { if (t.IsEnum) { return true; } if (t == typeof(BindingFlags)) { return true; } return false; } static void GenPushStr(Type t, string arg, string head, bool isByteBuffer = false) { if (t == typeof(int)) { sb.AppendFormat("{0}LuaDLL.lua_pushinteger(L, {1});\r\n", head, arg); } else if (t == typeof(bool)) { sb.AppendFormat("{0}LuaDLL.lua_pushboolean(L, {1});\r\n", head, arg); } else if (t == typeof(string)) { sb.AppendFormat("{0}LuaDLL.lua_pushstring(L, {1});\r\n", head, arg); } else if (t == typeof(IntPtr)) { sb.AppendFormat("{0}LuaDLL.lua_pushlightuserdata(L, {1});\r\n", head, arg); } else if (t == typeof(long)) { sb.AppendFormat("{0}LuaDLL.tolua_pushint64(L, {1});\r\n", head, arg); } else if (t == typeof(ulong)) { sb.AppendFormat("{0}LuaDLL.tolua_pushuint64(L, {1});\r\n", head, arg); } else if ((t.IsPrimitive)) { sb.AppendFormat("{0}LuaDLL.lua_pushnumber(L, {1});\r\n", head, arg); } else if (t.IsEnum) { sb.AppendFormat("{0}LuaDLL.lua_pushinteger(L, (int){1});\r\n", head, arg); } else { if (isByteBuffer && t == typeof(byte[])) { sb.AppendFormat("{0}LuaDLL.tolua_pushlstring(L, {1}, {1}.Length);\r\n", head, arg); } else { string str = GetPushFunction(t); sb.AppendFormat("{0}ToLua.{1}(L, {2});\r\n", head, str, arg); } } } static bool CompareParmsCount(_MethodBase l, _MethodBase r) { if (l == r) { return false; } int c1 = l.IsStatic ? 0 : 1; int c2 = r.IsStatic ? 0 : 1; c1 += l.GetParameters().Length; c2 += r.GetParameters().Length; return c1 == c2; } //decimal 类型扔掉了 static Dictionary typeSize = new Dictionary() { { typeof(char), 2 }, { typeof(byte), 3 }, { typeof(sbyte), 4 }, { typeof(ushort),5 }, { typeof(short), 6 }, { typeof(uint), 7 }, { typeof(int), 8 }, //{ typeof(ulong), 9 }, //{ typeof(long), 10 }, { typeof(decimal), 11 }, { typeof(float), 12 }, { typeof(double), 13 }, }; //-1 不存在替换, 1 保留左面, 2 保留右面 static int CompareMethod(_MethodBase l, _MethodBase r) { int s = 0; if (!CompareParmsCount(l, r)) { return -1; } else { ParameterInfo[] lp = l.GetParameters(); ParameterInfo[] rp = r.GetParameters(); List ll = new List(); List lr = new List(); if (!l.IsStatic) { ll.Add(type); } if (!r.IsStatic) { lr.Add(type); } for (int i = 0; i < lp.Length; i++) { ll.Add(GetParameterType(lp[i])); } for (int i = 0; i < rp.Length; i++) { lr.Add(GetParameterType(rp[i])); } for (int i = 0; i < ll.Count; i++) { if (!typeSize.ContainsKey(ll[i]) || !typeSize.ContainsKey(lr[i])) { if (ll[i] == lr[i]) { continue; } else { return -1; } } else if (ll[i].IsPrimitive && lr[i].IsPrimitive && s == 0) { s = typeSize[ll[i]] >= typeSize[lr[i]] ? 1 : 2; } else if (ll[i] != lr[i] && !ll[i].IsPrimitive && !lr[i].IsPrimitive) { return -1; } } if (s == 0 && l.IsStatic) { s = 2; } } return s; } static void Push(List<_MethodBase> list, _MethodBase r) { string name = GetMethodName(r.Method); int index = list.FindIndex((p) => { return GetMethodName(p.Method) == name && CompareMethod(p, r) >= 0; }); if (index >= 0) { if (CompareMethod(list[index], r) == 2) { Debugger.LogWarning("{0}.{1} has been dropped as function {2} more match lua", className, list[index].GetTotalName(), r.GetTotalName()); list.RemoveAt(index); list.Add(r); return; } else { Debugger.LogWarning("{0}.{1} has been dropped as function {2} more match lua", className, r.GetTotalName(), list[index].GetTotalName()); return; } } list.Add(r); } static void GenOverrideFuncBody(_MethodBase md, bool beIf, int checkTypeOffset) { int offset = md.IsStatic ? 0 : 1; int ret = md.GetReturnType() == typeof(void) ? 0 : 1; string strIf = beIf ? "if " : "else if "; if (HasOptionalParam(md.GetParameters())) { ParameterInfo[] paramInfos = md.GetParameters(); ParameterInfo param = paramInfos[paramInfos.Length - 1]; string str = GetTypeStr(param.ParameterType.GetElementType()); if (paramInfos.Length + offset > 1) { string strParams = md.GenParamTypes(0); sb.AppendFormat("\t\t\t{0}(TypeChecker.CheckTypes<{1}>(L, 1) && TypeChecker.CheckParamsType<{2}>(L, {3}, {4}))\r\n", strIf, strParams, str, paramInfos.Length + offset, GetCountStr(paramInfos.Length + offset - 1)); } else { sb.AppendFormat("\t\t\t{0}(TypeChecker.CheckParamsType<{1}>(L, {2}, {3}))\r\n", strIf, str, paramInfos.Length + offset, GetCountStr(paramInfos.Length + offset - 1)); } } else { ParameterInfo[] paramInfos = md.GetParameters(); if (paramInfos.Length + offset > checkTypeOffset) { string strParams = md.GenParamTypes(checkTypeOffset); sb.AppendFormat("\t\t\t{0}(count == {1} && TypeChecker.CheckTypes<{2}>(L, {3}))\r\n", strIf, paramInfos.Length + offset, strParams, checkTypeOffset + 1); } else { sb.AppendFormat("\t\t\t{0}(count == {1})\r\n", strIf, paramInfos.Length + offset); } } sb.AppendLineEx("\t\t\t{"); int count = md.ProcessParams(4, false, checkTypeOffset); sb.AppendFormat("\t\t\t\treturn {0};\r\n", ret + count); sb.AppendLineEx("\t\t\t}"); } static int[] CheckCheckTypePos(List list) where T : _MethodBase { int[] map = new int[list.Count]; for (int i = 0; i < list.Count;) { if (HasOptionalParam(list[i].GetParameters())) { if (list[0].IsConstructor) { for (int k = 0; k < map.Length; k++) { map[k] = 1; } } else { Array.Clear(map, 0, map.Length); } return map; } int c1 = list[i].GetParamsCount(); int count = c1; map[i] = count; int j = i + 1; for (; j < list.Count; j++) { int c2 = list[j].GetParamsCount(); if (c1 == c2) { count = Mathf.Min(count, list[i].GetEqualParamsCount(list[j])); } else { map[j] = c2; break; } for (int m = i; m <= j; m++) { map[m] = count; } } i = j; } return map; } static void GenOverrideDefinedFunc(MethodBase method) { string name = GetMethodName(method); FieldInfo field = extendType.GetField(name + "Defined"); string strfun = field.GetValue(null) as string; sb.AppendLineEx(strfun); return; } static _MethodBase GenOverrideFunc(string name) { List<_MethodBase> list = new List<_MethodBase>(); for (int i = 0; i < methods.Count; i++) { string curName = GetMethodName(methods[i].Method); if (curName == name && !IsGenericMethod(methods[i].Method)) { Push(list, methods[i]); } } if (list.Count == 1) { return list[0]; } else if(list.Count == 0) { return null; } list.Sort(Compare); int[] checkTypeMap = CheckCheckTypePos(list); sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int {0}(IntPtr L)\r\n", name == "Register" ? "_Register" : name); sb.AppendLineEx("\t{"); BeginTry(); sb.AppendLineEx("\t\t\tint count = LuaDLL.lua_gettop(L);"); sb.AppendLineEx(); for (int i = 0; i < list.Count; i++) { if (HasAttribute(list[i].Method, typeof(OverrideDefinedAttribute))) { GenOverrideDefinedFunc(list[i].Method); } else { GenOverrideFuncBody(list[i], i == 0, checkTypeMap[i]); } } sb.AppendLineEx("\t\t\telse"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\treturn LuaDLL.luaL_throw(L, \"invalid arguments to method: {0}.{1}\");\r\n", className, name); sb.AppendLineEx("\t\t\t}"); EndTry(); sb.AppendLineEx("\t}"); return null; } public static string CombineTypeStr(string space, string name) { if (string.IsNullOrEmpty(space)) { return name; } else { return space + "." + name; } } public static string GetBaseTypeStr(Type t) { if(t.IsGenericType) { return LuaMisc.GetTypeName(t); } else { return t.FullName.Replace("+", "."); } } //获取类型名字 public static string GetTypeStr(Type t) { if (t.IsByRef) { t = t.GetElementType(); return GetTypeStr(t); } else if (t.IsArray) { string str = GetTypeStr(t.GetElementType()); str += LuaMisc.GetArrayRank(t); return str; } else if(t == extendType) { return GetTypeStr(type); } else if(IsIEnumerator(t)) { return LuaMisc.GetTypeName(typeof(IEnumerator)); } return LuaMisc.GetTypeName(t); } //获取 typeof(string) 这样的名字 static string GetTypeOf(Type t, string sep) { string str; if (t.IsByRef) { t = t.GetElementType(); } if (IsNumberEnum(t)) { str = string.Format("uint{0}", sep); } else if (IsIEnumerator(t)) { str = string.Format("{0}{1}", GetTypeStr(typeof(IEnumerator)), sep); } else { str = string.Format("{0}{1}", GetTypeStr(t), sep); } return str; } static string GenParamTypes(ParameterInfo[] p, MethodBase mb, int offset = 0) { StringBuilder sb = new StringBuilder(); List list = new List(); if (!mb.IsStatic) { list.Add(type); } for (int i = 0; i < p.Length; i++) { if (IsParams(p[i])) { continue; } if (p[i].ParameterType.IsByRef && (p[i].Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { Type genericClass = typeof(LuaOut<>); Type t = genericClass.MakeGenericType(p[i].ParameterType); list.Add(t); } else { list.Add(GetGenericBaseType(mb, p[i].ParameterType)); } } for (int i = offset; i < list.Count - 1; i++) { sb.Append(GetTypeOf(list[i], ", ")); } if (list.Count > 0) { sb.Append(GetTypeOf(list[list.Count - 1], "")); } return sb.ToString(); } static void CheckObjectNull() { if (type.IsValueType) { sb.AppendLineEx("\t\t\tif (o == null)"); } else { sb.AppendLineEx("\t\t\tif (obj == null)"); } } static void GenGetFieldStr(string varName, Type varType, bool isStatic, bool isByteBuffer, bool beOverride = false) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int {0}_{1}(IntPtr L)\r\n", beOverride ? "_get" : "get", varName); sb.AppendLineEx("\t{"); if (isStatic) { string arg = string.Format("{0}.{1}", className, varName); BeginTry(); GenPushStr(varType, arg, "\t\t\t", isByteBuffer); sb.AppendLineEx("\t\t\treturn 1;"); EndTry(); } else { sb.AppendLineEx("\t\tobject o = null;\r\n"); BeginTry(); sb.AppendLineEx("\t\t\to = ToLua.ToObject(L, 1);"); sb.AppendFormat("\t\t\t{0} obj = ({0})o;\r\n", className); sb.AppendFormat("\t\t\t{0} ret = obj.{1};\r\n", GetTypeStr(varType), varName); GenPushStr(varType, "ret", "\t\t\t", isByteBuffer); sb.AppendLineEx("\t\t\treturn 1;"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t\tcatch(Exception e)"); sb.AppendLineEx("\t\t{"); sb.AppendFormat("\t\t\treturn LuaDLL.toluaL_exception(L, e, o, \"attempt to index {0} on a nil value\");\r\n", varName); sb.AppendLineEx("\t\t}"); } sb.AppendLineEx("\t}"); } static void GenGetEventStr(string varName, Type varType) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int get_{0}(IntPtr L)\r\n", varName); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\tToLua.Push(L, new EventObject(typeof({0})));\r\n",GetTypeStr(varType)); sb.AppendLineEx("\t\treturn 1;"); sb.AppendLineEx("\t}"); } static void GenIndexFunc() { for(int i = 0; i < fields.Length; i++) { if (fields[i].IsLiteral && fields[i].FieldType.IsPrimitive && !fields[i].FieldType.IsEnum) { continue; } bool beBuffer = IsByteBuffer(fields[i]); GenGetFieldStr(fields[i].Name, fields[i].FieldType, fields[i].IsStatic, beBuffer); } for (int i = 0; i < props.Length; i++) { if (!props[i].CanRead) { continue; } bool isStatic = true; int index = propList.IndexOf(props[i]); if (index >= 0) { isStatic = false; } _MethodBase md = methods.Find((p) => { return p.Name == "get_" + props[i].Name; }); bool beBuffer = IsByteBuffer(props[i]); GenGetFieldStr(props[i].Name, props[i].PropertyType, isStatic, beBuffer, md != null); } for (int i = 0; i < events.Length; i++) { GenGetEventStr(events[i].Name, events[i].EventHandlerType); } } static void GenSetFieldStr(string varName, Type varType, bool isStatic, bool beOverride = false, bool csharpLike = false) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int {0}_{1}(IntPtr L)\r\n", beOverride ? "_set" : "set", varName + (csharpLike ? "ter" : string.Empty)); sb.AppendLineEx("\t{"); if (!isStatic) { sb.AppendLineEx("\t\tobject o = null;\r\n"); BeginTry(); sb.AppendLineEx("\t\t\to = ToLua.ToObject(L, 1);"); sb.AppendFormat("\t\t\t{0} obj = ({0})o;\r\n", className); ProcessArg(varType, "\t\t\t", "arg0", 2); sb.AppendFormat("\t\t\tobj.{0} = arg0;\r\n", varName); if (type.IsValueType) { sb.AppendLineEx("\t\t\tToLua.SetBack(L, 1, obj);"); } sb.AppendLineEx("\t\t\treturn 0;"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t\tcatch(Exception e)"); sb.AppendLineEx("\t\t{"); sb.AppendFormat("\t\t\treturn LuaDLL.toluaL_exception(L, e, o, \"attempt to index {0} on a nil value\");\r\n", varName); sb.AppendLineEx("\t\t}"); } else { BeginTry(); ProcessArg(varType, "\t\t\t", "arg0", csharpLike ? 1 : 2); sb.AppendFormat("\t\t\t{0}.{1} = arg0;\r\n", className, varName); sb.AppendLineEx("\t\t\treturn 0;"); EndTry(); } sb.AppendLineEx("\t}"); } static void GenSetEventStr(string varName, Type varType, bool isStatic) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int set_{0}(IntPtr L)\r\n", varName); sb.AppendLineEx("\t{"); BeginTry(); if (!isStatic) { sb.AppendFormat("\t\t\t{0} obj = ({0})ToLua.CheckObject(L, 1, typeof({0}));\r\n", className); } string strVarType = GetTypeStr(varType); string objStr = isStatic ? className : "obj"; sb.AppendLineEx("\t\t\tEventObject arg0 = null;\r\n"); sb.AppendLineEx("\t\t\tif (LuaDLL.lua_isuserdata(L, 2) != 0)"); sb.AppendLineEx("\t\t\t{"); sb.AppendLineEx("\t\t\t\targ0 = (EventObject)ToLua.ToObject(L, 2);"); sb.AppendLineEx("\t\t\t}"); sb.AppendLineEx("\t\t\telse"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\treturn LuaDLL.luaL_throw(L, \"The event '{0}.{1}' can only appear on the left hand side of += or -= when used outside of the type '{0}'\");\r\n", className, varName); sb.AppendLineEx("\t\t\t}\r\n"); sb.AppendLineEx("\t\t\tif (arg0.op == EventOp.Add)"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\t{0} ev = ({0})arg0.func;\r\n", strVarType); sb.AppendFormat("\t\t\t\t{0}.{1} += ev;\r\n", objStr, varName); sb.AppendLineEx("\t\t\t}"); sb.AppendLineEx("\t\t\telse if (arg0.op == EventOp.Sub)"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\t{0} ev = ({0})arg0.func;\r\n", strVarType); sb.AppendFormat("\t\t\t\t{0}.{1} -= ev;\r\n", objStr, varName); sb.AppendLineEx("\t\t\t}\r\n"); sb.AppendLineEx("\t\t\treturn 0;"); EndTry(); sb.AppendLineEx("\t}"); GenCSharpLuaEvent(varName, varType, isStatic, true); GenCSharpLuaEvent(varName, varType, isStatic, false); } private static void GenCSharpLuaEvent(string varName, Type type, bool isStatic, bool isAdd) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int {0}{1}(IntPtr L)\r\n", isAdd ? "add" : "remove", varName); sb.AppendLineEx("\t{"); BeginTry(); sb.AppendFormat("\t\t\tToLua.CheckArgsCount(L, {0});\r\n", isStatic ? 1 : 2); string strVarType = GetTypeStr(type); string objStr = isStatic ? className : "obj"; if (!isStatic) { sb.AppendFormat("\t\t\tvar obj = ({0})ToLua.CheckObject(L, 1, typeof({0}));\r\n", className); } sb.AppendFormat("\t\t\tvar arg0 = ({0})ToLua.CheckDelegate<{0}>(L, {1});\r\n", strVarType, isStatic ? 1 : 2); sb.AppendFormat("\t\t\t{0}.{1} {2} arg0;\r\n", objStr, varName, isAdd ? "+=" : "-="); sb.AppendLineEx("\t\t\treturn 0;"); EndTry(); sb.AppendLineEx("\t}"); } private static void GenCSharpLuaValueTypeDefault() { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int __default__(IntPtr L)\r\n"); sb.AppendLineEx("\t{"); BeginTry(); sb.AppendFormat("\t\t\tvar o = new {0}();\r\n", className); sb.Append("\t\t\tToLua.PushValue(L, o);\r\n"); sb.AppendLineEx("\t\t\treturn 1;"); EndTry(); sb.AppendLineEx("\t}"); } private static void GenCSharpLuaValueTypeClone() { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int __clone__(IntPtr L)\r\n"); sb.AppendLineEx("\t{"); BeginTry(); sb.AppendFormat("\t\t\tToLua.CheckArgsCount(L, 1);\r\n"); sb.AppendFormat("\t\t\tvar obj = ({0})ToLua.CheckObject(L, 1, typeof({0}));\r\n", className); sb.Append("\t\t\tvar o = obj;\r\n"); sb.Append("\t\t\tToLua.PushValue(L, o);\r\n"); sb.Append("\t\t\tToLua.SetBack(L, 1, obj);\r\n"); sb.AppendLineEx("\t\t\treturn 1;"); EndTry(); sb.AppendLineEx("\t}"); } private static void GenCSharpLuaGetOrSet(_MethodBase m, string methodName) { string name = m.HasGetIndex() ? "get" : (m.HasSetIndex() ? "set" : null); if (name != null) { sb.AppendFormat("\t\tL.RegFunction(\"{0}\", {1});\r\n", name, methodName); } } static void GenNewIndexFunc() { for (int i = 0; i < fields.Length; i++) { if (fields[i].IsLiteral || fields[i].IsInitOnly || fields[i].IsPrivate) { continue; } GenSetFieldStr(fields[i].Name, fields[i].FieldType, fields[i].IsStatic); } for (int i = 0; i < props.Length; i++) { if (!props[i].CanWrite || !props[i].GetSetMethod(true).IsPublic) { continue; } bool isStatic = true; int index = propList.IndexOf(props[i]); if (index >= 0) { isStatic = false; } _MethodBase md = methods.Find((p) => { return p.Name == "set_" + props[i].Name; }); GenSetFieldStr(props[i].Name, props[i].PropertyType, isStatic, md != null); // 生成CSharp.lua兼容的版本 if(isStatic) GenSetFieldStr(props[i].Name, props[i].PropertyType, isStatic, md != null, true); } for (int i = 0; i < events.Length; i++) { bool isStatic = eventList.IndexOf(events[i]) < 0; GenSetEventStr(events[i].Name, events[i].EventHandlerType, isStatic); } } static void GenLuaFunctionRetValue(StringBuilder sb, Type t, string head, string name , bool beDefined = false) { if (t == typeof(bool)) { name = beDefined ? name : "bool " + name; sb.AppendFormat("{0}{1} = func.CheckBoolean();\r\n", head, name); } else if (t == typeof(long)) { name = beDefined ? name : "long " + name; sb.AppendFormat("{0}{1} = func.CheckLong();\r\n", head, name); } else if (t == typeof(ulong)) { name = beDefined ? name : "ulong " + name; sb.AppendFormat("{0}{1} = func.CheckULong();\r\n", head, name); } else if (t.IsPrimitive || IsNumberEnum(t)) { string type = GetTypeStr(t); name = beDefined ? name : type + " " + name; sb.AppendFormat("{0}{1} = ({2})func.CheckNumber();\r\n", head, name, type); } else if (t == typeof(string)) { name = beDefined ? name : "string " + name; sb.AppendFormat("{0}{1} = func.CheckString();\r\n", head, name); } else if (typeof(System.MulticastDelegate).IsAssignableFrom(t)) { name = beDefined ? name : GetTypeStr(t) + " " + name; sb.AppendFormat("{0}{1} = func.CheckDelegate();\r\n", head, name); } else if (t == typeof(Vector3)) { name = beDefined ? name : "UnityEngine.Vector3 " + name; sb.AppendFormat("{0}{1} = func.CheckVector3();\r\n", head, name); } else if (t == typeof(Quaternion)) { name = beDefined ? name : "UnityEngine.Quaternion " + name; sb.AppendFormat("{0}{1} = func.CheckQuaternion();\r\n", head, name); } else if (t == typeof(Vector2)) { name = beDefined ? name : "UnityEngine.Vector2 " + name; sb.AppendFormat("{0}{1} = func.CheckVector2();\r\n", head, name); } else if (t == typeof(Vector4)) { name = beDefined ? name : "UnityEngine.Vector4 " + name; sb.AppendFormat("{0}{1} = func.CheckVector4();\r\n", head, name); } else if (t == typeof(Color)) { name = beDefined ? name : "UnityEngine.Color " + name; sb.AppendFormat("{0}{1} = func.CheckColor();\r\n", head, name); } else if (t == typeof(Ray)) { name = beDefined ? name : "UnityEngine.Ray " + name; sb.AppendFormat("{0}{1} = func.CheckRay();\r\n", head, name); } else if (t == typeof(Bounds)) { name = beDefined ? name : "UnityEngine.Bounds " + name; sb.AppendFormat("{0}{1} = func.CheckBounds();\r\n", head, name); } else if (t == typeof(LayerMask)) { name = beDefined ? name : "UnityEngine.LayerMask " + name; sb.AppendFormat("{0}{1} = func.CheckLayerMask();\r\n", head, name); } else if (t == typeof(object)) { name = beDefined ? name : "object " + name; sb.AppendFormat("{0}{1} = func.CheckVariant();\r\n", head, name); } else if (t == typeof(byte[])) { name = beDefined ? name : "byte[] " + name; sb.AppendFormat("{0}{1} = func.CheckByteBuffer();\r\n", head, name); } else if (t == typeof(char[])) { name = beDefined ? name : "char[] " + name; sb.AppendFormat("{0}{1} = func.CheckCharBuffer();\r\n", head, name); } else { string type = GetTypeStr(t); name = beDefined ? name : type + " " + name; sb.AppendFormat("{0}{1} = ({2})func.CheckObject(typeof({2}));\r\n", head, name, type); //Debugger.LogError("GenLuaFunctionCheckValue undefined type:" + t.FullName); } } public static bool IsByteBuffer(Type type) { object[] attrs = type.GetCustomAttributes(true); for (int j = 0; j < attrs.Length; j++) { Type t = attrs[j].GetType(); if (t == typeof(LuaByteBufferAttribute)) { return true; } } return false; } public static bool IsByteBuffer(MemberInfo mb) { object[] attrs = mb.GetCustomAttributes(true); for (int j = 0; j < attrs.Length; j++) { Type t = attrs[j].GetType(); if (t == typeof(LuaByteBufferAttribute)) { return true; } } return false; } /*static void LuaFuncToDelegate(Type t, string head) { MethodInfo mi = t.GetMethod("Invoke"); ParameterInfo[] pi = mi.GetParameters(); int n = pi.Length; if (n == 0) { sb.AppendLineEx("() =>"); if (mi.ReturnType == typeof(void)) { sb.AppendFormat("{0}{{\r\n{0}\tfunc.Call();\r\n{0}}};\r\n", head); } else { sb.AppendFormat("{0}{{\r\n{0}\tfunc.BeginPCall();\r\n", head); sb.AppendFormat("{0}\tfunc.PCall();\r\n", head); GenLuaFunctionRetValue(sb, mi.ReturnType, head + "\t", "ret"); sb.AppendFormat("{0}\tfunc.EndPCall();\r\n", head); sb.AppendLineEx(head + "\treturn ret;"); sb.AppendFormat("{0}}};\r\n", head); } return; } sb.AppendFormat("(param0"); for (int i = 1; i < n; i++) { sb.AppendFormat(", param{0}", i); } sb.AppendFormat(") =>\r\n{0}{{\r\n{0}", head); sb.AppendLineEx("\tfunc.BeginPCall();"); for (int i = 0; i < n; i++) { string push = GetPushFunction(pi[i].ParameterType); if (!IsParams(pi[i])) { if (pi[i].ParameterType == typeof(byte[]) && IsByteBuffer(t)) { sb.AppendFormat("{0}\tfunc.PushByteBuffer(param{1});\r\n", head, i); } else { sb.AppendFormat("{0}\tfunc.{1}(param{2});\r\n", head, push, i); } } else { sb.AppendLineEx(); sb.AppendFormat("{0}\tfor (int i = 0; i < param{1}.Length; i++)\r\n", head, i); sb.AppendLineEx(head + "\t{"); sb.AppendFormat("{0}\t\tfunc.{1}(param{2}[i]);\r\n", head, push, i); sb.AppendLineEx(head + "\t}\r\n"); } } sb.AppendFormat("{0}\tfunc.PCall();\r\n", head); if (mi.ReturnType == typeof(void)) { for (int i = 0; i < pi.Length; i++) { if ((pi[i].Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { GenLuaFunctionRetValue(sb, pi[i].ParameterType, head + "\t", "param" + i, true); } } sb.AppendFormat("{0}\tfunc.EndPCall();\r\n", head); } else { GenLuaFunctionRetValue(sb, mi.ReturnType, head + "\t", "ret"); for (int i = 0; i < pi.Length; i++) { if ((pi[i].Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { GenLuaFunctionRetValue(sb, pi[i].ParameterType, head + "\t", "param" + i, true); } } sb.AppendFormat("{0}\tfunc.EndPCall();\r\n", head); sb.AppendLineEx(head + "\treturn ret;"); } sb.AppendFormat("{0}}};\r\n", head); }*/ static void GenDelegateBody(StringBuilder sb, Type t, string head, bool hasSelf = false) { MethodInfo mi = t.GetMethod("Invoke"); ParameterInfo[] pi = mi.GetParameters(); int n = pi.Length; if (n == 0) { if (mi.ReturnType == typeof(void)) { if (!hasSelf) { sb.AppendFormat("{0}{{\r\n{0}\tfunc.Call();\r\n{0}}}\r\n", head); } else { sb.AppendFormat("{0}{{\r\n{0}\tfunc.BeginPCall();\r\n", head); sb.AppendFormat("{0}\tfunc.Push(self);\r\n", head); sb.AppendFormat("{0}\tfunc.PCall();\r\n", head); sb.AppendFormat("{0}\tfunc.EndPCall();\r\n", head); sb.AppendFormat("{0}}}\r\n", head); } } else { sb.AppendFormat("{0}{{\r\n{0}\tfunc.BeginPCall();\r\n", head); if (hasSelf) sb.AppendFormat("{0}\tfunc.Push(self);\r\n", head); sb.AppendFormat("{0}\tfunc.PCall();\r\n", head); GenLuaFunctionRetValue(sb, mi.ReturnType, head + "\t", "ret"); sb.AppendFormat("{0}\tfunc.EndPCall();\r\n", head); sb.AppendLineEx(head + "\treturn ret;"); sb.AppendFormat("{0}}}\r\n", head); } return; } sb.AppendFormat("{0}{{\r\n{0}", head); sb.AppendLineEx("\tfunc.BeginPCall();"); if (hasSelf) sb.AppendFormat("{0}\tfunc.Push(self);\r\n", head); for (int i = 0; i < n; i++) { string push = GetPushFunction(pi[i].ParameterType); if (!IsParams(pi[i])) { if (pi[i].ParameterType == typeof(byte[]) && IsByteBuffer(t)) { sb.AppendFormat("{2}\tfunc.PushByteBuffer(param{1});\r\n", push, i, head); } else if ((pi[i].Attributes & ParameterAttributes.Out) == ParameterAttributes.None) { sb.AppendFormat("{2}\tfunc.{0}(param{1});\r\n", push, i, head); } } else { sb.AppendLineEx(); sb.AppendFormat("{0}\tfor (int i = 0; i < param{1}.Length; i++)\r\n", head, i); sb.AppendLineEx(head + "\t{"); sb.AppendFormat("{2}\t\tfunc.{0}(param{1}[i]);\r\n", push, i, head); sb.AppendLineEx(head + "\t}\r\n"); } } sb.AppendFormat("{0}\tfunc.PCall();\r\n", head); if (mi.ReturnType == typeof(void)) { for (int i = 0; i < pi.Length; i++) { if ((pi[i].Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { GenLuaFunctionRetValue(sb, pi[i].ParameterType.GetElementType(), head + "\t", "param" + i, true); } } sb.AppendFormat("{0}\tfunc.EndPCall();\r\n", head); } else { GenLuaFunctionRetValue(sb, mi.ReturnType, head + "\t", "ret"); for (int i = 0; i < pi.Length; i++) { if ((pi[i].Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { GenLuaFunctionRetValue(sb, pi[i].ParameterType.GetElementType(), head + "\t", "param" + i, true); } } sb.AppendFormat("{0}\tfunc.EndPCall();\r\n", head); sb.AppendLineEx(head + "\treturn ret;"); } sb.AppendFormat("{0}}}\r\n", head); } //static void GenToStringFunction() //{ // if ((op & MetaOp.ToStr) == 0) // { // return; // } // sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); // sb.AppendLineEx("\tstatic int Lua_ToString(IntPtr L)"); // sb.AppendLineEx("\t{"); // sb.AppendLineEx("\t\tobject obj = ToLua.ToObject(L, 1);\r\n"); // sb.AppendLineEx("\t\tif (obj != null)"); // sb.AppendLineEx("\t\t{"); // sb.AppendLineEx("\t\t\tLuaDLL.lua_pushstring(L, obj.ToString());"); // sb.AppendLineEx("\t\t}"); // sb.AppendLineEx("\t\telse"); // sb.AppendLineEx("\t\t{"); // sb.AppendLineEx("\t\t\tLuaDLL.lua_pushnil(L);"); // sb.AppendLineEx("\t\t}"); // sb.AppendLineEx(); // sb.AppendLineEx("\t\treturn 1;"); // sb.AppendLineEx("\t}"); //} static bool IsNeedOp(string name) { if (name == "op_Addition") { op |= MetaOp.Add; } else if (name == "op_Subtraction") { op |= MetaOp.Sub; } else if (name == "op_Equality") { op |= MetaOp.Eq; } else if (name == "op_Multiply") { op |= MetaOp.Mul; } else if (name == "op_Division") { op |= MetaOp.Div; } else if (name == "op_UnaryNegation") { op |= MetaOp.Neg; } else if (name == "ToString" && !isStaticClass) { op |= MetaOp.ToStr; } else { return false; } return true; } static void CallOpFunction(string name, int count, string ret) { string head = string.Empty; for (int i = 0; i < count; i++) { head += "\t"; } if (name == "op_Addition") { sb.AppendFormat("{0}{1} o = arg0 + arg1;\r\n", head, ret); } else if (name == "op_Subtraction") { sb.AppendFormat("{0}{1} o = arg0 - arg1;\r\n", head, ret); } else if (name == "op_Equality") { sb.AppendFormat("{0}{1} o = arg0 == arg1;\r\n", head, ret); } else if (name == "op_Multiply") { sb.AppendFormat("{0}{1} o = arg0 * arg1;\r\n", head, ret); } else if (name == "op_Division") { sb.AppendFormat("{0}{1} o = arg0 / arg1;\r\n", head, ret); } else if (name == "op_UnaryNegation") { sb.AppendFormat("{0}{1} o = -arg0;\r\n", head, ret); } } public static bool IsObsolete(MemberInfo mb) { object[] attrs = mb.GetCustomAttributes(true); for (int j = 0; j < attrs.Length; j++) { Type t = attrs[j].GetType() ; if (t == typeof(System.ObsoleteAttribute) || t == typeof(NoToLuaAttribute) || t == typeof(MonoPInvokeCallbackAttribute) || t.Name == "MonoNotSupportedAttribute" || t.Name == "MonoTODOAttribute") // || t.ToString() == "UnityEngine.WrapperlessIcall") { return true; } } if (IsMemberFilter(mb)) { return true; } return false; } public static bool HasAttribute(MemberInfo mb, Type atrtype) { object[] attrs = mb.GetCustomAttributes(true); for (int j = 0; j < attrs.Length; j++) { Type t = attrs[j].GetType(); if (t == atrtype) { return true; } } return false; } static void GenEnum() { fields = type.GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static); List list = new List(fields); for (int i = list.Count - 1; i > 0; i--) { if (IsObsolete(list[i])) { list.RemoveAt(i); } } fields = list.ToArray(); sb.AppendLineEx("\tpublic static void Register(LuaState L)"); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\tL.BeginEnum(typeof({0}));\r\n", className); for (int i = 0; i < fields.Length; i++) { //sb.AppendFormat("\t\tL.RegVar(\"{0}\", get_{0}, null);\r\n", fields[i].Name); string name = fields[i].Name; sb.AppendFormat("\t\tL.RegConstant(\"{0}\", {1});\r\n", name, className + '.' + name); } //sb.AppendFormat("\t\tL.RegFunction(\"IntToEnum\", IntToEnum);\r\n"); sb.AppendFormat("\t\tL.EndEnum();\r\n"); sb.AppendFormat("\t\tTypeTraits<{0}>.Check = CheckType;\r\n", className); sb.AppendFormat("\t\tStackTraits<{0}>.Push = Push;\r\n", className); sb.AppendLineEx("\t}"); sb.AppendLineEx(); sb.AppendFormat("\tstatic void Push(IntPtr L, {0} arg)\r\n", className); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tToLua.Push(L, arg);"); sb.AppendLineEx("\t}"); sb.AppendLineEx(); sb.AppendLineEx("\tstatic bool CheckType(IntPtr L, int pos)"); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\treturn TypeChecker.CheckEnumType(typeof({0}), L, pos);\r\n", className); sb.AppendLineEx("\t}"); /* for (int i = 0; i < fields.Length; i++) { sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int get_{0}(IntPtr L)\r\n", fields[i].Name); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\tToLua.Push(L, {0}.{1});\r\n", className, fields[i].Name); sb.AppendLineEx("\t\treturn 1;"); sb.AppendLineEx("\t}"); } sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendLineEx("\tstatic int IntToEnum(IntPtr L)"); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tint arg0 = (int)LuaDLL.lua_tonumber(L, 1);"); sb.AppendFormat("\t\t{0} o = ({0})arg0;\r\n", className); sb.AppendLineEx("\t\tToLua.Push(L, o);"); sb.AppendLineEx("\t\treturn 1;"); sb.AppendLineEx("\t}"); */ } static string CreateDelegate = @" public static Delegate CreateDelegate(Type t, LuaFunction func = null) { DelegateCreate Create = null; if (!dict.TryGetValue(t, out Create)) { throw new LuaException(string.Format(""Delegate {0} not register"", LuaMisc.GetTypeName(t))); } if (func != null) { LuaState state = func.GetLuaState(); LuaDelegate target = state.GetLuaDelegate(func); if (target != null) { return Delegate.CreateDelegate(t, target, target.method); } else { Delegate d = Create(func, null, false); target = d.Target as LuaDelegate; state.AddLuaDelegate(target, func); return d; } } return Create(null, null, false); } public static Delegate CreateDelegate(Type t, LuaFunction func, LuaTable self) { DelegateCreate Create = null; if (!dict.TryGetValue(t, out Create)) { throw new LuaException(string.Format(""Delegate {0} not register"", LuaMisc.GetTypeName(t))); } if (func != null) { LuaState state = func.GetLuaState(); LuaDelegate target = state.GetLuaDelegate(func, self); if (target != null) { return Delegate.CreateDelegate(t, target, target.method); } else { Delegate d = Create(func, self, true); target = d.Target as LuaDelegate; state.AddLuaDelegate(target, func, self); return d; } } return Create(null, null, true); } "; static string RemoveDelegate = @" public static Delegate RemoveDelegate(Delegate obj, LuaFunction func) { LuaState state = func.GetLuaState(); Delegate[] ds = obj.GetInvocationList(); for (int i = 0; i < ds.Length; i++) { LuaDelegate ld = ds[i].Target as LuaDelegate; if (ld != null && ld.func == func) { obj = Delegate.Remove(obj, ds[i]); state.DelayDispose(ld.func); break; } } return obj; } public static Delegate RemoveDelegate(Delegate obj, Delegate dg) { LuaDelegate remove = dg.Target as LuaDelegate; if (remove == null) { obj = Delegate.Remove(obj, dg); return obj; } LuaState state = remove.func.GetLuaState(); Delegate[] ds = obj.GetInvocationList(); for (int i = 0; i < ds.Length; i++) { LuaDelegate ld = ds[i].Target as LuaDelegate; if (ld != null && ld == remove) { obj = Delegate.Remove(obj, ds[i]); state.DelayDispose(ld.func); state.DelayDispose(ld.self); break; } } return obj; } "; static string GetDelegateParams(MethodInfo mi) { ParameterInfo[] infos = mi.GetParameters(); List list = new List(); for (int i = 0; i < infos.Length; i++) { string s2 = GetTypeStr(infos[i].ParameterType) + " param" + i; if (infos[i].ParameterType.IsByRef) { if (infos[i].Attributes == ParameterAttributes.Out) { s2 = "out " + s2; } else { s2 = "ref " + s2; } } list.Add(s2); } return string.Join(", ", list.ToArray()); } static string GetReturnValue(Type t) { if (t.IsPrimitive) { if (t == typeof(bool)) { return "false"; } else if (t == typeof(char)) { return "'\\0'"; } else { return "0"; } } else if (!t.IsValueType) { return "null"; } else { return string.Format("default({0})", GetTypeStr(t)); } } static string GetDefaultDelegateBody(MethodInfo md) { string str = "\r\n\t\t\t{\r\n"; bool flag = false; ParameterInfo[] pis = md.GetParameters(); for (int i = 0; i < pis.Length; i++) { if ((pis[i].Attributes & ParameterAttributes.Out) != ParameterAttributes.None) { str += string.Format("\t\t\t\tparam{0} = {1};\r\n", i, GetReturnValue(pis[i].ParameterType.GetElementType())); flag = true; } } if (flag) { if (md.ReturnType != typeof(void)) { str += "\t\t\treturn "; str += GetReturnValue(md.ReturnType); str += ";"; } str += "\t\t\t};\r\n\r\n"; return str; } if (md.ReturnType == typeof(void)) { return "{ };\r\n"; } else { return string.Format("{{ return {0}; }};\r\n", GetReturnValue(md.ReturnType)); } } public static void GenDelegates(DelegateType[] list) { usingList.Add("System"); usingList.Add("System.Collections.Generic"); for (int i = 0; i < list.Length; i++) { Type t = list[i].type; if (!typeof(System.Delegate).IsAssignableFrom(t)) { Debug.LogError(t.FullName + " not a delegate type"); return; } } sb.Append("public class DelegateFactory\r\n"); sb.Append("{\r\n"); sb.Append("\tpublic delegate Delegate DelegateCreate(LuaFunction func, LuaTable self, bool flag);\r\n"); sb.Append("\tpublic static Dictionary dict = new Dictionary();\r\n"); sb.Append("\tstatic DelegateFactory factory = new DelegateFactory();\r\n"); sb.AppendLineEx(); sb.Append("\tpublic static void Init()\r\n"); sb.Append("\t{\r\n"); sb.Append("\t\tRegister();\r\n"); sb.AppendLineEx("\t}\r\n"); sb.Append("\tpublic static void Register()\r\n"); sb.Append("\t{\r\n"); sb.Append("\t\tdict.Clear();\r\n"); for (int i = 0; i < list.Length; i++) { string type = list[i].strType; string name = list[i].name; sb.AppendFormat("\t\tdict.Add(typeof({0}), factory.{1});\r\n", type, name); } sb.AppendLineEx(); for (int i = 0; i < list.Length; i++) { string type = list[i].strType; string name = list[i].name; sb.AppendFormat("\t\tDelegateTraits<{0}>.Init(factory.{1});\r\n", type, name); } sb.AppendLineEx(); for (int i = 0; i < list.Length; i++) { string type = list[i].strType; string name = list[i].name; sb.AppendFormat("\t\tTypeTraits<{0}>.Init(factory.Check_{1});\r\n", type, name); } sb.AppendLineEx(); for (int i = 0; i < list.Length; i++) { string type = list[i].strType; string name = list[i].name; sb.AppendFormat("\t\tStackTraits<{0}>.Push = factory.Push_{1};\r\n", type, name); } sb.Append("\t}\r\n"); sb.Append(CreateDelegate); sb.AppendLineEx(RemoveDelegate); for (int i = 0; i < list.Length; i++) { Type t = list[i].type; string strType = list[i].strType; string name = list[i].name; MethodInfo mi = t.GetMethod("Invoke"); string args = GetDelegateParams(mi); //生成委托类 sb.AppendFormat("\tclass {0}_Event : LuaDelegate\r\n", name); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\tpublic {0}_Event(LuaFunction func) : base(func) {{ }}\r\n", name); sb.AppendFormat("\t\tpublic {0}_Event(LuaFunction func, LuaTable self) : base(func, self) {{ }}\r\n", name); sb.AppendLineEx(); sb.AppendFormat("\t\tpublic {0} Call({1})\r\n", GetTypeStr(mi.ReturnType), args); GenDelegateBody(sb, t, "\t\t"); sb.AppendLineEx(); sb.AppendFormat("\t\tpublic {0} CallWithSelf({1})\r\n", GetTypeStr(mi.ReturnType), args); GenDelegateBody(sb, t, "\t\t", true); sb.AppendLineEx("\t}\r\n"); //生成转换函数1 sb.AppendFormat("\tpublic {0} {1}(LuaFunction func, LuaTable self, bool flag)\r\n", strType, name); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tif (func == null)"); sb.AppendLineEx("\t\t{"); sb.AppendFormat("\t\t\t{0} fn = delegate({1}) {2}", strType, args, GetDefaultDelegateBody(mi)); sb.AppendLineEx("\t\t\treturn fn;"); sb.AppendLineEx("\t\t}\r\n"); sb.AppendLineEx("\t\tif(!flag)"); sb.AppendLineEx("\t\t{"); sb.AppendFormat("\t\t\t{0}_Event target = new {0}_Event(func);\r\n", name); sb.AppendFormat("\t\t\t{0} d = target.Call;\r\n", strType); sb.AppendLineEx("\t\t\ttarget.method = d.Method;"); sb.AppendLineEx("\t\t\treturn d;"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t\telse"); sb.AppendLineEx("\t\t{"); sb.AppendFormat("\t\t\t{0}_Event target = new {0}_Event(func, self);\r\n", name); sb.AppendFormat("\t\t\t{0} d = target.CallWithSelf;\r\n", strType); sb.AppendLineEx("\t\t\ttarget.method = d.Method;"); sb.AppendLineEx("\t\t\treturn d;"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t}\r\n"); sb.AppendFormat("\tbool Check_{0}(IntPtr L, int pos)\r\n", name); sb.AppendLineEx("\t{"); sb.AppendFormat("\t\treturn TypeChecker.CheckDelegateType(typeof({0}), L, pos);\r\n", strType); sb.AppendLineEx("\t}\r\n"); sb.AppendFormat("\tvoid Push_{0}(IntPtr L, {1} o)\r\n", name, strType); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tToLua.Push(L, o);"); sb.AppendLineEx("\t}\r\n"); } sb.AppendLineEx("}\r\n"); SaveFile(CustomSettings.saveDir + "DelegateFactory.cs"); Clear(); } static bool IsUseDefinedAttributee(MemberInfo mb) { object[] attrs = mb.GetCustomAttributes(false); for (int j = 0; j < attrs.Length; j++) { Type t = attrs[j].GetType(); if (t == typeof(UseDefinedAttribute)) { return true; } } return false; } static bool IsMethodEqualExtend(MethodBase a, MethodBase b) { if (a.Name != b.Name) { return false; } int c1 = a.IsStatic ? 0 : 1; int c2 = b.IsStatic ? 0 : 1; c1 += a.GetParameters().Length; c2 += b.GetParameters().Length; if (c1 != c2) return false; ParameterInfo[] lp = a.GetParameters(); ParameterInfo[] rp = b.GetParameters(); List ll = new List(); List lr = new List(); if (!a.IsStatic) { ll.Add(type); } if (!b.IsStatic) { lr.Add(type); } for (int i = 0; i < lp.Length; i++) { ll.Add(GetParameterType(lp[i])); } for (int i = 0; i < rp.Length; i++) { lr.Add(GetParameterType(rp[i])); } for (int i = 0; i < ll.Count; i++) { if (ll[i] != lr[i]) { return false; } } return true; } static void ProcessEditorExtend(Type extendType, List<_MethodBase> list) { if (extendType != null) { List list2 = new List(); list2.AddRange(extendType.GetMethods(BindingFlags.Instance | binding | BindingFlags.DeclaredOnly)); for (int i = list2.Count - 1; i >= 0; i--) { if (list2[i].Name.StartsWith("op_") || list2[i].Name.StartsWith("add_") || list2[i].Name.StartsWith("remove_")) { if (!IsNeedOp(list2[i].Name)) { continue; } } if (IsUseDefinedAttributee(list2[i])) { list.RemoveAll((md) => { return md.Name == list2[i].Name; }); } else { int index = list.FindIndex((md) => { return IsMethodEqualExtend(md.Method, list2[i]); }); if (index >= 0) { list.RemoveAt(index); } } if (!IsObsolete(list2[i])) { list.Add(new _MethodBase(list2[i])); } } FieldInfo field = extendType.GetField("AdditionNameSpace"); if (field != null) { string str = field.GetValue(null) as string; string[] spaces = str.Split(new char[] { ';' }); for (int i = 0; i < spaces.Length; i++) { usingList.Add(spaces[i]); } } } } static bool IsGenericType(MethodInfo md, Type t) { Type[] list = md.GetGenericArguments(); for (int i = 0; i < list.Length; i++) { if (list[i] == t) { return true; } } return false; } static void ProcessExtendType(Type extendType, List<_MethodBase> list) { if (extendType != null) { List list2 = new List(); list2.AddRange(extendType.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)); for (int i = list2.Count - 1; i >= 0; i--) { MethodInfo md = list2[i]; if (!md.IsDefined(typeof(ExtensionAttribute), false)) { continue; } ParameterInfo[] plist = md.GetParameters(); Type t = plist[0].ParameterType; if (t == type || t.IsAssignableFrom(type) || (IsGenericType(md, t) && (type == t.BaseType || type.IsSubclassOf(t.BaseType)))) { if (!IsObsolete(list2[i])) { _MethodBase mb = new _MethodBase(md); mb.BeExtend = true; list.Add(mb); } } } } } static void ProcessExtends(List<_MethodBase> list) { extendName = "ToLua_" + className.Replace(".", "_"); extendType = Type.GetType(extendName + ", Assembly-CSharp-Editor"); ProcessEditorExtend(extendType, list); string temp = null; for (int i = 0; i < extendList.Count; i++) { ProcessExtendType(extendList[i], list); string nameSpace = GetNameSpace(extendList[i], out temp); if (!string.IsNullOrEmpty(nameSpace)) { usingList.Add(nameSpace); } } } static void GetDelegateTypeFromMethodParams(_MethodBase m) { if (m.IsGenericMethod) { return; } ParameterInfo[] pifs = m.GetParameters(); for (int k = 0; k < pifs.Length; k++) { Type t = pifs[k].ParameterType; if (IsDelegateType(t)) { eventSet.Add(t); } } } public static void GenEventFunction(Type t, StringBuilder sb) { string funcName; string space = GetNameSpace(t, out funcName); funcName = CombineTypeStr(space, funcName); funcName = ConvertToLibSign(funcName); sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int {0}(IntPtr L)\r\n", funcName); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\ttry"); sb.AppendLineEx("\t\t{"); sb.AppendLineEx("\t\t\tint count = LuaDLL.lua_gettop(L);"); sb.AppendLineEx("\t\t\tLuaFunction func = ToLua.CheckLuaFunction(L, 1);"); sb.AppendLineEx(); sb.AppendLineEx("\t\t\tif (count == 1)"); sb.AppendLineEx("\t\t\t{"); sb.AppendFormat("\t\t\t\tDelegate arg1 = DelegateTraits<{0}>.Create(func);\r\n", GetTypeStr(t)); sb.AppendLineEx("\t\t\t\tToLua.Push(L, arg1);"); sb.AppendLineEx("\t\t\t}"); sb.AppendLineEx("\t\t\telse"); sb.AppendLineEx("\t\t\t{"); sb.AppendLineEx("\t\t\t\tLuaTable self = ToLua.CheckLuaTable(L, 2);"); sb.AppendFormat("\t\t\t\tDelegate arg1 = DelegateTraits<{0}>.Create(func, self);\r\n", GetTypeStr(t)); sb.AppendFormat("\t\t\t\tToLua.Push(L, arg1);\r\n"); sb.AppendLineEx("\t\t\t}"); sb.AppendLineEx("\t\t\treturn 1;"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t\tcatch(Exception e)"); sb.AppendLineEx("\t\t{"); sb.AppendLineEx("\t\t\treturn LuaDLL.toluaL_exception(L, e);"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t}"); } static void GenEventFunctions() { foreach (Type t in eventSet) { GenEventFunction(t, sb); } } static string RemoveChar(string str, char c) { int index = str.IndexOf(c); while (index > 0) { str = str.Remove(index, 1); index = str.IndexOf(c); } return str; } public static string ConvertToLibSign(string str) { if (string.IsNullOrEmpty(str)) { return null; } str = str.Replace('<', '_'); str = RemoveChar(str, '>'); str = str.Replace('[', 's'); str = RemoveChar(str, ']'); str = str.Replace('.', '_'); return str.Replace(',', '_'); } public static string GetNameSpace(Type t, out string libName) { if (t.IsGenericType) { return GetGenericNameSpace(t, out libName); } else { string space = t.FullName; if (space.Contains("+")) { space = space.Replace('+', '.'); int index = space.LastIndexOf('.'); libName = space.Substring(index + 1); return space.Substring(0, index); } else { libName = t.Namespace == null ? space : space.Substring(t.Namespace.Length + 1); return t.Namespace; } } } static string GetGenericNameSpace(Type t, out string libName) { Type[] gArgs = t.GetGenericArguments(); string typeName = t.FullName; int count = gArgs.Length; int pos = typeName.IndexOf("["); typeName = typeName.Substring(0, pos); string str = null; string name = null; int offset = 0; pos = typeName.IndexOf("+"); while (pos > 0) { str = typeName.Substring(0, pos); typeName = typeName.Substring(pos + 1); pos = str.IndexOf('`'); if (pos > 0) { count = (int)(str[pos + 1] - '0'); str = str.Substring(0, pos); str += "<" + string.Join(",", LuaMisc.GetGenericName(gArgs, offset, count)) + ">"; offset += count; } name = CombineTypeStr(name, str); pos = typeName.IndexOf("+"); } string space = name; str = typeName; if (offset < gArgs.Length) { pos = str.IndexOf('`'); count = (int)(str[pos + 1] - '0'); str = str.Substring(0, pos); str += "<" + string.Join(",", LuaMisc.GetGenericName(gArgs, offset, count)) + ">"; } libName = str; if (string.IsNullOrEmpty(space)) { space = t.Namespace; if (space != null) { libName = str.Substring(space.Length + 1); } } return space; } static Type GetParameterType(ParameterInfo info) { if (info.ParameterType == extendType) { return type; } return info.ParameterType; } } ================================================ FILE: Assets/ToLua/Editor/ToLuaExport.cs.meta ================================================ fileFormatVersion: 2 guid: 73e814f0ef0ab914181c1f1e0a989935 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/ToLuaMenu.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ //打开开关没有写入导出列表的纯虚类自动跳过 //#define JUMP_NODEFINED_ABSTRACT using UnityEngine; using UnityEditor; using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Text; using System.IO; using System.Diagnostics; using LuaInterface; using Object = UnityEngine.Object; using Debug = UnityEngine.Debug; using Debugger = LuaInterface.Debugger; using System.Threading; [InitializeOnLoad] public static class ToLuaMenu { //不需要导出或者无法导出的类型 public static List dropType = new List { typeof(ValueType), //不需要 #if UNITY_4_6 || UNITY_4_7 typeof(Motion), //很多平台只是空类 #endif #if UNITY_5_3_OR_NEWER typeof(UnityEngine.CustomYieldInstruction), #endif //typeof(UnityEngine.YieldInstruction), //无需导出的类 //typeof(UnityEngine.WaitForEndOfFrame), //内部支持 //typeof(UnityEngine.WaitForFixedUpdate), //typeof(UnityEngine.WaitForSeconds), typeof(UnityEngine.Mathf), //lua层支持 typeof(Plane), typeof(LayerMask), typeof(Vector3), typeof(Vector4), typeof(Vector2), typeof(Quaternion), typeof(Ray), typeof(Bounds), typeof(Color), typeof(Touch), typeof(RaycastHit), typeof(TouchPhase), //typeof(LuaInterface.LuaOutMetatable), //手写支持 typeof(LuaInterface.NullObject), typeof(System.Array), typeof(System.Reflection.MemberInfo), typeof(System.Reflection.BindingFlags), typeof(LuaClient), typeof(LuaInterface.LuaFunction), typeof(LuaInterface.LuaTable), typeof(LuaInterface.LuaThread), typeof(LuaInterface.LuaByteBuffer), //只是类型标识符 typeof(DelegateFactory), //无需导出,导出类支持lua函数转换为委托。如UIEventListener.OnClick(luafunc) }; //可以导出的内部支持类型 public static List baseType = new List { typeof(System.Object), typeof(System.Delegate), typeof(System.String), typeof(System.Enum), typeof(System.Type), typeof(System.Collections.IEnumerator), typeof(UnityEngine.Object), typeof(LuaInterface.EventObject), typeof(LuaInterface.LuaMethod), typeof(LuaInterface.LuaProperty), typeof(LuaInterface.LuaField), typeof(LuaInterface.LuaConstructor), }; private static bool beAutoGen = false; private static bool beCheck = true; static List allTypes = new List(); static ToLuaMenu() { string dir = CustomSettings.saveDir; string[] files = Directory.GetFiles(dir, "*.cs", SearchOption.TopDirectoryOnly); if (files.Length < 3 && beCheck) { if (EditorUtility.DisplayDialog("自动生成", "点击确定自动生成常用类型注册文件, 也可通过菜单逐步完成此功能", "确定", "取消")) { beAutoGen = true; GenLuaDelegates(); AssetDatabase.Refresh(); GenerateClassWraps(); GenLuaBinder(); beAutoGen = false; } beCheck = false; } } static string RemoveNameSpace(string name, string space) { if (space != null) { name = name.Remove(0, space.Length + 1); } return name; } public class BindType { public string name; //类名称 public Type type; public bool IsStatic; public string wrapName = ""; //产生的wrap文件名字 public string libName = ""; //注册到lua的名字 public Type baseType = null; public string nameSpace = null; //注册到lua的table层级 public List extendList = new List(); public BindType(Type t) { if (typeof(System.MulticastDelegate).IsAssignableFrom(t)) { throw new NotSupportedException(string.Format("\nDon't export Delegate {0} as a class, register it in customDelegateList", LuaMisc.GetTypeName(t))); } //if (IsObsolete(t)) //{ // throw new Exception(string.Format("\n{0} is obsolete, don't export it!", LuaMisc.GetTypeName(t))); //} type = t; nameSpace = ToLuaExport.GetNameSpace(t, out libName); name = ToLuaExport.CombineTypeStr(nameSpace, libName); libName = ToLuaExport.ConvertToLibSign(libName); if (name == "object") { wrapName = "System_Object"; name = "System.Object"; } else if (name == "string") { wrapName = "System_String"; name = "System.String"; } else { wrapName = name.Replace('.', '_'); wrapName = ToLuaExport.ConvertToLibSign(wrapName); } int index = CustomSettings.staticClassTypes.IndexOf(type); if (index >= 0 || (type.IsAbstract && type.IsSealed)) { IsStatic = true; } baseType = LuaMisc.GetExportBaseType(type); } public BindType SetBaseType(Type t) { baseType = t; return this; } public BindType AddExtendType(Type t) { if (!extendList.Contains(t)) { extendList.Add(t); } return this; } public BindType SetWrapName(string str) { wrapName = str; return this; } public BindType SetLibName(string str) { libName = str; return this; } public BindType SetNameSpace(string space) { nameSpace = space; return this; } public static bool IsObsolete(Type type) { object[] attrs = type.GetCustomAttributes(true); for (int j = 0; j < attrs.Length; j++) { Type t = attrs[j].GetType(); if (t == typeof(System.ObsoleteAttribute) || t == typeof(NoToLuaAttribute) || t.Name == "MonoNotSupportedAttribute" || t.Name == "MonoTODOAttribute") { return true; } } return false; } } static void AutoAddBaseType(BindType bt, bool beDropBaseType) { Type t = bt.baseType; if (t == null) { return; } if (CustomSettings.sealedList.Contains(t)) { CustomSettings.sealedList.Remove(t); Debugger.LogError("{0} not a sealed class, it is parent of {1}", LuaMisc.GetTypeName(t), bt.name); } if (t.IsInterface) { Debugger.LogWarning("{0} has a base type {1} is Interface, use SetBaseType to jump it", bt.name, t.FullName); bt.baseType = t.BaseType; } else if (dropType.IndexOf(t) >= 0) { Debugger.LogWarning("{0} has a base type {1} is a drop type", bt.name, t.FullName); bt.baseType = t.BaseType; } else if (!beDropBaseType || baseType.IndexOf(t) < 0) { int index = allTypes.FindIndex((iter) => { return iter.type == t; }); if (index < 0) { #if JUMP_NODEFINED_ABSTRACT if (t.IsAbstract && !t.IsSealed) { Debugger.LogWarning("not defined bindtype for {0}, it is abstract class, jump it, child class is {1}", LuaMisc.GetTypeName(t), bt.name); bt.baseType = t.BaseType; } else { Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", LuaMisc.GetTypeName(t), bt.name); bt = new BindType(t); allTypes.Add(bt); } #else Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", LuaMisc.GetTypeName(t), bt.name); bt = new BindType(t); allTypes.Add(bt); #endif } else { return; } } else { return; } AutoAddBaseType(bt, beDropBaseType); } static BindType[] GenBindTypes(BindType[] list, bool beDropBaseType = true) { allTypes = new List(list); for (int i = 0; i < list.Length; i++) { for (int j = i + 1; j < list.Length; j++) { if (list[i].type == list[j].type) throw new NotSupportedException("Repeat BindType:" + list[i].type); } if (dropType.IndexOf(list[i].type) >= 0) { Debug.LogWarning(list[i].type.FullName + " in dropType table, not need to export"); allTypes.Remove(list[i]); continue; } else if (beDropBaseType && baseType.IndexOf(list[i].type) >= 0) { Debug.LogWarning(list[i].type.FullName + " is Base Type, not need to export"); allTypes.Remove(list[i]); continue; } else if (list[i].type.IsEnum) { continue; } AutoAddBaseType(list[i], beDropBaseType); } return allTypes.ToArray(); } [MenuItem("Lua/Gen Lua Wrap Files", false, 1)] public static void GenerateClassWraps() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } if (!File.Exists(CustomSettings.saveDir)) { Directory.CreateDirectory(CustomSettings.saveDir); } allTypes.Clear(); BindType[] typeList = CustomSettings.customTypeList; BindType[] list = GenBindTypes(typeList); ToLuaExport.allTypes.AddRange(baseType); for (int i = 0; i < list.Length; i++) { ToLuaExport.allTypes.Add(list[i].type); } for (int i = 0; i < list.Length; i++) { ToLuaExport.Clear(); ToLuaExport.className = list[i].name; ToLuaExport.type = list[i].type; ToLuaExport.isStaticClass = list[i].IsStatic; ToLuaExport.baseType = list[i].baseType; ToLuaExport.wrapClassName = list[i].wrapName; ToLuaExport.libClassName = list[i].libName; ToLuaExport.extendList = list[i].extendList; ToLuaExport.Generate(CustomSettings.saveDir); } Debug.Log("Generate lua binding files over"); ToLuaExport.allTypes.Clear(); allTypes.Clear(); AssetDatabase.Refresh(); } static HashSet GetCustomTypeDelegates() { BindType[] list = CustomSettings.customTypeList; HashSet set = new HashSet(); BindingFlags binding = BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase | BindingFlags.Instance; for (int i = 0; i < list.Length; i++) { Type type = list[i].type; FieldInfo[] fields = type.GetFields(BindingFlags.GetField | BindingFlags.SetField | binding); PropertyInfo[] props = type.GetProperties(BindingFlags.GetProperty | BindingFlags.SetProperty | binding); MethodInfo[] methods = null; if (type.IsInterface) { methods = type.GetMethods(); } else { methods = type.GetMethods(BindingFlags.Instance | binding); } for (int j = 0; j < fields.Length; j++) { Type t = fields[j].FieldType; if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } for (int j = 0; j < props.Length; j++) { Type t = props[j].PropertyType; if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } for (int j = 0; j < methods.Length; j++) { MethodInfo m = methods[j]; if (m.IsGenericMethod) { continue; } ParameterInfo[] pifs = m.GetParameters(); for (int k = 0; k < pifs.Length; k++) { Type t = pifs[k].ParameterType; if (t.IsByRef) t = t.GetElementType(); if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } } } return set; } [MenuItem("Lua/Gen Lua Delegates", false, 2)] static void GenLuaDelegates() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } ToLuaExport.Clear(); List list = new List(); list.AddRange(CustomSettings.customDelegateList); HashSet set = GetCustomTypeDelegates(); foreach (Type t in set) { if (null == list.Find((p) => { return p.type == t; })) { list.Add(new DelegateType(t)); } } ToLuaExport.GenDelegates(list.ToArray()); set.Clear(); ToLuaExport.Clear(); AssetDatabase.Refresh(); Debug.Log("Create lua delegate over"); } static ToLuaTree InitTree() { ToLuaTree tree = new ToLuaTree(); ToLuaNode root = tree.GetRoot(); BindType[] list = GenBindTypes(CustomSettings.customTypeList); for (int i = 0; i < list.Length; i++) { string space = list[i].nameSpace; AddSpaceNameToTree(tree, root, space); } DelegateType[] dts = CustomSettings.customDelegateList; string str = null; for (int i = 0; i < dts.Length; i++) { string space = ToLuaExport.GetNameSpace(dts[i].type, out str); AddSpaceNameToTree(tree, root, space); } return tree; } static void AddSpaceNameToTree(ToLuaTree tree, ToLuaNode parent, string space) { if (space == null || space == string.Empty) { return; } string[] ns = space.Split(new char[] { '.' }); for (int j = 0; j < ns.Length; j++) { List> nodes = tree.Find((_t) => { return _t == ns[j]; }, j); if (nodes.Count == 0) { ToLuaNode node = new ToLuaNode(); node.value = ns[j]; parent.childs.Add(node); node.parent = parent; node.layer = j; parent = node; } else { bool flag = false; int index = 0; for (int i = 0; i < nodes.Count; i++) { int count = j; int size = j; ToLuaNode nodecopy = nodes[i]; while (nodecopy.parent != null) { nodecopy = nodecopy.parent; if (nodecopy.value != null && nodecopy.value == ns[--count]) { size--; } } if (size == 0) { index = i; flag = true; break; } } if (!flag) { ToLuaNode nnode = new ToLuaNode(); nnode.value = ns[j]; nnode.layer = j; nnode.parent = parent; parent.childs.Add(nnode); parent = nnode; } else { parent = nodes[index]; } } } } static string GetSpaceNameFromTree(ToLuaNode node) { string name = node.value; while (node.parent != null && node.parent.value != null) { node = node.parent; name = node.value + "." + name; } return name; } static string RemoveTemplateSign(string str) { str = str.Replace('<', '_'); int index = str.IndexOf('>'); while (index > 0) { str = str.Remove(index, 1); index = str.IndexOf('>'); } return str; } [MenuItem("Lua/Gen LuaBinder File", false, 4)] static void GenLuaBinder() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } allTypes.Clear(); ToLuaTree tree = InitTree(); StringBuilder sb = new StringBuilder(); List dtList = new List(); List list = new List(); list.AddRange(CustomSettings.customDelegateList); HashSet set = GetCustomTypeDelegates(); List backupList = new List(); backupList.AddRange(allTypes); ToLuaNode root = tree.GetRoot(); string libname = null; foreach (Type t in set) { if (null == list.Find((p) => { return p.type == t; })) { DelegateType dt = new DelegateType(t); AddSpaceNameToTree(tree, root, ToLuaExport.GetNameSpace(t, out libname)); list.Add(dt); } } sb.AppendLineEx("//this source code was auto-generated by tolua#, do not modify it"); sb.AppendLineEx("using System;"); sb.AppendLineEx("using UnityEngine;"); sb.AppendLineEx("using LuaInterface;"); sb.AppendLineEx(); sb.AppendLineEx("public static class LuaBinder"); sb.AppendLineEx("{"); sb.AppendLineEx("\tpublic static void Bind(LuaState L)"); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tfloat t = Time.realtimeSinceStartup;"); sb.AppendLineEx("\t\tL.BeginModule(null);"); GenRegisterInfo(null, sb, list, dtList); Action> begin = (node) => { if (node.value == null) { return; } sb.AppendFormat("\t\tL.BeginModule(\"{0}\");\r\n", node.value); string space = GetSpaceNameFromTree(node); GenRegisterInfo(space, sb, list, dtList); }; Action> end = (node) => { if (node.value != null) { sb.AppendLineEx("\t\tL.EndModule();"); } }; tree.DepthFirstTraversal(begin, end, tree.GetRoot()); sb.AppendLineEx("\t\tL.EndModule();"); if (CustomSettings.dynamicList.Count > 0) { sb.AppendLineEx("\t\tL.BeginPreLoad();"); for (int i = 0; i < CustomSettings.dynamicList.Count; i++) { Type t1 = CustomSettings.dynamicList[i]; BindType bt = backupList.Find((p) => { return p.type == t1; }); if (bt != null) sb.AppendFormat("\t\tL.AddPreLoad(\"{0}\", LuaOpen_{1}, typeof({0}));\r\n", bt.name, bt.wrapName); } sb.AppendLineEx("\t\tL.EndPreLoad();"); } sb.AppendLineEx("\t\tDebugger.Log(\"Register lua type cost time: {0}\", Time.realtimeSinceStartup - t);"); sb.AppendLineEx("\t}"); for (int i = 0; i < dtList.Count; i++) { ToLuaExport.GenEventFunction(dtList[i].type, sb); } if (CustomSettings.dynamicList.Count > 0) { for (int i = 0; i < CustomSettings.dynamicList.Count; i++) { Type t = CustomSettings.dynamicList[i]; BindType bt = backupList.Find((p) => { return p.type == t; }); if (bt != null) GenPreLoadFunction(bt, sb); } } sb.AppendLineEx("}\r\n"); allTypes.Clear(); string file = CustomSettings.saveDir + "LuaBinder.cs"; using (StreamWriter textWriter = new StreamWriter(file, false, Encoding.UTF8)) { textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } AssetDatabase.Refresh(); Debugger.Log("Generate LuaBinder over !"); } static void GenRegisterInfo(string nameSpace, StringBuilder sb, List delegateList, List wrappedDelegatesCache) { for (int i = 0; i < allTypes.Count; i++) { Type dt = CustomSettings.dynamicList.Find((p) => { return allTypes[i].type == p; }); if (dt == null && allTypes[i].nameSpace == nameSpace) { string str = "\t\t" + allTypes[i].wrapName + "Wrap.Register(L);\r\n"; sb.Append(str); allTypes.RemoveAt(i--); } } string funcName = null; for (int i = 0; i < delegateList.Count; i++) { DelegateType dt = delegateList[i]; Type type = dt.type; string typeSpace = ToLuaExport.GetNameSpace(type, out funcName); if (typeSpace == nameSpace) { funcName = ToLuaExport.ConvertToLibSign(funcName); string abr = dt.abr; abr = abr == null ? funcName : abr; sb.AppendFormat("\t\tL.RegFunction(\"{0}\", {1});\r\n", abr, dt.name); wrappedDelegatesCache.Add(dt); } } } static void GenPreLoadFunction(BindType bt, StringBuilder sb) { string funcName = "LuaOpen_" + bt.wrapName; sb.AppendLineEx("\r\n\t[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]"); sb.AppendFormat("\tstatic int {0}(IntPtr L)\r\n", funcName); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\ttry"); sb.AppendLineEx("\t\t{"); sb.AppendLineEx("\t\t\tLuaState state = LuaState.Get(L);"); sb.AppendFormat("\t\t\tstate.BeginPreModule(\"{0}\");\r\n", bt.nameSpace); sb.AppendFormat("\t\t\t{0}Wrap.Register(state);\r\n", bt.wrapName); sb.AppendFormat("\t\t\tint reference = state.GetMetaReference(typeof({0}));\r\n", bt.name); sb.AppendLineEx("\t\t\tstate.EndPreModule(L, reference);"); sb.AppendLineEx("\t\t\treturn 1;"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t\tcatch(Exception e)"); sb.AppendLineEx("\t\t{"); sb.AppendLineEx("\t\t\treturn LuaDLL.toluaL_exception(L, e);"); sb.AppendLineEx("\t\t}"); sb.AppendLineEx("\t}"); } static string GetOS() { return LuaConst.osDir; } static string CreateStreamDir(string dir) { dir = Application.streamingAssetsPath + "/" + dir; if (!File.Exists(dir)) { Directory.CreateDirectory(dir); } return dir; } static void BuildLuaBundle(string subDir, string sourceDir) { string[] files = Directory.GetFiles(sourceDir + subDir, "*.bytes"); string bundleName = subDir == null ? "lua.unity3d" : "lua" + subDir.Replace('/', '_') + ".unity3d"; bundleName = bundleName.ToLower(); #if UNITY_4_6 || UNITY_4_7 List list = new List(); for (int i = 0; i < files.Length; i++) { Object obj = AssetDatabase.LoadMainAssetAtPath(files[i]); list.Add(obj); } BuildAssetBundleOptions options = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.DeterministicAssetBundle; if (files.Length > 0) { string output = string.Format("{0}/{1}/" + bundleName, Application.streamingAssetsPath, GetOS()); File.Delete(output); BuildPipeline.BuildAssetBundle(null, list.ToArray(), output, options, EditorUserBuildSettings.activeBuildTarget); } #else for (int i = 0; i < files.Length; i++) { AssetImporter importer = AssetImporter.GetAtPath(files[i]); if (importer) { importer.assetBundleName = bundleName; importer.assetBundleVariant = null; } } #endif } static void ClearAllLuaFiles() { string osPath = Application.streamingAssetsPath + "/" + GetOS(); if (Directory.Exists(osPath)) { string[] files = Directory.GetFiles(osPath, "Lua*.unity3d"); for (int i = 0; i < files.Length; i++) { File.Delete(files[i]); } } string path = osPath + "/Lua"; if (Directory.Exists(path)) { Directory.Delete(path, true); } path = Application.streamingAssetsPath + "/Lua"; if (Directory.Exists(path)) { Directory.Delete(path, true); } path = Application.dataPath + "/temp"; if (Directory.Exists(path)) { Directory.Delete(path, true); } path = Application.dataPath + "/Resources/Lua"; if (Directory.Exists(path)) { Directory.Delete(path, true); } path = Application.persistentDataPath + "/" + GetOS() + "/Lua"; if (Directory.Exists(path)) { Directory.Delete(path, true); } } [MenuItem("Lua/Gen LuaWrap + Binder", false, 4)] static void GenLuaWrapBinder() { if (EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } beAutoGen = true; AssetDatabase.Refresh(); GenerateClassWraps(); GenLuaBinder(); beAutoGen = false; } [MenuItem("Lua/Generate All", false, 5)] static void GenLuaAll() { if (EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } beAutoGen = true; GenLuaDelegates(); AssetDatabase.Refresh(); GenerateClassWraps(); GenLuaBinder(); beAutoGen = false; } [MenuItem("Lua/Clear wrap files", false, 6)] static void ClearLuaWraps() { string[] files = Directory.GetFiles(CustomSettings.saveDir, "*.cs", SearchOption.TopDirectoryOnly); for (int i = 0; i < files.Length; i++) { File.Delete(files[i]); } ToLuaExport.Clear(); List list = new List(); ToLuaExport.GenDelegates(list.ToArray()); ToLuaExport.Clear(); StringBuilder sb = new StringBuilder(); sb.AppendLineEx("using System;"); sb.AppendLineEx("using LuaInterface;"); sb.AppendLineEx(); sb.AppendLineEx("public static class LuaBinder"); sb.AppendLineEx("{"); sb.AppendLineEx("\tpublic static void Bind(LuaState L)"); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tthrow new LuaException(\"Please generate LuaBinder files first!\");"); sb.AppendLineEx("\t}"); sb.AppendLineEx("}"); string file = CustomSettings.saveDir + "LuaBinder.cs"; using (StreamWriter textWriter = new StreamWriter(file, false, Encoding.UTF8)) { textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } AssetDatabase.Refresh(); } static void CopyLuaBytesFiles(string sourceDir, string destDir, bool appendext = true, string searchPattern = "*.lua", SearchOption option = SearchOption.AllDirectories) { if (!Directory.Exists(sourceDir)) { return; } string[] files = Directory.GetFiles(sourceDir, searchPattern, option); int len = sourceDir.Length; if (sourceDir[len - 1] == '/' || sourceDir[len - 1] == '\\') { --len; } for (int i = 0; i < files.Length; i++) { string str = files[i].Remove(0, len); string dest = destDir + "/" + str; if (appendext) dest += ".bytes"; string dir = Path.GetDirectoryName(dest); Directory.CreateDirectory(dir); File.Copy(files[i], dest, true); } } [MenuItem("Lua/Copy Lua files to Resources", false, 51)] public static void CopyLuaFilesToRes() { ClearAllLuaFiles(); string destDir = Application.dataPath + "/Resources" + "/Lua"; CopyLuaBytesFiles(LuaConst.luaDir, destDir); CopyLuaBytesFiles(LuaConst.toluaDir, destDir); AssetDatabase.Refresh(); Debug.Log("Copy lua files over"); } [MenuItem("Lua/Copy Lua files to Persistent", false, 52)] public static void CopyLuaFilesToPersistent() { ClearAllLuaFiles(); string destDir = Application.persistentDataPath + "/" + GetOS() + "/Lua"; CopyLuaBytesFiles(LuaConst.luaDir, destDir, false); CopyLuaBytesFiles(LuaConst.toluaDir, destDir, false); AssetDatabase.Refresh(); Debug.Log("Copy lua files over"); } static void GetAllDirs(string dir, List list) { string[] dirs = Directory.GetDirectories(dir); list.AddRange(dirs); for (int i = 0; i < dirs.Length; i++) { GetAllDirs(dirs[i], list); } } static void CopyDirectory(string source, string dest, string searchPattern = "*.lua", SearchOption option = SearchOption.AllDirectories) { string[] files = Directory.GetFiles(source, searchPattern, option); for (int i = 0; i < files.Length; i++) { string str = files[i].Remove(0, source.Length); string path = dest + "/" + str; string dir = Path.GetDirectoryName(path); Directory.CreateDirectory(dir); File.Copy(files[i], path, true); } } static void CopyBuildBat(string path, string tempDir) { if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64) { File.Copy(path + "/Luajit64/Build.bat", tempDir + "/Build.bat", true); } else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows) { if (IntPtr.Size == 4) { File.Copy(path + "/Luajit/Build.bat", tempDir + "/Build.bat", true); } else if (IntPtr.Size == 8) { File.Copy(path + "/Luajit64/Build.bat", tempDir + "/Build.bat", true); } } #if UNITY_5_3_OR_NEWER else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS) #else else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iPhone) #endif { //Debug.Log("iOS默认用64位,32位自行考虑"); File.Copy(path + "/Luajit64/Build.bat", tempDir + "/Build.bat", true); } else { File.Copy(path + "/Luajit/Build.bat", tempDir + "/Build.bat", true); } } [MenuItem("Lua/Build Lua files to Resources (PC)", false, 53)] public static void BuildLuaToResources() { ClearAllLuaFiles(); string tempDir = CreateStreamDir("Lua"); string destDir = Application.dataPath + "/Resources" + "/Lua"; string path = Application.dataPath.Replace('\\', '/'); path = path.Substring(0, path.LastIndexOf('/')); CopyBuildBat(path, tempDir); CopyLuaBytesFiles(LuaConst.luaDir, tempDir, false); Process proc = Process.Start(tempDir + "/Build.bat"); proc.WaitForExit(); CopyLuaBytesFiles(tempDir + "/Out/", destDir, false, "*.lua.bytes"); CopyLuaBytesFiles(LuaConst.toluaDir, destDir); Directory.Delete(tempDir, true); AssetDatabase.Refresh(); } [MenuItem("Lua/Build Lua files to Persistent (PC)", false, 54)] public static void BuildLuaToPersistent() { ClearAllLuaFiles(); string tempDir = CreateStreamDir("Lua"); string destDir = Application.persistentDataPath + "/" + GetOS() + "/Lua/"; string path = Application.dataPath.Replace('\\', '/'); path = path.Substring(0, path.LastIndexOf('/')); CopyBuildBat(path, tempDir); CopyLuaBytesFiles(LuaConst.luaDir, tempDir, false); Process proc = Process.Start(tempDir + "/Build.bat"); proc.WaitForExit(); CopyLuaBytesFiles(LuaConst.toluaDir, destDir, false); path = tempDir + "/Out/"; string[] files = Directory.GetFiles(path, "*.lua.bytes"); int len = path.Length; for (int i = 0; i < files.Length; i++) { path = files[i].Remove(0, len); path = path.Substring(0, path.Length - 6); path = destDir + path; File.Copy(files[i], path, true); } Directory.Delete(tempDir, true); AssetDatabase.Refresh(); } [MenuItem("Lua/Build bundle files not jit", false, 55)] public static void BuildNotJitBundles() { ClearAllLuaFiles(); CreateStreamDir(GetOS()); #if UNITY_4_6 || UNITY_4_7 string tempDir = CreateStreamDir("Lua"); #else string tempDir = Application.dataPath + "/temp/Lua"; if (!File.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } #endif CopyLuaBytesFiles(LuaConst.luaDir, tempDir); CopyLuaBytesFiles(LuaConst.toluaDir, tempDir); AssetDatabase.Refresh(); List dirs = new List(); GetAllDirs(tempDir, dirs); #if UNITY_5 || UNITY_5_3_OR_NEWER for (int i = 0; i < dirs.Count; i++) { string str = dirs[i].Remove(0, tempDir.Length); BuildLuaBundle(str.Replace('\\', '/'), "Assets/temp/Lua"); } BuildLuaBundle(null, "Assets/temp/Lua"); AssetDatabase.SaveAssets(); string output = string.Format("{0}/{1}", Application.streamingAssetsPath, GetOS()); BuildPipeline.BuildAssetBundles(output, BuildAssetBundleOptions.DeterministicAssetBundle, EditorUserBuildSettings.activeBuildTarget); //Directory.Delete(Application.dataPath + "/temp/", true); #else for (int i = 0; i < dirs.Count; i++) { string str = dirs[i].Remove(0, tempDir.Length); BuildLuaBundle(str.Replace('\\', '/'), "Assets/StreamingAssets/Lua"); } BuildLuaBundle(null, "Assets/StreamingAssets/Lua"); Directory.Delete(Application.streamingAssetsPath + "/Lua/", true); #endif AssetDatabase.Refresh(); } [MenuItem("Lua/Build Luajit bundle files (PC)", false, 56)] public static void BuildLuaBundles() { ClearAllLuaFiles(); CreateStreamDir(GetOS()); #if UNITY_4_6 || UNITY_4_7 string tempDir = CreateStreamDir("Lua"); #else string tempDir = Application.dataPath + "/temp/Lua"; if (!File.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } #endif string path = Application.dataPath.Replace('\\', '/'); path = path.Substring(0, path.LastIndexOf('/')); CopyBuildBat(path, tempDir); CopyLuaBytesFiles(LuaConst.luaDir, tempDir, false); Process proc = Process.Start(tempDir + "/Build.bat"); proc.WaitForExit(); CopyLuaBytesFiles(LuaConst.toluaDir, tempDir + "/Out"); AssetDatabase.Refresh(); string sourceDir = tempDir + "/Out"; List dirs = new List(); GetAllDirs(sourceDir, dirs); #if UNITY_5 || UNITY_5_3_OR_NEWER for (int i = 0; i < dirs.Count; i++) { string str = dirs[i].Remove(0, sourceDir.Length); BuildLuaBundle(str.Replace('\\', '/'), "Assets/temp/Lua/Out"); } BuildLuaBundle(null, "Assets/temp/Lua/Out"); AssetDatabase.Refresh(); string output = string.Format("{0}/{1}", Application.streamingAssetsPath, GetOS()); BuildPipeline.BuildAssetBundles(output, BuildAssetBundleOptions.DeterministicAssetBundle, EditorUserBuildSettings.activeBuildTarget); Directory.Delete(Application.dataPath + "/temp/", true); #else for (int i = 0; i < dirs.Count; i++) { string str = dirs[i].Remove(0, sourceDir.Length); BuildLuaBundle(str.Replace('\\', '/'), "Assets/StreamingAssets/Lua/Out"); } BuildLuaBundle(null, "Assets/StreamingAssets/Lua/Out/"); Directory.Delete(tempDir, true); #endif AssetDatabase.Refresh(); } [MenuItem("Lua/Clear all Lua files", false, 57)] public static void ClearLuaFiles() { ClearAllLuaFiles(); } [MenuItem("Lua/Gen BaseType Wrap", false, 101)] static void GenBaseTypeLuaWrap() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } string dir = CustomSettings.toluaBaseType; if (!File.Exists(dir)) { Directory.CreateDirectory(dir); } allTypes.Clear(); ToLuaExport.allTypes.AddRange(baseType); List btList = new List(); for (int i = 0; i < baseType.Count; i++) { btList.Add(new BindType(baseType[i])); } GenBindTypes(btList.ToArray(), false); BindType[] list = allTypes.ToArray(); for (int i = 0; i < list.Length; i++) { ToLuaExport.Clear(); ToLuaExport.className = list[i].name; ToLuaExport.type = list[i].type; ToLuaExport.isStaticClass = list[i].IsStatic; ToLuaExport.baseType = list[i].baseType; ToLuaExport.wrapClassName = list[i].wrapName; ToLuaExport.libClassName = list[i].libName; ToLuaExport.Generate(dir); } Debug.Log("Generate base type files over"); allTypes.Clear(); AssetDatabase.Refresh(); } static void CreateDefaultWrapFile(string path, string name) { StringBuilder sb = new StringBuilder(); path = path + name + ".cs"; sb.AppendLineEx("using System;"); sb.AppendLineEx("using LuaInterface;"); sb.AppendLineEx(); sb.AppendLineEx("public static class " + name); sb.AppendLineEx("{"); sb.AppendLineEx("\tpublic static void Register(LuaState L)"); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tthrow new LuaException(\"Please click menu Lua/Gen BaseType Wrap first!\");"); sb.AppendLineEx("\t}"); sb.AppendLineEx("}"); using (StreamWriter textWriter = new StreamWriter(path, false, Encoding.UTF8)) { textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } } [MenuItem("Lua/Clear BaseType Wrap", false, 102)] static void ClearBaseTypeLuaWrap() { CreateDefaultWrapFile(CustomSettings.toluaBaseType, "System_ObjectWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "System_DelegateWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "System_StringWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "System_EnumWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "System_TypeWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "System_Collections_IEnumeratorWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "UnityEngine_ObjectWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "LuaInterface_EventObjectWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "LuaInterface_LuaMethodWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "LuaInterface_LuaPropertyWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "LuaInterface_LuaFieldWrap"); CreateDefaultWrapFile(CustomSettings.toluaBaseType, "LuaInterface_LuaConstructorWrap"); Debug.Log("Clear base type wrap files over"); AssetDatabase.Refresh(); } [MenuItem("Lua/Enable Lua Injection &e", false, 102)] static void EnableLuaInjection() { bool EnableSymbols = false; if (UpdateMonoCecil(ref EnableSymbols) != -1) { BuildTargetGroup curBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; string existSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(curBuildTargetGroup); if (!existSymbols.Contains("ENABLE_LUA_INJECTION")) { PlayerSettings.SetScriptingDefineSymbolsForGroup(curBuildTargetGroup, existSymbols + ";ENABLE_LUA_INJECTION"); } AssetDatabase.Refresh(); } } #if ENABLE_LUA_INJECTION [MenuItem("Lua/Injection Remove &r", false, 5)] #endif static void RemoveInjection() { if (Application.isPlaying) { EditorUtility.DisplayDialog("警告", "游戏运行过程中无法操作", "确定"); return; } BuildTargetGroup curBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; string existSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(curBuildTargetGroup); PlayerSettings.SetScriptingDefineSymbolsForGroup(curBuildTargetGroup, existSymbols.Replace("ENABLE_LUA_INJECTION", "")); Debug.Log("Lua Injection Removed!"); } public static int UpdateMonoCecil(ref bool EnableSymbols) { string appFileName = Environment.GetCommandLineArgs()[0]; string appPath = Path.GetDirectoryName(appFileName); string directory = appPath + "/Data/Managed/"; if (UnityEngine.Application.platform == UnityEngine.RuntimePlatform.OSXEditor) { directory = appPath.Substring(0, appPath.IndexOf("MacOS")) + "Managed/"; } string suitedMonoCecilPath = directory + #if UNITY_2017_1_OR_NEWER "Unity.Cecil.dll"; #else "Mono.Cecil.dll"; #endif string suitedMonoCecilMdbPath = directory + #if UNITY_2017_1_OR_NEWER "Unity.Cecil.Mdb.dll"; #else "Mono.Cecil.Mdb.dll"; #endif string suitedMonoCecilPdbPath = directory + #if UNITY_2017_1_OR_NEWER "Unity.Cecil.Pdb.dll"; #else "Mono.Cecil.Pdb.dll"; #endif string suitedMonoCecilToolPath = directory + "Unity.CecilTools.dll"; if (!File.Exists(suitedMonoCecilPath) #if UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_3_OR_NEWER && !File.Exists(suitedMonoCecilMdbPath) && !File.Exists(suitedMonoCecilPdbPath) #endif ) { EnableSymbols = false; Debug.Log("Haven't found Mono.Cecil.dll!Symbols Will Be Disabled"); return -1; } bool bInjectionToolUpdated = false; string injectionToolPath = CustomSettings.injectionFilesPath + "Editor/"; string existMonoCecilPath = injectionToolPath + Path.GetFileName(suitedMonoCecilPath); string existMonoCecilPdbPath = injectionToolPath + Path.GetFileName(suitedMonoCecilPdbPath); string existMonoCecilMdbPath = injectionToolPath + Path.GetFileName(suitedMonoCecilMdbPath); string existMonoCecilToolPath = injectionToolPath + Path.GetFileName(suitedMonoCecilToolPath); try { bInjectionToolUpdated = TryUpdate(suitedMonoCecilPath, existMonoCecilPath) ? true : bInjectionToolUpdated; #if UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_3_OR_NEWER bInjectionToolUpdated = TryUpdate(suitedMonoCecilPdbPath, existMonoCecilPdbPath) ? true : bInjectionToolUpdated; bInjectionToolUpdated = TryUpdate(suitedMonoCecilMdbPath, existMonoCecilMdbPath) ? true : bInjectionToolUpdated; #endif TryUpdate(suitedMonoCecilToolPath, existMonoCecilToolPath); } catch (Exception e) { Debug.LogError(e.ToString()); return -1; } EnableSymbols = true; return bInjectionToolUpdated ? 1 : 0; } static bool TryUpdate(string srcPath, string destPath) { if (GetFileContentMD5(srcPath) != GetFileContentMD5(destPath)) { File.Copy(srcPath, destPath, true); return true; } return false; } static string GetFileContentMD5(string file) { if (!File.Exists(file)) { return string.Empty; } FileStream fs = new FileStream(file, FileMode.Open); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(fs); fs.Close(); StringBuilder sb = StringBuilderCache.Acquire(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return StringBuilderCache.GetStringAndRelease(sb); } } ================================================ FILE: Assets/ToLua/Editor/ToLuaMenu.cs.meta ================================================ fileFormatVersion: 2 guid: 97fb7996cd1338442af03841f30cddaf MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor/ToLuaTree.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System.Collections.Generic; using System; public class ToLuaNode { public List> childs = new List>(); public ToLuaNode parent = null; public T value; //添加命名空间节点所在位置,解决A.B.C/A.C存在相同名称却在不同命名空间所造成的Wrap问题 public int layer; } public class ToLuaTree { public ToLuaNode _root = null; private List> _list = null; public ToLuaTree() { _root = new ToLuaNode(); _list = new List>(); } //加入pos跟root里的pos比较,只有位置相同才是统一命名空间节点 void FindParent(List> list, List> root, Predicate match, int layer) { if (list == null || root == null) { return; } for (int i = 0; i < root.Count; i++) { // 加入layer跟root里的pos比较,只有位置相同才是统一命名空间节点 if (match(root[i].value) && root[i].layer == layer) { list.Add(root[i]); } FindParent(list, root[i].childs, match, layer); } } /*public void BreadthFirstTraversal(Action> action) { List> root = _root.childs; Queue> queue = new Queue>(); for (int i = 0; i < root.Count; i++) { queue.Enqueue(root[i]); } while (queue.Count > 0) { ToLuaNode node = queue.Dequeue(); action(node); if (node.childs != null) { for (int i = 0; i < node.childs.Count; i++) { queue.Enqueue(node.childs[i]); } } } }*/ public void DepthFirstTraversal(Action> begin, Action> end, ToLuaNode node) { begin(node); for (int i = 0; i < node.childs.Count; i++) { DepthFirstTraversal(begin, end, node.childs[i]); } end(node); } //只有位置相同才是统一命名空间节点 public List> Find(Predicate match, int layer) { _list.Clear(); FindParent(_list, _root.childs, match, layer); return _list; } public ToLuaNode GetRoot() { return _root; } } ================================================ FILE: Assets/ToLua/Editor/ToLuaTree.cs.meta ================================================ fileFormatVersion: 2 guid: 99b4e579c20c91f4d84ce5aa9add4672 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Editor.meta ================================================ fileFormatVersion: 2 guid: 3d9fa950d6c449e42893b939877b4ec7 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/01_HelloWorld/HelloWorld.cs ================================================ using UnityEngine; using LuaInterface; using System; public class HelloWorld : MonoBehaviour { void Awake() { LuaState lua = new LuaState(); lua.Start(); string hello = @" print('hello tolua#') "; lua.DoString(hello, "HelloWorld.cs"); lua.CheckTop(); lua.Dispose(); lua = null; } } ================================================ FILE: Assets/ToLua/Examples/01_HelloWorld/HelloWorld.cs.meta ================================================ fileFormatVersion: 2 guid: 1db6056d0e0ccb049ae392139c512608 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/01_HelloWorld/HelloWorld.unity.meta ================================================ fileFormatVersion: 2 guid: 7ce3f2dc80a0205428a5372f74800258 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/01_HelloWorld.meta ================================================ fileFormatVersion: 2 guid: 79324a58d1dd94843a6e15fb4d77da66 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/02_ScriptsFromFile/ScriptsFromFile.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System; using System.IO; //展示searchpath 使用,require 与 dofile 区别 public class ScriptsFromFile : MonoBehaviour { LuaState lua = null; private string strLog = ""; void Start () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += Log; #else Application.RegisterLogCallback(Log); #endif lua = new LuaState(); lua.Start(); //如果移动了ToLua目录,自己手动修复吧,只是例子就不做配置了 string fullPath = Application.dataPath + "\\ToLua/Examples/02_ScriptsFromFile"; lua.AddSearchPath(fullPath); } void Log(string msg, string stackTrace, LogType type) { strLog += msg; strLog += "\r\n"; } void OnGUI() { GUI.Label(new Rect(100, Screen.height / 2 - 100, 600, 400), strLog); if (GUI.Button(new Rect(50, 50, 120, 45), "DoFile")) { strLog = ""; lua.DoFile("ScriptsFromFile.lua"); } else if (GUI.Button(new Rect(50, 150, 120, 45), "Require")) { strLog = ""; lua.Require("ScriptsFromFile"); } lua.Collect(); lua.CheckTop(); } void OnApplicationQuit() { lua.Dispose(); lua = null; #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= Log; #else Application.RegisterLogCallback(null); #endif } } ================================================ FILE: Assets/ToLua/Examples/02_ScriptsFromFile/ScriptsFromFile.cs.meta ================================================ fileFormatVersion: 2 guid: 17346dbce1e39bd4b8cb9cdf6b9249e7 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/02_ScriptsFromFile/ScriptsFromFile.lua ================================================ print("This is a script from a utf8 file") print("tolua: 你好! こんにちは! 안녕하세요!") ================================================ FILE: Assets/ToLua/Examples/02_ScriptsFromFile/ScriptsFromFile.lua.meta ================================================ fileFormatVersion: 2 guid: fbc95a40dca6ccf448ff2a7f1905e751 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/02_ScriptsFromFile/ScriptsFromFile.unity.meta ================================================ fileFormatVersion: 2 guid: e011b54a109dd1c43b5ed71ca3590a32 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/02_ScriptsFromFile.meta ================================================ fileFormatVersion: 2 guid: 71ca7fe863de8dd4d8a6057d043df5e4 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/03_CallLuaFunction/CallLuaFunction.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System; public class CallLuaFunction : MonoBehaviour { private string script = @" function luaFunc(num) return num + 1 end test = {} test.luaFunc = luaFunc "; LuaFunction luaFunc = null; LuaState lua = null; string tips = null; void Start () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); lua = new LuaState(); lua.Start(); DelegateFactory.Init(); lua.DoString(script); //Get the function object luaFunc = lua.GetFunction("test.luaFunc"); if (luaFunc != null) { int num = luaFunc.Invoke(123456); Debugger.Log("generic call return: {0}", num); num = CallFunc(); Debugger.Log("expansion call return: {0}", num); Func Func = luaFunc.ToDelegate>(); num = Func(123456); Debugger.Log("Delegate call return: {0}", num); num = lua.Invoke("test.luaFunc", 123456, true); Debugger.Log("luastate call return: {0}", num); } lua.CheckTop(); } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } #if !TEST_GC void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 150, 400, 300), tips); } #endif void OnDestroy() { if (luaFunc != null) { luaFunc.Dispose(); luaFunc = null; } lua.Dispose(); lua = null; #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } int CallFunc() { luaFunc.BeginPCall(); luaFunc.Push(123456); luaFunc.PCall(); int num = (int)luaFunc.CheckNumber(); luaFunc.EndPCall(); return num; } } ================================================ FILE: Assets/ToLua/Examples/03_CallLuaFunction/CallLuaFunction.cs.meta ================================================ fileFormatVersion: 2 guid: 11338f45069e3e041b7c42b60897ce0a MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/03_CallLuaFunction/CallLuaFunction.unity.meta ================================================ fileFormatVersion: 2 guid: 9b95d9c7995843244812901527540c78 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/03_CallLuaFunction.meta ================================================ fileFormatVersion: 2 guid: 0b90da095ffcaa34891335989ba05ddf folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/04_AccessingLuaVariables/AccessingLuaVariables.cs ================================================ using UnityEngine; using System.Collections.Generic; using LuaInterface; public class AccessingLuaVariables : MonoBehaviour { private string script = @" print('Objs2Spawn is: '..Objs2Spawn) var2read = 42 varTable = {1,2,3,4,5} varTable.default = 1 varTable.map = {} varTable.map.name = 'map' meta = {name = 'meta'} setmetatable(varTable, meta) function TestFunc(strs) print('get func by variable') end "; void Start () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); LuaState lua = new LuaState(); lua.Start(); lua["Objs2Spawn"] = 5; lua.DoString(script); //通过LuaState访问 Debugger.Log("Read var from lua: {0}", lua["var2read"]); Debugger.Log("Read table var from lua: {0}", lua["varTable.default"]); //LuaState 拆串式table LuaFunction func = lua["TestFunc"] as LuaFunction; func.Call(); func.Dispose(); //cache成LuaTable进行访问 LuaTable table = lua.GetTable("varTable"); Debugger.Log("Read varTable from lua, default: {0} name: {1}", table["default"], table["map.name"]); table["map.name"] = "new"; //table 字符串只能是key Debugger.Log("Modify varTable name: {0}", table["map.name"]); table.AddTable("newmap"); LuaTable table1 = (LuaTable)table["newmap"]; table1["name"] = "table1"; Debugger.Log("varTable.newmap name: {0}", table1["name"]); table1.Dispose(); table1 = table.GetMetaTable(); if (table1 != null) { Debugger.Log("varTable metatable name: {0}", table1["name"]); } object[] list = table.ToArray(); for (int i = 0; i < list.Length; i++) { Debugger.Log("varTable[{0}], is {1}", i, list[i]); } table.Dispose(); lua.CheckTop(); lua.Dispose(); } private void OnApplicationQuit() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } string tips = null; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips); } } ================================================ FILE: Assets/ToLua/Examples/04_AccessingLuaVariables/AccessingLuaVariables.cs.meta ================================================ fileFormatVersion: 2 guid: 3121aadbc8cdbeb488fdc0cfd1032ead MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/04_AccessingLuaVariables/AccessingLuaVariables.unity.meta ================================================ fileFormatVersion: 2 guid: b440f9ea3ca78884cbc8bd834a84ee54 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/04_AccessingLuaVariables.meta ================================================ fileFormatVersion: 2 guid: 1b3a357bb0337ee438db20f82382e246 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/05_LuaCoroutine/LuaCoroutine.unity.meta ================================================ fileFormatVersion: 2 guid: 811fd4e3aec57234ea72e1ed44701a9c DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/05_LuaCoroutine/TestCoroutine.cs ================================================ using UnityEngine; using System; using System.Collections; using LuaInterface; //例子5和6展示的两套协同系统勿交叉使用,此为推荐方案 public class TestCoroutine : MonoBehaviour { public TextAsset luaFile = null; private LuaState lua = null; private LuaLooper looper = null; void Awake () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); lua = new LuaState(); lua.Start(); LuaBinder.Bind(lua); DelegateFactory.Init(); looper = gameObject.AddComponent(); looper.luaState = lua; lua.DoString(luaFile.text, "TestLuaCoroutine.lua"); LuaFunction f = lua.GetFunction("TestCortinue"); f.Call(); f.Dispose(); f = null; } void OnApplicationQuit() { looper.Destroy(); lua.Dispose(); lua = null; #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } string tips = null; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips); if (GUI.Button(new Rect(50, 50, 120, 45), "Start Counter")) { tips = null; LuaFunction func = lua.GetFunction("StartDelay"); func.Call(); func.Dispose(); } else if (GUI.Button(new Rect(50, 150, 120, 45), "Stop Counter")) { LuaFunction func = lua.GetFunction("StopDelay"); func.Call(); func.Dispose(); } else if (GUI.Button(new Rect(50, 250, 120, 45), "GC")) { lua.DoString("collectgarbage('collect')", "TestCoroutine.cs"); Resources.UnloadUnusedAssets(); } } } ================================================ FILE: Assets/ToLua/Examples/05_LuaCoroutine/TestCoroutine.cs.meta ================================================ fileFormatVersion: 2 guid: 3fdb28fb1b0a1eb4391deef05b03405d MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/05_LuaCoroutine.meta ================================================ fileFormatVersion: 2 guid: 4aab46dd051561242b5f1dd79f189a42 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/06_LuaCoroutine2/Coroutine.unity.meta ================================================ fileFormatVersion: 2 guid: 4db2739d8c3e5af4ca5647e7ded00f68 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/06_LuaCoroutine2/TestCoroutine2.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; //两套协同勿交叉使用,类unity原生,大量使用效率低 public class TestCoroutine2 : LuaClient { string script = @" function CoExample() WaitForSeconds(1) print('WaitForSeconds end time: '.. UnityEngine.Time.time) WaitForFixedUpdate() print('WaitForFixedUpdate end frameCount: '..UnityEngine.Time.frameCount) WaitForEndOfFrame() print('WaitForEndOfFrame end frameCount: '..UnityEngine.Time.frameCount) Yield(null) print('yield null end frameCount: '..UnityEngine.Time.frameCount) Yield(0) print('yield(0) end frameCime: '..UnityEngine.Time.frameCount) local www = UnityEngine.WWW('http://www.baidu.com') Yield(www) print('yield(www) end time: '.. UnityEngine.Time.time) local s = tolua.tolstring(www.bytes) print(s:sub(1, 128)) print('coroutine over') end function TestCo() StartCoroutine(CoExample) end local coDelay = nil function Delay() local c = 1 while true do WaitForSeconds(1) print('Count: '..c) c = c + 1 end end function StartDelay() coDelay = StartCoroutine(Delay) end function StopDelay() StopCoroutine(coDelay) coDelay = nil end "; protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } protected override void OnLoadFinished() { base.OnLoadFinished(); luaState.DoString(script, "TestCoroutine2.cs"); LuaFunction func = luaState.GetFunction("TestCo"); func.Call(); func.Dispose(); func = null; } //屏蔽,例子不需要运行 protected override void CallMain() { } bool beStart = false; string tips = null; void Start() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } new void OnApplicationQuit() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif base.OnApplicationQuit(); } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips); if (GUI.Button(new Rect(50, 50, 120, 45), "Start Counter")) { if (!beStart) { beStart = true; tips = ""; LuaFunction func = luaState.GetFunction("StartDelay"); func.Call(); func.Dispose(); } } else if (GUI.Button(new Rect(50, 150, 120, 45), "Stop Counter")) { if (beStart) { beStart = false; LuaFunction func = luaState.GetFunction("StopDelay"); func.Call(); func.Dispose(); } } } } ================================================ FILE: Assets/ToLua/Examples/06_LuaCoroutine2/TestCoroutine2.cs.meta ================================================ fileFormatVersion: 2 guid: 252cf94b5db18424a94f00ddbd580ee0 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/06_LuaCoroutine2.meta ================================================ fileFormatVersion: 2 guid: 2bf03102ccd94cb45afe01e02bf19184 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/07_LuaThread/TestLuaThread.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; public class TestLuaThread : MonoBehaviour { string script = @" function fib(n) local a, b = 0, 1 while n > 0 do a, b = b, a + b n = n - 1 end return a end function CoFunc(len) print('Coroutine started') local i = 0 for i = 0, len, 1 do local flag = coroutine.yield(fib(i)) if not flag then break end end print('Coroutine ended') end function Test() local co = coroutine.create(CoFunc) return co end "; LuaState state = null; LuaThread thread = null; string tips = null; void Start () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); state = new LuaState(); state.Start(); state.LogGC = true; state.DoString(script); LuaFunction func = state.GetFunction("Test"); func.BeginPCall(); func.PCall(); thread = func.CheckLuaThread(); thread.name = "LuaThread"; func.EndPCall(); func.Dispose(); func = null; thread.Resume(10); } void OnApplicationQuit() { if (thread != null) { thread.Dispose(); thread = null; } state.Dispose(); state = null; #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void Update() { state.CheckTop(); state.Collect(); } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips); if (GUI.Button(new Rect(10, 50, 120, 40), "Resume Thead")) { int ret = -1; if (thread != null && thread.Resume(true, out ret) == (int)LuaThreadStatus.LUA_YIELD) { Debugger.Log("lua yield: " + ret); } } else if (GUI.Button(new Rect(10, 150, 120, 40), "Close Thread")) { if (thread != null) { thread.Dispose(); thread = null; } } } } ================================================ FILE: Assets/ToLua/Examples/07_LuaThread/TestLuaThread.cs.meta ================================================ fileFormatVersion: 2 guid: cd0d38a2cd6c8794ebb1150cc3678db6 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/07_LuaThread/TestThread.unity.meta ================================================ fileFormatVersion: 2 guid: 4bc55bdc0d2bff34a9abc55c4eeebdc0 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/07_LuaThread.meta ================================================ fileFormatVersion: 2 guid: 34683a8c5207cb3438b3b06aa2ef38c8 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/08_AccessingArray/AccessingArray.cs ================================================ using UnityEngine; using LuaInterface; public class AccessingArray : MonoBehaviour { private string script = @" function TestArray(array) local len = array.Length for i = 0, len - 1 do print('Array: '..tostring(array[i])) end local iter = array:GetEnumerator() while iter:MoveNext() do print('iter: '..iter.Current) end local t = array:ToTable() for i = 1, #t do print('table: '.. tostring(t[i])) end local pos = array:BinarySearch(3) print('array BinarySearch: pos: '..pos..' value: '..array[pos]) pos = array:IndexOf(4) print('array indexof bbb pos is: '..pos) return 1, '123', true end "; LuaState lua = null; LuaFunction func = null; string tips = null; #pragma warning disable 0618 void Start() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); lua = new LuaState(); lua.Start(); lua.DoString(script, "AccessingArray.cs"); tips = ""; int[] array = { 1, 2, 3, 4, 5 }; func = lua.GetFunction("TestArray"); func.BeginPCall(); func.Push(array); func.PCall(); double arg1 = func.CheckNumber(); string arg2 = func.CheckString(); bool arg3 = func.CheckBoolean(); Debugger.Log("return is {0} {1} {2}", arg1, arg2, arg3); func.EndPCall(); //调用通用函数需要转换一下类型,避免可变参数拆成多个参数传递 object[] objs = func.LazyCall((object)array); if (objs != null) { Debugger.Log("return is {0} {1} {2}", objs[0], objs[1], objs[2]); } lua.CheckTop(); } #pragma warning restore 0618 void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } void OnApplicationQuit() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif func.Dispose(); lua.Dispose(); } } ================================================ FILE: Assets/ToLua/Examples/08_AccessingArray/AccessingArray.cs.meta ================================================ fileFormatVersion: 2 guid: 82a287200877e9344a7e6b2d58dfe019 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/08_AccessingArray/AccessingArray.unity.meta ================================================ fileFormatVersion: 2 guid: 3f3cdbddf148392458f85eed2085860c DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/08_AccessingArray.meta ================================================ fileFormatVersion: 2 guid: d74fee3fd9c8cb64e8d8083fb944a9c3 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_Dictionary_int_TestAccountWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_Collections_Generic_Dictionary_int_TestAccountWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Collections.Generic.Dictionary), typeof(System.Object), "AccountMap"); L.RegFunction(".geti", get_Item); L.RegFunction("get_Item", get_Item); L.RegFunction(".seti", set_Item); L.RegFunction("set_Item", set_Item); L.RegFunction("Add", Add); L.RegFunction("Clear", Clear); L.RegFunction("ContainsKey", ContainsKey); L.RegFunction("ContainsValue", ContainsValue); L.RegFunction("GetObjectData", GetObjectData); L.RegFunction("OnDeserialization", OnDeserialization); L.RegFunction("Remove", Remove); L.RegFunction("TryGetValue", TryGetValue); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("New", _CreateSystem_Collections_Generic_Dictionary_int_TestAccount); L.RegVar("this", _this, null); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Count", get_Count, null); L.RegVar("Comparer", get_Comparer, null); L.RegVar("Keys", get_Keys, null); L.RegVar("Values", get_Values, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_Collections_Generic_Dictionary_int_TestAccount(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 0) { System.Collections.Generic.Dictionary obj = new System.Collections.Generic.Dictionary(); ToLua.PushSealed(L, obj); return 1; } else if (count == 1 && TypeChecker.CheckTypes(L, 1)) { int arg0 = (int)LuaDLL.lua_tonumber(L, 1); System.Collections.Generic.Dictionary obj = new System.Collections.Generic.Dictionary(arg0); ToLua.PushSealed(L, obj); return 1; } else if (count == 1 && TypeChecker.CheckTypes>(L, 1)) { System.Collections.Generic.IDictionary arg0 = (System.Collections.Generic.IDictionary)ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary obj = new System.Collections.Generic.Dictionary(arg0); ToLua.PushSealed(L, obj); return 1; } else if (count == 1 && TypeChecker.CheckTypes>(L, 1)) { System.Collections.Generic.IEqualityComparer arg0 = (System.Collections.Generic.IEqualityComparer)ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary obj = new System.Collections.Generic.Dictionary(arg0); ToLua.PushSealed(L, obj); return 1; } else if (count == 2 && TypeChecker.CheckTypes>(L, 1)) { int arg0 = (int)LuaDLL.lua_tonumber(L, 1); System.Collections.Generic.IEqualityComparer arg1 = (System.Collections.Generic.IEqualityComparer)ToLua.ToObject(L, 2); System.Collections.Generic.Dictionary obj = new System.Collections.Generic.Dictionary(arg0, arg1); ToLua.PushSealed(L, obj); return 1; } else if (count == 2 && TypeChecker.CheckTypes, System.Collections.Generic.IEqualityComparer>(L, 1)) { System.Collections.Generic.IDictionary arg0 = (System.Collections.Generic.IDictionary)ToLua.ToObject(L, 1); System.Collections.Generic.IEqualityComparer arg1 = (System.Collections.Generic.IEqualityComparer)ToLua.ToObject(L, 2); System.Collections.Generic.Dictionary obj = new System.Collections.Generic.Dictionary(arg0, arg1); ToLua.PushSealed(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: System.Collections.Generic.Dictionary.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _get_this(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); TestAccount o = obj[arg0]; ToLua.PushSealed(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _set_this(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); TestAccount arg1 = (TestAccount)ToLua.CheckObject(L, 3, typeof(TestAccount)); obj[arg0] = arg1; return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _this(IntPtr L) { try { LuaDLL.lua_pushvalue(L, 1); LuaDLL.tolua_bindthis(L, _get_this, _set_this); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Item(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); TestAccount o = obj[arg0]; ToLua.PushSealed(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_Item(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); TestAccount arg1 = (TestAccount)ToLua.CheckObject(L, 3, typeof(TestAccount)); obj[arg0] = arg1; return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Add(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); TestAccount arg1 = (TestAccount)ToLua.CheckObject(L, 3, typeof(TestAccount)); obj.Add(arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Clear(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); obj.Clear(); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ContainsKey(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); bool o = obj.ContainsKey(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ContainsValue(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); TestAccount arg0 = (TestAccount)ToLua.CheckObject(L, 2, typeof(TestAccount)); bool o = obj.ContainsValue(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetObjectData(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); System.Runtime.Serialization.SerializationInfo arg0 = (System.Runtime.Serialization.SerializationInfo)ToLua.CheckObject(L, 2, typeof(System.Runtime.Serialization.SerializationInfo)); System.Runtime.Serialization.StreamingContext arg1 = StackTraits.Check(L, 3); obj.GetObjectData(arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int OnDeserialization(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); object arg0 = ToLua.ToVarObject(L, 2); obj.OnDeserialization(arg0); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Remove(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); bool o = obj.Remove(arg0); LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TryGetValue(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); TestAccount arg1 = null; bool o = obj.TryGetValue(arg0, out arg1); LuaDLL.lua_pushboolean(L, o); ToLua.PushSealed(L, arg1); return 2; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); System.Collections.IEnumerator o = obj.GetEnumerator(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)o; int ret = obj.Count; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Comparer(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)o; System.Collections.Generic.IEqualityComparer ret = obj.Comparer; ToLua.PushObject(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Comparer on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Keys(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)o; System.Collections.Generic.Dictionary.KeyCollection ret = obj.Keys; ToLua.PushSealed(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Keys on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Values(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary obj = (System.Collections.Generic.Dictionary)o; System.Collections.Generic.Dictionary.ValueCollection ret = obj.Values; ToLua.PushSealed(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Values on a nil value"); } } } ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_Dictionary_int_TestAccountWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 7eaa1793aebc03847bbeff73e29e711a MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Collections.Generic.Dictionary.KeyCollection), typeof(System.Object), "KeyCollection"); L.RegFunction("CopyTo", CopyTo); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("New", _CreateSystem_Collections_Generic_Dictionary_int_TestAccount_KeyCollection); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Count", get_Count, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_Collections_Generic_Dictionary_int_TestAccount_KeyCollection(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Collections.Generic.Dictionary arg0 = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); System.Collections.Generic.Dictionary.KeyCollection obj = new System.Collections.Generic.Dictionary.KeyCollection(arg0); ToLua.PushSealed(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: System.Collections.Generic.Dictionary.KeyCollection.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Collections.Generic.Dictionary.KeyCollection obj = (System.Collections.Generic.Dictionary.KeyCollection)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary.KeyCollection)); int[] arg0 = ToLua.CheckNumberArray(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); obj.CopyTo(arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Collections.Generic.Dictionary.KeyCollection obj = (System.Collections.Generic.Dictionary.KeyCollection)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary.KeyCollection)); System.Collections.IEnumerator o = obj.GetEnumerator(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary.KeyCollection obj = (System.Collections.Generic.Dictionary.KeyCollection)o; int ret = obj.Count; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } } ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap.cs.meta ================================================ fileFormatVersion: 2 guid: ae6d6c27412c9fa4e815ef0f87e01cc2 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Collections.Generic.Dictionary.ValueCollection), typeof(System.Object), "ValueCollection"); L.RegFunction("CopyTo", CopyTo); L.RegFunction("GetEnumerator", GetEnumerator); L.RegFunction("New", _CreateSystem_Collections_Generic_Dictionary_int_TestAccount_ValueCollection); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Count", get_Count, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_Collections_Generic_Dictionary_int_TestAccount_ValueCollection(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { System.Collections.Generic.Dictionary arg0 = (System.Collections.Generic.Dictionary)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary)); System.Collections.Generic.Dictionary.ValueCollection obj = new System.Collections.Generic.Dictionary.ValueCollection(arg0); ToLua.PushSealed(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: System.Collections.Generic.Dictionary.ValueCollection.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CopyTo(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); System.Collections.Generic.Dictionary.ValueCollection obj = (System.Collections.Generic.Dictionary.ValueCollection)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary.ValueCollection)); TestAccount[] arg0 = ToLua.CheckObjectArray(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); obj.CopyTo(arg0, arg1); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetEnumerator(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Collections.Generic.Dictionary.ValueCollection obj = (System.Collections.Generic.Dictionary.ValueCollection)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.Dictionary.ValueCollection)); System.Collections.IEnumerator o = obj.GetEnumerator(); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Count(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.Dictionary.ValueCollection obj = (System.Collections.Generic.Dictionary.ValueCollection)o; int ret = obj.Count; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Count on a nil value"); } } } ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap.cs.meta ================================================ fileFormatVersion: 2 guid: c353ebccdf1714241a37253dd58c9309 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_KeyValuePair_int_TestAccountWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class System_Collections_Generic_KeyValuePair_int_TestAccountWrap { public static void Register(LuaState L) { L.BeginClass(typeof(System.Collections.Generic.KeyValuePair), null, "KeyValuePair_int_TestAccount"); L.RegFunction("ToString", ToString); L.RegFunction("New", _CreateSystem_Collections_Generic_KeyValuePair_int_TestAccount); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("Key", get_Key, null); L.RegVar("Value", get_Value, null); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateSystem_Collections_Generic_KeyValuePair_int_TestAccount(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 1); TestAccount arg1 = (TestAccount)ToLua.CheckObject(L, 2, typeof(TestAccount)); System.Collections.Generic.KeyValuePair obj = new System.Collections.Generic.KeyValuePair(arg0, arg1); ToLua.PushValue(L, obj); return 1; } else if (count == 0) { System.Collections.Generic.KeyValuePair obj = new System.Collections.Generic.KeyValuePair(); ToLua.PushValue(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: System.Collections.Generic.KeyValuePair.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int ToString(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); System.Collections.Generic.KeyValuePair obj = (System.Collections.Generic.KeyValuePair)ToLua.CheckObject(L, 1, typeof(System.Collections.Generic.KeyValuePair)); string o = obj.ToString(); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Key(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.KeyValuePair obj = (System.Collections.Generic.KeyValuePair)o; int ret = obj.Key; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Key on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Value(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); System.Collections.Generic.KeyValuePair obj = (System.Collections.Generic.KeyValuePair)o; TestAccount ret = obj.Value; ToLua.PushSealed(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Value on a nil value"); } } } ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/System_Collections_Generic_KeyValuePair_int_TestAccountWrap.cs.meta ================================================ fileFormatVersion: 2 guid: e6f1375290fa13745bc07de7193ecc3e MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/TestAccountWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class TestAccountWrap { public static void Register(LuaState L) { L.BeginClass(typeof(TestAccount), typeof(System.Object)); L.RegFunction("New", _CreateTestAccount); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("id", get_id, set_id); L.RegVar("name", get_name, set_name); L.RegVar("sex", get_sex, set_sex); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateTestAccount(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3) { int arg0 = (int)LuaDLL.luaL_checknumber(L, 1); string arg1 = ToLua.CheckString(L, 2); int arg2 = (int)LuaDLL.luaL_checknumber(L, 3); TestAccount obj = new TestAccount(arg0, arg1, arg2); ToLua.PushSealed(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: TestAccount.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_id(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestAccount obj = (TestAccount)o; int ret = obj.id; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index id on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_name(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestAccount obj = (TestAccount)o; string ret = obj.name; LuaDLL.lua_pushstring(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index name on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_sex(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestAccount obj = (TestAccount)o; int ret = obj.sex; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index sex on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_id(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestAccount obj = (TestAccount)o; int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); obj.id = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index id on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_name(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestAccount obj = (TestAccount)o; string arg0 = ToLua.CheckString(L, 2); obj.name = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index name on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_sex(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestAccount obj = (TestAccount)o; int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); obj.sex = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index sex on a nil value"); } } } ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/TestAccountWrap.cs.meta ================================================ fileFormatVersion: 2 guid: b763e457bd5365e46bf64d146d0d5a3b MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/UseDictionary.cs ================================================ using UnityEngine; using System.Collections.Generic; using LuaInterface; public sealed class TestAccount { public int id; public string name; public int sex; public TestAccount(int id, string name, int sex) { this.id = id; this.name = name; this.sex = sex; } } public class UseDictionary : MonoBehaviour { Dictionary map = new Dictionary(); string script = @" function TestDict(map) local iter = map:GetEnumerator() while iter:MoveNext() do local v = iter.Current.Value print('id: '..v.id ..' name: '..v.name..' sex: '..v.sex) end local flag, account = map:TryGetValue(1, nil) if flag then print('TryGetValue result ok: '..account.name) end local keys = map.Keys iter = keys:GetEnumerator() print('------------print dictionary keys---------------') while iter:MoveNext() do print(iter.Current) end print('----------------------over----------------------') local values = map.Values iter = values:GetEnumerator() print('------------print dictionary values---------------') while iter:MoveNext() do print(iter.Current.name) end print('----------------------over----------------------') print('kick '..map[2].name) map:Remove(2) iter = map:GetEnumerator() while iter:MoveNext() do local v = iter.Current.Value print('id: '..v.id ..' name: '..v.name..' sex: '..v.sex) end end "; void Awake () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); map.Add(1, new TestAccount(1, "水水", 0)); map.Add(2, new TestAccount(2, "王伟", 1)); map.Add(3, new TestAccount(3, "王芳", 0)); LuaState luaState = new LuaState(); luaState.Start(); BindMap(luaState); luaState.DoString(script, "UseDictionary.cs"); LuaFunction func = luaState.GetFunction("TestDict"); func.BeginPCall(); func.Push(map); func.PCall(); func.EndPCall(); func.Dispose(); func = null; luaState.CheckTop(); luaState.Dispose(); luaState = null; } void OnApplicationQuit() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } string tips = ""; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips); } //示例方式,方便删除,正常导出无需手写下面代码 void BindMap(LuaState L) { L.BeginModule(null); TestAccountWrap.Register(L); L.BeginModule("System"); L.BeginModule("Collections"); L.BeginModule("Generic"); System_Collections_Generic_Dictionary_int_TestAccountWrap.Register(L); System_Collections_Generic_KeyValuePair_int_TestAccountWrap.Register(L); L.BeginModule("Dictionary"); System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap.Register(L); System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap.Register(L); L.EndModule(); L.EndModule(); L.EndModule(); L.EndModule(); L.EndModule(); } } ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/UseDictionary.cs.meta ================================================ fileFormatVersion: 2 guid: 23454681bd34d36498eafe3bb988240d MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary/UseDictionary.unity.meta ================================================ fileFormatVersion: 2 guid: 5dc40f31458a9544aa74bcdad6d15d06 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/09_Dictionary.meta ================================================ fileFormatVersion: 2 guid: d308146ac25b5a74d99ced6f74495105 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/10_Enum/AccessingEnum.cs ================================================ using UnityEngine; using System; using LuaInterface; public class AccessingEnum : MonoBehaviour { string script = @" space = nil function TestEnum(e) print('Enum is:'..tostring(e)) if space:ToInt() == 0 then print('enum ToInt() is ok') end if not space:Equals(0) then print('enum compare int is ok') end if space == e then print('enum compare enum is ok') end local s = UnityEngine.Space.IntToEnum(0) if space == s then print('IntToEnum change type is ok') end end function ChangeLightType(light, type) print('change light type to '..tostring(type)) light.type = type end "; LuaState state = null; void Start () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); state = new LuaState(); state.Start(); LuaBinder.Bind(state); state.DoString(script); state["space"] = Space.World; LuaFunction func = state.GetFunction("TestEnum"); func.BeginPCall(); func.Push(Space.World); func.PCall(); func.EndPCall(); func.Dispose(); func = null; } void OnApplicationQuit() { state.CheckTop(); state.Dispose(); state = null; #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } string tips = ""; int count = 1; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips); if (GUI.Button(new Rect(0, 60, 120, 50), "ChangeType")) { GameObject go = GameObject.Find("/Light"); Light light = go.GetComponent(); LuaFunction func = state.GetFunction("ChangeLightType"); func.BeginPCall(); func.Push(light); LightType type = (LightType)(count++ % 4); func.Push(type); func.PCall(); func.EndPCall(); func.Dispose(); } } } ================================================ FILE: Assets/ToLua/Examples/10_Enum/AccessingEnum.cs.meta ================================================ fileFormatVersion: 2 guid: acd101a7d0a84e64198674b06dba633d MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/10_Enum/AccessingEnum.unity.meta ================================================ fileFormatVersion: 2 guid: a217aecbea099fd4cbb21c9795f57884 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/10_Enum.meta ================================================ fileFormatVersion: 2 guid: fbe9c6c5abd052b488c851260cc2cb92 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/11_Delegate/TestDelegate.cs ================================================ using UnityEngine; using System; using System.Collections.Generic; using LuaInterface; public class TestDelegate: MonoBehaviour { private string script = @" function DoClick1(go) print('click1 gameObject is '..go.name) end function DoClick2(go) print('click2 gameObject is '..go.name) end function AddClick1(listener) if listener.onClick then listener.onClick = listener.onClick + DoClick1 else listener.onClick = DoClick1 end end function AddClick2(listener) if listener.onClick then listener.onClick = listener.onClick + DoClick2 else listener.onClick = DoClick2 end end function SetClick1(listener) if listener.onClick then listener.onClick:Destroy() end listener.onClick = DoClick1 end function RemoveClick1(listener) if listener.onClick then listener.onClick = listener.onClick - DoClick1 else print('empty delegate') end end function RemoveClick2(listener) if listener.onClick then listener.onClick = listener.onClick - DoClick2 else print('empty delegate') end end --测试重载问题 function TestOverride(listener) listener:SetOnFinished(TestEventListener.OnClick(DoClick1)) listener:SetOnFinished(TestEventListener.VoidDelegate(DoClick2)) end function TestEvent() print('this is a event') end function AddEvent(listener) listener.onClickEvent = listener.onClickEvent + TestEvent end function RemoveEvent(listener) listener.onClickEvent = listener.onClickEvent - TestEvent end local t = {name = 'byself'} function t:TestSelffunc() print('callback with self: '..self.name) end function AddSelfClick(listener) if listener.onClick then listener.onClick = listener.onClick + TestEventListener.OnClick(t.TestSelffunc, t) else listener.onClick = TestEventListener.OnClick(t.TestSelffunc, t) end end function RemoveSelfClick(listener) if listener.onClick then listener.onClick = listener.onClick - TestEventListener.OnClick(t.TestSelffunc, t) else print('empty delegate') end end "; LuaState state = null; TestEventListener listener = null; LuaFunction SetClick1 = null; LuaFunction AddClick1 = null; LuaFunction AddClick2 = null; LuaFunction RemoveClick1 = null; LuaFunction RemoveClick2 = null; LuaFunction TestOverride = null; LuaFunction RemoveEvent = null; LuaFunction AddEvent = null; LuaFunction AddSelfClick = null; LuaFunction RemoveSelfClick = null; //需要删除的转LuaFunction为委托,不需要删除的直接加或者等于即可 void Awake() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); state = new LuaState(); state.Start(); LuaBinder.Bind(state); Bind(state); state.LogGC = true; state.DoString(script); GameObject go = new GameObject("TestGo"); listener = (TestEventListener)go.AddComponent(typeof(TestEventListener)); SetClick1 = state.GetFunction("SetClick1"); AddClick1 = state.GetFunction("AddClick1"); AddClick2 = state.GetFunction("AddClick2"); RemoveClick1 = state.GetFunction("RemoveClick1"); RemoveClick2 = state.GetFunction("RemoveClick2"); TestOverride = state.GetFunction("TestOverride"); AddEvent = state.GetFunction("AddEvent"); RemoveEvent = state.GetFunction("RemoveEvent"); AddSelfClick = state.GetFunction("AddSelfClick"); RemoveSelfClick = state.GetFunction("RemoveSelfClick"); } void Bind(LuaState L) { L.BeginModule(null); TestEventListenerWrap.Register(state); L.EndModule(); DelegateFactory.dict.Add(typeof(TestEventListener.OnClick), TestEventListener_OnClick); DelegateFactory.dict.Add(typeof(TestEventListener.VoidDelegate), TestEventListener_VoidDelegate); DelegateTraits.Init(TestEventListener_OnClick); DelegateTraits.Init(TestEventListener_VoidDelegate); } void CallLuaFunction(LuaFunction func) { tips = ""; func.BeginPCall(); func.Push(listener); func.PCall(); func.EndPCall(); } //自动生成代码后拷贝过来 class TestEventListener_OnClick_Event : LuaDelegate { public TestEventListener_OnClick_Event(LuaFunction func) : base(func) { } public void Call(UnityEngine.GameObject param0) { func.BeginPCall(); func.Push(param0); func.PCall(); func.EndPCall(); } } public static TestEventListener.OnClick TestEventListener_OnClick(LuaFunction func, LuaTable self, bool flag) { if (func == null) { TestEventListener.OnClick fn = delegate { }; return fn; } TestEventListener_OnClick_Event target = new TestEventListener_OnClick_Event(func); TestEventListener.OnClick d = target.Call; target.method = d.Method; return d; } class TestEventListener_VoidDelegate_Event : LuaDelegate { public TestEventListener_VoidDelegate_Event(LuaFunction func) : base(func) { } public void Call(UnityEngine.GameObject param0) { func.BeginPCall(); func.Push(param0); func.PCall(); func.EndPCall(); } } public static TestEventListener.VoidDelegate TestEventListener_VoidDelegate(LuaFunction func, LuaTable self, bool flag) { if (func == null) { TestEventListener.VoidDelegate fn = delegate { }; return fn; } TestEventListener_VoidDelegate_Event target = new TestEventListener_VoidDelegate_Event(func); TestEventListener.VoidDelegate d = target.Call; target.method = d.Method; return d; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips); if (GUI.Button(new Rect(10, 10, 120, 40), " = OnClick1")) { CallLuaFunction(SetClick1); } else if (GUI.Button(new Rect(10, 60, 120, 40), " + Click1")) { CallLuaFunction(AddClick1); } else if (GUI.Button(new Rect(10, 110, 120, 40), " + Click2")) { CallLuaFunction(AddClick2); } else if (GUI.Button(new Rect(10, 160, 120, 40), " - Click1")) { CallLuaFunction(RemoveClick1); } else if (GUI.Button(new Rect(10, 210, 120, 40), " - Click2")) { CallLuaFunction(RemoveClick2); } else if (GUI.Button(new Rect(10, 260, 120, 40), "+ Click1 in C#")) { tips = ""; LuaFunction func = state.GetFunction("DoClick1"); TestEventListener.OnClick onClick = (TestEventListener.OnClick)DelegateTraits.Create(func); listener.onClick += onClick; } else if (GUI.Button(new Rect(10, 310, 120, 40), " - Click1 in C#")) { tips = ""; LuaFunction func = state.GetFunction("DoClick1"); listener.onClick = (TestEventListener.OnClick)DelegateFactory.RemoveDelegate(listener.onClick, func); func.Dispose(); func = null; } else if (GUI.Button(new Rect(10, 360, 120, 40), "OnClick")) { if (listener.onClick != null) { listener.onClick(gameObject); } else { Debug.Log("empty delegate!!"); } } else if (GUI.Button(new Rect(10, 410, 120, 40), "Override")) { CallLuaFunction(TestOverride); } else if (GUI.Button(new Rect(10, 460, 120, 40), "Force GC")) { //自动gc log: collect lua reference name , id xxx in thread state.LuaGC(LuaGCOptions.LUA_GCCOLLECT, 0); GC.Collect(); } else if (GUI.Button(new Rect(10, 510, 120, 40), "event +")) { CallLuaFunction(AddEvent); } else if (GUI.Button(new Rect(10, 560, 120, 40), "event -")) { CallLuaFunction(RemoveEvent); } else if (GUI.Button(new Rect(10, 610, 120, 40), "event call")) { listener.OnClickEvent(gameObject); } else if (GUI.Button(new Rect(200, 10, 120, 40), "+self call")) { CallLuaFunction(AddSelfClick); } else if (GUI.Button(new Rect(200, 60, 120, 40), "-self call")) { CallLuaFunction(RemoveSelfClick); } } void Update() { state.Collect(); state.CheckTop(); } void SafeRelease(ref LuaFunction luaRef) { if (luaRef != null) { luaRef.Dispose(); luaRef = null; } } string tips = ""; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnApplicationQuit() { SafeRelease(ref AddClick1); SafeRelease(ref AddClick2); SafeRelease(ref RemoveClick1); SafeRelease(ref RemoveClick2); SafeRelease(ref SetClick1); SafeRelease(ref TestOverride); state.Dispose(); state = null; #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } } ================================================ FILE: Assets/ToLua/Examples/11_Delegate/TestDelegate.cs.meta ================================================ fileFormatVersion: 2 guid: aebc047d4185a4942b0220c97c91154e MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/11_Delegate/TestEventListener.cs ================================================ using UnityEngine; using System; using System.Collections; using LuaInterface; public sealed class TestEventListener : MonoBehaviour { public delegate void VoidDelegate(GameObject go); public delegate void OnClick(GameObject go); public OnClick onClick = delegate { }; public event OnClick onClickEvent = delegate { }; public Func TestFunc = null; public void SetOnFinished(OnClick click) { Debugger.Log("SetOnFinished OnClick"); } public void SetOnFinished(VoidDelegate click) { Debugger.Log("SetOnFinished VoidDelegate"); } [NoToLuaAttribute] public void OnClickEvent(GameObject go) { onClickEvent(go); } } ================================================ FILE: Assets/ToLua/Examples/11_Delegate/TestEventListener.cs.meta ================================================ fileFormatVersion: 2 guid: b909bbc52f2fc814ab97a3b1038ec9ee MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/11_Delegate/TestEventListenerWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class TestEventListenerWrap { public static void Register(LuaState L) { L.BeginClass(typeof(TestEventListener), typeof(UnityEngine.MonoBehaviour)); L.RegFunction("SetOnFinished", SetOnFinished); L.RegFunction("__eq", op_Equality); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("onClick", get_onClick, set_onClick); L.RegVar("TestFunc", get_TestFunc, set_TestFunc); L.RegVar("onClickEvent", get_onClickEvent, set_onClickEvent); L.RegFunction("OnClick", TestEventListener_OnClick); L.RegFunction("VoidDelegate", TestEventListener_VoidDelegate); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int SetOnFinished(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 2)) { TestEventListener obj = (TestEventListener)ToLua.CheckObject(L, 1, typeof(TestEventListener)); TestEventListener.VoidDelegate arg0 = (TestEventListener.VoidDelegate)ToLua.ToObject(L, 2); obj.SetOnFinished(arg0); return 0; } else if (count == 2 && TypeChecker.CheckTypes(L, 2)) { TestEventListener obj = (TestEventListener)ToLua.CheckObject(L, 1, typeof(TestEventListener)); TestEventListener.OnClick arg0 = (TestEventListener.OnClick)ToLua.ToObject(L, 2); obj.SetOnFinished(arg0); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: TestEventListener.SetOnFinished"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int op_Equality(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.ToObject(L, 1); UnityEngine.Object arg1 = (UnityEngine.Object)ToLua.ToObject(L, 2); bool o = arg0 == arg1; LuaDLL.lua_pushboolean(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_onClick(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestEventListener obj = (TestEventListener)o; TestEventListener.OnClick ret = obj.onClick; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index onClick on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_TestFunc(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestEventListener obj = (TestEventListener)o; System.Func ret = obj.TestFunc; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index TestFunc on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_onClickEvent(IntPtr L) { ToLua.Push(L, new EventObject(typeof(TestEventListener.OnClick))); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_onClick(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestEventListener obj = (TestEventListener)o; TestEventListener.OnClick arg0 = (TestEventListener.OnClick)ToLua.CheckDelegate(L, 2); obj.onClick = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index onClick on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_TestFunc(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestEventListener obj = (TestEventListener)o; System.Func arg0 = (System.Func)ToLua.CheckDelegate>(L, 2); obj.TestFunc = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index TestFunc on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_onClickEvent(IntPtr L) { try { TestEventListener obj = (TestEventListener)ToLua.CheckObject(L, 1, typeof(TestEventListener)); EventObject arg0 = null; if (LuaDLL.lua_isuserdata(L, 2) != 0) { arg0 = (EventObject)ToLua.ToObject(L, 2); } else { return LuaDLL.luaL_throw(L, "The event 'TestEventListener.onClickEvent' can only appear on the left hand side of += or -= when used outside of the type 'TestEventListener'"); } if (arg0.op == EventOp.Add) { TestEventListener.OnClick ev = (TestEventListener.OnClick)arg0.func; obj.onClickEvent += ev; } else if (arg0.op == EventOp.Sub) { TestEventListener.OnClick ev = (TestEventListener.OnClick)arg0.func; obj.onClickEvent -= ev; } return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestEventListener_OnClick(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); LuaFunction func = ToLua.CheckLuaFunction(L, 1); if (count == 1) { Delegate arg1 = DelegateTraits.Create(func); ToLua.Push(L, arg1); } else { LuaTable self = ToLua.CheckLuaTable(L, 2); Delegate arg1 = DelegateTraits.Create(func, self); ToLua.Push(L, arg1); } return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestEventListener_VoidDelegate(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); LuaFunction func = ToLua.CheckLuaFunction(L, 1); if (count == 1) { Delegate arg1 = DelegateTraits.Create(func); ToLua.Push(L, arg1); } else { LuaTable self = ToLua.CheckLuaTable(L, 2); Delegate arg1 = DelegateTraits.Create(func, self); ToLua.Push(L, arg1); } return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/Examples/11_Delegate/TestEventListenerWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 1e84ecc8101f77e45bab712de82fed53 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/11_Delegate/UseDelegate.unity.meta ================================================ fileFormatVersion: 2 guid: 0c371c24024790e4fafc6efd6656ffa8 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/11_Delegate.meta ================================================ fileFormatVersion: 2 guid: bafe37b805a5b274aaee648a0b64bcb2 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/12_GameObject/TestGameObject.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; public class TestGameObject: MonoBehaviour { private string script = @" local Color = UnityEngine.Color local GameObject = UnityEngine.GameObject local ParticleSystem = UnityEngine.ParticleSystem function OnComplete() print('OnComplete CallBack') end local go = GameObject('go') go:AddComponent(typeof(ParticleSystem)) local node = go.transform node.position = Vector3.one print('gameObject is: '..tostring(go)) --go.transform:DOPath({Vector3.zero, Vector3.one * 10}, 1, DG.Tweening.PathType.Linear, DG.Tweening.PathMode.Full3D, 10, nil) --go.transform:DORotate(Vector3(0,0,360), 2, DG.Tweening.RotateMode.FastBeyond360):OnComplete(OnComplete) GameObject.Destroy(go, 2) go.name = '123' --print('delay destroy gameobject is: '..go.name) "; LuaState lua = null; void Start() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); lua = new LuaState(); lua.LogGC = true; lua.Start(); LuaBinder.Bind(lua); lua.DoString(script, "TestGameObject.cs"); } void Update() { lua.CheckTop(); lua.Collect(); } string tips = ""; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnApplicationQuit() { lua.Dispose(); lua = null; #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } } ================================================ FILE: Assets/ToLua/Examples/12_GameObject/TestGameObject.cs.meta ================================================ fileFormatVersion: 2 guid: 4a206b7d4dbb78541b0e1be49fa5d338 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/12_GameObject/TestGameObject.unity.meta ================================================ fileFormatVersion: 2 guid: bd44e2bbf67026a4eb7a12cc132f5515 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/12_GameObject.meta ================================================ fileFormatVersion: 2 guid: c05e0dc08239c724bba79944e7ccbcaa folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/13_CustomLoader/CustomLoader.unity.meta ================================================ fileFormatVersion: 2 guid: 64a15f71c3e8ada48bbf2dec47d8eb0d DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/13_CustomLoader/TestCustomLoader.cs ================================================ using UnityEngine; using System.IO; using LuaInterface; //use menu Lua->Copy lua files to Resources. 之后才能发布到手机 public class TestCustomLoader : LuaClient { string tips = "Test custom loader"; protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } protected override void CallMain() { LuaFunction func = luaState.GetFunction("Test"); func.Call(); func.Dispose(); } protected override void StartMain() { luaState.DoFile("TestLoader.lua"); CallMain(); } new void Awake() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += Logger; #else Application.RegisterLogCallback(Logger); #endif base.Awake(); } new void OnApplicationQuit() { base.OnApplicationQuit(); #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= Logger; #else Application.RegisterLogCallback(null); #endif } void Logger(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 200, 400, 400), tips); } } ================================================ FILE: Assets/ToLua/Examples/13_CustomLoader/TestCustomLoader.cs.meta ================================================ fileFormatVersion: 2 guid: bc2267b374446b24faf55d67673d8e63 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/13_CustomLoader.meta ================================================ fileFormatVersion: 2 guid: 9fc9a6d7d2170ce43bfdcb7197628a9d folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/14_Out/TestOut.unity.meta ================================================ fileFormatVersion: 2 guid: c1cff06827ae69d45ba691b5714e066d DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/14_Out/TestOutArg.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System; public class TestOutArg : MonoBehaviour { string script = @" local box = UnityEngine.BoxCollider function TestPick(ray) local _layer = 2 ^ LayerMask.NameToLayer('Default') local time = os.clock() local flag, hit = UnityEngine.Physics.Raycast(ray, nil, 5000, _layer) --local flag, hit = UnityEngine.Physics.Raycast(ray, RaycastHit.out, 5000, _layer) if flag then print('pick from lua, point: '..tostring(hit.point)) end end "; LuaState state = null; LuaFunction func = null; string tips = string.Empty; void Start () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); state = new LuaState(); LuaBinder.Bind(state); state.Start(); state.DoString(script, "TestOutArg.cs"); func = state.GetFunction("TestPick"); } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnApplicationQuit() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } private void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } void Update() { if (Input.GetMouseButtonDown(0)) { Camera camera = Camera.main; Ray ray = camera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; bool flag = Physics.Raycast(ray, out hit, 5000, 1 << LayerMask.NameToLayer("Default")); if (flag) { Debugger.Log("pick from c#, point: [{0}, {1}, {2}]", hit.point.x, hit.point.y, hit.point.z); } func.BeginPCall(); func.Push(ray); func.PCall(); func.EndPCall(); } state.CheckTop(); state.Collect(); } void OnDestroy() { func.Dispose(); func = null; state.Dispose(); state = null; } } ================================================ FILE: Assets/ToLua/Examples/14_Out/TestOutArg.cs.meta ================================================ fileFormatVersion: 2 guid: cb859a8f0bf518243b6fc7c57eeef886 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/14_Out.meta ================================================ fileFormatVersion: 2 guid: b9762f66a6f78d843b27a77925f63e3f folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/ProtoBuffer.unity.meta ================================================ fileFormatVersion: 2 guid: 1a4304ba0253d9241b8bf736a8607df6 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/TestProtoBuffer.cs ================================================ //#define USE_PROTOBUF_NET using UnityEngine; using System.Collections; using LuaInterface; using System; using System.IO; #if USE_PROTOBUF_NET using ProtoBuf; [ProtoContract] class Header { [ProtoMember(1, IsRequired = true)] public int cmd { get; set; } [ProtoMember(2, IsRequired = true)] public int seq { get; set; } } [ProtoContract] class Person { [ProtoMember(1, IsRequired = true)] public Header header { get; set; } [ProtoMember(2, IsRequired = true)] public long id { get; set; } [ProtoMember(3, IsRequired = true)] public string name { get; set; } [ProtoMember(4, IsRequired = false)] public int age { get; set; } [ProtoMember(5, IsRequired = false)] public string email { get; set; } [ProtoMember(6, IsRequired = true)] public int[] array; } #endif public class TestProtoBuffer : LuaClient { private string script = @" local common_pb = require 'Protol.common_pb' local person_pb = require 'Protol.person_pb' function Decoder() local msg = person_pb.Person() msg:ParseFromString(TestProtol.data) --tostring 不会打印默认值 print('person_pb decoder: '..tostring(msg)..'age: '..msg.age..'\nemail: '..msg.email) end function Encoder() local msg = person_pb.Person() msg.header.cmd = 10010 msg.header.seq = 1 msg.id = '1223372036854775807' msg.name = 'foo' --数组添加 msg.array:append(1) msg.array:append(2) --extensions 添加 local phone = msg.Extensions[person_pb.Phone.phones]:add() phone.num = '13788888888' phone.type = person_pb.Phone.MOBILE local pb_data = msg:SerializeToString() TestProtol.data = pb_data end "; private string tips = ""; //实际应用如Socket.Send(LuaStringBuffer buffer)函数发送协议, 在lua中调用Socket.Send(pb_data) //读取协议 Socket.PeekMsgPacket() {return MsgPacket}; lua 中,取协议字节流 MsgPack.data 为 LuaStringBuffer类型 //msg = Socket.PeekMsgPacket() //pb_data = msg.data new void Awake() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif base.Awake(); } protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } protected override void Bind() { base.Bind(); luaState.BeginModule(null); TestProtolWrap.Register(luaState); luaState.EndModule(); } //屏蔽,例子不需要运行 protected override void CallMain() { } protected override void OnLoadFinished() { base.OnLoadFinished(); luaState.DoString(script, "TestProtoBuffer.cs"); #if !USE_PROTOBUF_NET LuaFunction func = luaState.GetFunction("Encoder"); func.Call(); func.Dispose(); func = luaState.GetFunction("Decoder"); func.Call(); func.Dispose(); func = null; #else Person data = new Person(); data.id = 1223372036854775807; data.name = "foo"; data.header = new Header(); data.header.cmd = 10086; data.header.seq = 1; data.array = new int[2]; data.array[0] = 1; data.array[1] = 2; MemoryStream stream = new MemoryStream(); Serializer.Serialize(stream, data); TestProtol.data = stream.ToArray(); LuaFunction func = luaState.GetFunction("Decoder"); func.Call(); func.Dispose(); func = null; func = luaState.GetFunction("Encoder"); func.Call(); func.Dispose(); func = null; stream = new MemoryStream(TestProtol.data); data = Serializer.Deserialize(stream); Debugger.Log("Decoder from lua int64 is: {0}, cmd: {1}", data.id, data.header.cmd); #endif } void ShowTips(string msg, string stackTrace, LogType type) { tips = tips + msg + "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 250, Screen.height / 2 - 200, 500, 500), tips); } new void OnApplicationQuit() { base.Destroy(); #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } } ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/TestProtoBuffer.cs.meta ================================================ fileFormatVersion: 2 guid: 07805e704145c3b47b7c511a16d66d99 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/TestProtol.cs ================================================ using System; using LuaInterface; public static class TestProtol { [LuaByteBufferAttribute] public static byte[] data; } ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/TestProtol.cs.meta ================================================ fileFormatVersion: 2 guid: 486ec4f4b6496a94c85974a2e0c1bd78 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/TestProtolWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class TestProtolWrap { public static void Register(LuaState L) { L.BeginStaticLibs("TestProtol"); L.RegVar("data", get_data, set_data); L.EndStaticLibs(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_data(IntPtr L) { try { LuaDLL.tolua_pushlstring(L, TestProtol.data, TestProtol.data.Length); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_data(IntPtr L) { try { byte[] arg0 = ToLua.CheckByteBuffer(L, 2); TestProtol.data = arg0; return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/TestProtolWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 25408b0022185f34c9744c405ad5da65 timeCreated: 1515038394 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/common.proto ================================================ message Header { required int64 cmd = 1; required int32 seq = 2; } ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/common.proto.meta ================================================ fileFormatVersion: 2 guid: 760d09f03acd6ed4e94516e3b7439c54 timeCreated: 1498133645 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/person.proto ================================================ import "common.proto"; message Person { required Header header = 1; required int64 id = 2; required string name = 3; optional int32 age = 4 [default = 18]; optional string email = 5 [default = "topameng@qq.com"]; repeated int32 array = 6; extensions 10 to max; } message Phone { extend Person { repeated Phone phones = 10;} enum PHONE_TYPE { MOBILE = 1; HOME = 2; } optional string num = 1; optional PHONE_TYPE type = 2; } ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer/person.proto.meta ================================================ fileFormatVersion: 2 guid: f84fe6c5b2078174bb56bed15abd687b DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/15_ProtoBuffer.meta ================================================ fileFormatVersion: 2 guid: cac1317b8ab1d3a438e2fa736a69d7fe folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/16_Int64/TestInt64.cs ================================================ using UnityEngine; using System.Collections; using System; using LuaInterface; using System.Collections.Generic; public class TestInt64 : MonoBehaviour { private string tips = ""; string script = @" function TestInt64(x) x = 789 + x assert(tostring(x) == '9223372036854775807') local low, high = int64.tonum2(x) print('x value is: '..tostring(x)..' low is: '.. low .. ' high is: '..high.. ' type is: '.. tolua.typename(x)) local y = int64.new(1,2) local z = int64.new(1,2) if y == z then print('int64 equals is ok, value: '..int64.tostring(y)) end x = int64.new(123) if int64.equals(x, 123) then print('int64 equals to number ok') else print('int64 equals to number failed') end x = int64.new('78962871035984074') print('int64 is: '..tostring(x)) local str = tostring(int64.new(3605690779, 30459971)) local n2 = int64.new(str) local l, h = int64.tonum2(n2) print(str..':'..tostring(n2)..' low:'..l..' high:'..h) print('----------------------------uint64-----------------------------') x = uint64.new('18446744073709551615') print('uint64 max is: '..tostring(x)) l, h = uint64.tonum2(x) str = tostring(uint64.new(l, h)) print(str..':'..tostring(x)..' low:'..l..' high:'..h) return y end "; void Start() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); LuaState lua = new LuaState(); lua.Start(); lua.DoString(script, "TestInt64.cs"); LuaFunction func = lua.GetFunction("TestInt64"); func.BeginPCall(); func.Push(9223372036854775807 - 789); func.PCall(); long n64 = func.CheckLong(); Debugger.Log("int64 return from lua is: {0}", n64); func.EndPCall(); func.Dispose(); func = null; lua.CheckTop(); lua.Dispose(); lua = null; } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnDestroy() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } } ================================================ FILE: Assets/ToLua/Examples/16_Int64/TestInt64.cs.meta ================================================ fileFormatVersion: 2 guid: d2eb3e2c0caea144e8cbbb8de6ed33f8 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/16_Int64/TestInt64.unity.meta ================================================ fileFormatVersion: 2 guid: 9f5fdf9606a2d854590fcbd3926005e4 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/16_Int64.meta ================================================ fileFormatVersion: 2 guid: 56454d123fe4d2a47a2a1bf5e9a7399b folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/17_Inherit/Inherit.unity.meta ================================================ fileFormatVersion: 2 guid: a3cf1516f0a320b49a263c1fed026319 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/17_Inherit/TestInherit.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; public class TestInherit : MonoBehaviour { private string script = @" LuaTransform = { } function LuaTransform.Extend(u) local t = {} local _position = u.position tolua.setpeer(u, t) t.__index = t local get = tolua.initget(t) local set = tolua.initset(t) local _base = u.base --重写同名属性获取 get.position = function(self) return _position end --重写同名属性设置 set.position = function(self, v) if _position ~= v then _position = v _base.position = v end end --重写同名函数 function t:Translate(...) print('child Translate') _base:Translate(...) end return u end --既保证支持继承函数,又支持go.transform == transform 这样的比较 function Test(node) local v = Vector3.one local transform = LuaTransform.Extend(node) local t = os.clock() for i = 1, 200000 do transform.position = transform.position end print('LuaTransform get set cost', os.clock() - t) transform:Translate(1,1,1) local child = transform:Find('child') print('child is: ', tostring(child)) if child.parent == transform then print('LuaTransform compare to userdata transform is ok') end transform.xyz = 123 transform.xyz = 456 print('extern field xyz is: '.. transform.xyz) end "; LuaState lua = null; void Start () { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); lua = new LuaState(); lua.Start(); LuaBinder.Bind(lua); lua.DoString(script, "TestInherit.cs"); float time = Time.realtimeSinceStartup; for (int i = 0; i < 200000; i++) { Vector3 v = transform.position; transform.position = v; } time = Time.realtimeSinceStartup - time; Debugger.Log("c# Transform get set cost time: " + time); lua.Call("Test", transform, true); lua.Dispose(); lua = null; } string tips; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnDestroy() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } } ================================================ FILE: Assets/ToLua/Examples/17_Inherit/TestInherit.cs.meta ================================================ fileFormatVersion: 2 guid: a9cb964bd30f70946ab3ba186316e134 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/17_Inherit.meta ================================================ fileFormatVersion: 2 guid: 49da3d0eb205def459dc639d92b7cc77 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/18_Bundle/TesetAssetBundle.unity.meta ================================================ fileFormatVersion: 2 guid: 207ce505e47eb8542963d4972b45b05d DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/18_Bundle/TestABLoader.cs ================================================ using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; using LuaInterface; using System; //click Lua/Build lua bundle public class TestABLoader : MonoBehaviour { int bundleCount = int.MaxValue; string tips = null; IEnumerator CoLoadBundle(string name, string path) { using (WWW www = new WWW(path)) { if (www == null) { Debugger.LogError(name + " bundle not exists"); yield break; } yield return www; if (www.error != null) { Debugger.LogError(string.Format("Read {0} failed: {1}", path, www.error)); yield break; } --bundleCount; LuaFileUtils.Instance.AddSearchBundle(name, www.assetBundle); www.Dispose(); } } IEnumerator LoadFinished() { while (bundleCount > 0) { yield return null; } OnBundleLoad(); } public IEnumerator LoadBundles() { string streamingPath = Application.streamingAssetsPath.Replace('\\', '/'); #if UNITY_5 || UNITY_2017 || UNITY_2018 #if UNITY_ANDROID && !UNITY_EDITOR string main = streamingPath + "/" + LuaConst.osDir + "/" + LuaConst.osDir; #else string main = "file:///" + streamingPath + "/" + LuaConst.osDir + "/" + LuaConst.osDir; #endif WWW www = new WWW(main); yield return www; AssetBundleManifest manifest = (AssetBundleManifest)www.assetBundle.LoadAsset("AssetBundleManifest"); List list = new List(manifest.GetAllAssetBundles()); #else //此处应该配表获取 List list = new List() { "lua.unity3d", "lua_cjson.unity3d", "lua_system.unity3d", "lua_unityengine.unity3d", "lua_protobuf.unity3d", "lua_misc.unity3d", "lua_socket.unity3d", "lua_system_reflection.unity3d" }; #endif bundleCount = list.Count; for (int i = 0; i < list.Count; i++) { string str = list[i]; #if UNITY_ANDROID && !UNITY_EDITOR string path = streamingPath + "/" + LuaConst.osDir + "/" + str; #else string path = "file:///" + streamingPath + "/" + LuaConst.osDir + "/" + str; #endif string name = Path.GetFileNameWithoutExtension(str); StartCoroutine(CoLoadBundle(name, path)); } yield return StartCoroutine(LoadFinished()); } void Awake() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif LuaFileUtils file = new LuaFileUtils(); file.beZip = true; #if UNITY_ANDROID && UNITY_EDITOR if (IntPtr.Size == 8) { throw new Exception("can't run this in unity5.x process for 64 bits, switch to pc platform, or run it in android mobile"); } #endif StartCoroutine(LoadBundles()); } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 150, 400, 300), tips); } void OnApplicationQuit() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void OnBundleLoad() { LuaState state = new LuaState(); state.Start(); state.DoString("print('hello tolua#:'..tostring(Vector3.zero))"); state.DoFile("Main.lua"); LuaFunction func = state.GetFunction("Main"); func.Call(); func.Dispose(); state.Dispose(); state = null; } } ================================================ FILE: Assets/ToLua/Examples/18_Bundle/TestABLoader.cs.meta ================================================ fileFormatVersion: 2 guid: d357c949a4510b146a6e82777d131d20 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/18_Bundle.meta ================================================ fileFormatVersion: 2 guid: 07aecff784dcab84393e4fad04c7b35d folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/19_cjson/TestCJson.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; public class TestCJson : LuaClient { string script = @" local json = require 'cjson' function Test(str) local data = json.decode(str) print(data.glossary.title) s = json.encode(data) print(s) end "; protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } protected override void OpenLibs() { base.OpenLibs(); OpenCJson(); } protected override void OnLoadFinished() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif base.OnLoadFinished(); TextAsset text = (TextAsset)Resources.Load("jsonexample", typeof(TextAsset)); string str = text.ToString(); luaState.DoString(script); LuaFunction func = luaState.GetFunction("Test"); func.BeginPCall(); func.Push(str); func.PCall(); func.EndPCall(); func.Dispose(); } //屏蔽,例子不需要运行 protected override void CallMain() { } string tips; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } new void OnApplicationQuit() { base.OnApplicationQuit(); #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } } ================================================ FILE: Assets/ToLua/Examples/19_cjson/TestCJson.cs.meta ================================================ fileFormatVersion: 2 guid: b3dab0c9b55ca0f44a0d3b8a50edf396 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/19_cjson/testcjson.unity.meta ================================================ fileFormatVersion: 2 guid: 0dbc965b474b6824db5cb79d380403e4 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/19_cjson.meta ================================================ fileFormatVersion: 2 guid: 3c1a9e6cb95cdea4cbc97a336446abe8 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/20_utf8/TestUTF8.cs ================================================ using UnityEngine; using LuaInterface; public class TestUTF8 : LuaClient { string script = @" local utf8 = utf8 function Test() local l1 = utf8.len('你好') local l2 = utf8.len('こんにちは') print('chinese string len is: '..l1..' japanese sting len: '..l2) local s = '遍历字符串' for i in utf8.byte_indices(s) do local next = utf8.next(s, i) print(s:sub(i, next and next -1)) end local s1 = '天下风云出我辈' print('风云 count is: '..utf8.count(s1, '风云')) s1 = s1:gsub('风云', '風雲') local function replace(s, i, j, repl_char) if s:sub(i, j) == '辈' then return repl_char end end print(utf8.replace(s1, replace, '輩')) end "; protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } //屏蔽,例子不需要运行 protected override void CallMain() { } protected override void OnLoadFinished() { #if UNITY_4_6 || UNITY_4_7 Application.RegisterLogCallback(ShowTips); #else Application.logMessageReceived += ShowTips; #endif base.OnLoadFinished(); luaState.DoString(script, "TestUTF8.cs"); LuaFunction func = luaState.GetFunction("Test"); func.Call(); func.Dispose(); func = null; } string tips; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } new void OnApplicationQuit() { base.OnApplicationQuit(); #if UNITY_4_6 || UNITY_4_7 Application.RegisterLogCallback(null); #else Application.logMessageReceived -= ShowTips; #endif } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } } ================================================ FILE: Assets/ToLua/Examples/20_utf8/TestUTF8.cs.meta ================================================ fileFormatVersion: 2 guid: 0c58b879bbb37ee4891c46ef87989f91 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/20_utf8/utf8.unity.meta ================================================ fileFormatVersion: 2 guid: 74b6932cd0642734eb36e554528a9825 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/20_utf8.meta ================================================ fileFormatVersion: 2 guid: 48896cd2daf4f4542ba776681732210a folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/21_String/TestString.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System; using System.Reflection; using System.Text; public class TestString : LuaClient { string script = @" function Test() local str = System.String.New('男儿当自强') local index = str:IndexOfAny('儿自') print('and index is: '..index) local buffer = str:ToCharArray() print('str type is: '..type(str)..' buffer[0] is ' .. buffer[0]) local luastr = tolua.tolstring(buffer) print('lua string is: '..luastr..' type is: '..type(luastr)) luastr = tolua.tolstring(str) print('lua string is: '..luastr) end "; protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } //屏蔽,例子不需要运行 protected override void CallMain() { } protected override void OnLoadFinished() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif base.OnLoadFinished(); luaState.DoString(script); LuaFunction func = luaState.GetFunction("Test"); func.Call(); func.Dispose(); func = null; } string tips; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } new void OnApplicationQuit() { base.OnApplicationQuit(); #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } } ================================================ FILE: Assets/ToLua/Examples/21_String/TestString.cs.meta ================================================ fileFormatVersion: 2 guid: 73dc7ee420beffa4b9db2334045dabba MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/21_String/TestString.unity.meta ================================================ fileFormatVersion: 2 guid: 8e6bca3bb283b3247a8692ac6e03d4ff DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/21_String.meta ================================================ fileFormatVersion: 2 guid: d7bfd51b922b87a4ba399b7f73540493 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/22_Reflection/TestReflection.cs ================================================ using UnityEngine; using System.Collections.Generic; using LuaInterface; using System; using System.Reflection; public class TestReflection : LuaClient { string script = @" require 'tolua.reflection' tolua.loadassembly('Assembly-CSharp') local BindingFlags = require 'System.Reflection.BindingFlags' function DoClick() print('do click') end function Test() local t = typeof('TestExport') local func = tolua.getmethod(t, 'TestReflection') func:Call() func:Destroy() func = nil local objs = {Vector3.one, Vector3.zero} local array = tolua.toarray(objs, typeof(Vector3)) local obj = tolua.createinstance(t, array) --local constructor = tolua.getconstructor(t, typeof(Vector3):MakeArrayType()) --local obj = constructor:Call(array) --constructor:Destroy() func = tolua.getmethod(t, 'Test', typeof('System.Int32'):MakeByRefType()) local r, o = func:Call(obj, 123) print(r..':'..o) func:Destroy() local property = tolua.getproperty(t, 'Number') local num = property:Get(obj, null) print('object Number: '..num) property:Set(obj, 456, null) num = property:Get(obj, null) property:Destroy() print('object Number: '..num) local field = tolua.getfield(t, 'field') num = field:Get(obj) print('object field: '.. num) field:Set(obj, 2048) num = field:Get(obj) field:Destroy() print('object field: '.. num) field = tolua.getfield(t, 'OnClick') local onClick = field:Get(obj) onClick = onClick + DoClick field:Set(obj, onClick) local click = field:Get(obj) click:DynamicInvoke() field:Destroy() click:Destroy() end "; string tips = null; protected override LuaFileUtils InitLoader() { #if UNITY_4_6 || UNITY_4_7 Application.RegisterLogCallback(ShowTips); #else Application.logMessageReceived += ShowTips; #endif return new LuaResLoader(); } //屏蔽,例子不需要运行 protected override void CallMain() { } void TestAction() { Debugger.Log("Test Action"); } protected override void OnLoadFinished() { base.OnLoadFinished(); /*Type t = typeof(TestExport); MethodInfo md = t.GetMethod("TestReflection"); md.Invoke(null, null); Vector3[] array = new Vector3[] { Vector3.zero, Vector3.one }; object obj = Activator.CreateInstance(t, array); md = t.GetMethod("Test", new Type[] { typeof(int).MakeByRefType() }); object o = 123; object[] args = new object[] { o }; object ret = md.Invoke(obj, args); Debugger.Log(ret + " : " + args[0]); PropertyInfo p = t.GetProperty("Number"); int num = (int)p.GetValue(obj, null); Debugger.Log("object Number: {0}", num); p.SetValue(obj, 456, null); num = (int)p.GetValue(obj, null); Debugger.Log("object Number: {0}", num); FieldInfo f = t.GetField("field"); num = (int)f.GetValue(obj); Debugger.Log("object field: {0}", num); f.SetValue(obj, 2048); num = (int)f.GetValue(obj); Debugger.Log("object field: {0}", num);*/ luaState.CheckTop(); luaState.DoString(script, "TestReflection.cs"); LuaFunction func = luaState.GetFunction("Test"); func.Call(); func.Dispose(); func = null; } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } new void OnApplicationQuit() { #if UNITY_4_6 || UNITY_4_7 Application.RegisterLogCallback(ShowTips); #else Application.logMessageReceived += ShowTips; #endif Destroy(); } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 250, Screen.height / 2 - 150, 500, 300), tips); } } ================================================ FILE: Assets/ToLua/Examples/22_Reflection/TestReflection.cs.meta ================================================ fileFormatVersion: 2 guid: fab693360b2865f4a9121b9959993d29 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/22_Reflection/TestReflection.unity.meta ================================================ fileFormatVersion: 2 guid: 0c297fdd08a27a54a96505801547f7b2 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/22_Reflection.meta ================================================ fileFormatVersion: 2 guid: 1160a89e211090a4ea787fb5145cc984 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/23_List/UseList.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System.Collections.Generic; using System; //需要导出委托类型如下: //System.Predicate //System.Action //System.Comparison public class UseList : LuaClient { private string script = @" function Exist2(v) return v == 2 end function IsEven(v) return v % 2 == 0 end function NotExist(v) return false end function Compare(a, b) if a > b then return 1 elseif a == b then return 0 else return -1 end end function Test(list, list1) list:Add(123) print('Add result: list[0] is '..list[0]) list:AddRange(list1) print(string.format('AddRange result: list[1] is %d, list[2] is %d', list[1], list[2])) local const = list:AsReadOnly() print('AsReadOnley:'..const[0]) index = const:IndexOf(123) if index == 0 then print('const IndexOf is ok') end local pos = list:BinarySearch(1) print('BinarySearch 1 result is: '..pos) if list:Contains(123) then print('list Contain 123') else error('list Contains result fail') end if list:Exists(Exist2) then print('list exists 2') else error('list exists result fail') end if list:Find(Exist2) then print('list Find is ok') else print('list Find error') end local fa = list:FindAll(IsEven) if fa.Count == 2 then print('FindAll is ok') end --注意推导后的委托声明必须注册, 这里是System.Predicate local index = list:FindIndex(System.Predicate_int(Exist2)) if index == 2 then print('FindIndex is ok') end index = list:FindLastIndex(System.Predicate_int(Exist2)) if index == 2 then print('FindLastIndex is ok') end index = list:IndexOf(123) if index == 0 then print('IndexOf is ok') end index = list:LastIndexOf(123) if index == 0 then print('LastIndexOf is ok') end list:Remove(123) if list[0] ~= 123 then print('Remove is ok') end list:Insert(0, 123) if list[0] == 123 then print('Insert is ok') end list:RemoveAt(0) if list[0] ~= 123 then print('RemoveAt is ok') end list:Insert(0, 123) list:ForEach(function(v) print('foreach: '..v) end) local count = list.Count list:Sort(System.Comparison_int(Compare)) print('--------------sort list over----------------------') for i = 0, count - 1 do print('for:'..list[i]) end list:Clear() print('list Clear not count is '..list.Count) end "; protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } //屏蔽,例子不需要运行 protected override void CallMain() { } protected override void OnLoadFinished() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif base.OnLoadFinished(); luaState.DoString(script, "UseList.cs"); List list1 = new List(); list1.Add(1); list1.Add(2); list1.Add(4); LuaFunction func = luaState.GetFunction("Test"); func.BeginPCall(); func.Push(new List()); func.Push(list1); func.PCall(); func.EndPCall(); func.Dispose(); func = null; } string tips; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } new void OnApplicationQuit() { base.OnApplicationQuit(); #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips); } } ================================================ FILE: Assets/ToLua/Examples/23_List/UseList.cs.meta ================================================ fileFormatVersion: 2 guid: 8a4f97c41d925314c853a72d43fb5166 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/23_List/UseList.unity.meta ================================================ fileFormatVersion: 2 guid: a4f35714ff91744489f71618b0ae9fd8 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/23_List.meta ================================================ fileFormatVersion: 2 guid: 665099d7241e1a54fb217e3b172e21a7 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/24_Struct/PassStruct.cs ================================================ using UnityEngine; using LuaInterface; using System; using Debugger = LuaInterface.Debugger; namespace LuaInterface { public partial struct LuaValueType { public const int Rect = 13; } } public class PassStruct : LuaClient { private string script = @" Rect = {} function Rect.New(x,y,w,h) local rt = {x = x, y = y, w = w, h = h} setmetatable(rt, Rect) return rt end function Rect:Get() return self.x, self.y, self.w, self.h end Rect.__tostring = function(self) return '(x:'..self.x..', y:'..self.y..', width:'..self.w..', height:'..self.h..')' end function PrintRect(rt) print(tostring(rt)) return rt end setmetatable(Rect, Rect) AddValueType(Rect, 13) "; void PushRect(IntPtr L, Rect rt) { LuaDLL.lua_getref(L, NewRect.GetReference()); LuaDLL.lua_pushnumber(L, rt.xMin); LuaDLL.lua_pushnumber(L, rt.yMin); LuaDLL.lua_pushnumber(L, rt.width); LuaDLL.lua_pushnumber(L, rt.height); LuaDLL.lua_call(L, 4, 1); } Rect ToRectValue(IntPtr L, int pos) { pos = LuaDLL.abs_index(L, pos); LuaDLL.lua_getref(L, GetRect.GetReference()); LuaDLL.lua_pushvalue(L, pos); LuaDLL.lua_call(L, 1, 4); float x = (float)LuaDLL.lua_tonumber(L, -4); float y = (float)LuaDLL.lua_tonumber(L, -3); float w = (float)LuaDLL.lua_tonumber(L, -2); float h = (float)LuaDLL.lua_tonumber(L, -1); LuaDLL.lua_pop(L, 4); return new Rect(x, y, w, h); } Rect CheckRectValue(IntPtr L, int pos) { int type = LuaDLL.tolua_getvaluetype(L, pos); if (type != LuaValueType.Rect) { luaState.LuaTypeError(pos, "Rect", LuaValueTypeName.Get(type)); return new Rect(); } return ToRectValue(L, pos); } bool CheckRectType(IntPtr L, int pos) { return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Rect; } bool CheckNullRectType(IntPtr L, int pos) { LuaTypes luaType = LuaDLL.lua_type(L, pos); switch (luaType) { case LuaTypes.LUA_TNIL: return true; case LuaTypes.LUA_TTABLE: return LuaDLL.tolua_getvaluetype(L, pos) == LuaValueType.Rect; default: return false; } } object ToRectTable(IntPtr L, int pos) { return ToRectValue(L, pos); } string tips = null; void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } new void OnApplicationQuit() { base.OnApplicationQuit(); #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif } new void Awake() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif base.Awake(); } protected override void OnLoadFinished() { base.OnLoadFinished(); luaState.DoString(script, "PassStruct.cs"); NewRect = luaState.GetFunction("Rect.New"); GetRect = luaState.GetFunction("Rect.Get"); StackTraits.Init(PushRect, CheckRectValue, ToRectValue); //支持压入lua以及从lua栈读取 TypeTraits.Init(CheckRectType); //支持重载函数TypeCheck.CheckTypes TypeTraits>.Init(CheckNullRectType); //支持重载函数TypeCheck.CheckTypes LuaValueTypeName.names[LuaValueType.Rect] = "Rect"; //CheckType失败提示的名字 TypeChecker.LuaValueTypeMap[LuaValueType.Rect] = typeof(Rect); //用于支持类型匹配检查操作 ToLua.ToVarMap[LuaValueType.Rect] = ToRectTable; //Rect作为object读取 ToLua.VarPushMap[typeof(Rect)] = (L, o) => { PushRect(L, (Rect)o); }; //Rect作为object压入 //测试例子 LuaFunction func = luaState.GetFunction("PrintRect"); func.BeginPCall(); func.PushValue(new Rect(10, 20, 120, 50)); func.PCall(); Rect rt = func.CheckValue(); func.EndPCall(); Debugger.Log(rt); Debugger.Log(Vector3.one.ToString()); } LuaFunction NewRect = null; LuaFunction GetRect = null; protected override LuaFileUtils InitLoader() { return new LuaResLoader(); } private void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 220, Screen.height / 2 - 200, 400, 400), tips); } //屏蔽,例子不需要运行 protected override void CallMain() { } } ================================================ FILE: Assets/ToLua/Examples/24_Struct/PassStruct.cs.meta ================================================ fileFormatVersion: 2 guid: 51af02ba87a948543b788453b5bb790c timeCreated: 1495007962 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/24_Struct/Struct.unity.meta ================================================ fileFormatVersion: 2 guid: bab0d380ec96e4846bcd28c1d626d89f timeCreated: 1495007901 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/24_Struct.meta ================================================ fileFormatVersion: 2 guid: a817b98d5c7d23e4c9c6afb6ac646cbe folderAsset: yes timeCreated: 1495007845 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/Performance/Performance.unity.meta ================================================ fileFormatVersion: 2 guid: 0693d19658479a642a7faaa61feb2c09 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Performance/TestPerformance.cs ================================================ using System; using UnityEngine; using System.Collections.Generic; using LuaInterface; using System.Collections; using System.Runtime.InteropServices; public class TestPerformance : MonoBehaviour { LuaState state = null; private string tips = ""; private void Start() { #if UNITY_4_6 || UNITY_4_7 Application.RegisterLogCallback(ShowTips); #else Application.logMessageReceived += ShowTips; #endif new LuaResLoader(); state = new LuaState(); state.Start(); LuaBinder.Bind(state); state.DoFile("TestPerf.lua"); } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; } void OnApplicationQuit() { #if UNITY_4_6 || UNITY_4_7 Application.RegisterLogCallback(null); #else Application.logMessageReceived -= ShowTips; #endif state.Dispose(); state = null; } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 220, Screen.height / 2 - 200, 400, 400), tips); if (GUI.Button(new Rect(50, 50, 120, 45), "Test1")) { float time = Time.realtimeSinceStartup; for (int i = 0; i < 200000; i++) { Vector3 v = transform.position; transform.position = v + Vector3.one; } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("c# Transform getset cost time: " + time); transform.position = Vector3.zero; LuaFunction func = state.GetFunction("Test1"); func.BeginPCall(); func.Push(transform); func.PCall(); func.EndPCall(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(50, 150, 120, 45), "Test2")) { float time = Time.realtimeSinceStartup; for (int i = 0; i < 200000; i++) { transform.Rotate(Vector3.up, 1); } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("c# Transform.Rotate cost time: " + time); LuaFunction func = state.GetFunction("Test2"); func.BeginPCall(); func.Push(transform); func.PCall(); func.EndPCall(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(50, 250, 120, 45), "Test3")) { float time = Time.realtimeSinceStartup; for (int i = 0; i < 2000000; i++) { new Vector3(i, i, i); } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("c# new Vector3 cost time: " + time); LuaFunction func = state.GetFunction("Test3"); func.Call(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(50, 350, 120, 45), "Test4")) { float time = Time.realtimeSinceStartup; for (int i = 0; i < 20000; i++) { new GameObject(); } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("c# new GameObject cost time: " + time); //光gc了 LuaFunction func = state.GetFunction("Test4"); func.Call(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(50, 450, 120, 45), "Test5")) { int[] array = new int[1024]; for (int i = 0; i < 1024; i++) { array[i] = i; } float time = Time.realtimeSinceStartup; int total = 0; for (int j = 0; j < 100000; j++) { for (int i = 0; i < 1024; i++) { total += array[i]; } } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("Array cost time: " + time); List list = new List(array); time = Time.realtimeSinceStartup; total = 0; for (int j = 0; j < 100000; j++) { for (int i = 0; i < 1024; i++) { total += list[i]; } } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("Array cost time: " + time); LuaFunction func = state.GetFunction("TestTable"); func.Call(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(50, 550, 120, 40), "Test7")) { float time = Time.realtimeSinceStartup; Vector3 v1 = Vector3.zero; for (int i = 0; i < 200000; i++) { Vector3 v = new Vector3(i,i,i); v = Vector3.Normalize(v); v1 = v + v1; } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("Vector3 New Normalize cost: " + time); LuaFunction func = state.GetFunction("Test7"); func.Call(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(250, 50, 120, 40), "Test8")) { float time = Time.realtimeSinceStartup; for (int i = 0; i < 200000; i++) { Quaternion q1 = Quaternion.Euler(i, i, i); Quaternion q2 = Quaternion.Euler(i * 2, i * 2, i * 2); Quaternion.Slerp(q1, q2, 0.5f); } time = Time.realtimeSinceStartup - time; tips = ""; Debugger.Log("Quaternion Euler Slerp cost: " + time); LuaFunction func = state.GetFunction("Test8"); func.Call(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(250, 150, 120, 40), "Test9")) { tips = ""; LuaFunction func = state.GetFunction("Test9"); func.Call(); func.Dispose(); func = null; } else if (GUI.Button(new Rect(250, 250, 120, 40), "Quit")) { Application.Quit(); } if (state != null) { state.CheckTop(); state.Collect(); } } } ================================================ FILE: Assets/ToLua/Examples/Performance/TestPerformance.cs.meta ================================================ fileFormatVersion: 2 guid: e3be970387cfeea42a1944adffc6fffc MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/Performance.meta ================================================ fileFormatVersion: 2 guid: f240c18ff8d4eb44390f8d949e2f6fbd folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/README.md ================================================ ## 例子1 展示了最小的tolua#环境,以及执行一段lua代码操作代码如下: ``` csharp LuaState lua = new LuaState(); lua.Start(); string hello = @" print('hello tolua#') "; lua.DoString(hello, "HelloWorld.cs"); lua.CheckTop(); lua.Dispose(); lua = null; ``` LuaState封装了对lua 主要数据结构 lua_State 指针的各种堆栈操作。
一般对于客户端,推荐只创建一个LuaState对象。如果要使用多State需要在Unity中设置全局宏 MULTI_STATE
* LuaState.Start 需要在tolua代码加载到内存后调用。如果使用assetbunblde加载lua文件,调用Start()之前assetbundle必须加载好
* LuaState.DoString 执行一段lua代码,除了例子,比较少用这种方式加载代码,无法避免代码重复加载覆盖等,需调用者自己保证。第二个参数用于调试信息,或者error消息(用于提示出错代码所在文件名称)
* LuaState.CheckTop 检查是否堆栈是否平衡,一般放于update中,c#中任何使用lua堆栈操作,都需要调用者自己平衡堆栈(参考LuaFunction以及LuaTable代码), 当CheckTop出现警告时其实早已经离开了堆栈操作范围,这是需自行review代码。
* LuaState.Dispose 释放LuaState 以及其资源。
> **注意:** 此例子无法发布到手机 ## 例子2 展示了dofile跟require的区别, 代码如下: ``` csharp LuaState lua = null; void Start () { lua = new LuaState(); lua.Start(); //如果移动了ToLua目录,需要自己手动,这里只是例子就不做配置了 string fullPath = Application.dataPath + "/ToLua/Examples/02_ScriptsFromFile"; lua.AddSearchPath(fullPath); } void OnGUI() { if (GUI.Button(new Rect(50, 50, 120, 45), "DoFile")) { lua.DoFile("ScriptsFromFile.lua"); } else if (GUI.Button(new Rect(50, 150, 120, 45), "Require")) { lua.Require("ScriptsFromFile"); } lua.Collect(); lua.CheckTop(); } void OnApplicationQuit() { lua.Dispose(); lua = null; } ``` tolua#DoFile函数,跟lua保持一致行为,能多次执行一个文件。tolua#加入了新的Require函数,无论c#和lua谁先require一个lua文件, 都能保证加载唯一性
* LuaState.AddSearchPath 增加搜索目录, 这样DoFile跟Require函数可以只用文件名,无需写全路径
* LuaState.DoFile 加载一个lua文件, 注意dofile需要扩展名, 可反复执行, 后面的变量会覆盖之前的DoFile加载的变量
* LuaState.Require 同lua require(modname)操作, 加载指定模块并且把结果写入到package.loaded中,如果modname存在, 则直接返回package.loaded[modname]
* LuaState.Collect 垃圾回收, 对于被自动gc的LuaFunction, LuaTable, 以及委托减掉的LuaFunction, 延迟删除的Object之类。等等需要延迟处理的回收, 都在这里自动执行
> **注意:** 虽然有文件加载,但此例子无法发布到手机, 如果ToLua目录不在/Assets目录下, 需要修改代码中的目录位置
## 例子3 LuaFunction 展示了如何调用lua的函数, 主要代码如下: ``` csharp private string script = @" function luaFunc(num) return num + 1 end test = {} test.luaFunc = luaFunc "; LuaFunction luaFunc = null; LuaState lua = null; void Start () { new LuaResLoader(); lua = new LuaState(); lua.Start(); DelegateFactory.Init(); lua.DoString(script); //Get the function object luaFunc = lua.GetFunction("test.luaFunc"); if (func != null) { int num = luaFunc.Invoke(123456); Debugger.Log("generic call return: {0}", num); num = CallFunc(); Debugger.Log("expansion call return: {0}", num); Func Func = luaFunc.ToDelegate>(); num = Func(123456); Debugger.Log("Delegate call return: {0}", num); num = lua.Invoke("test.luaFunc", 123456, true); Debugger.Log("luastate call return: {0}", num); } lua.CheckTop(); } void OnDestroy() { if (luaFunc != null) { luaFunc.Dispose(); luaFunc = null; } lua.Dispose(); lua = null; } int CallFunc() { luaFunc.BeginPCall(); luaFunc.Push(123456); luaFunc.PCall(); int num = (int)luaFunc.CheckNumber(); luaFunc.EndPCall(); return num; } ``` tolua# 简化了lua函数的操作,通过LuaFunction封装(并缓存)一个lua函数,并提供各种操作, 建议频繁调用函数使用无GC方式。
* LuaState.GetLuaFunction 获取并缓存一个lua函数, 此函数支持串式操作, 如"test.luaFunc"代表test表中的luaFunc函数。
* LuaState.Invoke 临时调用一个lua function并返回一个值,这个操作并不缓存lua function,适合频率非常低的函数调用。
* LuaFunction.Call() 不需要返回值的函数调用操作
* LuaFunction.Invoke() 有一个返回值的函数调用操作
* LuaFunction.BeginPCall() 开始函数调用
* LuaFunction.Push() 压入函数调用需要的参数,通过众多的重载函数来解决参数转换gc问题
* LuaFunction.PCall() 调用lua函数
* LuaFunction.CheckNumber() 提取函数返回值, 并检查返回值为lua number类型
* LuaFunction.EndPCall() 结束lua函数调用, 清楚函数调用造成的堆栈变化
* LuaFunction.Dispose() 释放LuaFunction, 递减引用计数,如果引用计数为0, 则从_R表删除该函数
> **注意:** 无论Call还是PCall只相当于lua中的函数'.'调用。
请注意':'这种语法糖 self:call(...) == self.call(self, ...)
c# 中需要按后面方式调用, 即必须主动传入第一个参数self
## 例子4 展示了如何访问lua中变量,table的操作 ``` csharp private string script = @" print('Objs2Spawn is: '..Objs2Spawn) var2read = 42 varTable = {1,2,3,4,5} varTable.default = 1 varTable.map = {} varTable.map.name = 'map' meta = {name = 'meta'} setmetatable(varTable, meta) function TestFunc(strs) print('get func by variable') end "; void Start () { new LuaResLoader(); LuaState lua = new LuaState(); lua.Start(); lua["Objs2Spawn"] = 5; lua.DoString(script); //通过LuaState访问 Debugger.Log("Read var from lua: {0}", lua["var2read"]); Debugger.Log("Read table var from lua: {0}", lua["varTable.default"]); //LuaState 拆串式table LuaFunction func = lua["TestFunc"] as LuaFunction; func.Call(); func.Dispose(); //cache成LuaTable进行访问 LuaTable table = lua.GetTable("varTable"); Debugger.Log("Read varTable from lua, default: {0} name: {1}", table["default"], table["map.name"]); table["map.name"] = "new"; //table 字符串只能是key Debugger.Log("Modify varTable name: {0}", table["map.name"]); table.AddTable("newmap"); LuaTable table1 = (LuaTable)table["newmap"]; table1["name"] = "table1"; Debugger.Log("varTable.newmap name: {0}", table1["name"]); table1.Dispose(); table1 = table.GetMetaTable(); if (table1 != null) { Debugger.Log("varTable metatable name: {0}", table1["name"]); } object[] list = table.ToArray(); for (int i = 0; i < list.Length; i++) { Debugger.Log("varTable[{0}], is {1}", i, list[i]); } table.Dispose(); lua.CheckTop(); lua.Dispose(); } ``` * luaState["Objs2Spawn"] LuaState通过重载this操作符,访问lua _G表中的变量Objs2Spawn
* LuaState.GetTable 从lua中获取一个lua table, 可以串式访问比如lua.GetTable("varTable.map.name") 等于 varTable->map->name
* LuaTable 支持this操作符,但此this不支持串式访问。比如table["map.name"] "map.name" 只是一个key,不是table->map->name
* LuaTable.GetMetaTable() 可以获取当前table的metatable
* LuaTable.ToArray() 获取数组表中的所有对象存入到object[]表中
* LuaTable.AddTable(name) 在当前的table表中添加一个名字为name的表
* LuaTable.GetTable(key) 获取t[key]值到c#, 类似于 lua_gettable
* LuaTable.SetTable(key, value) 等价于t[k] = v的操作, 类似于lua_settable
* LuaTable.RawGet(key) 获取t[key]值到c#, 类似于 lua_rawget
* LuaTable.RawSet(key, value) 等价于t[k] = v的操作, 类似于lua_rawset
## 例子5 协同一 展示了如何使用lua协同, lua 代码如下: ``` lua function fib(n) local a, b = 0, 1 while n > 0 do a, b = b, a + b n = n - 1 end return a end function CoFunc() print('Coroutine started') for i = 1, 10, 1 do print(fib(i)) coroutine.wait(0.1) end print("current frameCount: "..Time.frameCount) coroutine.step() print("yield frameCount: "..Time.frameCount) local www = UnityEngine.WWW("http://www.baidu.com") coroutine.www(www) local s = tolua.tolstring(www.bytes) print(s:sub(1, 128)) print('Coroutine ended') end function TestCortinue() coroutine.start(CoFunc) end local coDelay = nil function Delay() local c = 1 while true do coroutine.wait(1) print("Count: "..c) c = c + 1 end end function StartDelay() coDelay = coroutine.start(Delay) end function StopDelay() coroutine.stop(coDelay) end ``` c#代码如下: ``` csharp new LuaResLoader(); lua = new LuaState(); lua.Start(); LuaBinder.Bind(lua); DelegateFactory.Init(); looper = gameObject.AddComponent(); looper.luaState = lua; lua.DoString(luaFile.text, "TestLuaCoroutine.lua"); LuaFunction f = lua.GetFunction("TestCortinue"); f.Call(); f.Dispose(); f = null; ``` * 必须启动LuaLooper驱动协同,这里将一个lua的半双工协同装换为类似unity的全双工协同
* fib函数负责计算一个斐那波契n
* coroutine.start 启动一个lua协同
* coroutine.wait 协同中等待一段时间,单位:秒
* coroutine.step 协同中等待一帧.
* coroutine.www 等待一个WWW完成.
* tolua.tolstring 转换byte数组为lua字符串缓冲
* coroutine.stop 停止一个正在lua将要执行的协同
================================================ FILE: Assets/ToLua/Examples/README.md.meta ================================================ fileFormatVersion: 2 guid: 9efe91d34eaff5a4ab3530e47ea50385 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/Protol/common_pb.lua.bytes ================================================ --Generated By protoc-gen-lua Do not Edit local protobuf = require "protobuf.protobuf" module('Protol.common_pb') HEADER = protobuf.Descriptor(); HEADER_CMD_FIELD = protobuf.FieldDescriptor(); HEADER_SEQ_FIELD = protobuf.FieldDescriptor(); HEADER_CMD_FIELD.name = "cmd" HEADER_CMD_FIELD.full_name = ".Header.cmd" HEADER_CMD_FIELD.number = 1 HEADER_CMD_FIELD.index = 0 HEADER_CMD_FIELD.label = 2 HEADER_CMD_FIELD.has_default_value = false HEADER_CMD_FIELD.default_value = 0 HEADER_CMD_FIELD.type = 5 HEADER_CMD_FIELD.cpp_type = 1 HEADER_SEQ_FIELD.name = "seq" HEADER_SEQ_FIELD.full_name = ".Header.seq" HEADER_SEQ_FIELD.number = 2 HEADER_SEQ_FIELD.index = 1 HEADER_SEQ_FIELD.label = 2 HEADER_SEQ_FIELD.has_default_value = false HEADER_SEQ_FIELD.default_value = 0 HEADER_SEQ_FIELD.type = 5 HEADER_SEQ_FIELD.cpp_type = 1 HEADER.name = "Header" HEADER.full_name = ".Header" HEADER.nested_types = {} HEADER.enum_types = {} HEADER.fields = {HEADER_CMD_FIELD, HEADER_SEQ_FIELD} HEADER.is_extendable = false HEADER.extensions = {} Header = protobuf.Message(HEADER) ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/Protol/common_pb.lua.bytes.meta ================================================ fileFormatVersion: 2 guid: dae780f9dbb4a634bbc8605c0cd7bd13 timeCreated: 1498123941 licenseType: Pro TextScriptImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/Protol/person_pb.lua.bytes ================================================ --Generated By protoc-gen-lua Do not Edit local protobuf = require "protobuf.protobuf" local common_pb = require("Protol.common_pb") module('Protol.person_pb') PERSON = protobuf.Descriptor(); PERSON_HEADER_FIELD = protobuf.FieldDescriptor(); PERSON_ID_FIELD = protobuf.FieldDescriptor(); PERSON_NAME_FIELD = protobuf.FieldDescriptor(); PERSON_AGE_FIELD = protobuf.FieldDescriptor(); PERSON_EMAIL_FIELD = protobuf.FieldDescriptor(); PERSON_ARRAY_FIELD = protobuf.FieldDescriptor(); PHONE = protobuf.Descriptor(); PHONE_PHONE_TYPE = protobuf.EnumDescriptor(); PHONE_PHONE_TYPE_MOBILE_ENUM = protobuf.EnumValueDescriptor(); PHONE_PHONE_TYPE_HOME_ENUM = protobuf.EnumValueDescriptor(); PHONE_NUM_FIELD = protobuf.FieldDescriptor(); PHONE_TYPE_FIELD = protobuf.FieldDescriptor(); PHONE_PHONES_FIELD = protobuf.FieldDescriptor(); PERSON_HEADER_FIELD.name = "header" PERSON_HEADER_FIELD.full_name = ".Person.header" PERSON_HEADER_FIELD.number = 1 PERSON_HEADER_FIELD.index = 0 PERSON_HEADER_FIELD.label = 2 PERSON_HEADER_FIELD.has_default_value = false PERSON_HEADER_FIELD.default_value = nil PERSON_HEADER_FIELD.message_type = common_pb.HEADER PERSON_HEADER_FIELD.type = 11 PERSON_HEADER_FIELD.cpp_type = 10 PERSON_ID_FIELD.name = "id" PERSON_ID_FIELD.full_name = ".Person.id" PERSON_ID_FIELD.number = 2 PERSON_ID_FIELD.index = 1 PERSON_ID_FIELD.label = 2 PERSON_ID_FIELD.has_default_value = false PERSON_ID_FIELD.default_value = 0 PERSON_ID_FIELD.type = 3 PERSON_ID_FIELD.cpp_type = 2 PERSON_NAME_FIELD.name = "name" PERSON_NAME_FIELD.full_name = ".Person.name" PERSON_NAME_FIELD.number = 3 PERSON_NAME_FIELD.index = 2 PERSON_NAME_FIELD.label = 2 PERSON_NAME_FIELD.has_default_value = false PERSON_NAME_FIELD.default_value = "" PERSON_NAME_FIELD.type = 9 PERSON_NAME_FIELD.cpp_type = 9 PERSON_AGE_FIELD.name = "age" PERSON_AGE_FIELD.full_name = ".Person.age" PERSON_AGE_FIELD.number = 4 PERSON_AGE_FIELD.index = 3 PERSON_AGE_FIELD.label = 1 PERSON_AGE_FIELD.has_default_value = true PERSON_AGE_FIELD.default_value = 18 PERSON_AGE_FIELD.type = 5 PERSON_AGE_FIELD.cpp_type = 1 PERSON_EMAIL_FIELD.name = "email" PERSON_EMAIL_FIELD.full_name = ".Person.email" PERSON_EMAIL_FIELD.number = 5 PERSON_EMAIL_FIELD.index = 4 PERSON_EMAIL_FIELD.label = 1 PERSON_EMAIL_FIELD.has_default_value = true PERSON_EMAIL_FIELD.default_value = "topameng@qq.com" PERSON_EMAIL_FIELD.type = 9 PERSON_EMAIL_FIELD.cpp_type = 9 PERSON_ARRAY_FIELD.name = "array" PERSON_ARRAY_FIELD.full_name = ".Person.array" PERSON_ARRAY_FIELD.number = 6 PERSON_ARRAY_FIELD.index = 5 PERSON_ARRAY_FIELD.label = 3 PERSON_ARRAY_FIELD.has_default_value = false PERSON_ARRAY_FIELD.default_value = {} PERSON_ARRAY_FIELD.type = 5 PERSON_ARRAY_FIELD.cpp_type = 1 PERSON.name = "Person" PERSON.full_name = ".Person" PERSON.nested_types = {} PERSON.enum_types = {} PERSON.fields = {PERSON_HEADER_FIELD, PERSON_ID_FIELD, PERSON_NAME_FIELD, PERSON_AGE_FIELD, PERSON_EMAIL_FIELD, PERSON_ARRAY_FIELD} PERSON.is_extendable = true PERSON.extensions = {} PHONE_PHONE_TYPE_MOBILE_ENUM.name = "MOBILE" PHONE_PHONE_TYPE_MOBILE_ENUM.index = 0 PHONE_PHONE_TYPE_MOBILE_ENUM.number = 1 PHONE_PHONE_TYPE_HOME_ENUM.name = "HOME" PHONE_PHONE_TYPE_HOME_ENUM.index = 1 PHONE_PHONE_TYPE_HOME_ENUM.number = 2 PHONE_PHONE_TYPE.name = "PHONE_TYPE" PHONE_PHONE_TYPE.full_name = ".Phone.PHONE_TYPE" PHONE_PHONE_TYPE.values = {PHONE_PHONE_TYPE_MOBILE_ENUM,PHONE_PHONE_TYPE_HOME_ENUM} PHONE_NUM_FIELD.name = "num" PHONE_NUM_FIELD.full_name = ".Phone.num" PHONE_NUM_FIELD.number = 1 PHONE_NUM_FIELD.index = 0 PHONE_NUM_FIELD.label = 1 PHONE_NUM_FIELD.has_default_value = false PHONE_NUM_FIELD.default_value = "" PHONE_NUM_FIELD.type = 9 PHONE_NUM_FIELD.cpp_type = 9 PHONE_TYPE_FIELD.name = "type" PHONE_TYPE_FIELD.full_name = ".Phone.type" PHONE_TYPE_FIELD.number = 2 PHONE_TYPE_FIELD.index = 1 PHONE_TYPE_FIELD.label = 1 PHONE_TYPE_FIELD.has_default_value = false PHONE_TYPE_FIELD.default_value = nil PHONE_TYPE_FIELD.enum_type = PHONE_PHONE_TYPE PHONE_TYPE_FIELD.type = 14 PHONE_TYPE_FIELD.cpp_type = 8 PHONE_PHONES_FIELD.name = "phones" PHONE_PHONES_FIELD.full_name = ".Phone.phones" PHONE_PHONES_FIELD.number = 10 PHONE_PHONES_FIELD.index = 0 PHONE_PHONES_FIELD.label = 3 PHONE_PHONES_FIELD.has_default_value = false PHONE_PHONES_FIELD.default_value = {} PHONE_PHONES_FIELD.message_type = PHONE PHONE_PHONES_FIELD.type = 11 PHONE_PHONES_FIELD.cpp_type = 10 PHONE.name = "Phone" PHONE.full_name = ".Phone" PHONE.nested_types = {} PHONE.enum_types = {PHONE_PHONE_TYPE} PHONE.fields = {PHONE_NUM_FIELD, PHONE_TYPE_FIELD} PHONE.is_extendable = false PHONE.extensions = {PHONE_PHONES_FIELD} Person = protobuf.Message(PERSON) Phone = protobuf.Message(PHONE) Person.RegisterExtension(PHONE_PHONES_FIELD) ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/Protol/person_pb.lua.bytes.meta ================================================ fileFormatVersion: 2 guid: 9a5684e0e56583c43b809876b457c953 timeCreated: 1498113766 licenseType: Pro TextScriptImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/Protol.meta ================================================ fileFormatVersion: 2 guid: 0882b1dfb9d5f9e408ec017206a4946a folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestErrorStack.lua.bytes ================================================ function Show() error('this is error') end function ShowStack(go) TestStack.Test1(go) end function Instantiate(obj) local go = UnityEngine.Object.Instantiate(obj) print(go.name) end function TestRay(ray) return Vector3.zero end function PushLuaError() TestStack.PushLuaError() end function Test3() TestStack.Test3() end function Test4() TestStack.Test4() end function Test5() TestStack.Test5() end function SendMsgError(go) go:SendMessage("OnSendMsg"); end function resume(co, ...) local r, msg = nil local func = function(...) r, msg = coroutine.resume(co, ...) if not r then print('xxxxxxxxxxxxxxxxxxxxxx') error(msg) end end pcall(func, ...) return r, msg end function Test6() print('--------------------------') --TestStack.Test6() local co = coroutine.create(function() coroutine.yield() print('hahahahaha') TestStack.Test6(go) end) coroutine.resume(co) local r, msg = coroutine.resume(co) print('go error') print(msg) print('--------------------------') end function Test8() TestArgError('123') end _event = { name = 'event' } _event.__index = function(t, k) return rawget(_event, k) end setmetatable(_event, _event) function _event:Add(func, obj) print('xxxxxxxxxxxxxxxxxxxxxxxxxx') end _event.__call = function() end testev = {} setmetatable(testev, _event) function TestCo(...) local name = TestTableInCo(...) print("table.name is: "..name) end function TestCoTable() local co = coroutine.create(TestCo) local r, msg = coroutine.resume(co, testev) if not r then print("TestCoTable: "..msg) end end ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestErrorStack.lua.bytes.meta ================================================ fileFormatVersion: 2 guid: a540e20118516b1449b2bb6293d1030a TextScriptImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestLoader.lua.bytes ================================================ print("This is a script from a utf8 file") print("tolua: 你好! こんにちは! 안녕하세요!") function Test() print("this is lua file load by Resource.Load") end ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestLoader.lua.bytes.meta ================================================ fileFormatVersion: 2 guid: d249a195df84a8e448b95867fdc844df TextScriptImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestLuaCoroutine.lua.bytes ================================================ function fib(n) local a, b = 0, 1 while n > 0 do a, b = b, a + b n = n - 1 end return a end function CoFunc() print('Coroutine started') for i = 0, 10, 1 do print(fib(i)) coroutine.wait(0.1) end print("current frameCount: "..Time.frameCount) coroutine.step() print("yield frameCount: "..Time.frameCount) local www = UnityEngine.WWW("http://www.baidu.com") coroutine.www(www) local s = tolua.tolstring(www.bytes) print(s:sub(1, 128)) print('Coroutine ended') end function TestCortinue() coroutine.start(CoFunc) end local coDelay = nil function Delay() local c = 1 while true do coroutine.wait(1) print("Count: "..c) c = c + 1 end end function StartDelay() coDelay = coroutine.start(Delay) end function StopDelay() coroutine.stop(coDelay) end ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestLuaCoroutine.lua.bytes.meta ================================================ fileFormatVersion: 2 guid: 3e90f8f033d17114297577d8cde2677e TextScriptImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestPerf.lua.bytes ================================================ local Vector3 = Vector3 local Quaternion = Quaternion local Normalize = Vector3.Normalize --local verbo = require("jit.v") --verbo.start() function Test1(transform) local one = Vector3.one local t = os.clock() for i = 1,200000 do transform.position = transform.position end t = os.clock() - t print("Transform.position lua cost time: ", t) end function Test2(transform) local up = Vector3.up local t = os.clock() for i = 1,200000 do transform:Rotate(up, 1) end t = os.clock() - t print("Transform.Rotate lua cost time: ", t) end function Test3() local t = os.clock() local New = Vector3.New for i = 1, 200000 do local v = New(i, i, i) end t = os.clock() - t print("Vector3.New lua cost time: ", t) end --会存在大量gc操作 function Test4() local GameObject = UnityEngine.GameObject local t = os.clock() local go = GameObject.New() local node = go.transform for i = 1,100000 do --GameObject.New() go = node.gameObject end t = os.clock() - t print("GameObject.New lua cost time: ", t) end function Test5() local t = os.clock() local GameObject = UnityEngine.GameObject local SkinnedMeshRenderer = UnityEngine.SkinnedMeshRenderer local tp = typeof(SkinnedMeshRenderer) for i = 1,20000 do local go = GameObject.New() go:AddComponent(tp) local c = go:GetComponent(tp) c.castShadows=false c.receiveShadows=false end print("Test5 lua cost time: ", os.clock() - t) end function Test6() local t = os.clock() for i = 1,200000 do local t = Input.GetTouch(0) local p = Input.mousePosition --Physics.RayCast end print("lua cost time: ", os.clock() - t) end function Test7() local Vector3 = Vector3 local t = os.clock() for i = 1, 200000 do local v = Vector3.New(i,i,i) Vector3.Normalize(v) end print("lua Vector3 New Normalize cost time: ", os.clock() - t) end function Test8() local Quaternion = Quaternion local t = os.clock() for i=1,200000 do local q1 = Quaternion.Euler(i, i, i) local q2 = Quaternion.Euler(i * 2, i * 2, i * 2) Quaternion.Slerp(Quaternion.identity, q1, 0.5) end print("Quaternion Euler Slerp const: ", os.clock() - t) end function Test9() local total = 0 local t = os.clock() for i = 0, 1000000 do total = total + i - (i/2) * (i + 3) / (i + 5) end print("math cal cost: ", os.clock() - t) end function TestTable() local array = {} for i = 1, 1024 do array[i] = i end local total = 0 local t = os.clock() for j = 1, 100000 do for i = 1, 1024 do total = total + array[i] end end print("Array cost time: ", os.clock() - t) end ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/TestPerf.lua.bytes.meta ================================================ fileFormatVersion: 2 guid: 07657567fb0a4fe439b7e52f48d787e1 TextScriptImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/ToLuaInjectionTestInjector.lua.bytes ================================================ local ToLuaInjectionTestInjector = {} --ToLuaInjectionTestInjector[".ctor"] = function() --请注意ToLuaInjection.cs中的injectIgnoring字段已经默认过滤掉了Constructor,如果要测试构造函数的注入,请去掉InjectFilter.IgnoreConstructor这个过滤项 -- Only After Does Matter --return function(self) -- print("Lua Inject Constructor") --end, LuaInterface.InjectType.After ------------------------------------------------------- --return function(self) -- print("Lua Inject Constructor") --end, LuaInterface.InjectType.Before ------------------------------------------------------- --end --ToLuaInjectionTestInjector[".ctor_bool"] = function() --请注意ToLuaInjection.cs中的injectIgnoring字段已经默认过滤掉了Constructor,如果要测试构造函数的注入,请去掉InjectFilter.IgnoreConstructor这个过滤项 -- Only After Does Matter --return function(self, state) -- print("Lua Inject Constructor_bool " .. tostring(state)) --end, LuaInterface.InjectType.After --end ToLuaInjectionTestInjector.set_PropertyTest = function() return function (self, value) print("Lua Inject Property set :" .. value) end, LuaInterface.InjectType.After ------------------------------------------------------- --return function (self, value) -- print("Lua Inject Property set :") -- return {3} --end, LuaInterface.InjectType.Replace ------------------------------------------------------- end ToLuaInjectionTestInjector.get_PropertyTest = function() return function (self) print("Lua Inject Property get :") end, LuaInterface.InjectType.After ------------------------------------------------------- --return function (self) -- print("Lua Inject Property get :") --end, LuaInterface.InjectType.Before ------------------------------------------------------- --return function (self) -- print("Lua Inject Property get :") -- return 2 --end, LuaInterface.InjectType.Replace ------------------------------------------------------- end ToLuaInjectionTestInjector.TestRef = function() --return function (self, count) -- print("Lua Inject TestRef ") -- count = 10 -- return { count , 3} --end, LuaInterface.InjectType.After ------------------------------------------------------- --return function (self, count) -- print("Lua Inject TestRef ") -- count = 10 -- return { count , 3} --end, LuaInterface.InjectType.ReplaceWithPreInvokeBase ------------------------------------------------------- return function (self, count) print("Lua Inject TestRef ") count = 10 return { count , 3} end, LuaInterface.InjectType.ReplaceWithPostInvokeBase ------------------------------------------------------- --return function (self, count) -- print("Lua Inject TestRef ") -- count = 10 -- return { count , 3} --end, LuaInterface.InjectType.Replace ------------------------------------------------------- --return function (self, count) -- print("Lua Inject TestRef ") -- count = 10 -- return { count , 3} --end, LuaInterface.InjectType.Before ------------------------------------------------------- end ToLuaInjectionTestInjector["TestOverload-int-bool"] = function() return function (self, count, state) print("Lua Inject TestOverload-int-bool " .. tostring(state)) end, LuaInterface.InjectType.After end ToLuaInjectionTestInjector["TestOverload-int-bool&"] = function() --return function (self, param1, param2) -- print("Lua Inject TestOverload-int-bool& ") -- return {false} --end, LuaInterface.InjectType.After ------------------------------------------------------- --return function (self, param1, param2) -- print("Lua Inject TestOverload-int-bool& ") -- return {false} --end, LuaInterface.InjectType.Before ------------------------------------------------------- return function (self, param1, param2) print("Lua Inject TestOverload-int-bool& ") return {false} end, LuaInterface.InjectType.Replace ------------------------------------------------------- end ToLuaInjectionTestInjector["TestOverload-bool-int"] = function() return function (self, param1, param2) print("Lua Inject TestOverload-bool-int " .. param2) end, LuaInterface.InjectType.After end ToLuaInjectionTestInjector.TestCoroutine = function() return function (self, delay, coroutineState) print("Lua Inject TestCoroutine " .. coroutineState) end, LuaInterface.InjectType.After ------------------------------------------------------- --return function (self, delay) -- return WrapLuaCoroutine(function() -- print("Lua Inject TestCoroutine Pulse" .. delay) -- return false -- end) --end, LuaInterface.InjectType.Replace ------------------------------------------------------- --return function (self, delay) -- local state = true -- local cor -- local function StartLuaCoroutine() -- if cor == nil then -- cor = coroutine.start(function() -- print("Lua Coroutine Before") -- coroutine.wait(delay) -- state = false -- print("Lua Coroutine After") -- end) -- end -- end -- -- return WrapLuaCoroutine(function() -- StartLuaCoroutine() -- return state -- end) --end, LuaInterface.InjectType.Replace ------------------------------------------------------- end --InjectByName("ToLuaInjectionTest", ToLuaInjectionTestInjector) InjectByModule(ToLuaInjectionTest, ToLuaInjectionTestInjector) ================================================ FILE: Assets/ToLua/Examples/Resources/Lua/ToLuaInjectionTestInjector.lua.bytes.meta ================================================ fileFormatVersion: 2 guid: 4d4ade31977a9ce4f92428e0889cee1d timeCreated: 1536241531 licenseType: Pro TextScriptImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/Resources/Lua.meta ================================================ fileFormatVersion: 2 guid: d26bf1a8a6d42954eb332fd9957140d1 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources/jsonexample.json ================================================ { "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Mark up Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } } ================================================ FILE: Assets/ToLua/Examples/Resources/jsonexample.json.meta ================================================ fileFormatVersion: 2 guid: 7d7edaf98b78bd84297bb888bf41ed02 TextScriptImporter: userData: ================================================ FILE: Assets/ToLua/Examples/Resources.meta ================================================ fileFormatVersion: 2 guid: cd85633be4068ee4b8d8f4744a4a9386 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestInstantiate.cs ================================================ using UnityEngine; using System; using LuaInterface; public class TestInstantiate : MonoBehaviour { void Awake() { LuaState state = LuaState.Get(IntPtr.Zero); try { LuaFunction func = state.GetFunction("Show"); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); func = null; } catch (Exception e) { state.ThrowLuaException(e); } } void Start() { Debugger.Log("start"); } } ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestInstantiate.cs.meta ================================================ fileFormatVersion: 2 guid: b3f31488b17b6394f8cc6e000f1001ab MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestInstantiate.prefab.meta ================================================ fileFormatVersion: 2 guid: ec8a2f7e4eaf1c64e8393014e602047c NativeFormatImporter: userData: ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestInstantiate2.cs ================================================ using UnityEngine; using System; using LuaInterface; public class TestInstantiate2 : MonoBehaviour { void Awake() { try { throw new Exception("Instantiate exception 2"); } catch (Exception e) { LuaState state = LuaState.Get(IntPtr.Zero); state.ThrowLuaException(e); } } } ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestInstantiate2.cs.meta ================================================ fileFormatVersion: 2 guid: 901668bc322ed714d9c7c74febc9bd8b MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestInstantiate2.prefab.meta ================================================ fileFormatVersion: 2 guid: 0e472cc047eb20841bbb7c64dfeb0d78 NativeFormatImporter: userData: ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestLuaStack.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System; using System.Runtime.InteropServices; //检测合理报错 public class TestLuaStack : MonoBehaviour { public GameObject go = null; public GameObject go2 = null; public static LuaFunction show = null; public static LuaFunction testRay = null; public static LuaFunction showStack = null; public static LuaFunction test4 = null; private static GameObject testGo = null; private string tips = ""; public static TestLuaStack Instance = null; [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Test1(IntPtr L) { try { show.BeginPCall(); show.PCall(); show.EndPCall(); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 0; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int PushLuaError(IntPtr L) { try { testRay.BeginPCall(); testRay.Push(Instance); testRay.PCall(); testRay.EndPCall(); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 0; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Test3(IntPtr L) { try { testRay.BeginPCall(); testRay.PCall(); testRay.CheckRay(); testRay.EndPCall(); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 0; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Test4(IntPtr L) { try { show.BeginPCall(); show.PCall(); show.EndPCall(); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 0; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Test5(IntPtr L) { try { test4.BeginPCall(); test4.PCall(); bool ret = test4.CheckBoolean(); ret = !ret; test4.EndPCall(); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 0; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Test6(IntPtr L) { try { throw new LuaException("this a lua exception"); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestOutOfBound(IntPtr L) { try { Transform transform = testGo.transform; Transform node = transform.GetChild(20); ToLua.Push(L, node); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestArgError(IntPtr L) { try { LuaDLL.luaL_typerror(L, 1, "number"); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 0; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestTableInCo(IntPtr L) { try { LuaTable table = ToLua.CheckLuaTable(L, 1); string str = (string)table["name"]; ToLua.Push(L, str); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestCycle(IntPtr L) { try { LuaState state = LuaState.Get(L); LuaFunction func = state.GetFunction("TestCycle"); int c = (int)LuaDLL.luaL_checknumber(L, 1); if (c <= 2) { LuaDLL.lua_pushnumber(L, 1); } else { func.BeginPCall(); func.Push(c - 1); func.PCall(); int n1 = (int)func.CheckNumber(); func.EndPCall(); func.BeginPCall(); func.Push(c - 2); func.PCall(); int n2 = (int)func.CheckNumber(); func.EndPCall(); LuaDLL.lua_pushnumber(L, n1 + n2); } return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestNull(IntPtr L) { try { GameObject go = (GameObject)ToLua.CheckObject(L, 1, typeof(GameObject)); ToLua.Push(L, go.name); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestAddComponent(IntPtr L) { try { GameObject go = (GameObject)ToLua.CheckObject(L, 1, typeof(GameObject)); go.AddComponent(); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } static void TestMul1() { throw new Exception("multi stack error"); } static void TestMul0() { TestMul1(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestMulStack(IntPtr L) { try { TestMul0(); return 0; } catch (Exception e) { //Debugger.Log("xxxx" + e.StackTrace); return LuaDLL.toluaL_exception(L, e); } } void OnSendMsg() { try { LuaFunction func = state.GetFunction("TestStack.Test6"); func.BeginPCall(); func.PCall(); func.EndPCall(); } catch(Exception e) { state.ThrowLuaException(e); } } LuaState state = null; public TextAsset text = null; static Action TestDelegate = delegate { }; void Awake() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif Instance = this; new LuaResLoader(); testGo = gameObject; state = new LuaState(); state.Start(); LuaBinder.Bind(state); state.BeginModule(null); state.RegFunction("TestArgError", TestArgError); state.RegFunction("TestTableInCo", TestTableInCo); state.RegFunction("TestCycle", TestCycle); state.RegFunction("TestNull", TestNull); state.RegFunction("TestAddComponent", TestAddComponent); state.RegFunction("TestOutOfBound", TestOutOfBound); state.RegFunction("TestMulStack", TestMulStack); state.BeginStaticLibs("TestStack"); state.RegFunction("Test1", Test1); state.RegFunction("PushLuaError", PushLuaError); state.RegFunction("Test3", Test3); state.RegFunction("Test4", Test4); state.RegFunction("Test5", Test5); state.RegFunction("Test6", Test6); state.EndStaticLibs(); state.EndModule(); //state.DoFile("TestErrorStack.lua"); state.Require("TestErrorStack"); show = state.GetFunction("Show"); testRay = state.GetFunction("TestRay"); showStack = state.GetFunction("ShowStack"); test4 = state.GetFunction("Test4"); TestDelegate += TestD1; TestDelegate += TestD2; } void Update() { state.CheckTop(); } void OnApplicationQuit() { #if UNITY_5 || UNITY_2017 || UNITY_2018 Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif state.Dispose(); state = null; } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; if (type == LogType.Error || type == LogType.Exception) { tips += stackTrace; } } void TestD1() { Debugger.Log("delegate 1"); TestDelegate -= TestD2; } void TestD2() { Debugger.Log("delegate 2"); } void OnGUI() { GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 150, 800, 400), tips); if (GUI.Button(new Rect(10, 10, 120, 40), "Error1")) { tips = ""; showStack.BeginPCall(); showStack.Push(go); showStack.PCall(); showStack.EndPCall(); showStack.Dispose(); showStack = null; } else if (GUI.Button(new Rect(10, 60, 120, 40), "Instantiate Error")) { tips = ""; LuaFunction func = state.GetFunction("Instantiate"); func.BeginPCall(); func.Push(go); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 110, 120, 40), "Check Error")) { tips = ""; LuaFunction func = state.GetFunction("TestRay"); func.BeginPCall(); func.PCall(); func.CheckRay(); //返回值出错 func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 160, 120, 40), "Push Error")) { tips = ""; LuaFunction func = state.GetFunction("TestRay"); func.BeginPCall(); func.Push(Instance); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 210, 120, 40), "LuaPushError")) { //需要改lua文件让其出错 tips = ""; LuaFunction func = state.GetFunction("PushLuaError"); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 260, 120, 40), "Check Error")) { tips = ""; LuaFunction func = state.GetFunction("Test5"); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 310, 120, 40), "Test Resume")) { tips = ""; LuaFunction func = state.GetFunction("Test6"); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 360, 120, 40), "out of bound")) { tips = ""; LuaFunction func = state.GetFunction("TestOutOfBound"); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 410, 120, 40), "TestArgError")) { tips = ""; LuaFunction func = state.GetFunction("Test8"); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 460, 120, 40), "TestFuncDispose")) { tips = ""; LuaFunction func = state.GetFunction("Test8"); func.Dispose(); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 510, 120, 40), "SendMessage")) { tips = ""; gameObject.SendMessage("OnSendMsg"); } else if (GUI.Button(new Rect(10, 560, 120, 40), "SendMessageInLua")) { LuaFunction func = state.GetFunction("SendMsgError"); func.BeginPCall(); func.Push(gameObject); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(10, 610, 120, 40), "AddComponent")) { tips = ""; LuaFunction func = state.GetFunction("TestAddComponent"); func.BeginPCall(); func.Push(gameObject); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(210, 10, 120, 40), "TableGetSet")) { tips = ""; LuaTable table = state.GetTable("testev"); int top = state.LuaGetTop(); try { state.Push(table); state.LuaGetField(-1, "Add"); LuaFunction func = state.CheckLuaFunction(-1); if (func != null) { func.Call(); func.Dispose(); } state.LuaPop(1); state.Push(123456); state.LuaSetField(-2, "value"); state.LuaGetField(-1, "value"); int n = (int)state.LuaCheckNumber(-1); Debugger.Log("value is: " + n); state.LuaPop(1); state.Push("Add"); state.LuaGetTable(-2); func = state.CheckLuaFunction(-1); if (func != null) { func.Call(); func.Dispose(); } state.LuaPop(1); state.Push("look"); state.Push(456789); state.LuaSetTable(-3); state.LuaGetField(-1, "look"); n = (int)state.LuaCheckNumber(-1); Debugger.Log("look: " + n); } catch (Exception e) { state.LuaSetTop(top); throw e; } state.LuaSetTop(top); } else if (GUI.Button(new Rect(210, 60, 120, 40), "TestTableInCo")) { tips = ""; LuaFunction func = state.GetFunction("TestCoTable"); func.BeginPCall(); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(210, 110, 120, 40), "Instantiate2 Error")) { tips = ""; LuaFunction func = state.GetFunction("Instantiate"); func.BeginPCall(); func.Push(go2); func.PCall(); func.EndPCall(); func.Dispose(); } else if (GUI.Button(new Rect(210, 160, 120, 40), "Instantiate3 Error")) { tips = ""; UnityEngine.Object.Instantiate(go2); } else if (GUI.Button(new Rect(210, 210, 120, 40), "TestCycle")) { tips = ""; int n = 20; LuaFunction func = state.GetFunction("TestCycle"); func.BeginPCall(); func.Push(n); func.PCall(); int c = (int)func.CheckNumber(); func.EndPCall(); Debugger.Log("Fib({0}) is {1}", n, c); } else if (GUI.Button(new Rect(210, 260, 120, 40), "TestNull")) { tips = ""; Action action = ()=> { LuaFunction func = state.GetFunction("TestNull"); func.BeginPCall(); func.PushObject(null); func.PCall(); func.EndPCall(); }; StartCoroutine(TestCo(action)); } else if (GUI.Button(new Rect(210, 310, 120, 40), "TestMulti")) { tips = ""; LuaFunction func = state.GetFunction("TestMulStack"); func.BeginPCall(); func.PushObject(null); func.PCall(); func.EndPCall(); } } IEnumerator TestCo(Action action) { yield return new WaitForSeconds(0.1f); action(); } } ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestLuaStack.cs.meta ================================================ fileFormatVersion: 2 guid: b40a6eeee975862489a712e1a3d79ed1 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestErrorStack/TestLuaStack.unity.meta ================================================ fileFormatVersion: 2 guid: 706020e5c3f37944995bfe00955fdd39 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/TestErrorStack.meta ================================================ fileFormatVersion: 2 guid: 00b15eee8aab8d64e844fc53ee7395de folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/TestInjection/BaseTestWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using System.Runtime.InteropServices; using LuaInterface; public class BaseTestWrap { public static void Register(LuaState L) { L.BeginClass(typeof(BaseTest), typeof(System.Object)); L.RegFunction("TestRef", TestRef); L.RegFunction("New", _CreateBaseTest); L.RegVar("PropertyTest", get_PropertyTest, set_PropertyTest); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateBaseTest(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 0) { BaseTest obj = new BaseTest(); ToLua.PushObject(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: BaseTest.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestRef(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); BaseTest obj = (BaseTest)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = obj.TestRef(ref arg0); LuaDLL.lua_pushinteger(L, o); LuaDLL.lua_pushinteger(L, arg0); return 2; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_PropertyTest(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); BaseTest obj = (BaseTest)o; int ret = obj.PropertyTest; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index PropertyTest on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_PropertyTest(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); BaseTest obj = (BaseTest)o; int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); obj.PropertyTest = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index PropertyTest on a nil value"); } } } ================================================ FILE: Assets/ToLua/Examples/TestInjection/BaseTestWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 823570c1e66fe6e45b87a838ec075e76 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestInjection/TestInjection.cs ================================================ using UnityEngine; using LuaInterface; using System.Collections; [LuaInterface.NoToLua] public class TestInjection : MonoBehaviour { string tips = ""; bool m_isMouseDown; int m_fontSize = 28; int m_logFontSize = 0; float scaleThreshold; LuaState luaState = null; Color m_normalColor; GUIStyle m_fontStyle; GUIStyle m_windowStyle; Rect m_windowRect; Vector2 m_scrollViewPos; Vector2 m_distance; // Use this for initialization void Start() { InitGUI(); #if UNITY_5 || UNITY_2017_1_OR_NEWER Application.logMessageReceived += ShowTips; #else Application.RegisterLogCallback(ShowTips); #endif new LuaResLoader(); luaState = new LuaState(); luaState.Start(); LuaBinder.Bind(luaState); //For InjectByModule ////////////////////////////////////////////////////// luaState.BeginModule(null); BaseTestWrap.Register(luaState); ToLuaInjectionTestWrap.Register(luaState); luaState.EndModule(); ////////////////////////////////////////////////////// #if ENABLE_LUA_INJECTION #if UNITY_EDITOR if (UnityEditor.EditorPrefs.GetInt(Application.dataPath + "InjectStatus") == 1) { #else if (true) { #endif ///此处Require是示例专用,暖更新的lua代码都要放到LuaInjectionBus.lua中统一require luaState.Require("ToLuaInjectionTestInjector"); int counter = 0; bool state = true; ToLuaInjectionTest test = new ToLuaInjectionTest(true); test = new ToLuaInjectionTest(); StartCoroutine(test.TestCoroutine(0.3f)); test.TestOverload(1, state); test.TestOverload(1, ref state); Debug.Log("TestOverload ref result:" + state); test.TestOverload(state, 1); int refResult = test.TestRef(ref counter); Debug.Log(string.Format("TestRef return result:{0}; ref result:{1}", refResult, counter)); Debug.Log("Property Get Test:" + test.PropertyTest); test.PropertyTest = 2; Debug.Log("Property Set Test:" + test.PropertyTest); System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < 10000000; ++i) { test.NoInject(true, 1); } sw.Stop(); long noInjectMethodCostTime = sw.ElapsedMilliseconds; sw.Reset(); sw.Start(); for (int i = 0; i < 10000000; ++i) { test.Inject(true, 1); } sw.Stop(); Debug.Log("time cost ratio:" + (double)sw.ElapsedMilliseconds / noInjectMethodCostTime); } else #endif { Debug.LogError("查看是否开启了宏ENABLE_LUA_INJECTION并执行了菜单命令——\"Lua=>Inject All\""); } } void InitGUI() { m_windowRect.x = 0; m_windowRect.y = 0; m_windowRect.width = Screen.width; m_windowRect.height = Screen.height; m_logFontSize = (int)(m_fontSize * Screen.width * Screen.height / (1280 * 720)); m_normalColor = Color.white; m_fontStyle = new GUIStyle(); m_fontStyle.normal.textColor = m_normalColor; m_fontStyle.fontSize = m_logFontSize; //设置窗口颜色 m_windowStyle = new GUIStyle(); Texture2D windowTexture = new Texture2D(1, 1); windowTexture.SetPixel(0, 0, Color.black); windowTexture.Apply(); m_windowStyle.normal.background = windowTexture; scaleThreshold = Screen.width / 1100.0f; } void OnApplicationQuit() { #if UNITY_5 || UNITY_2017_1_OR_NEWER Application.logMessageReceived -= ShowTips; #else Application.RegisterLogCallback(null); #endif luaState.Dispose(); luaState = null; } Vector2 MousePoisition { get { return new Vector2(-Input.mousePosition.x, Input.mousePosition.y); } } //鼠标拖拽控制 private void MouseDragView(ref Vector2 viewPos) { if (Input.GetMouseButtonDown(0)) { m_distance = viewPos - MousePoisition; m_isMouseDown = true; } else if (Input.GetMouseButtonUp(0)) { m_isMouseDown = false; } if (m_isMouseDown) { viewPos = MousePoisition + m_distance; } } /// /// 非常简陋的一个log窗口,不要用到项目中,仅用来示例 /// /// void LogWindow(int id) { GUILayout.BeginHorizontal(); if (GUILayout.Button("+", GUILayout.MinHeight(50 * scaleThreshold))) { m_logFontSize = Mathf.Min(64, ++m_logFontSize); m_fontStyle.fontSize = m_logFontSize; } if (GUILayout.Button("-", GUILayout.MinHeight(50 * scaleThreshold))) { m_logFontSize = Mathf.Max(1, --m_logFontSize); m_fontStyle.fontSize = m_logFontSize; } GUILayout.EndHorizontal(); m_scrollViewPos = GUILayout.BeginScrollView(m_scrollViewPos, false, false); MouseDragView(ref m_scrollViewPos); GUILayout.Label(tips, m_fontStyle); GUILayout.Space(2); GUILayout.EndScrollView(); GUILayout.BeginHorizontal(); GUILayout.Label(string.Format("Font Size ({0})", m_logFontSize)); GUILayout.EndHorizontal(); } void OnGUI() { m_windowRect = GUI.Window(0, m_windowRect, LogWindow, "Log Window", m_windowStyle); } void ShowTips(string msg, string stackTrace, LogType type) { tips += msg; tips += "\r\n"; if (type == LogType.Error || type == LogType.Exception) { tips += stackTrace; } } } ================================================ FILE: Assets/ToLua/Examples/TestInjection/TestInjection.cs.meta ================================================ fileFormatVersion: 2 guid: f95133dba6f6a1a40936257b1a8b3dae timeCreated: 1515035194 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/TestInjection/TestInjection.unity.meta ================================================ fileFormatVersion: 2 guid: 05dc1e98babb44f47ad2a28a88b76380 timeCreated: 1515035207 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/TestInjection/ToLuaInjectionTest.cs ================================================ using System.Collections; using UnityEngine; public class BaseTest { private int propertyTest; public virtual int TestRef(ref int count) { Debug.Log("CS:Base TestRef"); ++count; return 1; } public virtual int PropertyTest { get { Debug.Log("CS: Base PropertyTestGet"); return propertyTest; } set { Debug.Log("CS: Base PropertyTestSet"); propertyTest = value; } } } public class ToLuaInjectionTest : BaseTest { private int propertyTest; public ToLuaInjectionTest() { Debug.Log("CS:Constructor Test"); } public ToLuaInjectionTest(bool state) { Debug.Log("CS:Constructor Test " + state); } public override int PropertyTest { get { Debug.Log("CS:PropertyTestGet"); return propertyTest; } set { Debug.Log("CS:PropertyTestSet"); propertyTest = value; } } public override int TestRef(ref int count) { Debug.Log("CS:Override TestRef"); ++count; return 2; } public void TestOverload(int param1, bool param2) { Debug.Log("CS:TestOverload"); } public void TestOverload(int param1, ref bool param2) { Debug.Log("CS:TestOverload"); param2 = !param2; } public void TestOverload(bool param1, int param2) { Debug.Log("CS:TestOverload"); } #pragma warning disable 0219 [LuaInterface.NoToLua] public void NoInject(bool param1, int param2) { int a = 0; int b = ++a; } public void Inject(bool param1, int param2) { int a = 0; int b = ++a; } #pragma warning restore 0219 public IEnumerator TestCoroutine(float delay) { Debug.Log("CS:TestCoroutine Run"); yield return new WaitForSeconds(delay); Debug.Log("CS:TestCoroutine End"); } } ================================================ FILE: Assets/ToLua/Examples/TestInjection/ToLuaInjectionTest.cs.meta ================================================ fileFormatVersion: 2 guid: 80e29c43f1cea9d4988c36fd2f6c26c1 timeCreated: 1514883665 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/TestInjection/ToLuaInjectionTestWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using System.Runtime.InteropServices; using LuaInterface; public class ToLuaInjectionTestWrap { public static void Register(LuaState L) { L.BeginClass(typeof(ToLuaInjectionTest), typeof(BaseTest)); L.RegFunction("TestRef", TestRef); L.RegFunction("TestOverload", TestOverload); L.RegFunction("TestCoroutine", TestCoroutine); L.RegFunction("New", _CreateToLuaInjectionTest); L.RegVar("PropertyTest", get_PropertyTest, set_PropertyTest); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateToLuaInjectionTest(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 0) { ToLuaInjectionTest obj = new ToLuaInjectionTest(); ToLua.PushObject(L, obj); return 1; } else if (count == 1) { bool arg0 = LuaDLL.luaL_checkboolean(L, 1); ToLuaInjectionTest obj = new ToLuaInjectionTest(arg0); ToLua.PushObject(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: ToLuaInjectionTest.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestRef(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); ToLuaInjectionTest obj = (ToLuaInjectionTest)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = obj.TestRef(ref arg0); LuaDLL.lua_pushinteger(L, o); LuaDLL.lua_pushinteger(L, arg0); return 2; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestOverload(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3 && TypeChecker.CheckTypes(L, 2)) { ToLuaInjectionTest obj = (ToLuaInjectionTest)ToLua.CheckObject(L, 1); bool arg0 = LuaDLL.lua_toboolean(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); obj.TestOverload(arg0, arg1); return 0; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { ToLuaInjectionTest obj = (ToLuaInjectionTest)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); bool arg1 = LuaDLL.lua_toboolean(L, 3); obj.TestOverload(arg0, ref arg1); LuaDLL.lua_pushboolean(L, arg1); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 2)) { ToLuaInjectionTest obj = (ToLuaInjectionTest)ToLua.CheckObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); bool arg1 = LuaDLL.lua_toboolean(L, 3); obj.TestOverload(arg0, arg1); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: ToLuaInjectionTest.TestOverload"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestCoroutine(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); ToLuaInjectionTest obj = (ToLuaInjectionTest)ToLua.CheckObject(L, 1); float arg0 = (float)LuaDLL.luaL_checknumber(L, 2); System.Collections.IEnumerator o = obj.TestCoroutine(arg0); ToLua.Push(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_PropertyTest(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); ToLuaInjectionTest obj = (ToLuaInjectionTest)o; int ret = obj.PropertyTest; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index PropertyTest on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_PropertyTest(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); ToLuaInjectionTest obj = (ToLuaInjectionTest)o; int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); obj.PropertyTest = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index PropertyTest on a nil value"); } } } ================================================ FILE: Assets/ToLua/Examples/TestInjection/ToLuaInjectionTestWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 14459b5f9debe5f47b5a300b6f1acfe8 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestInjection.meta ================================================ fileFormatVersion: 2 guid: 38c5ccf43aa1bef4ab5def4faf0a5aba folderAsset: yes timeCreated: 1515035158 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples/TestOverload/TestExportWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class TestExportWrap { public static void Register(LuaState L) { L.BeginClass(typeof(TestExport), typeof(System.Object)); L.RegFunction(".geti", get_Item); L.RegFunction("get_Item", get_Item); L.RegFunction(".seti", set_Item); L.RegFunction("set_Item", set_Item); L.RegFunction("TestByteBuffer", TestByteBuffer); L.RegFunction("Test", Test); L.RegFunction("TestChar", TestChar); L.RegFunction("Test33", Test33); L.RegFunction("TestGeneric", TestGeneric); L.RegFunction("TestEnum", TestEnum); L.RegFunction("TestCheckParamNumber", TestCheckParamNumber); L.RegFunction("TestCheckParamString", TestCheckParamString); L.RegFunction("TestReflection", TestReflection); L.RegFunction("TestRefGameObject", TestRefGameObject); L.RegFunction("DoClick", DoClick); L.RegFunction("TestNullable", TestNullable); L.RegFunction("New", _CreateTestExport); L.RegVar("this", _this, null); L.RegFunction("__tostring", ToLua.op_ToString); L.RegVar("field", get_field, set_field); L.RegVar("OnClick", get_OnClick, set_OnClick); L.RegVar("OnRefEvent", get_OnRefEvent, set_OnRefEvent); L.RegVar("buffer", get_buffer, set_buffer); L.RegVar("Number", get_Number, set_Number); L.RegFunction("TestBuffer", TestExport_TestBuffer); L.RegFunction("TestRefEvent", TestExport_TestRefEvent); L.EndClass(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _CreateTestExport(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 0) { TestExport obj = new TestExport(); ToLua.PushSealed(L, obj); return 1; } else if (count == 1 && TypeChecker.CheckTypes(L, 1)) { UnityEngine.Vector3 arg0 = ToLua.ToVector3(L, 1); TestExport obj = new TestExport(arg0); ToLua.PushSealed(L, obj); return 1; } else if (count == 1 && TypeChecker.CheckTypes(L, 1)) { UnityEngine.Vector3[] arg0 = ToLua.ToStructArray(L, 1); TestExport obj = new TestExport(arg0); ToLua.PushSealed(L, obj); return 1; } else if (count == 2) { UnityEngine.Vector3 arg0 = ToLua.ToVector3(L, 1); string arg1 = ToLua.CheckString(L, 2); TestExport obj = new TestExport(arg0, arg1); ToLua.PushSealed(L, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: TestExport.New"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _get_this(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2) { TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = obj[arg0]; LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); char arg0 = (char)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int o = obj[arg0, arg1]; LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to operator method: TestExport.this"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _set_this(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3) { TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); obj[arg0] = arg1; return 0; } else if (count == 4) { TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); char arg0 = (char)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); obj[arg0, arg1] = arg2; return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to operator method: TestExport.this"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int _this(IntPtr L) { try { LuaDLL.lua_pushvalue(L, 1); LuaDLL.tolua_bindthis(L, _get_this, _set_this); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Item(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); int o = TestExport.get_Item(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 1 && TypeChecker.CheckTypes(L, 1)) { double arg0 = (double)LuaDLL.lua_tonumber(L, 1); int o = TestExport.get_Item(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2) { TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int o = obj[arg0]; LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { int arg0 = (int)LuaDLL.lua_tonumber(L, 1); int arg1 = (int)LuaDLL.lua_tonumber(L, 2); int arg2 = (int)LuaDLL.lua_tonumber(L, 3); int o = TestExport.get_Item(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); char arg0 = (char)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int o = obj[arg0, arg1]; LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: TestExport.get_Item"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_Item(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1) { double arg0 = (double)LuaDLL.luaL_checknumber(L, 1); int o = TestExport.set_Item(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3) { TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); obj[arg0] = arg1; return 0; } else if (count == 4) { TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); char arg0 = (char)LuaDLL.luaL_checknumber(L, 2); int arg1 = (int)LuaDLL.luaL_checknumber(L, 3); int arg2 = (int)LuaDLL.luaL_checknumber(L, 4); obj[arg0, arg1] = arg2; return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: TestExport.set_Item"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestByteBuffer(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); TestExport.TestBuffer arg0 = (TestExport.TestBuffer)ToLua.CheckDelegate(L, 2); obj.TestByteBuffer(arg0); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Test(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 1 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); int o = obj.Test(); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes>(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); int arg0; int o = obj.Test(out arg0); LuaDLL.lua_pushinteger(L, o); LuaDLL.lua_pushinteger(L, arg0); return 2; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); double arg0 = (double)LuaDLL.lua_tonumber(L, 2); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { string arg0 = ToLua.ToString(L, 1); string arg1 = ToLua.ToString(L, 2); int o = TestExport.Test(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); TestExport.Space arg0 = (TestExport.Space)ToLua.ToObject(L, 2); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); bool arg0 = LuaDLL.lua_toboolean(L, 2); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); int[,] arg0 = (int[,])ToLua.ToObject(L, 2); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 2 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); string[] arg0 = ToLua.ToStringArray(L, 2); bool arg1 = LuaDLL.lua_toboolean(L, 3); int o = obj.Test(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); int arg1 = (int)LuaDLL.lua_tonumber(L, 3); int o = obj.Test(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); string arg1 = ToLua.ToString(L, 3); int o = obj.Test(arg0, arg1); LuaDLL.lua_pushinteger(L, o); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); object arg0 = ToLua.ToVarObject(L, 2); string arg1 = ToLua.ToString(L, 3); int arg2 = (int)LuaDLL.lua_tonumber(L, 4); int o = obj.Test(arg0, arg1, arg2); LuaDLL.lua_pushinteger(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); int[] arg0 = ToLua.ToParamsNumber(L, 2, count - 1); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); string[] arg0 = ToLua.ToParamsString(L, 2, count - 1); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else if (TypeChecker.CheckTypes(L, 1) && TypeChecker.CheckParamsType(L, 2, count - 1)) { TestExport obj = (TestExport)ToLua.ToObject(L, 1); object[] arg0 = ToLua.ToParamsObject(L, 2, count - 1); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: TestExport.Test"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestChar(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); char arg0 = (char)LuaDLL.luaL_checknumber(L, 2); int o = obj.Test(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int Test33(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); System.Action arg0 = (System.Action)ToLua.CheckDelegate>(L, 2); int o = obj.Test33(ref arg0); LuaDLL.lua_pushinteger(L, o); ToLua.Push(L, arg0); return 2; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestGeneric(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); UnityEngine.Component arg0 = (UnityEngine.Component)ToLua.CheckObject(L, 2); int o = obj.TestGeneric(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestEnum(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); TestExport.Space arg0 = (TestExport.Space)ToLua.CheckObject(L, 2, typeof(TestExport.Space)); int o = obj.TestEnum(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestCheckParamNumber(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); int[] arg0 = ToLua.CheckParamsNumber(L, 2, count - 1); int o = obj.TestCheckParamNumber(arg0); LuaDLL.lua_pushinteger(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestCheckParamString(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); string[] arg0 = ToLua.CheckParamsString(L, 2, count - 1); string o = obj.TestCheckParamString(arg0); LuaDLL.lua_pushstring(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestReflection(IntPtr L) { try { ToLua.CheckArgsCount(L, 0); TestExport.TestReflection(); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestRefGameObject(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); UnityEngine.GameObject arg0 = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); TestExport.TestRefGameObject(ref arg0); ToLua.PushSealed(L, arg0); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int DoClick(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); obj.DoClick(); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestNullable(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); TestExport obj = (TestExport)ToLua.CheckObject(L, 1, typeof(TestExport)); System.Nullable arg0 = ToLua.CheckNullable(L, 2); System.Nullable o = obj.TestNullable(arg0); ToLua.PusNullable(L, o); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_field(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; int ret = obj.field; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index field on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_OnClick(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; System.Action ret = obj.OnClick; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index OnClick on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_OnRefEvent(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; TestExport.TestRefEvent ret = obj.OnRefEvent; ToLua.Push(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index OnRefEvent on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_buffer(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; byte[] ret = obj.buffer; LuaDLL.tolua_pushlstring(L, ret, ret.Length); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index buffer on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_Number(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; int ret = obj.Number; LuaDLL.lua_pushinteger(L, ret); return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Number on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_field(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); obj.field = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index field on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_OnClick(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; System.Action arg0 = (System.Action)ToLua.CheckDelegate(L, 2); obj.OnClick = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index OnClick on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_OnRefEvent(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; TestExport.TestRefEvent arg0 = (TestExport.TestRefEvent)ToLua.CheckDelegate(L, 2); obj.OnRefEvent = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index OnRefEvent on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_buffer(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; byte[] arg0 = ToLua.CheckByteBuffer(L, 2); obj.buffer = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index buffer on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int set_Number(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); TestExport obj = (TestExport)o; int arg0 = (int)LuaDLL.luaL_checknumber(L, 2); obj.Number = arg0; return 0; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e, o, "attempt to index Number on a nil value"); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestExport_TestBuffer(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); LuaFunction func = ToLua.CheckLuaFunction(L, 1); if (count == 1) { Delegate arg1 = DelegateTraits.Create(func); ToLua.Push(L, arg1); } else { LuaTable self = ToLua.CheckLuaTable(L, 2); Delegate arg1 = DelegateTraits.Create(func, self); ToLua.Push(L, arg1); } return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int TestExport_TestRefEvent(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); LuaFunction func = ToLua.CheckLuaFunction(L, 1); if (count == 1) { Delegate arg1 = DelegateTraits.Create(func); ToLua.Push(L, arg1); } else { LuaTable self = ToLua.CheckLuaTable(L, 2); Delegate arg1 = DelegateTraits.Create(func, self); ToLua.Push(L, arg1); } return 1; } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } } } ================================================ FILE: Assets/ToLua/Examples/TestOverload/TestExportWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 93a993f96184f9043b307249752cde32 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestOverload/TestExport_SpaceWrap.cs ================================================ //this source code was auto-generated by tolua#, do not modify it using System; using LuaInterface; public class TestExport_SpaceWrap { public static void Register(LuaState L) { L.BeginEnum(typeof(TestExport.Space)); L.RegVar("World", get_World, null); L.RegFunction("IntToEnum", IntToEnum); L.EndEnum(); TypeTraits.Check = CheckType; StackTraits.Push = Push; } static void Push(IntPtr L, TestExport.Space arg) { ToLua.Push(L, arg); } static bool CheckType(IntPtr L, int pos) { return TypeChecker.CheckEnumType(typeof(TestExport.Space), L, pos); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int get_World(IntPtr L) { ToLua.Push(L, TestExport.Space.World); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int IntToEnum(IntPtr L) { int arg0 = (int)LuaDLL.lua_tonumber(L, 1); TestExport.Space o = (TestExport.Space)arg0; ToLua.Push(L, o); return 1; } } ================================================ FILE: Assets/ToLua/Examples/TestOverload/TestExport_SpaceWrap.cs.meta ================================================ fileFormatVersion: 2 guid: 3e8176bbf31cef9418a3a1aa76f1f018 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestOverload/TestOverload.cs ================================================ using UnityEngine; using System.Collections; using LuaInterface; using System; using System.Reflection; public class TestEnum { public TestEnum() { } public void Test(UnityEngine.Space e) { } } public sealed class TestExport { [LuaByteBufferAttribute] public delegate void TestBuffer(byte[] buffer); public enum Space { World = 1 } public int field = 1024; public System.Action OnClick = delegate { }; public delegate void TestRefEvent(ref GameObject go); public TestRefEvent OnRefEvent; //public int Item { get; set; } private int number = 123; public int Number { get { return number; } set { number = value; } } public int this[int pos] { get { return pos; } set { Debugger.Log(value); } } public int this[char index, int pos] { get { return 0; } set { Debugger.Log(value); } } [LuaByteBufferAttribute] public byte[] buffer; public static int get_Item(string pos) { return 0; } public static int get_Item(double pos) { return 0; } public static int get_Item(int i, int j, int k) { return 0; } public static int set_Item(double pos) { return 0; } public void TestByteBuffer(TestBuffer tb) { } public int Test(object o, string str) { Debugger.Log("call Test(object o, string str)"); return 1; } public int Test(object o, string str, int n) { Debugger.Log("call Test(object o, string str, int n)"); return 111; } [LuaRenameAttribute(Name = "TestChar")] public int Test(char c) { Debugger.Log("call Test(char c)"); return 2; } public int Test() { return -1; } public int Test(bool b) { Debugger.Log("call Test(bool b)"); return 15; } public int Test(int[,] objs) { Debugger.Log("call Test(int[,] objs)"); return 16; } public int Test(int i) { Debugger.Log("call Test(int i)"); return 3; } //有这个函数要扔掉上面两个精度不匹配的,因为lua是double public int Test(double d) { Debugger.Log("call Test(double d)"); return 4; } public int Test(out int i) { i = 1024; Debugger.Log("call Test(ref int i)"); return 3; } public int Test(int i, int j) { Debugger.Log("call Test(int i, int j)"); return 5; } public int Test(string str) { Debugger.Log("call Test(string str)"); return 6; } public static int Test(string str1, string str2) { Debugger.Log("call static Test(string str1, string str2)"); return 7; } public int Test(object o) { Debugger.Log("call Test(object o)"); return 8; } public int Test(params int[] objs) { Debugger.Log("call Test(params int[] objs)"); return 12; } public int Test(params string[] objs) { Debugger.Log("call Test(params int[] objs)"); return 13; } public int Test(string[] objs, bool flag) { Debugger.Log("call Test(string[] objs, bool flag)"); return 20; } public int Test(params object[] objs) { Debugger.Log("call Test(params object[] objs)"); return 9; } public int Test(Space e) { Debugger.Log("call Test(Space e)"); return 10; } public int Test33(ref System.Action action) { Debugger.Log("ref System.Action action"); return 14; } public int TestGeneric (T t) where T : Component { Debugger.Log("TestGeneric(T t) Call"); return 11; } public int TestEnum(Space e) { Debugger.Log("call TestEnum(Space e)"); return 10; } public int TestCheckParamNumber(params int[] ns) { Debugger.Log("call TestCheckParamNumber(params int[] ns)"); int n = 0; for (int i = 0; i < ns.Length; i++) { n += ns[i]; } return n; } public string TestCheckParamString(params string[] ss) { Debugger.Log("call TestCheckParamNumber(params string[] ss)"); string str = null; for (int i = 0; i < ss.Length; i++) { str += ss[i]; } return str; } public static void TestReflection() { Debugger.Log("call TestReflection()"); } public static void TestRefGameObject(ref GameObject go) { } public void DoClick() { OnClick(); } public TestExport() { Debugger.Log("call TestExport()"); } public TestExport(Vector3[] v) { Debugger.Log("call TestExport(params Vector3[] v)"); } public TestExport(Vector3 v, string str) { Debugger.Log("call TestExport(Vector3 v, string str)"); } public TestExport(Vector3 v) { Debugger.Log("call TestExport(Vector3 v)"); } public Nullable TestNullable(Nullable v) { Debugger.Log("call TestNullable(Nullable v)"); return v; } } public class TestOverload : MonoBehaviour { private string script = @" require 'TestExport' local out = require 'tolua.out' local GameObject = UnityEngine.GameObject function Test(to) assert(to:Test(1) == 4) local flag, num = to:Test(out.int) assert(flag == 3 and num == 1024, 'Test(out)') assert(to:Test('hello') == 6, 'Test(string)') assert(to:Test(System.Object.New()) == 8) assert(to:Test(true) == 15) assert(to:Test(123, 456) == 5) assert(to:Test('123', '456') == 1) assert(to:Test(System.Object.New(), '456') == 1) assert(to:Test('123', 456) == 9) assert(to:Test('123', System.Object.New()) == 9) assert(to:Test(1,2,3) == 12) assert(to:Test('hello') == 6) assert(TestExport.Test('hello', 'world') == 7) assert(to:TestGeneric(GameObject().transform) == 11) assert(to:TestCheckParamNumber(1,2,3) == 6) assert(to:TestCheckParamString('1', '2', '3') == '123') assert(to:Test(TestExport.Space.World) == 10) print(to.this:get(123)) to.this:set(1, 456) local v = to:TestNullable(Vector3.New(1,2,3)) print(v.z) end "; void Awake () { LuaState state = new LuaState(); state.Start(); LuaBinder.Bind(state); Bind(state); state.DoString(script, "TestOverload.cs"); TestExport to = new TestExport(); LuaFunction func = state.GetFunction("Test"); func.Call(to); state.Dispose(); } void Bind(LuaState state) { state.BeginModule(null); TestExportWrap.Register(state); state.BeginModule("TestExport"); TestExport_SpaceWrap.Register(state); state.EndModule(); state.EndModule(); } } ================================================ FILE: Assets/ToLua/Examples/TestOverload/TestOverload.cs.meta ================================================ fileFormatVersion: 2 guid: ccb167912a52c2f4e9f88a1bc02d5083 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Examples/TestOverload/TestOverload.unity.meta ================================================ fileFormatVersion: 2 guid: 45830782541ee7a49b44eb5a02d7ecef DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Examples/TestOverload.meta ================================================ fileFormatVersion: 2 guid: c47782a99562c02499fb1602381bfe8d folderAsset: yes timeCreated: 1486461631 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Examples.meta ================================================ fileFormatVersion: 2 guid: 940a49ebae9b91b4fb0682c92d968933 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Injection/Editor/CustomCecilRocks/MethodBodyRocks.cs ================================================ #if ENABLE_LUA_INJECTION // // Author: // Jb Evain (jbevain@gmail.com) // // Copyright (c) 2008 - 2015 Jb Evain // Copyright (c) 2008 - 2011 Novell, Inc. // // Licensed under the MIT/X11 license. // using System; using Mono.Cecil; using Mono.Cecil.Cil; namespace CustomCecilRocks { public static class MethodBodyRocks { public static void SimplifyMacros (this MethodBody self) { if (self == null) throw new ArgumentNullException ("self"); foreach (var instruction in self.Instructions) { if (instruction.OpCode.OpCodeType != OpCodeType.Macro) continue; switch (instruction.OpCode.Code) { case Code.Ldarg_0: ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (0)); break; case Code.Ldarg_1: ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (1)); break; case Code.Ldarg_2: ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (2)); break; case Code.Ldarg_3: ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (3)); break; case Code.Ldloc_0: ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [0]); break; case Code.Ldloc_1: ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [1]); break; case Code.Ldloc_2: ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [2]); break; case Code.Ldloc_3: ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [3]); break; case Code.Stloc_0: ExpandMacro (instruction, OpCodes.Stloc, self.Variables [0]); break; case Code.Stloc_1: ExpandMacro (instruction, OpCodes.Stloc, self.Variables [1]); break; case Code.Stloc_2: ExpandMacro (instruction, OpCodes.Stloc, self.Variables [2]); break; case Code.Stloc_3: ExpandMacro (instruction, OpCodes.Stloc, self.Variables [3]); break; case Code.Ldarg_S: instruction.OpCode = OpCodes.Ldarg; break; case Code.Ldarga_S: instruction.OpCode = OpCodes.Ldarga; break; case Code.Starg_S: instruction.OpCode = OpCodes.Starg; break; case Code.Ldloc_S: instruction.OpCode = OpCodes.Ldloc; break; case Code.Ldloca_S: instruction.OpCode = OpCodes.Ldloca; break; case Code.Stloc_S: instruction.OpCode = OpCodes.Stloc; break; case Code.Ldc_I4_M1: ExpandMacro (instruction, OpCodes.Ldc_I4, -1); break; case Code.Ldc_I4_0: ExpandMacro (instruction, OpCodes.Ldc_I4, 0); break; case Code.Ldc_I4_1: ExpandMacro (instruction, OpCodes.Ldc_I4, 1); break; case Code.Ldc_I4_2: ExpandMacro (instruction, OpCodes.Ldc_I4, 2); break; case Code.Ldc_I4_3: ExpandMacro (instruction, OpCodes.Ldc_I4, 3); break; case Code.Ldc_I4_4: ExpandMacro (instruction, OpCodes.Ldc_I4, 4); break; case Code.Ldc_I4_5: ExpandMacro (instruction, OpCodes.Ldc_I4, 5); break; case Code.Ldc_I4_6: ExpandMacro (instruction, OpCodes.Ldc_I4, 6); break; case Code.Ldc_I4_7: ExpandMacro (instruction, OpCodes.Ldc_I4, 7); break; case Code.Ldc_I4_8: ExpandMacro (instruction, OpCodes.Ldc_I4, 8); break; case Code.Ldc_I4_S: ExpandMacro (instruction, OpCodes.Ldc_I4, (int) (sbyte) instruction.Operand); break; case Code.Br_S: instruction.OpCode = OpCodes.Br; break; case Code.Brfalse_S: instruction.OpCode = OpCodes.Brfalse; break; case Code.Brtrue_S: instruction.OpCode = OpCodes.Brtrue; break; case Code.Beq_S: instruction.OpCode = OpCodes.Beq; break; case Code.Bge_S: instruction.OpCode = OpCodes.Bge; break; case Code.Bgt_S: instruction.OpCode = OpCodes.Bgt; break; case Code.Ble_S: instruction.OpCode = OpCodes.Ble; break; case Code.Blt_S: instruction.OpCode = OpCodes.Blt; break; case Code.Bne_Un_S: instruction.OpCode = OpCodes.Bne_Un; break; case Code.Bge_Un_S: instruction.OpCode = OpCodes.Bge_Un; break; case Code.Bgt_Un_S: instruction.OpCode = OpCodes.Bgt_Un; break; case Code.Ble_Un_S: instruction.OpCode = OpCodes.Ble_Un; break; case Code.Blt_Un_S: instruction.OpCode = OpCodes.Blt_Un; break; case Code.Leave_S: instruction.OpCode = OpCodes.Leave; break; } } } static void ExpandMacro (Instruction instruction, OpCode opcode, object operand) { instruction.OpCode = opcode; instruction.Operand = operand; } static void MakeMacro (Instruction instruction, OpCode opcode) { instruction.OpCode = opcode; instruction.Operand = null; } public static void Optimize (this MethodBody self) { if (self == null) throw new ArgumentNullException ("self"); OptimizeLongs (self); OptimizeMacros (self); } static void OptimizeLongs (this MethodBody self) { for (var i = 0; i < self.Instructions.Count; i++) { var instruction = self.Instructions [i]; if (instruction.OpCode.Code != Code.Ldc_I8) continue; var l = (long) instruction.Operand; if (l >= int.MaxValue || l <= int.MinValue) continue; ExpandMacro (instruction, OpCodes.Ldc_I4, (int) l); self.Instructions.Insert (++i, Instruction.Create (OpCodes.Conv_I8)); } } public static void OptimizeMacros (this MethodBody self) { if (self == null) throw new ArgumentNullException ("self"); var method = self.Method; foreach (var instruction in self.Instructions) { int index; switch (instruction.OpCode.Code) { case Code.Ldarg: index = ((ParameterDefinition) instruction.Operand).Index; if (index == -1 && instruction.Operand == self.ThisParameter) index = 0; else if (method.HasThis) index++; switch (index) { case 0: MakeMacro (instruction, OpCodes.Ldarg_0); break; case 1: MakeMacro (instruction, OpCodes.Ldarg_1); break; case 2: MakeMacro (instruction, OpCodes.Ldarg_2); break; case 3: MakeMacro (instruction, OpCodes.Ldarg_3); break; default: if (index < 256) ExpandMacro (instruction, OpCodes.Ldarg_S, instruction.Operand); break; } break; case Code.Ldloc: index = ((VariableDefinition) instruction.Operand).Index; switch (index) { case 0: MakeMacro (instruction, OpCodes.Ldloc_0); break; case 1: MakeMacro (instruction, OpCodes.Ldloc_1); break; case 2: MakeMacro (instruction, OpCodes.Ldloc_2); break; case 3: MakeMacro (instruction, OpCodes.Ldloc_3); break; default: if (index < 256) ExpandMacro (instruction, OpCodes.Ldloc_S, instruction.Operand); break; } break; case Code.Stloc: index = ((VariableDefinition) instruction.Operand).Index; switch (index) { case 0: MakeMacro (instruction, OpCodes.Stloc_0); break; case 1: MakeMacro (instruction, OpCodes.Stloc_1); break; case 2: MakeMacro (instruction, OpCodes.Stloc_2); break; case 3: MakeMacro (instruction, OpCodes.Stloc_3); break; default: if (index < 256) ExpandMacro (instruction, OpCodes.Stloc_S, instruction.Operand); break; } break; case Code.Ldarga: index = ((ParameterDefinition) instruction.Operand).Index; if (index == -1 && instruction.Operand == self.ThisParameter) index = 0; else if (method.HasThis) index++; if (index < 256) ExpandMacro (instruction, OpCodes.Ldarga_S, instruction.Operand); break; case Code.Ldloca: if (((VariableDefinition) instruction.Operand).Index < 256) ExpandMacro (instruction, OpCodes.Ldloca_S, instruction.Operand); break; case Code.Ldc_I4: int i = (int) instruction.Operand; switch (i) { case -1: MakeMacro (instruction, OpCodes.Ldc_I4_M1); break; case 0: MakeMacro (instruction, OpCodes.Ldc_I4_0); break; case 1: MakeMacro (instruction, OpCodes.Ldc_I4_1); break; case 2: MakeMacro (instruction, OpCodes.Ldc_I4_2); break; case 3: MakeMacro (instruction, OpCodes.Ldc_I4_3); break; case 4: MakeMacro (instruction, OpCodes.Ldc_I4_4); break; case 5: MakeMacro (instruction, OpCodes.Ldc_I4_5); break; case 6: MakeMacro (instruction, OpCodes.Ldc_I4_6); break; case 7: MakeMacro (instruction, OpCodes.Ldc_I4_7); break; case 8: MakeMacro (instruction, OpCodes.Ldc_I4_8); break; default: if (i >= -128 && i < 128) ExpandMacro (instruction, OpCodes.Ldc_I4_S, (sbyte) i); break; } break; } } OptimizeBranches (self); } static void OptimizeBranches (MethodBody body) { ComputeOffsets (body); foreach (var instruction in body.Instructions) { if (instruction.OpCode.OperandType != OperandType.InlineBrTarget) continue; if (OptimizeBranch (instruction)) ComputeOffsets (body); } } static bool OptimizeBranch (Instruction instruction) { var offset = ((Instruction) instruction.Operand).Offset - (instruction.Offset + instruction.OpCode.Size + 4); if (!(offset >= -128 && offset <= 127)) return false; switch (instruction.OpCode.Code) { case Code.Br: instruction.OpCode = OpCodes.Br_S; break; case Code.Brfalse: instruction.OpCode = OpCodes.Brfalse_S; break; case Code.Brtrue: instruction.OpCode = OpCodes.Brtrue_S; break; case Code.Beq: instruction.OpCode = OpCodes.Beq_S; break; case Code.Bge: instruction.OpCode = OpCodes.Bge_S; break; case Code.Bgt: instruction.OpCode = OpCodes.Bgt_S; break; case Code.Ble: instruction.OpCode = OpCodes.Ble_S; break; case Code.Blt: instruction.OpCode = OpCodes.Blt_S; break; case Code.Bne_Un: instruction.OpCode = OpCodes.Bne_Un_S; break; case Code.Bge_Un: instruction.OpCode = OpCodes.Bge_Un_S; break; case Code.Bgt_Un: instruction.OpCode = OpCodes.Bgt_Un_S; break; case Code.Ble_Un: instruction.OpCode = OpCodes.Ble_Un_S; break; case Code.Blt_Un: instruction.OpCode = OpCodes.Blt_Un_S; break; case Code.Leave: instruction.OpCode = OpCodes.Leave_S; break; } return true; } static void ComputeOffsets (MethodBody body) { var offset = 0; foreach (var instruction in body.Instructions) { instruction.Offset = offset; offset += instruction.GetSize (); } } public static ParameterDefinition GetParameter (this MethodBody self, int index) { var method = self.Method; if (method.HasThis) { if (index == 0) return self.ThisParameter; index--; } var parameters = method.Parameters; if (index < 0 || index >= parameters.Count) return null; return parameters [index]; } } } #endif ================================================ FILE: Assets/ToLua/Injection/Editor/CustomCecilRocks/MethodBodyRocks.cs.meta ================================================ fileFormatVersion: 2 guid: 86b293140e547b342a6037d11e939fce MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/Editor/CustomCecilRocks.meta ================================================ fileFormatVersion: 2 guid: 5c0193e665c01f54eb307adc123ddb74 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/Editor/ToLuaInjection.cs ================================================ #if ENABLE_LUA_INJECTION using System; using System.IO; using System.Xml; using System.Text; using System.Linq; using UnityEngine; using UnityEditor; using Mono.Cecil; using Mono.Cecil.Cil; using Unity.CecilTools; using Unity.CecilTools.Extensions; using CustomCecilRocks; using System.Reflection; using LuaInterface; using UnityEditor.Callbacks; using System.Collections.Generic; using MethodBody = Mono.Cecil.Cil.MethodBody; class InjectedMethodInfo { public string methodFullSignature; public string methodOverloadSignature; public string methodPublishedName; public string methodName; public int methodIndex; } [InitializeOnLoad] public static class ToLuaInjection { static int offset = 0; static int methodCounter = 0; static bool EnableSymbols = true; static Instruction cursor; static VariableDefinition flagDef; static VariableDefinition funcDef; static TypeReference intTypeRef; static TypeReference injectFlagTypeRef; static TypeReference noToLuaAttrTypeRef; static TypeDefinition injectStationTypeDef; static TypeDefinition luaFunctionTypeDef; static TypeDefinition luaTableTypeDef; static MethodReference injectFlagGetter; static MethodReference injectedFuncGetter; static HashSet dropTypeGroup = new HashSet(); static HashSet injectableTypeGroup = new HashSet(); static Dictionary resultTableGroup = new Dictionary(); static SortedDictionary> bridgeInfo = new SortedDictionary>(); static OpCode[] ldargs = new OpCode[] { OpCodes.Ldarg_0, OpCodes.Ldarg_1, OpCodes.Ldarg_2, OpCodes.Ldarg_3 }; static OpCode[] ldcI4s = new OpCode[] { OpCodes.Ldc_I4_1, OpCodes.Ldc_I4_2, OpCodes.Ldc_I4_4, OpCodes.Ldc_I4_8 }; const string assemblyPath = "./Library/ScriptAssemblies/Assembly-CSharp.dll"; const InjectType injectType = InjectType.After | InjectType.Before | InjectType.Replace | InjectType.ReplaceWithPreInvokeBase | InjectType.ReplaceWithPostInvokeBase; const InjectFilter injectIgnoring = InjectFilter.IgnoreGeneric | InjectFilter.IgnoreConstructor;// | InjectFilter.IgnoreNoToLuaAttr | InjectFilter.IgnoreProperty; static HashSet dropGenericNameGroup = new HashSet { }; static HashSet dropNamespaceGroup = new HashSet { "LuaInterface", }; static HashSet forceInjectTypeGroup = new HashSet { }; static ToLuaInjection() { LoadAndCheckAssembly(true); InjectAll(); } static void InjectAll() { var injectionStatus = EditorPrefs.GetInt(Application.dataPath + "WaitForInjection", 0); if (Application.isPlaying || EditorApplication.isCompiling || injectionStatus == 0) { return; } bool bInjectInterupted = !LoadBlackList() || ToLuaMenu.UpdateMonoCecil(ref EnableSymbols) != 0 || !LoadBridgeEditorInfo(); if (!bInjectInterupted) { CacheInjectableTypeGroup(); Inject(); AssetDatabase.Refresh(); } } [PostProcessBuildAttribute()] static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) { var injectionStatus = EditorPrefs.GetInt(Application.dataPath + "WaitForInjection", 0); if (injectionStatus == 0) { Debug.LogError("Inject Failed!!!"); } EditorPrefs.SetInt(Application.dataPath + "WaitForInjection", 0); } [PostProcessScene] static void OnPostProcessScene() { if (BuildPipeline.isBuildingPlayer) { EditorPrefs.SetInt(Application.dataPath + "WaitForInjection", 1); } InjectAll(); } [DidReloadScripts] static void OnDidReloadScripts() { if (!BuildPipeline.isBuildingPlayer) { EditorPrefs.SetInt(Application.dataPath + "WaitForInjection", 0); } } [MenuItem("Lua/Inject All &i", false, 5)] static void InjectByMenu() { if (Application.isPlaying) { EditorUtility.DisplayDialog("警告", "游戏运行过程中无法操作", "确定"); return; } EditorPrefs.SetInt(Application.dataPath + "WaitForInjection", 1); if (EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器编译完成", "确定"); return; } InjectAll(); } static AssemblyDefinition LoadAndCheckAssembly(bool bPulse) { var assemblyReader = new ReaderParameters { ReadSymbols = EnableSymbols, AssemblyResolver = GetAssemblyResolver() }; AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyPath, assemblyReader); var alreadyInjected = assembly.CustomAttributes.Any((attr) => { return attr.AttributeType.FullName == "LuaInterface.UseDefinedAttribute"; }); EditorPrefs.SetInt(Application.dataPath + "InjectStatus", alreadyInjected ? 1 : 0); if (bPulse) { Clean(assembly); } return assembly; } static void Inject() { AssemblyDefinition assembly = null; try { assembly = LoadAndCheckAssembly(false); if (InjectPrepare(assembly)) { foreach (var module in assembly.Modules) { int cursor = 0; int typesCount = module.Types.Count; foreach (var type in module.Types) { ++cursor; EditorUtility.DisplayProgressBar("Injecting:" + module.FullyQualifiedName, type.FullName, (float)cursor / typesCount); if (!InjectProcess(assembly, type)) { EditorUtility.ClearProgressBar(); return; } } } EditorUtility.ClearProgressBar(); UpdateInjectionCacheSize(); ExportInjectionBridgeInfo(); WriteInjectedAssembly(assembly, assemblyPath); resultTableGroup.Clear(); EditorApplication.Beep(); Debug.Log("Lua Injection Finished!"); EditorPrefs.SetInt(Application.dataPath + "InjectStatus", 1); } } catch (Exception e) { Debug.LogError(e.ToString()); } finally { if (assembly != null) { Clean(assembly); } } } static bool InjectPrepare(AssemblyDefinition assembly) { bool alreadyInjected = EditorPrefs.GetInt(Application.dataPath + "InjectStatus") == 1; if (alreadyInjected) { Debug.Log("Already Injected!"); return false; } resultTableGroup.Clear(); var injectAttrType = assembly.MainModule.Types.Single(type => type.FullName == "LuaInterface.UseDefinedAttribute"); var attrCtorInfo = injectAttrType.Methods.Single(method => method.IsConstructor); assembly.CustomAttributes.Add(new CustomAttribute(attrCtorInfo)); intTypeRef = assembly.MainModule.TypeSystem.Int32; injectFlagTypeRef = assembly.MainModule.TypeSystem.Byte; noToLuaAttrTypeRef = assembly.MainModule.Types.Single(type => type.FullName == "LuaInterface.NoToLuaAttribute"); injectStationTypeDef = assembly.MainModule.Types.Single(type => type.FullName == "LuaInterface.LuaInjectionStation"); luaFunctionTypeDef = assembly.MainModule.Types.Single(method => method.FullName == "LuaInterface.LuaFunction"); luaTableTypeDef = assembly.MainModule.Types.Single(method => method.FullName == "LuaInterface.LuaTable"); injectFlagGetter = injectStationTypeDef.Methods.Single(method => method.Name == "GetInjectFlag"); injectedFuncGetter = injectStationTypeDef.Methods.Single(method => method.Name == "GetInjectionFunction"); return true; } static BaseAssemblyResolver GetAssemblyResolver() { DefaultAssemblyResolver resolver = new DefaultAssemblyResolver(); AppDomain.CurrentDomain .GetAssemblies() .Select(assem => Path.GetDirectoryName(assem.ManifestModule.FullyQualifiedName)) .Distinct() .Foreach(dir => resolver.AddSearchDirectory(dir)); return resolver; } static bool InjectProcess(AssemblyDefinition assembly, TypeDefinition type) { if (!DoesTypeInjectable(type)) { return true; } foreach (var nestedType in type.NestedTypes) { if (!InjectProcess(assembly, nestedType)) { return false; } } foreach (var target in type.Methods) { if (target.IsGenericMethodDefinition()) { continue; } if (!DoesMethodInjectable(target)) { continue; } int methodIndex = AppendMethod(target); if (methodIndex == -1) { return false; } if (target.IsEnumerator()) { InjectCoroutine(assembly, target, methodIndex); } else { InjectMethod(assembly, target, methodIndex); } } return true; } static void FillBegin(MethodDefinition target, int methodIndex) { MethodBody targetBody = target.Body; ILProcessor il = targetBody.GetILProcessor(); targetBody.InitLocals = true; flagDef = new VariableDefinition(injectFlagTypeRef); funcDef = new VariableDefinition(luaFunctionTypeDef); targetBody.Variables.Add(flagDef); targetBody.Variables.Add(funcDef); Instruction startInsertPos = targetBody.Instructions[0]; il.InsertBefore(startInsertPos, il.Create(OpCodes.Ldc_I4, methodIndex)); il.InsertBefore(startInsertPos, il.Create(OpCodes.Call, injectFlagGetter)); il.InsertBefore(startInsertPos, il.Create(OpCodes.Stloc, flagDef)); il.InsertBefore(startInsertPos, il.Create(OpCodes.Ldloc, flagDef)); il.InsertBefore(startInsertPos, il.Create(OpCodes.Brfalse, startInsertPos)); il.InsertBefore(startInsertPos, il.Create(OpCodes.Ldc_I4, methodIndex)); il.InsertBefore(startInsertPos, il.Create(OpCodes.Call, injectedFuncGetter)); il.InsertBefore(startInsertPos, il.Create(OpCodes.Stloc, funcDef)); offset = targetBody.Instructions.IndexOf(startInsertPos); } #region GenericMethod static void InjectGenericMethod(AssemblyDefinition assembly, MethodDefinition target, int methodIndex) { } #endregion GenericMethod #region Coroutine static void InjectCoroutine(AssemblyDefinition assembly, MethodDefinition target, int methodIndex) { InjectType runtimeInjectType = GetMethodRuntimeInjectType(target); if (runtimeInjectType == InjectType.None) { return; } target.Body.SimplifyMacros(); FillBegin(target, methodIndex); FillReplaceCoroutine(target, runtimeInjectType & InjectType.Replace); FillCoroutineMonitor(target, runtimeInjectType & (~InjectType.Replace), methodIndex); target.Body.OptimizeMacros(); } static void FillReplaceCoroutine(MethodDefinition target, InjectType runtimeInjectType) { if (runtimeInjectType == InjectType.None) { return; } MethodBody targetBody = target.Body; ILProcessor il = targetBody.GetILProcessor(); cursor = GetMethodNextInsertPosition(target, null, false); if (cursor != null) { il.InsertBefore(cursor, il.Create(OpCodes.Ldloc, flagDef)); il.InsertBefore(cursor, il.Create(ldcI4s[(int)InjectType.Replace / 2])); il.InsertBefore(cursor, il.Create(OpCodes.Bne_Un, cursor)); il.InsertBefore(cursor, il.Create(OpCodes.Ldloc, funcDef)); FillArgs(target, cursor, null); il.InsertBefore(cursor, il.Create(OpCodes.Call, GetLuaMethodInvoker(target, false, false))); il.InsertBefore(cursor, il.Create(OpCodes.Ret)); } } static void FillCoroutineMonitor(MethodDefinition target, InjectType runtimeInjectType, int methodIndex) { if (runtimeInjectType == InjectType.None) { return; } MethodBody targetBody = target.Body; FieldDefinition hostField = null; var coroutineEntity = targetBody.Variables[0].VariableType.Resolve(); if (!target.DeclaringType.NestedTypes.Any(type => coroutineEntity == type)) { return; } cursor = GetMethodNextInsertPosition(target, cursor, true); CopyCoroutineCreatorReference(target, coroutineEntity, ref hostField); var coroutineCarrier = coroutineEntity.Methods.Single(method => method.Name == "MoveNext"); CopyCreatorArgsToCarrier(target, coroutineCarrier); FillBegin(coroutineCarrier, methodIndex); var fillInjectInfoFunc = GetCoroutineInjectInfoFiller(target, hostField); FillInjectMethod(coroutineCarrier, fillInjectInfoFunc, runtimeInjectType & InjectType.After); FillInjectMethod(coroutineCarrier, fillInjectInfoFunc, runtimeInjectType & InjectType.Before); } static Action GetCoroutineInjectInfoFiller(MethodDefinition coroutineCreator, FieldDefinition hostRef) { return (coroutineCarrier, runtimeInjectType) => { MethodBody targetBody = coroutineCarrier.Body; ILProcessor il = targetBody.GetILProcessor(); il.InsertBefore(cursor, il.Create(OpCodes.Ldloc, funcDef)); if (coroutineCreator.HasThis) { il.InsertBefore(cursor, il.Create(OpCodes.Ldarg_0)); il.InsertBefore(cursor, il.Create(OpCodes.Ldfld, hostRef)); } CopyCarrierFieldsToArg(coroutineCreator, coroutineCarrier); FillCoroutineState(coroutineCarrier); il.InsertBefore(cursor, il.Create(OpCodes.Call, GetLuaMethodInvoker(coroutineCreator, true, true))); }; } static void CopyCoroutineCreatorReference(MethodDefinition coroutineCreator, TypeDefinition coroutineCarrier, ref FieldDefinition hostField) { if (coroutineCreator.HasThis) { ILProcessor il = coroutineCreator.Body.GetILProcessor(); hostField = new FieldDefinition("__iHost", Mono.Cecil.FieldAttributes.Public, coroutineCreator.DeclaringType); coroutineCarrier.Fields.Add(hostField); il.InsertBefore(cursor, il.Create(OpCodes.Ldloc_0)); il.InsertBefore(cursor, il.Create(OpCodes.Ldarg_0)); il.InsertBefore(cursor, il.Create(OpCodes.Stfld, hostField)); } } static void CopyCreatorArgsToCarrier(MethodDefinition coroutineCreator, MethodDefinition coroutineCarrier) { ILProcessor il = coroutineCreator.Body.GetILProcessor(); var carrierFields = coroutineCarrier.DeclaringType.Fields; coroutineCreator .Parameters .Foreach(param => { var name = "<$>" + param.Name; if (!carrierFields.Any(field => field.Name == name)) { var hostArg = new FieldDefinition(name, Mono.Cecil.FieldAttributes.Public, param.ParameterType); carrierFields.Add(hostArg); il.InsertBefore(cursor, il.Create(OpCodes.Ldloc_0)); il.InsertBefore(cursor, il.Create(OpCodes.Ldarg, param)); il.InsertBefore(cursor, il.Create(OpCodes.Stfld, hostArg)); } }); } static void CopyCarrierFieldsToArg(MethodDefinition coroutineCreator, MethodDefinition coroutineCarrier) { ILProcessor il = coroutineCarrier.Body.GetILProcessor(); var carrierFields = coroutineCarrier.DeclaringType.Fields; coroutineCreator .Parameters .Select(param => "<$>" + param.Name) .Foreach(name => { var arg = carrierFields.Single(field => field.Name == name); il.InsertBefore(cursor, il.Create(OpCodes.Ldarg_0)); il.InsertBefore(cursor, il.Create(OpCodes.Ldfld, arg)); }); } static void FillCoroutineState(MethodDefinition coroutineCarrier) { MethodBody targetBody = coroutineCarrier.Body; ILProcessor il = targetBody.GetILProcessor(); il.InsertBefore(cursor, il.Create(OpCodes.Ldarg_0)); var stateField = coroutineCarrier.DeclaringType.Fields.Single(field => field.Name == "$PC"); il.InsertBefore(cursor, il.Create(OpCodes.Ldfld, stateField)); } #endregion Coroutine #region NormalMethod static void InjectMethod(AssemblyDefinition assembly, MethodDefinition target, int methodIndex) { target.Body.SimplifyMacros(); FillBegin(target, methodIndex); InjectType runtimeInjectType = GetMethodRuntimeInjectType(target); FillInjectMethod(target, FillInjectInfo, runtimeInjectType & InjectType.After); FillInjectMethod(target, FillInjectInfo, runtimeInjectType & (~InjectType.After)); target.Body.OptimizeMacros(); } static void FillInjectMethod(MethodDefinition target, Action fillInjectInfo, InjectType runtimeInjectType) { if (runtimeInjectType == InjectType.None) { return; } MethodBody targetBody = target.Body; ILProcessor il = targetBody.GetILProcessor(); cursor = GetMethodNextInsertPosition(target, null, runtimeInjectType.HasFlag(InjectType.After)); while (cursor != null) { bool bAfterInject = runtimeInjectType == InjectType.After; Instruction startPos = il.Create(OpCodes.Ldloc, flagDef); if (bAfterInject) { /// Replace instruction with references reserved Instruction endPos = il.Create(OpCodes.Ret); int replaceIndex = targetBody.Instructions.IndexOf(cursor); cursor.OpCode = startPos.OpCode; cursor.Operand = startPos.Operand; il.InsertAfter(targetBody.Instructions[replaceIndex], endPos); cursor = targetBody.Instructions[replaceIndex + 1]; } else il.InsertBefore(cursor, startPos); il.InsertBefore(cursor, il.Create(ldcI4s[(int)InjectType.After / 2])); il.InsertBefore(cursor, il.Create(bAfterInject ? OpCodes.Bne_Un : OpCodes.Ble_Un, cursor)); fillInjectInfo(target, runtimeInjectType); cursor = GetMethodNextInsertPosition(target, cursor, runtimeInjectType.HasFlag(InjectType.After)); } } static void FillInjectInfo(MethodDefinition target, InjectType runtimeInjectType) { FillBaseCall(target, runtimeInjectType, true); FillLuaMethodCall(target, runtimeInjectType == InjectType.After); FillBaseCall(target, runtimeInjectType, false); FillJumpInfo(target, runtimeInjectType == InjectType.After); } static void FillBaseCall(MethodDefinition target, InjectType runtimeInjectType, bool preCall) { MethodBody targetBody = target.Body; ILProcessor il = targetBody.GetILProcessor(); InjectType curBaseInjectType = preCall ? InjectType.ReplaceWithPreInvokeBase : InjectType.ReplaceWithPostInvokeBase; if (runtimeInjectType.HasFlag(curBaseInjectType)) { Instruction end = il.Create(OpCodes.Nop); il.InsertBefore(cursor, end); il.InsertBefore(end, il.Create(OpCodes.Ldloc, flagDef)); il.InsertBefore(end, il.Create(OpCodes.Ldc_I4, (int)curBaseInjectType)); il.InsertBefore(end, il.Create(OpCodes.Bne_Un, end)); FillArgs(target, end, PostProcessBaseMethodArg); il.InsertBefore(end, il.Create(OpCodes.Call, target.GetBaseMethodInstance())); if (!target.ReturnVoid()) { il.InsertBefore(end, il.Create(OpCodes.Pop)); } } } static void FillLuaMethodCall(MethodDefinition target, bool bConfirmPopReturnValue) { ILProcessor il = target.Body.GetILProcessor(); Instruction start = il.Create(OpCodes.Ldloc, funcDef); if (cursor.Previous.OpCode == OpCodes.Nop) { cursor.Previous.OpCode = start.OpCode; cursor.Previous.Operand = start.Operand; } else { il.InsertBefore(cursor, start); } FillArgs(target, cursor, ParseArgumentReference); il.InsertBefore(cursor, il.Create(OpCodes.Call, GetLuaMethodInvoker(target, bConfirmPopReturnValue, false))); CacheResultTable(target, bConfirmPopReturnValue); UpdatePassedByReferenceParams(target, bConfirmPopReturnValue); } static void CacheResultTable(MethodDefinition target, bool bConfirmPopReturnValue) { ILProcessor il = target.Body.GetILProcessor(); if (target.GotPassedByReferenceParam()) { il.InsertBefore(cursor, il.Create(OpCodes.Stloc, GetResultTable(target))); } } static VariableDefinition GetResultTable(MethodDefinition target) { VariableDefinition luaTable = null; resultTableGroup.TryGetValue(target, out luaTable); if (luaTable == null) { luaTable = new VariableDefinition(luaTableTypeDef); target.Body.Variables.Add(luaTable); resultTableGroup.Add(target, luaTable); } return luaTable; } static void UpdatePassedByReferenceParams(MethodDefinition target, bool bConfirmPopReturnValue) { if (!target.GotPassedByReferenceParam()) { return; } int updateCount = 0; ILProcessor il = target.Body.GetILProcessor(); VariableDefinition luaTable = GetResultTable(target); var rawGetGenericMethod = luaTableTypeDef.Methods.Single(method => method.Name == "RawGetIndex"); foreach (var param in target.Parameters) { if (!param.ParameterType.IsByReference) { continue; } var paramType = ElementType.For(param.ParameterType); il.InsertBefore(cursor, il.Create(OpCodes.Ldarg, param)); il.InsertBefore(cursor, il.Create(OpCodes.Ldloc, luaTable)); il.InsertBefore(cursor, il.Create(OpCodes.Ldc_I4, ++updateCount)); il.InsertBefore(cursor, il.Create(OpCodes.Call, rawGetGenericMethod.MakeGenericMethod(paramType))); if (paramType.IsValueType) { il.InsertBefore(cursor, il.Create(OpCodes.Stobj, paramType)); } else { il.InsertBefore(cursor, il.Create(OpCodes.Stind_Ref)); } } if (!bConfirmPopReturnValue && !target.ReturnVoid()) { il.InsertBefore(cursor, il.Create(OpCodes.Ldloc, luaTable)); il.InsertBefore(cursor, il.Create(OpCodes.Ldc_I4, ++updateCount)); il.InsertBefore(cursor, il.Create(OpCodes.Call, rawGetGenericMethod.MakeGenericMethod(target.ReturnType))); } } static void FillJumpInfo(MethodDefinition target, bool bConfirmPopReturnValue) { MethodBody targetBody = target.Body; ILProcessor il = targetBody.GetILProcessor(); if (!bConfirmPopReturnValue) { Instruction retIns = il.Create(OpCodes.Ret); if (!injectType.HasFlag(InjectType.Before)) { if (cursor.Previous.OpCode == OpCodes.Nop) { cursor.Previous.OpCode = retIns.OpCode; cursor.Previous.Operand = retIns.Operand; retIns = cursor.Previous; } else { il.InsertBefore(cursor, retIns); } } else { Instruction start = il.Create(OpCodes.Ldloc, flagDef); if (cursor.Previous.OpCode == OpCodes.Nop) { cursor.Previous.OpCode = start.OpCode; cursor.Previous.Operand = start.Operand; il.InsertAfter(cursor.Previous, retIns); } else { il.InsertBefore(cursor, retIns); il.InsertBefore(retIns, start); } Instruction popIns = il.Create(OpCodes.Pop); bool bGotReturnValue = !target.ReturnVoid(); if (bGotReturnValue) { il.InsertBefore(cursor, popIns); } il.InsertBefore(retIns, il.Create(ldcI4s[(int)InjectType.Before / 2])); il.InsertBefore(retIns, il.Create(OpCodes.Ble_Un, bGotReturnValue ? popIns : cursor)); } } else if (cursor.Previous.OpCode == OpCodes.Nop) { targetBody.Instructions.Remove(cursor.Previous); } } #endregion NormalMethod static void FillArgs(MethodDefinition target, Instruction endPoint, Action parseReferenceProcess) { MethodBody targetBody = target.Body; ILProcessor il = targetBody.GetILProcessor(); int paramCount = target.Parameters.Count + (target.HasThis ? 1 : 0); for (int i = 0; i < paramCount; ++i) { if (i < ldargs.Length) { il.InsertBefore(endPoint, il.Create(ldargs[i])); } else if (i <= byte.MaxValue) { il.InsertBefore(endPoint, il.Create(OpCodes.Ldarg_S, (byte)i)); } else { il.InsertBefore(endPoint, il.Create(OpCodes.Ldarg, (short)i)); } if (parseReferenceProcess != null) { parseReferenceProcess(target, endPoint, i); } } } static void PostProcessBaseMethodArg(MethodDefinition target, Instruction endPoint, int paramIndex) { var declaringType = target.DeclaringType; ILProcessor il = target.Body.GetILProcessor(); if (paramIndex == 0 && declaringType.IsValueType) { il.InsertBefore(endPoint, il.Create(OpCodes.Ldobj, declaringType)); il.InsertBefore(endPoint, il.Create(OpCodes.Box, declaringType)); } } static void ParseArgumentReference(MethodDefinition target, Instruction endPoint, int paramIndex) { ParameterDefinition param = null; ILProcessor il = target.Body.GetILProcessor(); if (target.HasThis) { if (paramIndex > 0) { param = target.Parameters[paramIndex - 1]; } else if (target.DeclaringType.IsValueType) { il.InsertBefore(endPoint, il.Create(OpCodes.Ldobj, target.DeclaringType)); } } else if (!target.HasThis) { param = target.Parameters[paramIndex]; } if (param != null && param.ParameterType.IsByReference) { TypeReference paramType = ElementType.For(param.ParameterType); if (paramType.IsValueType) { il.InsertBefore(endPoint, il.Create(OpCodes.Ldobj, paramType)); } else { il.InsertBefore(endPoint, il.Create(OpCodes.Ldind_Ref)); } } } static Instruction GetMethodNextInsertPosition(MethodDefinition target, Instruction curPoint, bool bInsertBeforeRet) { MethodBody targetBody = target.Body; if (target.IsConstructor || bInsertBeforeRet) { if (curPoint != null) { return targetBody.Instructions .SkipWhile(ins => ins != curPoint) .FirstOrDefault(ins => ins != curPoint && ins.OpCode == OpCodes.Ret); } else { return targetBody.Instructions .FirstOrDefault(ins => ins.OpCode == OpCodes.Ret); } } else { if (curPoint != null) return null; else return targetBody.Instructions[offset]; } } static InjectType GetMethodRuntimeInjectType(MethodDefinition target) { InjectType type = injectType; //bool bOverrideParantMethodFlag = target.IsVirtual && target.IsReuseSlot; var parantMethod = target.GetBaseMethodInstance(); if (target.IsConstructor) { type &= ~InjectType.Before; type &= ~InjectType.Replace; type &= ~InjectType.ReplaceWithPostInvokeBase; type &= ~InjectType.ReplaceWithPreInvokeBase; } else if (parantMethod == null || target.IsEnumerator()) { type &= ~InjectType.ReplaceWithPostInvokeBase; type &= ~InjectType.ReplaceWithPreInvokeBase; } else if (!target.HasBody) { type &= ~InjectType.After; type &= ~InjectType.Before; } return type; } static MethodReference GetLuaMethodInvoker(MethodDefinition prototypeMethod, bool bIgnoreReturnValue, bool bAppendCoroutineState) { MethodReference injectMethod = null; GetLuaInvoker(prototypeMethod, bIgnoreReturnValue, bAppendCoroutineState, ref injectMethod); FillLuaInvokerGenericArguments(prototypeMethod, bIgnoreReturnValue, bAppendCoroutineState, ref injectMethod); return injectMethod; } static void GetLuaInvoker(MethodDefinition prototypeMethod, bool bIgnoreReturnValue, bool bAppendCoroutineState, ref MethodReference invoker) { bool bRequireResult = prototypeMethod.GotPassedByReferenceParam() || (!bIgnoreReturnValue && !prototypeMethod.ReturnVoid()); string methodName = bRequireResult ? "Invoke" : "Call"; int paramCount = prototypeMethod.Parameters.Count; int paramExtraCount = prototypeMethod.HasThis ? 1 : 0; paramExtraCount = bAppendCoroutineState ? paramExtraCount + 1 : paramExtraCount; paramCount += paramExtraCount; invoker = luaFunctionTypeDef.Methods.FirstOrDefault(method => { return method.Name == methodName && method.Parameters.Count == paramCount && bRequireResult == !method.ReturnVoid(); }); if (invoker == null) { Debug.Log(prototypeMethod.FullName + " Got too many parameters!!!Skipped!!!"); } } static void FillLuaInvokerGenericArguments(MethodDefinition prototypeMethod, bool bIgnoreReturnValue, bool bAppendCoroutineState, ref MethodReference invoker) { if (invoker.HasGenericParameters) { GenericInstanceMethod genericInjectMethod = new GenericInstanceMethod(invoker.CloneMethod()); if (prototypeMethod.HasThis) { genericInjectMethod.GenericArguments.Add(prototypeMethod.DeclaringType); } foreach (ParameterDefinition parameter in prototypeMethod.Parameters) { var paramType = parameter.ParameterType.IsByReference ? ElementType.For(parameter.ParameterType) : parameter.ParameterType; genericInjectMethod.GenericArguments.Add(paramType); } if (bAppendCoroutineState) { genericInjectMethod.GenericArguments.Add(intTypeRef); } if (prototypeMethod.GotPassedByReferenceParam()) { genericInjectMethod.GenericArguments.Add(luaTableTypeDef); } else if (!bIgnoreReturnValue && !prototypeMethod.ReturnVoid()) { genericInjectMethod.GenericArguments.Add(prototypeMethod.ReturnType); } invoker = genericInjectMethod; } } static void UpdateInjectionCacheSize() { var staticConstructor = injectStationTypeDef.Methods.Single((method) => { return method.Name == ".cctor"; }); var il = staticConstructor.Body.GetILProcessor(); Instruction loadStaticFieldIns = null; loadStaticFieldIns = staticConstructor .Body .Instructions .FirstOrDefault(ins => { return ins.OpCode == OpCodes.Ldsfld && (ins.Operand as FieldReference).Name == "cacheSize"; }); var loadCacheSizeIns = il.Create(OpCodes.Ldc_I4, methodCounter + 1); il.InsertBefore(loadStaticFieldIns, loadCacheSizeIns); il.InsertBefore(loadStaticFieldIns, il.Create(OpCodes.Stsfld, (loadStaticFieldIns.Operand as FieldReference))); } static void WriteInjectedAssembly(AssemblyDefinition assembly, string assemblyPath) { var writerParameters = new WriterParameters { WriteSymbols = EnableSymbols }; assembly.Write(assemblyPath, writerParameters); } static void ExportInjectionBridgeInfo() { ExportInjectionPublishInfo(bridgeInfo); ExportInjectionEditorInfo(bridgeInfo); } static void ExportInjectionPublishInfo(SortedDictionary> data) { var temp = data.ToDictionary( typeInfo => typeInfo.Key, typeinfo => { return typeinfo.Value .OrderBy(methodInfo => methodInfo.methodPublishedName) .ToDictionary( methodInfo => methodInfo.methodPublishedName, methodInfo => methodInfo.methodIndex ); } ); StringBuilder sb = StringBuilderCache.Acquire(); sb.Append("return "); ToLuaText.TransferDic(temp, sb); sb.Remove(sb.Length - 1, 1); File.WriteAllText(CustomSettings.baseLuaDir + "System/Injection/InjectionBridgeInfo.lua", StringBuilderCache.GetStringAndRelease(sb)); } static int AppendMethod(MethodDefinition method) { string methodSignature = GetMethodSignature(method); string methodFullSignature = method.FullName; InjectedMethodInfo newInfo = new InjectedMethodInfo(); string typeName = ToLuaInjectionHelper.GetTypeName(method.DeclaringType, true); List typeMethodIndexGroup = null; bridgeInfo.TryGetValue(typeName, out typeMethodIndexGroup); if (typeMethodIndexGroup == null) { typeMethodIndexGroup = new List(); newInfo.methodPublishedName = method.Name; bridgeInfo.Add(typeName, typeMethodIndexGroup); } else { InjectedMethodInfo existInfo = typeMethodIndexGroup.Find(info => info.methodOverloadSignature == methodSignature); if (existInfo == null) { existInfo = typeMethodIndexGroup.Find(info => info.methodName == method.Name); if (existInfo != null) { newInfo.methodPublishedName = methodSignature; existInfo.methodPublishedName = existInfo.methodOverloadSignature; } else { newInfo.methodPublishedName = method.Name; } } else { if (existInfo.methodFullSignature != methodFullSignature) { Debug.LogError(typeName + "." + existInfo.methodPublishedName + " 签名跟历史签名不一致,无法增量,Injection中断,请修改函数签名、或者直接删掉InjectionBridgeEditorInfo.xml(该操作会导致无法兼容线上版的包体,需要强制换包)!"); EditorPrefs.SetInt(Application.dataPath + "WaitForInjection", 0); return -1; } return existInfo.methodIndex; } } newInfo.methodName = method.Name; newInfo.methodOverloadSignature = methodSignature; newInfo.methodFullSignature = methodFullSignature; newInfo.methodIndex = ++methodCounter; typeMethodIndexGroup.Add(newInfo); return methodCounter; } static string GetMethodSignature(MethodDefinition method) { StringBuilder paramsTypeNameBuilder = StringBuilderCache.Acquire(); paramsTypeNameBuilder.Append(method.Name); foreach (var param in method.Parameters) { paramsTypeNameBuilder .Append("-") .Append(ToLuaInjectionHelper.GetTypeName(param.ParameterType)); } return StringBuilderCache.GetStringAndRelease(paramsTypeNameBuilder); } static void ExportInjectionEditorInfo(SortedDictionary> data) { string incrementalFilePath = CustomSettings.injectionFilesPath + "InjectionBridgeEditorInfo.xml"; if (File.Exists(incrementalFilePath)) { File.Delete(incrementalFilePath); } var doc = new XmlDocument(); var fileInforRoot = doc.CreateElement("Root"); doc.AppendChild(fileInforRoot); foreach (var type in data) { XmlElement typeNode = doc.CreateElement("Type"); typeNode.SetAttribute("Name", type.Key); var sortedMethodsGroup = type.Value.OrderBy(info => info.methodPublishedName); foreach (var method in sortedMethodsGroup) { XmlElement typeMethodNode = doc.CreateElement("Method"); typeMethodNode.SetAttribute("Name", method.methodName); typeMethodNode.SetAttribute("PublishedName", method.methodPublishedName); typeMethodNode.SetAttribute("Signature", method.methodOverloadSignature); typeMethodNode.SetAttribute("FullSignature", method.methodFullSignature); typeMethodNode.SetAttribute("Index", method.methodIndex.ToString()); typeNode.AppendChild(typeMethodNode); } fileInforRoot.AppendChild(typeNode); } doc.Save(incrementalFilePath); } static bool LoadBridgeEditorInfo() { bridgeInfo.Clear(); methodCounter = 0; string incrementalFilePath = CustomSettings.injectionFilesPath + "InjectionBridgeEditorInfo.xml"; if (!File.Exists(incrementalFilePath)) { return true; } var doc = new XmlDocument(); doc.Load(incrementalFilePath); var fileInfoRoot = doc.FindChildByName("Root"); if (fileInfoRoot == null) { return true; } foreach (XmlNode typeChild in fileInfoRoot.ChildNodes) { List typeMethodInfo = new List(); string typeName = typeChild.FindAttributeByName("Name").Value; foreach (XmlNode methodChild in typeChild.ChildNodes) { InjectedMethodInfo info = new InjectedMethodInfo(); info.methodName = methodChild.FindAttributeByName("Name").Value; info.methodPublishedName = methodChild.FindAttributeByName("PublishedName").Value; info.methodOverloadSignature = methodChild.FindAttributeByName("Signature").Value; info.methodFullSignature = methodChild.FindAttributeByName("FullSignature").Value; info.methodIndex = int.Parse(methodChild.FindAttributeByName("Index").Value); typeMethodInfo.Add(info); methodCounter = Math.Max(methodCounter, info.methodIndex); } bridgeInfo.Add(typeName, typeMethodInfo); } return true; } static void Clean(AssemblyDefinition assembly) { if (assembly.MainModule.SymbolReader != null) { assembly.MainModule.SymbolReader.Dispose(); } } static void CacheInjectableTypeGroup() { injectableTypeGroup.Clear(); Assembly assebly = Assembly.Load("Assembly-CSharp"); foreach (Type t in assebly.GetTypes()) { if (DoesTypeInjectable(t)) { injectableTypeGroup.Add(t.FullName); } } } static bool DoesTypeInjectable(Type type) { if (dropTypeGroup.Contains(type.FullName) || (type.DeclaringType != null && dropTypeGroup.Contains(type.DeclaringType.FullName))) { return false; } if (type.IsGenericType) { Type genericTypeDefinition = type.GetGenericTypeDefinition(); if (dropGenericNameGroup.Contains(genericTypeDefinition.FullName)) { return false; } } if (typeof(System.Delegate).IsAssignableFrom(type)) { return false; } if (type.FullName.Contains("<") || type.IsInterface) { return false; } if (!injectIgnoring.HasFlag(InjectFilter.IgnoreNoToLuaAttr)) { foreach (var attr in type.GetCustomAttributes(true)) { Type attrT = attr.GetType(); if (attrT == typeof(LuaInterface.NoToLuaAttribute)) { return false; } } } return true; } static bool DoesTypeInjectable(TypeDefinition type) { if (dropNamespaceGroup.Contains(type.SafeNamespace())) { return false; } if (!injectableTypeGroup.Contains(type.FullName.Replace("/", "+"))) { return false; } if (injectIgnoring.HasFlag(InjectFilter.IgnoreConstructor) && type.Methods.Count == 1) { return false; } if (!injectIgnoring.HasFlag(InjectFilter.IgnoreNoToLuaAttr)) { if (type.CustomAttributes.Any((attr) => attr.AttributeType == noToLuaAttrTypeRef)) { return false; } } return true; } static bool DoesMethodInjectable(MethodDefinition method) { if (method.IsSpecialName) { if (method.Name == ".cctor") { return false; } bool bIgnoreConstructor = injectIgnoring.HasFlag(InjectFilter.IgnoreConstructor) || method.DeclaringType.IsAssignableTo("UnityEngine.MonoBehaviour") || method.DeclaringType.IsAssignableTo("UnityEngine.ScriptableObject"); if (method.IsConstructor) { if (bIgnoreConstructor) { return false; } } else { ///Skip add_、remove_、op_、Finalize if (!method.IsGetter && !method.IsSetter) { return false; } } } if (method.Name.Contains("<") || method.IsUnmanaged || method.IsAbstract || method.IsPInvokeImpl || !method.HasBody) { return false; } /// Skip Unsafe if (method.Body.Variables.Any(var => var.VariableType.IsPointer) || method.Parameters.Any(param => param.ParameterType.IsPinned)) { return false; } /// Hmm... Sometimes method.IsSpecialName Got False if (method.Name == "Finalize") { return false; } if ((method.IsGetter || method.IsSetter) && injectIgnoring.HasFlag(InjectFilter.IgnoreProperty)) { return false; } if (!injectIgnoring.HasFlag(InjectFilter.IgnoreNoToLuaAttr)) { if (method.CustomAttributes.Any((attr) => attr.AttributeType == noToLuaAttrTypeRef)) { return false; } } if (method.ReturnType.IsAssignableTo("System.Collections.IEnumerable")) { return false; } MethodReference luaInjector = null; GetLuaInvoker(method, true, false, ref luaInjector); if (luaInjector == null) { return false; } return true; } static bool LoadBlackList() { if (File.Exists(InjectionBlackListGenerator.blackListFilePath)) { dropTypeGroup.UnionWith(File.ReadAllLines(InjectionBlackListGenerator.blackListFilePath)); dropTypeGroup.ExceptWith(forceInjectTypeGroup); } else { if (EditorUtility.DisplayDialog("警告", "由于Injection会额外增加代码量,故可以先设置一些Injection跳过的代码目录(比如NGUI插件代码目录),减少生成的代码量", "设置黑名单", "全量生成")) { InjectionBlackListGenerator.Open(); InjectionBlackListGenerator.onBlackListGenerated += InjectAll; return false; } } return true; } } public static class SystemXMLExtension { public static XmlNode FindChildByName(this XmlNode root, string childName) { var child = root.FirstChild; while (child != null) { if (child.Name.Equals(childName)) { return child; } else { child = child.NextSibling; } } return null; } public static XmlAttribute FindAttributeByName(this XmlNode node, string attributeName) { var attributeCollection = node.Attributes; for (int i = 0; i < attributeCollection.Count; i++) { if (attributeCollection[i].Name.Equals(attributeName)) { return attributeCollection[i]; } } return null; } } #endif ================================================ FILE: Assets/ToLua/Injection/Editor/ToLuaInjection.cs.meta ================================================ fileFormatVersion: 2 guid: 576ad269863310b4aba201ae8896a3ef timeCreated: 1512461674 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/Editor/ToLuaInjectionHelper.cs ================================================ #if ENABLE_LUA_INJECTION using System; using System.Collections.Generic; using Mono.Cecil; using Mono.Cecil.Cil; using Unity.CecilTools; using System.Linq; [Flags] public enum InjectFilter { IgnoreConstructor = 1, IgnoreProperty = 1 << 1, IgnoreGeneric = 1 << 2, IgnoreNoToLuaAttr = 1 << 3, } public static class ToLuaInjectionHelper { public static string GetArrayRank(TypeReference t) { ArrayType type = t as ArrayType; int count = type.Rank; if (count == 1) { return "[]"; } using (CString.Block()) { CString sb = CString.Alloc(64); sb.Append('['); for (int i = 1; i < count; i++) { sb.Append(','); } sb.Append(']'); return sb.ToString(); } } public static string GetTypeName(TypeReference t, bool bFull = false) { if (t.IsArray) { string str = GetTypeName(ElementType.For(t)); str += GetArrayRank(t); return str; } else if (t.IsByReference) { //t = t.GetElementType(); return GetTypeName(ElementType.For(t)) + "&"; } else if (t.IsGenericInstance) { return GetGenericName(t, bFull); } else if (t.MetadataType == MetadataType.Void) { return "void"; } else { string name = GetPrimitiveTypeStr(t, bFull); return name.Replace('+', '.'); } } public static string[] GetGenericName(Mono.Collections.Generic.Collection types, int offset, int count, bool bFull) { string[] results = new string[count]; for (int i = 0; i < count; i++) { int pos = i + offset; if (types[pos].IsGenericInstance) { results[i] = GetGenericName(types[pos], bFull); } else { results[i] = GetTypeName(types[pos]); } } return results; } public static MethodReference GetBaseMethodInstance(this MethodDefinition target) { MethodDefinition baseMethodDef = null; var baseType = target.DeclaringType.BaseType; while (baseType != null) { if (baseType.MetadataToken.TokenType == TokenType.TypeRef) { break; } var baseTypeDef = baseType.Resolve(); baseMethodDef = MetadataResolver.GetMethod(baseTypeDef.Methods, target); if (baseMethodDef != null && !baseMethodDef.IsAbstract) { if (baseType.IsGenericInstance) { MethodReference baseMethodRef = baseType.Module.Import(baseMethodDef); var baseTypeInstance = (GenericInstanceType)baseType; return baseMethodRef.MakeGenericMethod(baseTypeInstance.GenericArguments.ToArray()); } break; } else baseMethodDef = null; baseType = baseTypeDef.BaseType; } return baseMethodDef; } public static bool IsGenericTypeDefinition(this TypeReference type) { if (type.HasGenericParameters) { return true; } else if (type.IsByReference || type.IsArray) { return ElementType.For(type).IsGenericTypeDefinition(); } else if (type.IsNested) { var parent = type.DeclaringType; while (parent != null) { if (parent.IsGenericTypeDefinition()) { return true; } if (parent.IsNested) { parent = parent.DeclaringType; } else { break; } } } return type.IsGenericParameter; } public static bool IsGenericMethodDefinition(this MethodDefinition md) { if (md.HasGenericParameters #if UNITY_5_2 || UNITY_5_3 || UNITY_5_3_OR_NEWER || md.ContainsGenericParameter #endif ) { return true; } if (md.DeclaringType != null && md.DeclaringType.IsGenericTypeDefinition()) { return true; } if (md.ReturnType.IsGenericTypeDefinition()) { return true; } foreach (var param in md.Parameters) { if (param.ParameterType.IsGenericTypeDefinition()) { return true; } } return false; } public static bool GotPassedByReferenceParam(this MethodReference md) { return md.Parameters.Any(param => param.ParameterType.IsByReference); } public static TypeReference MakeGenericType(this TypeReference self, params TypeReference[] arguments) { if (self.GenericParameters.Count != arguments.Length) { throw new ArgumentException(); } var instance = new GenericInstanceType(self); foreach (var argument in arguments) { instance.GenericArguments.Add(argument); } return instance; } public static MethodReference MakeGenericMethod(this MethodReference self, params TypeReference[] arguments) { if (self.DeclaringType.IsGenericTypeDefinition()) { return self.CloneMethod(self.DeclaringType.MakeGenericType(arguments)); } else { var genericInstanceMethod = new GenericInstanceMethod(self.CloneMethod()); foreach (var argument in arguments) { genericInstanceMethod.GenericArguments.Add(argument); } return genericInstanceMethod; } } public static MethodReference CloneMethod(this MethodReference self, TypeReference declaringType = null) { var reference = new MethodReference(self.Name, self.ReturnType, declaringType ?? self.DeclaringType) { HasThis = self.HasThis, ExplicitThis = self.ExplicitThis, CallingConvention = self.CallingConvention, }; foreach (ParameterDefinition parameterDef in self.Parameters) { reference.Parameters.Add(new ParameterDefinition(parameterDef.Name, parameterDef.Attributes, parameterDef.ParameterType)); } foreach (GenericParameter genParamDef in self.GenericParameters) { reference.GenericParameters.Add(new GenericParameter(genParamDef.Name, reference)); } return reference; } public static bool IsEnumerator(this MethodDefinition md) { return md.ReturnType.FullName == "System.Collections.IEnumerator"; } public static bool ReturnVoid(this MethodDefinition target) { return target.ReturnType.FullName == "System.Void"; } public static bool HasFlag(this LuaInterface.InjectType flag, LuaInterface.InjectType destFlag) { return (flag & destFlag) == destFlag; } public static bool HasFlag(this LuaInterface.InjectType flag, byte destFlag) { return ((byte)flag & destFlag) == destFlag; } public static bool HasFlag(this InjectFilter flag, InjectFilter destFlag) { return (flag & destFlag) == destFlag; } public static string GetPrimitiveTypeStr(TypeReference t, bool bFull) { switch (t.MetadataType) { case MetadataType.Single: return "float"; case MetadataType.String: return "string"; case MetadataType.Int32: return "int"; case MetadataType.Double: return "double"; case MetadataType.Boolean: return "bool"; case MetadataType.UInt32: return "uint"; case MetadataType.SByte: return "sbyte"; case MetadataType.Byte: return "byte"; case MetadataType.Int16: return "short"; case MetadataType.UInt16: return "ushort"; case MetadataType.Char: return "char"; case MetadataType.Int64: return "long"; case MetadataType.UInt64: return "ulong"; case MetadataType.Object: return "object"; default: return bFull ? t.FullName.Replace("/", "+") : t.Name; } } static string CombineTypeStr(string space, string name) { if (string.IsNullOrEmpty(space)) { return name; } else { return space + "." + name; } } static string GetGenericName(TypeReference t, bool bFull) { GenericInstanceType type = t as GenericInstanceType; var gArgs = type.GenericArguments; string typeName = bFull ? t.FullName.Replace("/", "+") : t.Name; int count = gArgs.Count; int pos = typeName.IndexOf("["); if (pos > 0) { typeName = typeName.Substring(0, pos); } string str = null; string name = null; int offset = 0; pos = typeName.IndexOf("+"); while (pos > 0) { str = typeName.Substring(0, pos); typeName = typeName.Substring(pos + 1); pos = str.IndexOf('`'); if (pos > 0) { count = (int)(str[pos + 1] - '0'); str = str.Substring(0, pos); str += "<" + string.Join(",", GetGenericName(gArgs, offset, count, bFull)) + ">"; offset += count; } name = CombineTypeStr(name, str); pos = typeName.IndexOf("+"); } str = typeName; if (offset < gArgs.Count) { pos = str.IndexOf('`'); count = (int)(str[pos + 1] - '0'); str = str.Substring(0, pos); str += "<" + string.Join(",", GetGenericName(gArgs, offset, count, bFull)) + ">"; } return CombineTypeStr(name, str); } public static void Foreach(this IEnumerable source, Action callback) { foreach (var val in source) { callback(val); } } } #endif ================================================ FILE: Assets/ToLua/Injection/Editor/ToLuaInjectionHelper.cs.meta ================================================ fileFormatVersion: 2 guid: dce8c9cb062a97740b01381922e799a1 timeCreated: 1513238253 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/Editor/ToLuaText.cs ================================================ using System; using System.Text; using System.Reflection; using System.Collections.Generic; public interface LuaSerialization { bool Serialize(StringBuilder sb, int indent); //void UnSerilize(IntPtr L); } public static class ToLuaText { static Type listTypeDefinition = typeof(List<>); static Type dictionaryTypeDefinition = typeof(Dictionary<,>); static MethodInfo customTransferGenericMethod; static MethodInfo listTransferGenericMethod; static MethodInfo arrayTransferGenericMethod; static MethodInfo dictionaryTransferGenericMethod; static ToLuaText() { var classType = typeof(ToLuaText); customTransferGenericMethod = classType.GetMethod("TransferCustomData", BindingFlags.Static | BindingFlags.NonPublic); listTransferGenericMethod = classType.GetMethod("TransferList"); arrayTransferGenericMethod = classType.GetMethod("TransferArray"); dictionaryTransferGenericMethod = classType.GetMethod("TransferDic"); } public static bool TransferList(List list, StringBuilder sb, int indent = 0) { return TransferArray(list.ToArray(), sb, indent); } public static bool TransferArray(T[] array, StringBuilder sb, int indent = 0) { bool bSerializeSuc = false; int validContentLength = sb.Length; NestBegin(sb, indent); if (array.Length <= 0) { bSerializeSuc = false; WipeInvalidContent(sb, validContentLength); return bSerializeSuc; } foreach (var item in array) { if (SerializeData(sb, indent, item)) bSerializeSuc = true; } if (!IsCommonData(typeof(T))) sb.Append("\n"); else sb.Remove(sb.Length - 2, 2);///移除最后一个", "字符组,为了部分满足强迫症 if (bSerializeSuc) NestEnd(sb, indent); else WipeInvalidContent(sb, validContentLength); return bSerializeSuc; } public static bool TransferDic(Dictionary dic, StringBuilder sb, int indent = 0) { var keyType = typeof(T); bool bSerializeSuc = false; int validContentLength = sb.Length; NestBegin(sb, indent); if (dic.Count <= 0/* || !IsDataTypeSerializable(keyType)*/) { bSerializeSuc = false; WipeInvalidContent(sb, validContentLength); return bSerializeSuc; } string keyDataFormat = keyType == typeof(string) ? "[\"{0}\"] = " : "[{0}] = "; ++indent; foreach (var item in dic) { int tempValidContentLength = sb.Length; sb.Append("\n"); AppendIndent(sb, indent); /// 不管是不是自定义数据,只要tostring能用就行 sb.AppendFormat(keyDataFormat, item.Key); if (SerializeData(sb, indent, item.Value)) bSerializeSuc = true; else WipeInvalidContent(sb, tempValidContentLength); } --indent; sb.Append("\n"); if (bSerializeSuc) NestEnd(sb, indent); else WipeInvalidContent(sb, validContentLength); return bSerializeSuc; } public static MethodInfo MakeGenericArrayTransferMethod(Type type) { return arrayTransferGenericMethod.MakeGenericMethod(new Type[] { type }); } public static void AppendIndent(StringBuilder sb, int indent) { for (int i = 0; i < indent; ++i) sb.Append("\t"); } public static void AppendValue(Type valueType, string value, StringBuilder sb) { string dataFormat = valueType == typeof(string) ? "\"{0}\", " : "{0}, "; sb.AppendFormat(dataFormat, value.Replace("\n", @"\n").Replace("\"", @"\""")); } public static void WipeInvalidContent(StringBuilder sb, int validLength) { sb.Remove(validLength, sb.Length - validLength); } static bool TransferCustomData(T data, StringBuilder sb, int indent = 0) where T : LuaSerialization { LuaSerialization serializor = data as LuaSerialization; return serializor.Serialize(sb, indent); } static bool SerializeNestData(StringBuilder sb, int indent, T data, MethodInfo transferMethod) { bool bSerializeSuc = false; int validContentLength = sb.Length; if (transferMethod != null) { ++indent; sb.Append("\n"); bSerializeSuc = (bool)transferMethod.Invoke(null, new object[] { data, sb, indent }); if (!bSerializeSuc) WipeInvalidContent(sb, validContentLength); --indent; } return bSerializeSuc; } static bool SerializeData(StringBuilder sb, int indent, T Data) { Type dataType = typeof(T); bool bSerializeSuc = false; if (dataType.IsPrimitive || dataType == typeof(string)) { AppendValue(dataType, Data.ToString(), sb); bSerializeSuc = true; } else { MethodInfo nestEleTranferMethod = GetCollectionTransferMethod(dataType); bSerializeSuc = SerializeNestData(sb, indent, Data, nestEleTranferMethod); } return bSerializeSuc; } static MethodInfo GetCollectionTransferMethod(Type collectionType) { MethodInfo method = null; if (typeof(LuaSerialization).IsAssignableFrom(collectionType)) method = customTransferGenericMethod.MakeGenericMethod(collectionType); else if (collectionType.GetGenericTypeDefinition() == dictionaryTypeDefinition) method = dictionaryTransferGenericMethod.MakeGenericMethod(collectionType.GetGenericArguments()); else if (collectionType.GetGenericTypeDefinition() == listTypeDefinition) method = listTransferGenericMethod.MakeGenericMethod(collectionType.GetGenericArguments()); else if (collectionType.IsArray) method = arrayTransferGenericMethod.MakeGenericMethod(new Type[] { collectionType.GetElementType() }); return method; } static void NestBegin(StringBuilder sb, int indent) { AppendIndent(sb, indent); sb.Append("{"); } static void NestEnd(StringBuilder sb, int indent) { AppendIndent(sb, indent); sb.Append("},"); } static bool IsDataTypeSerializable(Type type) { if (type != typeof(int) && type != typeof(string)) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(string.Format("Can't Serialize Specify Data Type : {0} To Lua", type)); return false; } return true; } static bool IsCommonData(Type type) { if (type == typeof(string) || type.IsPrimitive) return true; return false; } } ================================================ FILE: Assets/ToLua/Injection/Editor/ToLuaText.cs.meta ================================================ fileFormatVersion: 2 guid: 5de9ab9717d9977429063071523fae1a timeCreated: 1513060947 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/Editor/ToluaInjectionBlackListPanel.cs ================================================ using System; using System.Xml; using System.IO; using System.Linq; using UnityEngine; using UnityEditor; using System.Reflection; using UnityEditorInternal; using System.Collections.Generic; using System.Text.RegularExpressions; public class InjectionBlackListGenerator : EditorWindow { public static string blackListFilePath = CustomSettings.injectionFilesPath + "InjectionBlackList.txt"; public static Action onBlackListGenerated; static string pathsInfoSavedPath; static HashSet specifiedDropType = new HashSet { }; const string nestRegex = @" (?<= (? paths; ReorderableList pathUIList; Vector2 scrollPosition = Vector2.zero; HashSet blackList = new HashSet(); Dictionary, string>> assetExtentions = new Dictionary, string>> { { "*.cs", SearchTypeInCSFile }, { "*.dll", SearchTypeInAssembly }, }; #if ENABLE_LUA_INJECTION [MenuItem("Lua/Generate LuaInjection BlackList")] #endif public static void Open() { GetWindow("LuaInjection", true); } void OnListHeaderGUI(Rect rect) { EditorGUI.LabelField(rect, "Scripts Path"); } void OnListElementGUI(Rect rect, int index, bool isactive, bool isfocused) { const float GAP = 5; string info = paths[index]; rect.y++; Rect r = rect; r.width = 16; r.height = 18; r.xMin = r.xMax + GAP; r.xMax = rect.xMax - 50 - GAP; GUI.enabled = false; info = GUI.TextField(r, info); GUI.enabled = true; r.xMin = r.xMax + GAP; r.width = 50; if (GUI.Button(r, "Select")) { var path = SelectFolder(); if (path != null) { paths[index] = path; } } } string SelectFolder() { string dataPath = Application.dataPath; string selectedPath = EditorUtility.OpenFolderPanel("Path", dataPath, ""); if (!string.IsNullOrEmpty(selectedPath)) { return GetRelativePath(selectedPath); } return null; } string GetRelativePath(string absolutePath) { if (absolutePath.StartsWith(Application.dataPath)) { return "Assets/" + absolutePath.Substring(Application.dataPath.Length + 1); } else { ShowNotification(new GUIContent("不能在Assets目录之外!")); } return null; } void AddNewPath() { string path = SelectFolder(); if (!string.IsNullOrEmpty(path)) { paths.Add(path); } } void InitFilterListDrawer() { if (pathUIList != null) { return; } pathUIList = new ReorderableList(paths, typeof(string)); pathUIList.drawElementCallback = OnListElementGUI; pathUIList.drawHeaderCallback = OnListHeaderGUI; pathUIList.draggable = true; pathUIList.elementHeight = 22; pathUIList.onAddCallback = (list) => AddNewPath(); } void OnGUI() { InitPathsInfo(); InitFilterListDrawer(); bool execGenerate = false; GUILayout.BeginHorizontal(EditorStyles.toolbar); { if (GUILayout.Button("Add", EditorStyles.toolbarButton)) { AddNewPath(); } if (GUILayout.Button("Save", EditorStyles.toolbarButton)) { SavePathsInfo(); } GUILayout.FlexibleSpace(); if (GUILayout.Button("Generate", EditorStyles.toolbarButton)) { execGenerate = true; } } GUILayout.EndHorizontal(); GUILayout.BeginVertical(); { scrollPosition = GUILayout.BeginScrollView(scrollPosition); { pathUIList.DoLayoutList(); } GUILayout.EndScrollView(); } GUILayout.EndVertical(); if (execGenerate) { Generate(); Close(); } } void Generate() { if (paths.Count == 0) { EditorUtility.DisplayDialog("提示", "没有选中任何可跳过的路径", "确定"); return; } blackList.Clear(); foreach (var path in paths) { foreach (var extention in assetExtentions) { var files = from fileName in Directory.GetFiles(path, extention.Key, SearchOption.AllDirectories) let validFullFileName = fileName.Replace("\\", "/") let bEditorScriptFile = validFullFileName.Contains("/Editor/") //let bToluaGeneratedFile = validFullFileName.Contains("/GenerateWrapFiles/") where !bEditorScriptFile /*&& !bToluaGeneratedFile*/ select validFullFileName; int index = 0; foreach (var fileFullPath in files) { EditorUtility.DisplayProgressBar("Searching", fileFullPath, (float)index / files.Count()); extention.Value(blackList, fileFullPath); ++index; } EditorUtility.ClearProgressBar(); } } blackList.UnionWith(specifiedDropType); SaveBlackList(); SavePathsInfo(); if (onBlackListGenerated != null) { onBlackListGenerated(); } onBlackListGenerated = null; Debug.Log("BlackList Generated!!!"); } static void SearchTypeInCSFile(HashSet typeSet, string fileFullPath) { var fileContent = File.ReadAllText(fileFullPath); if (string.IsNullOrEmpty(fileContent)) { return; } int nestCount = 0; int lastTypeMatchedIndex = 0; Stack nestIndexStack = new Stack(); Stack nestStack = new Stack(); var matchResult = Regex.Match(fileContent, nestRegex, RegexOptions.IgnorePatternWhitespace); while (matchResult.Success) { string typeName = matchResult.Value; if (string.IsNullOrEmpty(typeName)) { matchResult = matchResult.NextMatch(); continue; } lastTypeMatchedIndex = nestIndexStack.Count > 0 ? nestIndexStack.Peek() : 0; string matchSubString = fileContent.Substring(lastTypeMatchedIndex, matchResult.Index - lastTypeMatchedIndex); var beginBraceMatchResult = Regex.Matches(matchSubString, "(?= nestCount) { if (compareTag == nestCount) { nestStack.Pop(); } if (compareTag > nestCount) { nestCount++; } nestIndexStack.Pop(); } else if (compareTag < nestCount && compareTag > 0) { int searchedStackCount = nestStack.Count - compareTag; for (int i = 0; i < searchedStackCount; ++i) { nestStack.Pop(); } nestCount = nestStack.Count; if (nestCount > 0) { nestIndexStack.Pop(); } } string prefix = ""; foreach (var name in nestStack) { prefix = name + prefix; } string typeFullName = prefix + typeName; if (!typeSet.Contains(typeFullName) && !bNamespaceMatched) { typeSet.Add(typeFullName); } string nestTag = (bNamespaceMatched ? "." : "+"); nestStack.Push(typeName + nestTag); matchResult = matchResult.NextMatch(); } } static void SearchTypeInAssembly(HashSet typeSet, string assemblyPath) { Assembly assembly = null; try { assembly = Assembly.LoadFile(assemblyPath); } catch { } if (assembly == null) { return; } try { foreach (Type t in assembly.GetTypes()) { bool bNotPrimitiveType = t.IsClass || (t.IsValueType && !t.IsPrimitive && !t.IsEnum); bool bCustomType = bNotPrimitiveType && !t.FullName.Contains("<"); if (bCustomType && !typeSet.Contains(t.FullName) && !t.ContainsGenericParameters) { typeSet.Add(t.FullName); } } } catch (Exception e) { Debug.LogError(e.ToString()); } } void InitPathsInfo() { if (pathsInfoSavedPath == null) { pathsInfoSavedPath = CustomSettings.injectionFilesPath + "LuaInjectionSkipPaths.txt"; } if (paths != null) { return; } if (File.Exists(pathsInfoSavedPath)) { paths = new List(File.ReadAllLines(pathsInfoSavedPath)); } else { paths = new List(); string toluaPath = GetRelativePath(CustomSettings.injectionFilesPath.Substring(0, CustomSettings.injectionFilesPath.Length - "Injection/".Length)); paths.Add(toluaPath + "Core/"); paths.Add(toluaPath + "Injection/"); paths.Add(toluaPath + "Misc/"); paths.Add(toluaPath + "Injection/"); paths.Add(toluaPath + "Misc/"); paths.Add(Application.dataPath + "/Plugins/"); paths.Add(CustomSettings.toluaBaseType); paths.Add(GetRelativePath(CustomSettings.saveDir)); } } void SavePathsInfo() { File.WriteAllLines(pathsInfoSavedPath, paths.ToArray()); AssetDatabase.Refresh(); } void SaveBlackList() { try { if (File.Exists(blackListFilePath)) { File.Delete(blackListFilePath); } File.WriteAllLines(blackListFilePath, blackList.ToArray()); } catch (Exception e) { Debug.LogError(e.ToString()); } AssetDatabase.Refresh(); } } ================================================ FILE: Assets/ToLua/Injection/Editor/ToluaInjectionBlackListPanel.cs.meta ================================================ fileFormatVersion: 2 guid: 55ebe04f71192174990387365881eac4 timeCreated: 1512567263 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/Editor.meta ================================================ fileFormatVersion: 2 guid: 408aa6da49448a544942370044596d77 folderAsset: yes timeCreated: 1515031012 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/InjectionBlackList.txt ================================================ LuaInterface.MonoPInvokeCallbackAttribute LuaInterface.NoToLuaAttribute LuaInterface.UseDefinedAttribute LuaInterface.OverrideDefinedAttribute LuaInterface.LuaByteBufferAttribute LuaInterface.LuaRenameAttribute LuaInterface.LuaBaseRef LuaInterface.LuaBeatEvent LuaInterface.LuaIndexes LuaInterface.LuaRIDX LuaInterface.ToLuaFlags LuaInterface.Lua_Debug LuaInterface.LuaDLL LuaInterface.LuaEvent LuaInterface.LuaException LuaInterface.LuaFileUtils LuaInterface.LuaFunction LuaInterface.LuaFunction+FuncData LuaInterface.LuaMatchType LuaInterface.LuaMethodCache LuaInterface.GCRef LuaInterface.LuaByteBuffer LuaInterface.LuaOut LuaInterface.NullObject LuaInterface.nil LuaInterface.LuaDelegate LuaInterface.LuaMisc LuaInterface.LuaInteger64 LuaInterface.TouchBits LuaInterface.RaycastBits LuaInterface.EventObject LuaInterface.LuaStackOp LuaInterface.LuaState LuaInterface.LuaStatePtr LuaInterface.LuaStatic LuaInterface.LuaTable LuaInterface.LuaArrayTable LuaInterface.LuaArrayTable+Enumerator LuaInterface.LuaDictTable LuaInterface.LuaDictTable+Enumerator LuaInterface.LuaDictEntry LuaInterface.LuaThread LuaInterface.LuaUnityLibs LuaInterface.LuaValueType LuaInterface.LuaValueTypeName LuaInterface.LuaObjectPool LuaInterface.LuaObjectPool+PoolNode LuaInterface.ObjectTranslator LuaInterface.ObjectTranslator+DelayGC LuaInterface.ObjectTranslator+CompareObject LuaInterface.ToLua LuaInterface.TypeChecker LuaInterface.TypeTraits LuaInterface.DelegateTraits LuaInterface.StackTraits LuaInterface.LuaInjectionStation LuaClient LuaCoroutine LuaLooper LuaProfiler LuaResLoader CString ExtensionLibs NumberFormatter StringPool CString+CStringBlock NumberFormatter+CustomInfo ConstStringTable LuaInterface.Debugger LuaInterface.ExtensionMethods LuaInterface.StringBuilderCache LuaInterface_EventObjectWrap LuaInterface_LuaConstructorWrap LuaInterface_LuaFieldWrap LuaInterface_LuaMethodWrap LuaInterface_LuaOutWrap LuaInterface_LuaPropertyWrap System_ArrayWrap System_Collections_Generic_DictionaryWrap System_Collections_Generic_Dictionary_KeyCollectionWrap System_Collections_Generic_Dictionary_ValueCollectionWrap System_Collections_Generic_KeyValuePairWrap System_Collections_Generic_ListWrap System_Collections_IEnumeratorWrap System_Collections_ObjectModel_ReadOnlyCollectionWrap System_DelegateWrap System_EnumWrap System_NullObjectWrap System_ObjectWrap System_StringWrap System_TypeWrap UnityEngine_CoroutineWrap UnityEngine_ObjectWrap DelegateFactory LuaBinder LuaInterface_DebuggerWrap UnityEngine_AnimationBlendModeWrap UnityEngine_AnimationClipWrap UnityEngine_AnimationStateWrap UnityEngine_AnimationWrap UnityEngine_AnimatorWrap UnityEngine_ApplicationWrap UnityEngine_AssetBundleWrap UnityEngine_AsyncOperationWrap UnityEngine_AudioClipWrap UnityEngine_AudioSourceWrap UnityEngine_BehaviourWrap UnityEngine_BlendWeightsWrap UnityEngine_BoxColliderWrap UnityEngine_CameraClearFlagsWrap UnityEngine_CameraWrap UnityEngine_CapsuleColliderWrap UnityEngine_CharacterControllerWrap UnityEngine_ColliderWrap UnityEngine_ComponentWrap UnityEngine_Experimental_Director_DirectorPlayerWrap UnityEngine_GameObjectWrap UnityEngine_InputWrap UnityEngine_KeyCodeWrap UnityEngine_LightTypeWrap UnityEngine_LightWrap UnityEngine_MaterialWrap UnityEngine_MeshColliderWrap UnityEngine_MeshRendererWrap UnityEngine_MonoBehaviourWrap UnityEngine_ParticleSystemWrap UnityEngine_PhysicsWrap UnityEngine_PlayModeWrap UnityEngine_QualitySettingsWrap UnityEngine_QueueModeWrap UnityEngine_RendererWrap UnityEngine_RenderSettingsWrap UnityEngine_RenderTextureWrap UnityEngine_ResourcesWrap UnityEngine_RigidbodyWrap UnityEngine_ScreenWrap UnityEngine_ShaderWrap UnityEngine_SkinnedMeshRendererWrap UnityEngine_SleepTimeoutWrap UnityEngine_SpaceWrap UnityEngine_SphereColliderWrap UnityEngine_Texture2DWrap UnityEngine_TextureWrap UnityEngine_TimeWrap UnityEngine_TrackedReferenceWrap UnityEngine_TransformWrap UnityEngine_WrapModeWrap UnityEngine_WWWWrap ================================================ FILE: Assets/ToLua/Injection/InjectionBlackList.txt.meta ================================================ fileFormatVersion: 2 guid: 449a10dea407bc04ea1bbb6f9d42bbd8 timeCreated: 1515037624 licenseType: Pro TextScriptImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/InjectionBridgeEditorInfo.xml ================================================ ================================================ FILE: Assets/ToLua/Injection/InjectionBridgeEditorInfo.xml.meta ================================================ fileFormatVersion: 2 guid: 7a03414dd6167d14db5ffeec44c8ebf9 timeCreated: 1536240865 licenseType: Pro TextScriptImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/LuaInjectionSkipPaths.txt ================================================ Assets/ToLua/Core/ Assets/ToLua/Injection/ Assets/ToLua/Misc/ Assets/ToLua/Reflection/ Assets/Plugins/ Assets/ToLua/BaseType/ Assets/Source/Generate/ ================================================ FILE: Assets/ToLua/Injection/LuaInjectionSkipPaths.txt.meta ================================================ fileFormatVersion: 2 guid: 4b40d8aec6722dd489e0cf5180707926 timeCreated: 1515038066 licenseType: Pro TextScriptImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection/LuaInjectionStation.cs ================================================ using System; using System.Collections; using System.Collections.Generic; namespace LuaInterface { [Flags] public enum InjectType { None = 0, After = 1, Before = 1 << 1, Replace = 1 << 2, ReplaceWithPreInvokeBase = 1 << 3, ReplaceWithPostInvokeBase = 1 << 4 } public class LuaInjectionStation { public const byte NOT_INJECTION_FLAG = 0; public const byte INVALID_INJECTION_FLAG = byte.MaxValue; static int cacheSize = 0; static byte[] injectionFlagCache; static LuaFunction[] injectFunctionCache; static LuaInjectionStation() { injectionFlagCache = new byte[cacheSize]; injectFunctionCache = new LuaFunction[cacheSize]; } [NoToLua] public static byte GetInjectFlag(int index) { byte result = injectionFlagCache[index]; if (result == INVALID_INJECTION_FLAG) { return NOT_INJECTION_FLAG; } else if (result == NOT_INJECTION_FLAG) { /// Delay injection not supported if (LuaState.GetInjectInitState(index)) { injectionFlagCache[index] = INVALID_INJECTION_FLAG; } } return result; } [NoToLua] public static LuaFunction GetInjectionFunction(int index) { return injectFunctionCache[index]; } public static void CacheInjectFunction(int index, byte injectFlag, LuaFunction func) { if (index >= cacheSize) { return; } injectFunctionCache[index] = func; injectionFlagCache[index] = injectFlag; } public static void Clear() { for (int i = 0, len = injectionFlagCache.Length; i < len; ++i) { injectionFlagCache[i] = 0; injectFunctionCache[i] = null; } } } } ================================================ FILE: Assets/ToLua/Injection/LuaInjectionStation.cs.meta ================================================ fileFormatVersion: 2 guid: 50962a9cc65f2be42af0d2419c4bc074 timeCreated: 1512461673 licenseType: Pro MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Injection.meta ================================================ fileFormatVersion: 2 guid: eb513010fb16d5d4199be09f3c2f60c4 folderAsset: yes timeCreated: 1515031211 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/Build.bat ================================================ @echo off cd /d %~dp0 rd /s/q Out mkdir jit mkdir Out xcopy /Y /D ..\..\..\Luajit\jit jit setlocal enabledelayedexpansion for /r %%i in (*.lua) do ( set v=%%~dpi call :loop set v=!v:%~dp0=! if not exist %~dp0out\!v! (mkdir %~dp0Out\!v!) ) for /r %%i in (*.lua) do ( set v=%%i set v=!v:%~dp0=! call :loop ..\..\..\Luajit\luajit.exe -b -g !v! Out\!v!.bytes ) rd /s/q jit rd /s/q .\Out\jit\ xcopy /Y /D /S Out ..\..\StreamingAssets\Lua setlocal disabledelayedexpansion :loop if "!v:~-1!"==" " set "v=!v:~0,-1!" & goto loop ================================================ FILE: Assets/ToLua/Lua/Build.bat.meta ================================================ fileFormatVersion: 2 guid: df27f3565c885a1419249346792d53b7 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/System/Injection/InjectionBridgeInfo.lua ================================================ return { ["AccessingArray"] = { ["OnApplicationQuit"] = 54, ["OnGUI"] = 53, ["ShowTips"] = 52, ["Start"] = 51, }, ["AccessingEnum"] = { ["OnApplicationQuit"] = 104, ["OnGUI"] = 106, ["ShowTips"] = 105, ["Start"] = 103, }, ["AccessingLuaVariables"] = { ["OnApplicationQuit"] = 32, ["OnGUI"] = 34, ["ShowTips"] = 33, ["Start"] = 31, }, ["BaseTest"] = { ["get_PropertyTest"] = 259, ["set_PropertyTest"] = 260, ["TestRef"] = 258, }, ["BaseTestWrap"] = { ["_CreateBaseTest"] = 254, ["get_PropertyTest"] = 256, ["Register"] = 253, ["set_PropertyTest"] = 257, ["TestRef"] = 255, }, ["CallLuaFunction"] = { ["CallFunc"] = 30, ["OnDestroy"] = 29, ["OnGUI"] = 28, ["ShowTips"] = 27, ["Start"] = 26, }, ["HelloWorld"] = { ["Awake"] = 21, }, ["LuaInterface_InjectTypeWrap"] = { ["CheckType"] = 3, ["get_After"] = 5, ["get_Before"] = 6, ["get_None"] = 4, ["get_Replace"] = 7, ["get_ReplaceWithPostInvokeBase"] = 9, ["get_ReplaceWithPreInvokeBase"] = 8, ["IntToEnum"] = 10, ["Push"] = 2, ["Register"] = 1, }, ["LuaInterface_LuaInjectionStationWrap"] = { ["_CreateLuaInterface_LuaInjectionStation"] = 12, ["CacheInjectFunction"] = 13, ["Register"] = 11, }, ["LuaProfilerWrap"] = { ["BeginSample"] = 17, ["Clear"] = 15, ["EndSample"] = 18, ["get_list"] = 19, ["GetID"] = 16, ["Register"] = 14, ["set_list"] = 20, }, ["PassStruct"] = { ["Awake"] = 217, ["CallMain"] = 221, ["CheckNullRectType"] = 213, ["CheckRectType"] = 212, ["CheckRectValue"] = 211, ["InitLoader"] = 219, ["OnApplicationQuit"] = 216, ["OnGUI"] = 220, ["OnLoadFinished"] = 218, ["PushRect"] = 209, ["ShowTips"] = 215, ["ToRectTable"] = 214, ["ToRectValue"] = 210, }, ["ScriptsFromFile"] = { ["Log"] = 23, ["OnApplicationQuit"] = 25, ["OnGUI"] = 24, ["Start"] = 22, }, ["System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap"] = { ["_CreateSystem_Collections_Generic_Dictionary_int_TestAccount_KeyCollection"] = 76, ["CopyTo"] = 77, ["get_Count"] = 79, ["GetEnumerator"] = 78, ["Register"] = 75, }, ["System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap"] = { ["_CreateSystem_Collections_Generic_Dictionary_int_TestAccount_ValueCollection"] = 81, ["CopyTo"] = 82, ["get_Count"] = 84, ["GetEnumerator"] = 83, ["Register"] = 80, }, ["System_Collections_Generic_Dictionary_int_TestAccountWrap"] = { ["_CreateSystem_Collections_Generic_Dictionary_int_TestAccount"] = 56, ["_get_this"] = 57, ["_set_this"] = 58, ["_this"] = 59, ["Add"] = 62, ["Clear"] = 63, ["ContainsKey"] = 64, ["ContainsValue"] = 65, ["get_Comparer"] = 72, ["get_Count"] = 71, ["get_Item"] = 60, ["get_Keys"] = 73, ["get_Values"] = 74, ["GetEnumerator"] = 70, ["GetObjectData"] = 66, ["OnDeserialization"] = 67, ["Register"] = 55, ["Remove"] = 68, ["set_Item"] = 61, ["TryGetValue"] = 69, }, ["System_Collections_Generic_KeyValuePair_int_TestAccountWrap"] = { ["_CreateSystem_Collections_Generic_KeyValuePair_int_TestAccount"] = 86, ["get_Key"] = 88, ["get_Value"] = 89, ["Register"] = 85, ["ToString"] = 87, }, ["TestABLoader"] = { ["Awake"] = 172, ["CoLoadBundle"] = 169, ["LoadBundles"] = 171, ["LoadFinished"] = 170, ["OnApplicationQuit"] = 175, ["OnBundleLoad"] = 176, ["OnGUI"] = 174, ["ShowTips"] = 173, }, ["TestAccountWrap"] = { ["_CreateTestAccount"] = 91, ["get_id"] = 92, ["get_name"] = 93, ["get_sex"] = 94, ["Register"] = 90, ["set_id"] = 95, ["set_name"] = 96, ["set_sex"] = 97, }, ["TestCJson"] = { ["CallMain"] = 180, ["InitLoader"] = 177, ["OnApplicationQuit"] = 182, ["OnGUI"] = 183, ["OnLoadFinished"] = 179, ["OpenLibs"] = 178, ["ShowTips"] = 181, }, ["TestCoroutine"] = { ["Awake"] = 35, ["OnApplicationQuit"] = 36, ["OnGUI"] = 38, ["ShowTips"] = 37, }, ["TestCoroutine2"] = { ["CallMain"] = 41, ["InitLoader"] = 39, ["OnApplicationQuit"] = 44, ["OnGUI"] = 45, ["OnLoadFinished"] = 40, ["ShowTips"] = 43, ["Start"] = 42, }, ["TestCustomLoader"] = { ["Awake"] = 140, ["CallMain"] = 138, ["InitLoader"] = 137, ["Logger"] = 142, ["OnApplicationQuit"] = 141, ["OnGUI"] = 143, ["StartMain"] = 139, }, ["TestDelegate"] = { ["Awake"] = 109, ["Bind"] = 110, ["CallLuaFunction"] = 111, ["OnApplicationQuit"] = 118, ["OnGUI"] = 114, ["SafeRelease"] = 116, ["ShowTips"] = 117, ["TestEventListener_OnClick"] = 112, ["TestEventListener_VoidDelegate"] = 113, ["Update"] = 115, }, ["TestDelegate.TestEventListener_OnClick_Event"] = { ["Call"] = 107, }, ["TestDelegate.TestEventListener_VoidDelegate_Event"] = { ["Call"] = 108, }, ["TestEnum"] = { ["Test"] = 312, }, ["TestEventListener"] = { ["SetOnFinished-OnClick"] = 119, ["SetOnFinished-VoidDelegate"] = 120, }, ["TestEventListenerWrap"] = { ["get_onClick"] = 124, ["get_onClickEvent"] = 126, ["get_TestFunc"] = 125, ["op_Equality"] = 123, ["Register"] = 121, ["set_onClick"] = 127, ["set_onClickEvent"] = 129, ["set_TestFunc"] = 128, ["SetOnFinished"] = 122, ["TestEventListener_OnClick"] = 130, ["TestEventListener_VoidDelegate"] = 131, }, ["TestExport"] = { ["DoClick"] = 348, ["get_Item-char-int"] = 317, ["get_Item-double"] = 320, ["get_Item-int"] = 315, ["get_Item-int-int-int"] = 321, ["get_Item-string"] = 319, ["get_Number"] = 313, ["set_Item-char-int-int"] = 318, ["set_Item-double"] = 322, ["set_Item-int-int"] = 316, ["set_Number"] = 314, ["Test"] = 327, ["Test33"] = 342, ["Test-bool"] = 328, ["TestByteBuffer"] = 323, ["Test-char"] = 326, ["TestCheckParamNumber"] = 344, ["TestCheckParamString"] = 345, ["Test-double"] = 331, ["TestEnum"] = 343, ["Test-int"] = 330, ["Test-int&"] = 332, ["Test-int[,]"] = 329, ["Test-int[]"] = 337, ["Test-int-int"] = 333, ["TestNullable"] = 349, ["Test-object"] = 336, ["Test-object[]"] = 340, ["Test-object-string"] = 324, ["Test-object-string-int"] = 325, ["TestRefGameObject"] = 347, ["TestReflection"] = 346, ["Test-Space"] = 341, ["Test-string"] = 334, ["Test-string[]"] = 338, ["Test-string[]-bool"] = 339, ["Test-string-string"] = 335, }, ["TestExport_SpaceWrap"] = { ["CheckType"] = 309, ["get_World"] = 310, ["IntToEnum"] = 311, ["Push"] = 308, ["Register"] = 307, }, ["TestExportWrap"] = { ["_CreateTestExport"] = 277, ["_get_this"] = 278, ["_set_this"] = 279, ["_this"] = 280, ["DoClick"] = 293, ["get_buffer"] = 298, ["get_field"] = 295, ["get_Item"] = 281, ["get_Number"] = 299, ["get_OnClick"] = 296, ["get_OnRefEvent"] = 297, ["Register"] = 276, ["set_buffer"] = 303, ["set_field"] = 300, ["set_Item"] = 282, ["set_Number"] = 304, ["set_OnClick"] = 301, ["set_OnRefEvent"] = 302, ["Test"] = 284, ["Test33"] = 286, ["TestByteBuffer"] = 283, ["TestChar"] = 285, ["TestCheckParamNumber"] = 289, ["TestCheckParamString"] = 290, ["TestEnum"] = 288, ["TestExport_TestBuffer"] = 305, ["TestExport_TestRefEvent"] = 306, ["TestGeneric"] = 287, ["TestNullable"] = 294, ["TestRefGameObject"] = 292, ["TestReflection"] = 291, }, ["TestGameObject"] = { ["OnApplicationQuit"] = 135, ["OnGUI"] = 136, ["ShowTips"] = 134, ["Start"] = 132, ["Update"] = 133, }, ["TestInherit"] = { ["OnDestroy"] = 167, ["OnGUI"] = 168, ["ShowTips"] = 166, ["Start"] = 165, }, ["TestInstantiate"] = { ["Awake"] = 226, ["Start"] = 227, }, ["TestInstantiate2"] = { ["Awake"] = 228, }, ["TestInt64"] = { ["OnDestroy"] = 163, ["OnGUI"] = 164, ["ShowTips"] = 162, ["Start"] = 161, }, ["TestLuaStack"] = { ["Awake"] = 245, ["OnApplicationQuit"] = 247, ["OnGUI"] = 251, ["OnSendMsg"] = 244, ["PushLuaError"] = 230, ["ShowTips"] = 248, ["Test1"] = 229, ["Test3"] = 231, ["Test4"] = 232, ["Test5"] = 233, ["Test6"] = 234, ["TestAddComponent"] = 240, ["TestArgError"] = 236, ["TestCo"] = 252, ["TestCycle"] = 238, ["TestD1"] = 249, ["TestD2"] = 250, ["TestMul0"] = 242, ["TestMul1"] = 241, ["TestMulStack"] = 243, ["TestNull"] = 239, ["TestOutOfBound"] = 235, ["TestTableInCo"] = 237, ["Update"] = 246, }, ["TestLuaThread"] = { ["OnApplicationQuit"] = 47, ["OnGUI"] = 50, ["ShowTips"] = 48, ["Start"] = 46, ["Update"] = 49, }, ["TestOutArg"] = { ["OnApplicationQuit"] = 146, ["OnDestroy"] = 149, ["OnGUI"] = 147, ["ShowTips"] = 145, ["Start"] = 144, ["Update"] = 148, }, ["TestOverload"] = { ["Awake"] = 350, ["Bind"] = 351, }, ["TestPerformance"] = { ["OnApplicationQuit"] = 224, ["OnGUI"] = 225, ["ShowTips"] = 223, ["Start"] = 222, }, ["TestProtoBuffer"] = { ["Awake"] = 150, ["Bind"] = 152, ["CallMain"] = 153, ["InitLoader"] = 151, ["OnApplicationQuit"] = 157, ["OnGUI"] = 156, ["OnLoadFinished"] = 154, ["ShowTips"] = 155, }, ["TestProtolWrap"] = { ["get_data"] = 159, ["Register"] = 158, ["set_data"] = 160, }, ["TestReflection"] = { ["CallMain"] = 197, ["InitLoader"] = 196, ["OnApplicationQuit"] = 201, ["OnGUI"] = 202, ["OnLoadFinished"] = 199, ["ShowTips"] = 200, ["TestAction"] = 198, }, ["TestString"] = { ["CallMain"] = 191, ["InitLoader"] = 190, ["OnApplicationQuit"] = 194, ["OnGUI"] = 195, ["OnLoadFinished"] = 192, ["ShowTips"] = 193, }, ["TestUTF8"] = { ["CallMain"] = 185, ["InitLoader"] = 184, ["OnApplicationQuit"] = 188, ["OnGUI"] = 189, ["OnLoadFinished"] = 186, ["ShowTips"] = 187, }, ["ToLuaInjectionTest"] = { ["get_PropertyTest"] = 261, ["Inject"] = 267, ["set_PropertyTest"] = 262, ["TestCoroutine"] = 268, ["TestOverload-bool-int"] = 266, ["TestOverload-int-bool"] = 264, ["TestOverload-int-bool&"] = 265, ["TestRef"] = 263, }, ["ToLuaInjectionTestWrap"] = { ["_CreateToLuaInjectionTest"] = 270, ["get_PropertyTest"] = 274, ["Register"] = 269, ["set_PropertyTest"] = 275, ["TestCoroutine"] = 273, ["TestOverload"] = 272, ["TestRef"] = 271, }, ["UseDictionary"] = { ["Awake"] = 98, ["BindMap"] = 102, ["OnApplicationQuit"] = 99, ["OnGUI"] = 101, ["ShowTips"] = 100, }, ["UseList"] = { ["CallMain"] = 204, ["InitLoader"] = 203, ["OnApplicationQuit"] = 207, ["OnGUI"] = 208, ["OnLoadFinished"] = 205, ["ShowTips"] = 206, }, } ================================================ FILE: Assets/ToLua/Lua/System/Injection/InjectionBridgeInfo.lua.meta ================================================ fileFormatVersion: 2 guid: ddd0929c7e5e87a43ac765a3d62c90a7 timeCreated: 1514865200 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/System/Injection/LuaInjectionBus.lua ================================================ --[[MIT License Copyright (c) 2018 Jonson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.]]-- --Load All The Injectores --require "System.Injection.ToLuaInjectionTestInjector" ================================================ FILE: Assets/ToLua/Lua/System/Injection/LuaInjectionBus.lua.meta ================================================ fileFormatVersion: 2 guid: 3f358679c92622642a844c157ce4fece timeCreated: 1514865200 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/System/Injection/LuaInjectionStation.lua ================================================ --[[ --- File:LuaInjectionStation.lua --- Created by Jonson --- DateTime: 2018/1/2 10:24 ]]-- local pcall = pcall local pairs = pairs local error = error local rawset = rawset local rawget = rawget local string = string local tolua_tag = tolua_tag local getmetatable = getmetatable local CSLuaInjectStation local bridgeInfo = require "System.Injection.InjectionBridgeInfo" local function Check(csModule) local existmt = getmetatable(csModule) if rawget(existmt, tolua_tag) ~= 1 then error("Can't Inject") end return existmt end local function CacheCSLuaInjectStation() if CSLuaInjectStation == nil then CSLuaInjectStation = LuaInterface.LuaInjectionStation end end local function UpdateFunctionReference(metatable, injectInfo) local oldIndexMetamethod = metatable.__index local newMethodGroup = {} for funcName, infoPipeline in pairs(injectInfo) do local injectFunction, injectFlag = infoPipeline() if injectFlag == LuaInterface.InjectType.Replace or injectFlag == LuaInterface.InjectType.ReplaceWithPostInvokeBase or injectFlag == LuaInterface.InjectType.ReplaceWithPreInvokeBase then rawset(newMethodGroup, funcName, injectFunction) end end metatable.__index = function(t, k) --Ignore Overload Function local injectFunc = rawget(newMethodGroup, k) if injectFunc ~= nil then return injectFunc end local status, result = pcall(oldIndexMetamethod, t, k) if status then return result else error(result) return nil end end end function InjectByModule(csModule, injectInfo) local mt = Check(csModule) local moduleName = mt[".name"] InjectByName(moduleName, injectInfo) UpdateFunctionReference(mt, injectInfo) end --Won't Update Function Reference In Lua Env function InjectByName(moduleName, injectInfo) CacheCSLuaInjectStation() local moduleBridgeInfo = rawget(bridgeInfo, moduleName) if moduleBridgeInfo == nil then error(string.format("Module %s Can't Inject", moduleName)) end for funcName, infoPipeline in pairs(injectInfo) do local injectFunction, injectFlag = infoPipeline() local injectIndex = rawget(moduleBridgeInfo, funcName) if injectIndex == nil then error(string.format("Function %s Doesn't Exist In Module %s", funcName, moduleName)) end CSLuaInjectStation.CacheInjectFunction(injectIndex, injectFlag:ToInt(), injectFunction) end end require "System.Injection.LuaInjectionBus" ================================================ FILE: Assets/ToLua/Lua/System/Injection/LuaInjectionStation.lua.meta ================================================ fileFormatVersion: 2 guid: 78b8ba284d726bf48803904bd5ada5c4 timeCreated: 1514865423 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/System/Injection.meta ================================================ fileFormatVersion: 2 guid: cd35ae0a721aca5469a1dc038b2b6158 folderAsset: yes timeCreated: 1515034041 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/System/Reflection/BindingFlags.lua ================================================ if System.Reflection == nil then System.Reflection = {} end local function GetMask(...) local arg = {...} local value = 0 for i = 1, #arg do value = value + arg[i] end return value end local BindingFlags = { Default = 0, IgnoreCase = 1, DeclaredOnly = 2, Instance = 4, Static = 8, Public = 16, NonPublic = 32, FlattenHierarchy = 64, InvokeMethod = 256, CreateInstance = 512, GetField = 1024, SetField = 2048, GetProperty = 4096, SetProperty = 8192, PutDispProperty = 16384, PutRefDispProperty = 32768, ExactBinding = 65536, SuppressChangeType = 131072, OptionalParamBinding = 262144, IgnoreReturn = 16777216, } System.Reflection.BindingFlags = BindingFlags System.Reflection.BindingFlags.GetMask = GetMask return BindingFlags ================================================ FILE: Assets/ToLua/Lua/System/Reflection/BindingFlags.lua.meta ================================================ fileFormatVersion: 2 guid: 447334b96205b8040b534702d8d806c6 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/System/Reflection.meta ================================================ fileFormatVersion: 2 guid: b31921aad5a29bf48b69fbad423de1be folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/System/Timer.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local setmetatable = setmetatable local UpdateBeat = UpdateBeat local CoUpdateBeat = CoUpdateBeat local Time = Time Timer = {} local Timer = Timer local mt = {__index = Timer} --unscaled false 采用deltaTime计时,true 采用 unscaledDeltaTime计时 function Timer.New(func, duration, loop, unscaled) unscaled = unscaled or false and true loop = loop or 1 return setmetatable({func = func, duration = duration, time = duration, loop = loop, unscaled = unscaled, running = false}, mt) end function Timer:Start() self.running = true if not self.handle then self.handle = UpdateBeat:CreateListener(self.Update, self) end UpdateBeat:AddListener(self.handle) end function Timer:Reset(func, duration, loop, unscaled) self.duration = duration self.loop = loop or 1 self.unscaled = unscaled self.func = func self.time = duration end function Timer:Stop() self.running = false if self.handle then UpdateBeat:RemoveListener(self.handle) end end function Timer:Update() if not self.running then return end local delta = self.unscaled and Time.unscaledDeltaTime or Time.deltaTime self.time = self.time - delta if self.time <= 0 then self.func() if self.loop > 0 then self.loop = self.loop - 1 self.time = self.time + self.duration end if self.loop == 0 then self:Stop() elseif self.loop < 0 then self.time = self.time + self.duration end end end --给协同使用的帧计数timer FrameTimer = {} local FrameTimer = FrameTimer local mt2 = {__index = FrameTimer} function FrameTimer.New(func, count, loop) local c = Time.frameCount + count loop = loop or 1 return setmetatable({func = func, loop = loop, duration = count, count = c, running = false}, mt2) end function FrameTimer:Reset(func, count, loop) self.func = func self.duration = count self.loop = loop self.count = Time.frameCount + count end function FrameTimer:Start() if not self.handle then self.handle = CoUpdateBeat:CreateListener(self.Update, self) end CoUpdateBeat:AddListener(self.handle) self.running = true end function FrameTimer:Stop() self.running = false if self.handle then CoUpdateBeat:RemoveListener(self.handle) end end function FrameTimer:Update() if not self.running then return end if Time.frameCount >= self.count then self.func() if self.loop > 0 then self.loop = self.loop - 1 end if self.loop == 0 then self:Stop() else self.count = Time.frameCount + self.duration end end end CoTimer = {} local CoTimer = CoTimer local mt3 = {__index = CoTimer} function CoTimer.New(func, duration, loop) loop = loop or 1 return setmetatable({duration = duration, loop = loop, func = func, time = duration, running = false}, mt3) end function CoTimer:Start() if not self.handle then self.handle = CoUpdateBeat:CreateListener(self.Update, self) end self.running = true CoUpdateBeat:AddListener(self.handle) end function CoTimer:Reset(func, duration, loop) self.duration = duration self.loop = loop or 1 self.func = func self.time = duration end function CoTimer:Stop() self.running = false if self.handle then CoUpdateBeat:RemoveListener(self.handle) end end function CoTimer:Update() if not self.running then return end if self.time <= 0 then self.func() if self.loop > 0 then self.loop = self.loop - 1 self.time = self.time + self.duration end if self.loop == 0 then self:Stop() elseif self.loop < 0 then self.time = self.time + self.duration end end self.time = self.time - Time.deltaTime end ================================================ FILE: Assets/ToLua/Lua/System/Timer.lua.meta ================================================ fileFormatVersion: 2 guid: e891968e6d367cf4da81d8c24a52c358 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/System/ValueType.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local ValueType = {} ValueType[Vector3] = 1 ValueType[Quaternion] = 2 ValueType[Vector2] = 3 ValueType[Color] = 4 ValueType[Vector4] = 5 ValueType[Ray] = 6 ValueType[Bounds] = 7 ValueType[Touch] = 8 ValueType[LayerMask] = 9 ValueType[RaycastHit] = 10 ValueType[int64] = 11 ValueType[uint64] = 12 local function GetValueType() local getmetatable = getmetatable local ValueType = ValueType return function(udata) local meta = getmetatable(udata) if meta == nil then return 0 end return ValueType[meta] or 0 end end function AddValueType(table, type) ValueType[table] = type end GetLuaValueType = GetValueType() ================================================ FILE: Assets/ToLua/Lua/System/ValueType.lua.meta ================================================ fileFormatVersion: 2 guid: fab9e4d6fcf702740a4c66965903ed1f DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/System/coroutine.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local create = coroutine.create local running = coroutine.running local resume = coroutine.resume local yield = coroutine.yield local error = error local unpack = unpack local debug = debug local FrameTimer = FrameTimer local CoTimer = CoTimer local comap = {} local pool = {} setmetatable(comap, {__mode = "kv"}) function coroutine.start(f, ...) local co = create(f) if running() == nil then local flag, msg = resume(co, ...) if not flag then error(debug.traceback(co, msg)) end else local args = {...} local timer = nil local action = function() comap[co] = nil timer.func = nil local flag, msg = resume(co, unpack(args, 1, table.maxn(args))) table.insert(pool, timer) if not flag then timer:Stop() error(debug.traceback(co, msg)) end end if #pool > 0 then timer = table.remove(pool) timer:Reset(action, 0, 1) else timer = FrameTimer.New(action, 0, 1) end comap[co] = timer timer:Start() end return co end function coroutine.wait(t, co, ...) local args = {...} co = co or running() local timer = nil local action = function() comap[co] = nil timer.func = nil local flag, msg = resume(co, unpack(args, 1, table.maxn(args))) if not flag then timer:Stop() error(debug.traceback(co, msg)) return end end timer = CoTimer.New(action, t, 1) comap[co] = timer timer:Start() return yield() end function coroutine.step(t, co, ...) local args = {...} co = co or running() local timer = nil local action = function() comap[co] = nil timer.func = nil local flag, msg = resume(co, unpack(args, 1, table.maxn(args))) table.insert(pool, timer) if not flag then timer:Stop() error(debug.traceback(co, msg)) return end end if #pool > 0 then timer = table.remove(pool) timer:Reset(action, t or 1, 1) else timer = FrameTimer.New(action, t or 1, 1) end comap[co] = timer timer:Start() return yield() end function coroutine.www(www, co) co = co or running() local timer = nil local action = function() if not www.isDone then return end comap[co] = nil timer:Stop() timer.func = nil local flag, msg = resume(co) table.insert(pool, timer) if not flag then error(debug.traceback(co, msg)) return end end if #pool > 0 then timer = table.remove(pool) timer:Reset(action, 1, -1) else timer = FrameTimer.New(action, 1, -1) end comap[co] = timer timer:Start() return yield() end function coroutine.stop(co) local timer = comap[co] if timer ~= nil then comap[co] = nil timer:Stop() timer.func = nil end end ================================================ FILE: Assets/ToLua/Lua/System/coroutine.lua.meta ================================================ fileFormatVersion: 2 guid: 69692ffc56243fb4a8d655a208364fec DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/System.meta ================================================ fileFormatVersion: 2 guid: c23205cbb914d9943ba97091e50d9d34 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Bounds.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local rawget = rawget local setmetatable = setmetatable local type = type local Vector3 = Vector3 local zero = Vector3.zero local Bounds = { center = Vector3.zero, extents = Vector3.zero, } local get = tolua.initget(Bounds) Bounds.__index = function(t,k) local var = rawget(Bounds, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end Bounds.__call = function(t, center, size) return setmetatable({center = center, extents = size * 0.5}, Bounds) end function Bounds.New(center, size) return setmetatable({center = center, extents = size * 0.5}, Bounds) end function Bounds:Get() local size = self:GetSize() return self.center, size end function Bounds:GetSize() return self.extents * 2 end function Bounds:SetSize(value) self.extents = value * 0.5 end function Bounds:GetMin() return self.center - self.extents end function Bounds:SetMin(value) self:SetMinMax(value, self:GetMax()) end function Bounds:GetMax() return self.center + self.extents end function Bounds:SetMax(value) self:SetMinMax(self:GetMin(), value) end function Bounds:SetMinMax(min, max) self.extents = (max - min) * 0.5 self.center = min + self.extents end function Bounds:Encapsulate(point) self:SetMinMax(Vector3.Min(self:GetMin(), point), Vector3.Max(self:GetMax(), point)) end function Bounds:Expand(amount) if type(amount) == "number" then amount = amount * 0.5 self.extents:Add(Vector3.New(amount, amount, amount)) else self.extents:Add(amount * 0.5) end end function Bounds:Intersects(bounds) local min = self:GetMin() local max = self:GetMax() local min2 = bounds:GetMin() local max2 = bounds:GetMax() return min.x <= max2.x and max.x >= min2.x and min.y <= max2.y and max.y >= min2.y and min.z <= max2.z and max.z >= min2.z end function Bounds:Contains(p) local min = self:GetMin() local max = self:GetMax() if p.x < min.x or p.y < min.y or p.z < min.z or p.x > max.x or p.y > max.y or p.z > max.z then return false end return true end function Bounds:IntersectRay(ray) local tmin = -Mathf.Infinity local tmax = Mathf.Infinity local t0, t1, f local t = self:GetCenter () - ray:GetOrigin() local p = {t.x, t.y, t.z} t = self.extents local extent = {t.x, t.y, t.z} t = ray:GetDirection() local dir = {t.x, t.y, t.z} for i = 1, 3 do f = 1 / dir[i] t0 = (p[i] + extent[i]) * f t1 = (p[i] - extent[i]) * f if t0 < t1 then if t0 > tmin then tmin = t0 end if t1 < tmax then tmax = t1 end if tmin > tmax then return false end if tmax < 0 then return false end else if t1 > tmin then tmin = t1 end if t0 < tmax then tmax = t0 end if tmin > tmax then return false end if tmax < 0 then return false end end end return true, tmin end function Bounds:ClosestPoint(point) local t = point - self:GetCenter() local closest = {t.x, t.y, t.z} local et = self.extents local extent = {et.x, et.y, et.z} local distance = 0 local delta for i = 1, 3 do if closest[i] < - extent[i] then delta = closest[i] + extent[i] distance = distance + delta * delta closest[i] = -extent[i] elseif closest[i] > extent[i] then delta = closest[i] - extent[i] distance = distance + delta * delta closest[i] = extent[i] end end if distance == 0 then return point, 0 else outPoint = closest + self:GetCenter() return outPoint, distance end end function Bounds:Destroy() self.center = nil self.size = nil end Bounds.__tostring = function(self) return string.format("Center: %s, Extents %s", tostring(self.center), tostring(self.extents)) end Bounds.__eq = function(a, b) return a.center == b.center and a.extents == b.extents end get.size = Bounds.GetSize get.min = Bounds.GetMin get.max = Bounds.GetMax UnityEngine.Bounds = Bounds setmetatable(Bounds, Bounds) return Bounds ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Bounds.lua.meta ================================================ fileFormatVersion: 2 guid: 8643f0e46fe222e48919766d7b0c7c5f DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Color.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local rawget = rawget local setmetatable = setmetatable local type = type local Mathf = Mathf local Color = {} local get = tolua.initget(Color) Color.__index = function(t,k) local var = rawget(Color, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end Color.__call = function(t, r, g, b, a) return setmetatable({r = r or 0, g = g or 0, b = b or 0, a = a or 1}, Color) end function Color.New(r, g, b, a) return setmetatable({r = r or 0, g = g or 0, b = b or 0, a = a or 1}, Color) end function Color:Set(r, g, b, a) self.r = r self.g = g self.b = b self.a = a or 1 end function Color:Get() return self.r, self.g, self.b, self.a end function Color:Equals(other) return self.r == other.r and self.g == other.g and self.b == other.b and self.a == other.a end function Color.Lerp(a, b, t) t = Mathf.Clamp01(t) return Color.New(a.r + t * (b.r - a.r), a.g + t * (b.g - a.g), a.b + t * (b.b - a.b), a.a + t * (b.a - a.a)) end function Color.LerpUnclamped(a, b, t) return Color.New(a.r + t * (b.r - a.r), a.g + t * (b.g - a.g), a.b + t * (b.b - a.b), a.a + t * (b.a - a.a)) end function Color.HSVToRGB(H, S, V, hdr) hdr = hdr and false or true local white = Color.New(1,1,1,1) if S == 0 then white.r = V white.g = V white.b = V return white end if V == 0 then white.r = 0 white.g = 0 white.b = 0 return white end white.r = 0 white.g = 0 white.b = 0; local num = S local num2 = V local f = H * 6; local num4 = Mathf.Floor(f) local num5 = f - num4 local num6 = num2 * (1 - num) local num7 = num2 * (1 - (num * num5)) local num8 = num2 * (1 - (num * (1 - num5))) local num9 = num4 local flag = num9 + 1 if flag == 0 then white.r = num2 white.g = num6 white.b = num7 elseif flag == 1 then white.r = num2 white.g = num8 white.b = num6 elseif flag == 2 then white.r = num7 white.g = num2 white.b = num6 elseif flag == 3 then white.r = num6 white.g = num2 white.b = num8 elseif flag == 4 then white.r = num6 white.g = num7 white.b = num2 elseif flag == 5 then white.r = num8 white.g = num6 white.b = num2 elseif flag == 6 then white.r = num2 white.g = num6 white.b = num7 elseif flag == 7 then white.r = num2 white.g = num8 white.b = num6 end if not hdr then white.r = Mathf.Clamp(white.r, 0, 1) white.g = Mathf.Clamp(white.g, 0, 1) white.b = Mathf.Clamp(white.b, 0, 1) end return white end local function RGBToHSVHelper(offset, dominantcolor, colorone, colortwo) local V = dominantcolor if V ~= 0 then local num = 0 if colorone > colortwo then num = colortwo else num = colorone end local num2 = V - num local H = 0 local S = 0 if num2 ~= 0 then S = num2 / V H = offset + (colorone - colortwo) / num2 else S = 0 H = offset + (colorone - colortwo) end H = H / 6 if H < 0 then H = H + 1 end return H, S, V end return 0, 0, V end function Color.RGBToHSV(rgbColor) if rgbColor.b > rgbColor.g and rgbColor.b > rgbColor.r then return RGBToHSVHelper(4, rgbColor.b, rgbColor.r, rgbColor.g) elseif rgbColor.g > rgbColor.r then return RGBToHSVHelper(2, rgbColor.g, rgbColor.b, rgbColor.r) else return RGBToHSVHelper(0, rgbColor.r, rgbColor.g, rgbColor.b) end end function Color.GrayScale(a) return 0.299 * a.r + 0.587 * a.g + 0.114 * a.b end Color.__tostring = function(self) return string.format("RGBA(%f,%f,%f,%f)", self.r, self.g, self.b, self.a) end Color.__add = function(a, b) return Color.New(a.r + b.r, a.g + b.g, a.b + b.b, a.a + b.a) end Color.__sub = function(a, b) return Color.New(a.r - b.r, a.g - b.g, a.b - b.b, a.a - b.a) end Color.__mul = function(a, b) if type(b) == "number" then return Color.New(a.r * b, a.g * b, a.b * b, a.a * b) elseif getmetatable(b) == Color then return Color.New(a.r * b.r, a.g * b.g, a.b * b.b, a.a * b.a) end end Color.__div = function(a, d) return Color.New(a.r / d, a.g / d, a.b / d, a.a / d) end Color.__eq = function(a,b) return a.r == b.r and a.g == b.g and a.b == b.b and a.a == b.a end get.red = function() return Color.New(1,0,0,1) end get.green = function() return Color.New(0,1,0,1) end get.blue = function() return Color.New(0,0,1,1) end get.white = function() return Color.New(1,1,1,1) end get.black = function() return Color.New(0,0,0,1) end get.yellow = function() return Color.New(1, 0.9215686, 0.01568628, 1) end get.cyan = function() return Color.New(0,1,1,1) end get.magenta = function() return Color.New(1,0,1,1) end get.gray = function() return Color.New(0.5,0.5,0.5,1) end get.clear = function() return Color.New(0,0,0,0) end get.gamma = function(c) return Color.New(Mathf.LinearToGammaSpace(c.r), Mathf.LinearToGammaSpace(c.g), Mathf.LinearToGammaSpace(c.b), c.a) end get.linear = function(c) return Color.New(Mathf.GammaToLinearSpace(c.r), Mathf.GammaToLinearSpace(c.g), Mathf.GammaToLinearSpace(c.b), c.a) end get.maxColorComponent = function(c) return Mathf.Max(Mathf.Max(c.r, c.g), c.b) end get.grayscale = Color.GrayScale UnityEngine.Color = Color setmetatable(Color, Color) return Color ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Color.lua.meta ================================================ fileFormatVersion: 2 guid: 54770d2645593c347ac25713a6d332e3 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Color32.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local rawget = rawget local setmetatable = setmetatable local type = type local Mathf = Mathf local Color32 = {} local get = tolua.initget(Color32) Color32.__index = function(t,k) local var = rawget(Color32, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end Color32.__call = function(t, r, g, b, a) return setmetatable({r = r or 0, g = g or 0, b = b or 0, a = a or 255}, Color32) end function Color32.New(r, g, b, a) return setmetatable({r = r or 0, g = g or 0, b = b or 0, a = a or 255}, Color32) end function Color32:Set(r, g, b, a) self.r = r self.g = g self.b = b self.a = a or 255 end function Color32:Get() return self.r, self.g, self.b, self.a end function Color32:Equals(other) return self.r == other.r and self.g == other.g and self.b == other.b and self.a == other.a end function Color32.Lerp(a, b, t) t = Mathf.Clamp01(t) return Color32.New(a.r + t * (b.r - a.r), a.g + t * (b.g - a.g), a.b + t * (b.b - a.b), a.a + t * (b.a - a.a)) end function Color32.LerpUnclamped(a, b, t) return Color32.New(a.r + t * (b.r - a.r), a.g + t * (b.g - a.g), a.b + t * (b.b - a.b), a.a + t * (b.a - a.a)) end Color32.__tostring = function(self) return string.format("RGBA(%f,%f,%f,%f)", self.r, self.g, self.b, self.a) end Color32.__add = function(a, b) return Color32.New(a.r + b.r, a.g + b.g, a.b + b.b, a.a + b.a) end Color32.__sub = function(a, b) return Color32.New(a.r - b.r, a.g - b.g, a.b - b.b, a.a - b.a) end Color32.__mul = function(a, b) if type(b) == "number" then return Color32.New(a.r * b, a.g * b, a.b * b, a.a * b) elseif getmetatable(b) == Color32 then return Color32.New(a.r * b.r, a.g * b.g, a.b * b.b, a.a * b.a) end end Color32.__div = function(a, d) return Color32.New(a.r / d, a.g / d, a.b / d, a.a / d) end Color32.__eq = function(a,b) return a.r == b.r and a.g == b.g and a.b == b.b and a.a == b.a end UnityEngine.Color32 = Color32 setmetatable(Color32, Color32) return Color32 ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Color32.lua.meta ================================================ fileFormatVersion: 2 guid: 8f6f1125c9c29f74c93411831e239a76 DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/LayerMask.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local Layer = Layer local rawget = rawget local setmetatable = setmetatable local LayerMask = {} LayerMask.__index = function(t,k) return rawget(LayerMask, k) end LayerMask.__call = function(t,v) return setmetatable({value = value or 0}, LayerMask) end function LayerMask.New(value) return setmetatable({value = value or 0}, LayerMask) end function LayerMask:Get() return self.value end function LayerMask.NameToLayer(name) return Layer[name] end function LayerMask.GetMask(...) local arg = {...} local value = 0 for i = 1, #arg do local n = LayerMask.NameToLayer(arg[i]) if n ~= nil then value = value + 2 ^ n end end return value end UnityEngine.LayerMask = LayerMask setmetatable(LayerMask, LayerMask) return LayerMask ================================================ FILE: Assets/ToLua/Lua/UnityEngine/LayerMask.lua.meta ================================================ fileFormatVersion: 2 guid: 08700fd491ce4cf4ba55fd9832b9f9cf DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Mathf.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local math = math local floor = math.floor local abs = math.abs local Mathf = Mathf Mathf.Deg2Rad = math.rad(1) Mathf.Epsilon = 1.4013e-45 Mathf.Infinity = math.huge Mathf.NegativeInfinity = -math.huge Mathf.PI = math.pi Mathf.Rad2Deg = math.deg(1) Mathf.Abs = math.abs Mathf.Acos = math.acos Mathf.Asin = math.asin Mathf.Atan = math.atan Mathf.Atan2 = math.atan2 Mathf.Ceil = math.ceil Mathf.Cos = math.cos Mathf.Exp = math.exp Mathf.Floor = math.floor Mathf.Log = math.log Mathf.Log10 = math.log10 Mathf.Max = math.max Mathf.Min = math.min Mathf.Pow = math.pow Mathf.Sin = math.sin Mathf.Sqrt = math.sqrt Mathf.Tan = math.tan Mathf.Deg = math.deg Mathf.Rad = math.rad Mathf.Random = math.random function Mathf.Approximately(a, b) return abs(b - a) < math.max(1e-6 * math.max(abs(a), abs(b)), 1.121039e-44) end function Mathf.Clamp(value, min, max) if value < min then value = min elseif value > max then value = max end return value end function Mathf.Clamp01(value) if value < 0 then return 0 elseif value > 1 then return 1 end return value end function Mathf.DeltaAngle(current, target) local num = Mathf.Repeat(target - current, 360) if num > 180 then num = num - 360 end return num end function Mathf.Gamma(value, absmax, gamma) local flag = false if value < 0 then flag = true end local num = abs(value) if num > absmax then return (not flag) and num or -num end local num2 = math.pow(num / absmax, gamma) * absmax return (not flag) and num2 or -num2 end function Mathf.InverseLerp(from, to, value) if from < to then if value < from then return 0 end if value > to then return 1 end value = value - from value = value/(to - from) return value end if from <= to then return 0 end if value < to then return 1 end if value > from then return 0 end return 1 - ((value - to) / (from - to)) end function Mathf.Lerp(from, to, t) return from + (to - from) * Mathf.Clamp01(t) end function Mathf.LerpAngle(a, b, t) local num = Mathf.Repeat(b - a, 360) if num > 180 then num = num - 360 end return a + num * Mathf.Clamp01(t) end function Mathf.LerpUnclamped(a, b, t) return a + (b - a) * t; end function Mathf.MoveTowards(current, target, maxDelta) if abs(target - current) <= maxDelta then return target end return current + Mathf.Sign(target - current) * maxDelta end function Mathf.MoveTowardsAngle(current, target, maxDelta) target = current + Mathf.DeltaAngle(current, target) return Mathf.MoveTowards(current, target, maxDelta) end function Mathf.PingPong(t, length) t = Mathf.Repeat(t, length * 2) return length - abs(t - length) end function Mathf.Repeat(t, length) return t - (floor(t / length) * length) end function Mathf.Round(num) return floor(num + 0.5) end function Mathf.Sign(num) if num > 0 then num = 1 elseif num < 0 then num = -1 else num = 0 end return num end function Mathf.SmoothDamp(current, target, currentVelocity, smoothTime, maxSpeed, deltaTime) maxSpeed = maxSpeed or Mathf.Infinity deltaTime = deltaTime or Time.deltaTime smoothTime = Mathf.Max(0.0001, smoothTime) local num = 2 / smoothTime local num2 = num * deltaTime local num3 = 1 / (1 + num2 + 0.48 * num2 * num2 + 0.235 * num2 * num2 * num2) local num4 = current - target local num5 = target local max = maxSpeed * smoothTime num4 = Mathf.Clamp(num4, -max, max) target = current - num4 local num7 = (currentVelocity + (num * num4)) * deltaTime currentVelocity = (currentVelocity - num * num7) * num3 local num8 = target + (num4 + num7) * num3 if (num5 > current) == (num8 > num5) then num8 = num5 currentVelocity = (num8 - num5) / deltaTime end return num8,currentVelocity end function Mathf.SmoothDampAngle(current, target, currentVelocity, smoothTime, maxSpeed, deltaTime) deltaTime = deltaTime or Time.deltaTime maxSpeed = maxSpeed or Mathf.Infinity target = current + Mathf.DeltaAngle(current, target) return Mathf.SmoothDamp(current, target, currentVelocity, smoothTime, maxSpeed, deltaTime) end function Mathf.SmoothStep(from, to, t) t = Mathf.Clamp01(t) t = -2 * t * t * t + 3 * t * t return to * t + from * (1 - t) end function Mathf.HorizontalAngle(dir) return math.deg(math.atan2(dir.x, dir.z)) end function Mathf.IsNan(number) return not (number == number) end UnityEngine.Mathf = Mathf return Mathf ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Mathf.lua.meta ================================================ fileFormatVersion: 2 guid: 5cfbc4fb807d4e444bd41df7de6c249e DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Plane.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local setmetatable = setmetatable local Mathf = Mathf local Vector3 = Vector3 local Plane = {} Plane.__index = function(t,k) return rawget(Plane, k) end Plane.__call = function(t,v) return Plane.New(v) end function Plane.New(normal, d) return setmetatable({normal = normal:Normalize(), distance = d}, Plane) end function Plane:Get() return self.normal, self.distance end function Plane:Raycast(ray) local a = Vector3.Dot(ray.direction, self.normal) local num2 = -Vector3.Dot(ray.origin, self.normal) - self.distance if Mathf.Approximately(a, 0) then return false, 0 end local enter = num2 / a return enter > 0, enter end function Plane:SetNormalAndPosition(inNormal, inPoint) self.normal = inNormal:Normalize() self.distance = -Vector3.Dot(inNormal, inPoint) end function Plane:Set3Points(a, b, c) self.normal = Vector3.Normalize(Vector3.Cross(b - a, c - a)) self.distance = -Vector3.Dot(self.normal, a) end function Plane:GetDistanceToPoint(inPt) return Vector3.Dot(self.normal, inPt) + self.distance end function Plane:GetSide(inPt) return (Vector3.Dot(self.normal, inPt) + self.distance) > 0 end function Plane:SameSide(inPt0, inPt1) local distanceToPoint = self:GetDistanceToPoint(inPt0) local num2 = self:GetDistanceToPoint(inPt1) return (distanceToPoint > 0 and num2 > 0) or (distanceToPoint <= 0 and num2 <= 0) end UnityEngine.Plane = Plane setmetatable(Plane, Plane) return Plane ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Plane.lua.meta ================================================ fileFormatVersion: 2 guid: a3971497c90061f4d9c0e9a99b5bbcbe DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Profiler.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2018 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local LuaProfiler = LuaProfiler local vmdef = jit and require("jit.vmdef") --通过文件名和行数指定一个函数名字 local ffnames = { event = { [20] = "_xpcall.__call", [142] = "event.__call", }, slot = { [11] = "slot.__call", }, MainScene = { [250] = "MainScene.Update" } } --不需要Profiler的函数 local blacklist = { ["ipairs_aux"] = 1, ["_xpcall.__call"] = 1, ["unknow"] = 1, } local profiler = { mark = 1, cache = 1, } local stacktrace = {} function profiler:scan(t, name) if self.mark[t] then return end self.mark[t] = true for k, v in pairs(t) do if type(k) == "string" then if type(v) == "function" then local str = k if name then str = name ..".".. str end if not blacklist[str] and k ~= "__index" and k ~= "__newindex" then self.cache[v] = {name = str, id = -1} end elseif type(v) == "table" and not self.mark[v] then self:scan(v, k) end elseif name and k == tolua.gettag or k == tolua.settag then self:scan(v, name) end end end function profiler:scanlibs() local t = package.loaded self.mark[t] = true for k, v in pairs(t) do if type(k) == "string" and type(v) == "table" then self:scan(v, k) local mt = getmetatable(v) if mt then self:scan(mt, k) end end end end local function findstack(func) local pos = #stacktrace + 1 for i, v in ipairs(stacktrace) do if v == func then pos = i end end return pos end local function jitreturn(count) local top = #stacktrace if top > 0 then local ar = debug.getinfo (5, "f") if ar then local func = ar.func local index = findstack(func) if index > top then ar = debug.getinfo(6, "f") if ar then func = ar.func index = findstack(func) or index end end for i = index + 1, top do table.remove(stacktrace) LuaProfiler.EndSample() end end end end local function BeginSample(name, func, cache) jitreturn() table.insert(stacktrace, func) if cache.id == -1 then cache.name = name cache.id = LuaProfiler.GetID(name) end LuaProfiler.BeginSample(cache.id) end local function BeginSampleNick(name, func, cache) jitreturn() table.insert(stacktrace, func) local id = -1 if cache.nick == nil then cache.nick = {} end id = cache.nick[name] if not id then id = LuaProfiler.GetID(name) cache.nick[name] = id end LuaProfiler.BeginSample(id) end function profiler_hook(event, line) if event == 'call' then local name = nil local func = debug.getinfo (2, 'f').func local cache = profiler.cache[func] if cache then name = cache.name end if blacklist[name] then return end if name == "event.__call" then local ar = debug.getinfo (2, 'n') BeginSampleNick(ar.name or name, func, cache) elseif name then BeginSample(name, func, cache) else local ar = debug.getinfo (2, 'Sn') local method = ar.name local linedefined = ar.linedefined if not cache then cache = {name = "unknow", id = -1} profiler.cache[func] = cache end if ar.short_src == "[C]" then if method == "__index" or method == "__newindex" then return end local name = tostring(func) local index = name:match("function: builtin#(%d+)") if not index then if method then name = method BeginSample(method, func, cache) elseif linedefined ~= -1 then name = ar.short_src .. linedefined BeginSample(name, func, cache) end else name = vmdef.ffnames[tonumber(index)] if not blacklist[name] then BeginSample(name, func, cache) end end elseif linedefined ~= -1 or method then local short_src = ar.short_src method = method or linedefined local name = nil name = short_src:match('([^/\\]+)%.%w+$') name = name or short_src:match('([^/\\]+)$') local ffname = ffnames[name] if ffname then name = ffname[linedefined] else name = name .. "." .. method end if not name then name = short_src .. "." .. method end BeginSample(name, func, cache) else BeginSample(name, func, cache) end end elseif event == "return" then local top = #stacktrace if top == 0 then return end local ar = debug.getinfo (2, 'f') if ar.func == stacktrace[top] then table.remove(stacktrace) LuaProfiler.EndSample() else local index = findstack(ar.func) if index > top then return end for i = index, top do table.remove(stacktrace) LuaProfiler.EndSample() end end end end function profiler:start() self.mark = {} self.cache = {__mode = "k"} self:scan(_G, nil) self:scanlibs() self.mark = nil debug.sethook(profiler_hook, 'cr', 0) end function profiler:print() for k, v in pairs(self.cache) do print(v.name) end end function profiler:stop() debug.sethook(nil) self.cache = nil end return profiler ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Profiler.lua.meta ================================================ fileFormatVersion: 2 guid: 37c51fa1e5d7c094f8620b364c731293 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Quaternion.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local math = math local sin = math.sin local cos = math.cos local acos = math.acos local asin = math.asin local sqrt = math.sqrt local min = math.min local max = math.max local sign = math.sign local atan2 = math.atan2 local clamp = Mathf.Clamp local abs = math.abs local setmetatable = setmetatable local getmetatable = getmetatable local rawget = rawget local rawset = rawset local Vector3 = Vector3 local rad2Deg = Mathf.Rad2Deg local halfDegToRad = 0.5 * Mathf.Deg2Rad local _forward = Vector3.forward local _up = Vector3.up local _next = { 2, 3, 1 } local Quaternion = {} local get = tolua.initget(Quaternion) Quaternion.__index = function(t, k) local var = rawget(Quaternion, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end Quaternion.__newindex = function(t, name, k) if name == "eulerAngles" then t:SetEuler(k) else rawset(t, name, k) end end function Quaternion.New(x, y, z, w) local t = {x = x or 0, y = y or 0, z = z or 0, w = w or 0} setmetatable(t, Quaternion) return t end local _new = Quaternion.New Quaternion.__call = function(t, x, y, z, w) local t = {x = x or 0, y = y or 0, z = z or 0, w = w or 0} setmetatable(t, Quaternion) return t end function Quaternion:Set(x,y,z,w) self.x = x or 0 self.y = y or 0 self.z = z or 0 self.w = w or 0 end function Quaternion:Clone() return _new(self.x, self.y, self.z, self.w) end function Quaternion:Get() return self.x, self.y, self.z, self.w end function Quaternion.Dot(a, b) return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w end function Quaternion.Angle(a, b) local dot = Quaternion.Dot(a, b) if dot < 0 then dot = -dot end return acos(min(dot, 1)) * 2 * 57.29578 end function Quaternion.AngleAxis(angle, axis) local normAxis = axis:Normalize() angle = angle * halfDegToRad local s = sin(angle) local w = cos(angle) local x = normAxis.x * s local y = normAxis.y * s local z = normAxis.z * s return _new(x,y,z,w) end function Quaternion.Equals(a, b) return a.x == b.x and a.y == b.y and a.z == b.z and a.w == b.w end function Quaternion.Euler(x, y, z) if y == nil and z == nil then y = x.y z = x.z x = x.x end x = x * 0.0087266462599716 y = y * 0.0087266462599716 z = z * 0.0087266462599716 local sinX = sin(x) x = cos(x) local sinY = sin(y) y = cos(y) local sinZ = sin(z) z = cos(z) local q = {x = y * sinX * z + sinY * x * sinZ, y = sinY * x * z - y * sinX * sinZ, z = y * x * sinZ - sinY * sinX * z, w = y * x * z + sinY * sinX * sinZ} setmetatable(q, Quaternion) return q end function Quaternion:SetEuler(x, y, z) if y == nil and z == nil then y = x.y z = x.z x = x.x end x = x * 0.0087266462599716 y = y * 0.0087266462599716 z = z * 0.0087266462599716 local sinX = sin(x) local cosX = cos(x) local sinY = sin(y) local cosY = cos(y) local sinZ = sin(z) local cosZ = cos(z) self.w = cosY * cosX * cosZ + sinY * sinX * sinZ self.x = cosY * sinX * cosZ + sinY * cosX * sinZ self.y = sinY * cosX * cosZ - cosY * sinX * sinZ self.z = cosY * cosX * sinZ - sinY * sinX * cosZ return self end function Quaternion:Normalize() local quat = self:Clone() quat:SetNormalize() return quat end function Quaternion:SetNormalize() local n = self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w if n ~= 1 and n > 0 then n = 1 / sqrt(n) self.x = self.x * n self.y = self.y * n self.z = self.z * n self.w = self.w * n end end --产生一个新的从from到to的四元数 function Quaternion.FromToRotation(from, to) local quat = Quaternion.New() quat:SetFromToRotation(from, to) return quat end --设置当前四元数为 from 到 to的旋转, 注意from和to同 forward平行会同unity不一致 function Quaternion:SetFromToRotation1(from, to) local v0 = from:Normalize() local v1 = to:Normalize() local d = Vector3.Dot(v0, v1) if d > -1 + 1e-6 then local s = sqrt((1+d) * 2) local invs = 1 / s local c = Vector3.Cross(v0, v1) * invs self:Set(c.x, c.y, c.z, s * 0.5) elseif d > 1 - 1e-6 then return _new(0, 0, 0, 1) else local axis = Vector3.Cross(Vector3.right, v0) if axis:SqrMagnitude() < 1e-6 then axis = Vector3.Cross(Vector3.forward, v0) end self:Set(axis.x, axis.y, axis.z, 0) return self end return self end local function MatrixToQuaternion(rot, quat) local trace = rot[1][1] + rot[2][2] + rot[3][3] if trace > 0 then local s = sqrt(trace + 1) quat.w = 0.5 * s s = 0.5 / s quat.x = (rot[3][2] - rot[2][3]) * s quat.y = (rot[1][3] - rot[3][1]) * s quat.z = (rot[2][1] - rot[1][2]) * s quat:SetNormalize() else local i = 1 local q = {0, 0, 0} if rot[2][2] > rot[1][1] then i = 2 end if rot[3][3] > rot[i][i] then i = 3 end local j = _next[i] local k = _next[j] local t = rot[i][i] - rot[j][j] - rot[k][k] + 1 local s = 0.5 / sqrt(t) q[i] = s * t local w = (rot[k][j] - rot[j][k]) * s q[j] = (rot[j][i] + rot[i][j]) * s q[k] = (rot[k][i] + rot[i][k]) * s quat:Set(q[1], q[2], q[3], w) quat:SetNormalize() end end function Quaternion:SetFromToRotation(from, to) from = from:Normalize() to = to:Normalize() local e = Vector3.Dot(from, to) if e > 1 - 1e-6 then self:Set(0, 0, 0, 1) elseif e < -1 + 1e-6 then local left = {0, from.z, from.y} local mag = left[2] * left[2] + left[3] * left[3] --+ left[1] * left[1] = 0 if mag < 1e-6 then left[1] = -from.z left[2] = 0 left[3] = from.x mag = left[1] * left[1] + left[3] * left[3] end local invlen = 1/sqrt(mag) left[1] = left[1] * invlen left[2] = left[2] * invlen left[3] = left[3] * invlen local up = {0, 0, 0} up[1] = left[2] * from.z - left[3] * from.y up[2] = left[3] * from.x - left[1] * from.z up[3] = left[1] * from.y - left[2] * from.x local fxx = -from.x * from.x local fyy = -from.y * from.y local fzz = -from.z * from.z local fxy = -from.x * from.y local fxz = -from.x * from.z local fyz = -from.y * from.z local uxx = up[1] * up[1] local uyy = up[2] * up[2] local uzz = up[3] * up[3] local uxy = up[1] * up[2] local uxz = up[1] * up[3] local uyz = up[2] * up[3] local lxx = -left[1] * left[1] local lyy = -left[2] * left[2] local lzz = -left[3] * left[3] local lxy = -left[1] * left[2] local lxz = -left[1] * left[3] local lyz = -left[2] * left[3] local rot = { {fxx + uxx + lxx, fxy + uxy + lxy, fxz + uxz + lxz}, {fxy + uxy + lxy, fyy + uyy + lyy, fyz + uyz + lyz}, {fxz + uxz + lxz, fyz + uyz + lyz, fzz + uzz + lzz}, } MatrixToQuaternion(rot, self) else local v = Vector3.Cross(from, to) local h = (1 - e) / Vector3.Dot(v, v) local hx = h * v.x local hz = h * v.z local hxy = hx * v.y local hxz = hx * v.z local hyz = hz * v.y local rot = { {e + hx*v.x, hxy - v.z, hxz + v.y}, {hxy + v.z, e + h*v.y*v.y, hyz-v.x}, {hxz - v.y, hyz + v.x, e + hz*v.z}, } MatrixToQuaternion(rot, self) end end function Quaternion:Inverse() local quat = Quaternion.New() quat.x = -self.x quat.y = -self.y quat.z = -self.z quat.w = self.w return quat end function Quaternion.Lerp(q1, q2, t) t = clamp(t, 0, 1) local q = {x = 0, y = 0, z = 0, w = 1} if Quaternion.Dot(q1, q2) < 0 then q.x = q1.x + t * (-q2.x -q1.x) q.y = q1.y + t * (-q2.y -q1.y) q.z = q1.z + t * (-q2.z -q1.z) q.w = q1.w + t * (-q2.w -q1.w) else q.x = q1.x + (q2.x - q1.x) * t q.y = q1.y + (q2.y - q1.y) * t q.z = q1.z + (q2.z - q1.z) * t q.w = q1.w + (q2.w - q1.w) * t end Quaternion.SetNormalize(q) setmetatable(q, Quaternion) return q end function Quaternion.LookRotation(forward, up) local mag = forward:Magnitude() if mag < 1e-6 then error("error input forward to Quaternion.LookRotation"..tostring(forward)) return nil end forward = forward / mag up = up or _up local right = Vector3.Cross(up, forward) right:SetNormalize() up = Vector3.Cross(forward, right) right = Vector3.Cross(up, forward) --[[ local quat = _new(0,0,0,1) local rot = { {right.x, up.x, forward.x}, {right.y, up.y, forward.y}, {right.z, up.z, forward.z}, } MatrixToQuaternion(rot, quat) return quat--]] local t = right.x + up.y + forward.z if t > 0 then local x, y, z, w t = t + 1 local s = 0.5 / sqrt(t) w = s * t x = (up.z - forward.y) * s y = (forward.x - right.z) * s z = (right.y - up.x) * s local ret = _new(x, y, z, w) ret:SetNormalize() return ret else local rot = { {right.x, up.x, forward.x}, {right.y, up.y, forward.y}, {right.z, up.z, forward.z}, } local q = {0, 0, 0} local i = 1 if up.y > right.x then i = 2 end if forward.z > rot[i][i] then i = 3 end local j = _next[i] local k = _next[j] local t = rot[i][i] - rot[j][j] - rot[k][k] + 1 local s = 0.5 / sqrt(t) q[i] = s * t local w = (rot[k][j] - rot[j][k]) * s q[j] = (rot[j][i] + rot[i][j]) * s q[k] = (rot[k][i] + rot[i][k]) * s local ret = _new(q[1], q[2], q[3], w) ret:SetNormalize() return ret end end function Quaternion:SetIdentity() self.x = 0 self.y = 0 self.z = 0 self.w = 1 end local function UnclampedSlerp(q1, q2, t) local dot = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w if dot < 0 then dot = -dot q2 = setmetatable({x = -q2.x, y = -q2.y, z = -q2.z, w = -q2.w}, Quaternion) end if dot < 0.95 then local angle = acos(dot) local invSinAngle = 1 / sin(angle) local t1 = sin((1 - t) * angle) * invSinAngle local t2 = sin(t * angle) * invSinAngle q1 = {x = q1.x * t1 + q2.x * t2, y = q1.y * t1 + q2.y * t2, z = q1.z * t1 + q2.z * t2, w = q1.w * t1 + q2.w * t2} setmetatable(q1, Quaternion) return q1 else q1 = {x = q1.x + t * (q2.x - q1.x), y = q1.y + t * (q2.y - q1.y), z = q1.z + t * (q2.z - q1.z), w = q1.w + t * (q2.w - q1.w)} Quaternion.SetNormalize(q1) setmetatable(q1, Quaternion) return q1 end end function Quaternion.Slerp(from, to, t) if t < 0 then t = 0 elseif t > 1 then t = 1 end return UnclampedSlerp(from, to, t) end function Quaternion.RotateTowards(from, to, maxDegreesDelta) local angle = Quaternion.Angle(from, to) if angle == 0 then return to end local t = min(1, maxDegreesDelta / angle) return UnclampedSlerp(from, to, t) end local function Approximately(f0, f1) return abs(f0 - f1) < 1e-6 end function Quaternion:ToAngleAxis() local angle = 2 * acos(self.w) if Approximately(angle, 0) then return angle * 57.29578, Vector3.New(1, 0, 0) end local div = 1 / sqrt(1 - sqrt(self.w)) return angle * 57.29578, Vector3.New(self.x * div, self.y * div, self.z * div) end local pi = Mathf.PI local half_pi = pi * 0.5 local two_pi = 2 * pi local negativeFlip = -0.0001 local positiveFlip = two_pi - 0.0001 local function SanitizeEuler(euler) if euler.x < negativeFlip then euler.x = euler.x + two_pi elseif euler.x > positiveFlip then euler.x = euler.x - two_pi end if euler.y < negativeFlip then euler.y = euler.y + two_pi elseif euler.y > positiveFlip then euler.y = euler.y - two_pi end if euler.z < negativeFlip then euler.z = euler.z + two_pi elseif euler.z > positiveFlip then euler.z = euler.z + two_pi end end --from http://www.geometrictools.com/Documentation/EulerAngles.pdf --Order of rotations: YXZ function Quaternion:ToEulerAngles() local x = self.x local y = self.y local z = self.z local w = self.w local check = 2 * (y * z - w * x) if check < 0.999 then if check > -0.999 then local v = Vector3.New( -asin(check), atan2(2 * (x * z + w * y), 1 - 2 * (x * x + y * y)), atan2(2 * (x * y + w * z), 1 - 2 * (x * x + z * z))) SanitizeEuler(v) v:Mul(rad2Deg) return v else local v = Vector3.New(half_pi, atan2(2 * (x * y - w * z), 1 - 2 * (y * y + z * z)), 0) SanitizeEuler(v) v:Mul(rad2Deg) return v end else local v = Vector3.New(-half_pi, atan2(-2 * (x * y - w * z), 1 - 2 * (y * y + z * z)), 0) SanitizeEuler(v) v:Mul(rad2Deg) return v end end function Quaternion:Forward() return self:MulVec3(_forward) end function Quaternion.MulVec3(self, point) local vec = Vector3.New() local num = self.x * 2 local num2 = self.y * 2 local num3 = self.z * 2 local num4 = self.x * num local num5 = self.y * num2 local num6 = self.z * num3 local num7 = self.x * num2 local num8 = self.x * num3 local num9 = self.y * num3 local num10 = self.w * num local num11 = self.w * num2 local num12 = self.w * num3 vec.x = (((1 - (num5 + num6)) * point.x) + ((num7 - num12) * point.y)) + ((num8 + num11) * point.z) vec.y = (((num7 + num12) * point.x) + ((1 - (num4 + num6)) * point.y)) + ((num9 - num10) * point.z) vec.z = (((num8 - num11) * point.x) + ((num9 + num10) * point.y)) + ((1 - (num4 + num5)) * point.z) return vec end Quaternion.__mul = function(lhs, rhs) if Quaternion == getmetatable(rhs) then return Quaternion.New((((lhs.w * rhs.x) + (lhs.x * rhs.w)) + (lhs.y * rhs.z)) - (lhs.z * rhs.y), (((lhs.w * rhs.y) + (lhs.y * rhs.w)) + (lhs.z * rhs.x)) - (lhs.x * rhs.z), (((lhs.w * rhs.z) + (lhs.z * rhs.w)) + (lhs.x * rhs.y)) - (lhs.y * rhs.x), (((lhs.w * rhs.w) - (lhs.x * rhs.x)) - (lhs.y * rhs.y)) - (lhs.z * rhs.z)) elseif Vector3 == getmetatable(rhs) then return lhs:MulVec3(rhs) end end Quaternion.__unm = function(q) return Quaternion.New(-q.x, -q.y, -q.z, -q.w) end Quaternion.__eq = function(lhs,rhs) return Quaternion.Dot(lhs, rhs) > 0.999999 end Quaternion.__tostring = function(self) return "["..self.x..","..self.y..","..self.z..","..self.w.."]" end get.identity = function() return _new(0, 0, 0, 1) end get.eulerAngles = Quaternion.ToEulerAngles UnityEngine.Quaternion = Quaternion setmetatable(Quaternion, Quaternion) return Quaternion ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Quaternion.lua.meta ================================================ fileFormatVersion: 2 guid: bc8181e6244125146a87c5b83c380a92 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Ray.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local rawget = rawget local setmetatable = setmetatable local Vector3 = Vector3 local Ray = { direction = Vector3.zero, origin = Vector3.zero, } local get = tolua.initget(Ray) Ray.__index = function(t,k) local var = rawget(Ray, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end Ray.__call = function(t, direction, origin) return Ray.New(direction, origin) end function Ray.New(direction, origin) local ray = {} ray.direction = direction:Normalize() ray.origin = origin setmetatable(ray, Ray) return ray end function Ray:GetPoint(distance) local dir = self.direction * distance dir:Add(self.origin) return dir end function Ray:Get() local o = self.origin local d = self.direction return o.x, o.y, o.z, d.x, d.y, d.z end Ray.__tostring = function(self) return string.format("Origin:(%f,%f,%f),Dir:(%f,%f, %f)", self.origin.x, self.origin.y, self.origin.z, self.direction.x, self.direction.y, self.direction.z) end UnityEngine.Ray = Ray setmetatable(Ray, Ray) return Ray ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Ray.lua.meta ================================================ fileFormatVersion: 2 guid: 436d981c3546acd44a03048767c0d85a DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/RaycastHit.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local rawget = rawget local setmetatable = setmetatable RaycastBits = { Collider = 1, Normal = 2, Point = 4, Rigidbody = 8, Transform = 16, ALL = 31, } local RaycastBits = RaycastBits local RaycastHit = {} local get = tolua.initget(RaycastHit) RaycastHit.__index = function(t,k) local var = rawget(RaycastHit, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end --c# 创建 function RaycastHit.New(collider, distance, normal, point, rigidbody, transform) local hit = {collider = collider, distance = distance, normal = normal, point = point, rigidbody = rigidbody, transform = transform} setmetatable(hit, RaycastHit) return hit end function RaycastHit:Init(collider, distance, normal, point, rigidbody, transform) self.collider = collider self.distance = distance self.normal = normal self.point = point self.rigidbody = rigidbody self.transform = transform end function RaycastHit:Get() return self.collider, self.distance, self.normal, self.point, self.rigidbody, self.transform end function RaycastHit:Destroy() self.collider = nil self.rigidbody = nil self.transform = nil end function RaycastHit.GetMask(...) local arg = {...} local value = 0 for i = 1, #arg do local n = RaycastBits[arg[i]] or 0 if n ~= 0 then value = value + n end end if value == 0 then value = RaycastBits["all"] end return value end UnityEngine.RaycastHit = RaycastHit setmetatable(RaycastHit, RaycastHit) return RaycastHit ================================================ FILE: Assets/ToLua/Lua/UnityEngine/RaycastHit.lua.meta ================================================ fileFormatVersion: 2 guid: 707a4e1a225007d45923200abf2c9c13 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Time.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local rawget = rawget local uTime = UnityEngine.Time local gettime = tolua.gettime local _Time = { deltaTime = 0, fixedDeltaTime = 0, maximumDeltaTime = 0.3333333, fixedTime = 0, frameCount = 1, realtimeSinceStartup=0, time = 0, timeScale = 1, timeSinceLevelLoad = 0, unscaledDeltaTime = 0, unscaledTime = 0, } local _set = {} function _set.fixedDeltaTime(v) _Time.fixedDeltaTime = v uTime.fixedDeltaTime = v end function _set.maximumDeltaTime(v) _Time.maximumDeltaTime = v uTime.maximumDeltaTime = v end function _set.timeScale(v) _Time.timeScale = v uTime.timeScale = v end function _set.captureFramerate(v) _Time.captureFramerate = v uTime.captureFramerate = v end function _set.timeSinceLevelLoad(v) _Time.timeSinceLevelLoad = v end _Time.__index = function(t, k) local var = rawget(_Time, k) if var then return var end return uTime.__index(uTime, k) end _Time.__newindex = function(t, k, v) local func = rawget(_set, k) if func then return func(v) end error(string.format("Property or indexer `UnityEngine.Time.%s' cannot be assigned to (it is read only)", k)) end local Time = {} local counter = 1 function Time:SetDeltaTime(deltaTime, unscaledDeltaTime) local _Time = _Time _Time.deltaTime = deltaTime _Time.unscaledDeltaTime = unscaledDeltaTime counter = counter - 1 if counter == 0 and uTime then _Time.time = uTime.time _Time.timeSinceLevelLoad = uTime.timeSinceLevelLoad _Time.unscaledTime = uTime.unscaledTime _Time.realtimeSinceStartup = uTime.realtimeSinceStartup _Time.frameCount = uTime.frameCount counter = 1000000 else _Time.time = _Time.time + deltaTime _Time.realtimeSinceStartup = _Time.realtimeSinceStartup + unscaledDeltaTime _Time.timeSinceLevelLoad = _Time.timeSinceLevelLoad + deltaTime _Time.unscaledTime = _Time.unscaledTime + unscaledDeltaTime end end function Time:SetFixedDelta(fixedDeltaTime) _Time.deltaTime = fixedDeltaTime _Time.fixedDeltaTime = fixedDeltaTime _Time.fixedTime = _Time.fixedTime + fixedDeltaTime end function Time:SetFrameCount() _Time.frameCount = _Time.frameCount + 1 end function Time:SetTimeScale(scale) local last = _Time.timeScale _Time.timeScale = scale uTime.timeScale = scale return last end function Time:GetTimestamp() return gettime() end UnityEngine.Time = Time setmetatable(Time, _Time) if uTime ~= nil then _Time.maximumDeltaTime = uTime.maximumDeltaTime _Time.timeScale = uTime.timeScale end return Time ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Time.lua.meta ================================================ fileFormatVersion: 2 guid: 0f2e1d9dee4ecaf4b8734c59f1c9f3b5 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Touch.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local zero = Vector2.zero local rawget = rawget local setmetatable = setmetatable TouchPhase = { Began = 0, Moved = 1, Stationary = 2, Ended = 3, Canceled = 4, } TouchBits = { DeltaPosition = 1, Position = 2, RawPosition = 4, ALL = 7, } local TouchPhase = TouchPhase local TouchBits = TouchBits local Touch = {} local get = tolua.initget(Touch) Touch.__index = function(t,k) local var = rawget(Touch, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end --c# 创建 function Touch.New(fingerId, position, rawPosition, deltaPosition, deltaTime, tapCount, phase) return setmetatable({fingerId = fingerId or 0, position = position or zero, rawPosition = rawPosition or zero, deltaPosition = deltaPosition or zero, deltaTime = deltaTime or 0, tapCount = tapCount or 0, phase = phase or 0}, Touch) end function Touch:Init(fingerId, position, rawPosition, deltaPosition, deltaTime, tapCount, phase) self.fingerId = fingerId self.position = position self.rawPosition = rawPosition self.deltaPosition = deltaPosition self.deltaTime = deltaTime self.tapCount = tapCount self.phase = phase end function Touch:Destroy() self.position = nil self.rawPosition = nil self.deltaPosition = nil end function Touch.GetMask(...) local arg = {...} local value = 0 for i = 1, #arg do local n = TouchBits[arg[i]] or 0 if n ~= 0 then value = value + n end end if value == 0 then value = TouchBits["all"] end return value end UnityEngine.TouchPhase = TouchPhase UnityEngine.Touch = Touch setmetatable(Touch, Touch) return Touch ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Touch.lua.meta ================================================ fileFormatVersion: 2 guid: 48ee0c1b8478eba4f9338e5ec4a14d40 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Vector2.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local sqrt = math.sqrt local setmetatable = setmetatable local rawget = rawget local math = math local acos = math.acos local max = math.max local Vector2 = {} local get = tolua.initget(Vector2) Vector2.__index = function(t,k) local var = rawget(Vector2, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end Vector2.__call = function(t, x, y) return setmetatable({x = x or 0, y = y or 0}, Vector2) end function Vector2.New(x, y) return setmetatable({x = x or 0, y = y or 0}, Vector2) end function Vector2:Set(x,y) self.x = x or 0 self.y = y or 0 end function Vector2:Get() return self.x, self.y end function Vector2:SqrMagnitude() return self.x * self.x + self.y * self.y end function Vector2:Clone() return setmetatable({x = self.x, y = self.y}, Vector2) end function Vector2.Normalize(v) local x = v.x local y = v.y local magnitude = sqrt(x * x + y * y) if magnitude > 1e-05 then x = x / magnitude y = y / magnitude else x = 0 y = 0 end return setmetatable({x = x, y = y}, Vector2) end function Vector2:SetNormalize() local magnitude = sqrt(self.x * self.x + self.y * self.y) if magnitude > 1e-05 then self.x = self.x / magnitude self.y = self.y / magnitude else self.x = 0 self.y = 0 end return self end function Vector2.Dot(lhs, rhs) return lhs.x * rhs.x + lhs.y * rhs.y end function Vector2.Angle(from, to) local x1,y1 = from.x, from.y local d = sqrt(x1 * x1 + y1 * y1) if d > 1e-5 then x1 = x1/d y1 = y1/d else x1,y1 = 0,0 end local x2,y2 = to.x, to.y d = sqrt(x2 * x2 + y2 * y2) if d > 1e-5 then x2 = x2/d y2 = y2/d else x2,y2 = 0,0 end d = x1 * x2 + y1 * y2 if d < -1 then d = -1 elseif d > 1 then d = 1 end return acos(d) * 57.29578 end function Vector2.Magnitude(v) return sqrt(v.x * v.x + v.y * v.y) end function Vector2.Reflect(dir, normal) local dx = dir.x local dy = dir.y local nx = normal.x local ny = normal.y local s = -2 * (dx * nx + dy * ny) return setmetatable({x = s * nx + dx, y = s * ny + dy}, Vector2) end function Vector2.Distance(a, b) return sqrt((a.x - b.x) ^ 2 + (a.y - b.y) ^ 2) end function Vector2.Lerp(a, b, t) if t < 0 then t = 0 elseif t > 1 then t = 1 end return setmetatable({x = a.x + (b.x - a.x) * t, y = a.y + (b.y - a.y) * t}, Vector2) end function Vector2.LerpUnclamped(a, b, t) return setmetatable({x = a.x + (b.x - a.x) * t, y = a.y + (b.y - a.y) * t}, Vector2) end function Vector2.MoveTowards(current, target, maxDistanceDelta) local cx = current.x local cy = current.y local x = target.x - cx local y = target.y - cy local s = x * x + y * y if s > maxDistanceDelta * maxDistanceDelta and s ~= 0 then s = maxDistanceDelta / sqrt(s) return setmetatable({x = cx + x * s, y = cy + y * s}, Vector2) end return setmetatable({x = target.x, y = target.y}, Vector2) end function Vector2.ClampMagnitude(v, maxLength) local x = v.x local y = v.y local sqrMag = x * x + y * y if sqrMag > maxLength * maxLength then local mag = maxLength / sqrt(sqrMag) x = x * mag y = y * mag return setmetatable({x = x, y = y}, Vector2) end return setmetatable({x = x, y = y}, Vector2) end function Vector2.SmoothDamp(current, target, Velocity, smoothTime, maxSpeed, deltaTime) deltaTime = deltaTime or Time.deltaTime maxSpeed = maxSpeed or math.huge smoothTime = math.max(0.0001, smoothTime) local num = 2 / smoothTime local num2 = num * deltaTime num2 = 1 / (1 + num2 + 0.48 * num2 * num2 + 0.235 * num2 * num2 * num2) local tx = target.x local ty = target.y local cx = current.x local cy = current.y local vecx = cx - tx local vecy = cy - ty local m = vecx * vecx + vecy * vecy local n = maxSpeed * smoothTime if m > n * n then m = n / sqrt(m) vecx = vecx * m vecy = vecy * m end m = Velocity.x n = Velocity.y local vec3x = (m + num * vecx) * deltaTime local vec3y = (n + num * vecy) * deltaTime Velocity.x = (m - num * vec3x) * num2 Velocity.y = (n - num * vec3y) * num2 m = cx - vecx + (vecx + vec3x) * num2 n = cy - vecy + (vecy + vec3y) * num2 if (tx - cx) * (m - tx) + (ty - cy) * (n - ty) > 0 then m = tx n = ty Velocity.x = 0 Velocity.y = 0 end return setmetatable({x = m, y = n}, Vector2), Velocity end function Vector2.Max(a, b) return setmetatable({x = math.max(a.x, b.x), y = math.max(a.y, b.y)}, Vector2) end function Vector2.Min(a, b) return setmetatable({x = math.min(a.x, b.x), y = math.min(a.y, b.y)}, Vector2) end function Vector2.Scale(a, b) return setmetatable({x = a.x * b.x, y = a.y * b.y}, Vector2) end function Vector2:Div(d) self.x = self.x / d self.y = self.y / d return self end function Vector2:Mul(d) self.x = self.x * d self.y = self.y * d return self end function Vector2:Add(b) self.x = self.x + b.x self.y = self.y + b.y return self end function Vector2:Sub(b) self.x = self.x - b.x self.y = self.y - b.y return end Vector2.__tostring = function(self) return string.format("(%f,%f)", self.x, self.y) end Vector2.__div = function(va, d) return setmetatable({x = va.x / d, y = va.y / d}, Vector2) end Vector2.__mul = function(a, d) if type(d) == "number" then return setmetatable({x = a.x * d, y = a.y * d}, Vector2) else return setmetatable({x = a * d.x, y = a * d.y}, Vector2) end end Vector2.__add = function(a, b) return setmetatable({x = a.x + b.x, y = a.y + b.y}, Vector2) end Vector2.__sub = function(a, b) return setmetatable({x = a.x - b.x, y = a.y - b.y}, Vector2) end Vector2.__unm = function(v) return setmetatable({x = -v.x, y = -v.y}, Vector2) end Vector2.__eq = function(a,b) return ((a.x - b.x) ^ 2 + (a.y - b.y) ^ 2) < 9.999999e-11 end get.up = function() return setmetatable({x = 0, y = 1}, Vector2) end get.right = function() return setmetatable({x = 1, y = 0}, Vector2) end get.zero = function() return setmetatable({x = 0, y = 0}, Vector2) end get.one = function() return setmetatable({x = 1, y = 1}, Vector2) end get.magnitude = Vector2.Magnitude get.normalized = Vector2.Normalize get.sqrMagnitude = Vector2.SqrMagnitude UnityEngine.Vector2 = Vector2 setmetatable(Vector2, Vector2) return Vector2 ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Vector2.lua.meta ================================================ fileFormatVersion: 2 guid: ebac0a3bf4e463249a78081c5cc3abcf DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Vector3.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local math = math local acos = math.acos local sqrt = math.sqrt local max = math.max local min = math.min local clamp = Mathf.Clamp local cos = math.cos local sin = math.sin local abs = math.abs local sign = Mathf.Sign local setmetatable = setmetatable local rawset = rawset local rawget = rawget local type = type local rad2Deg = 57.295779513082 local deg2Rad = 0.017453292519943 local Vector3 = {} local get = tolua.initget(Vector3) Vector3.__index = function(t,k) local var = rawget(Vector3, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end function Vector3.New(x, y, z) local t = {x = x or 0, y = y or 0, z = z or 0} setmetatable(t, Vector3) return t end local _new = Vector3.New Vector3.__call = function(t,x,y,z) local t = {x = x or 0, y = y or 0, z = z or 0} setmetatable(t, Vector3) return t end function Vector3:Set(x,y,z) self.x = x or 0 self.y = y or 0 self.z = z or 0 end function Vector3.Get(v) return v.x, v.y, v.z end function Vector3:Clone() return setmetatable({x = self.x, y = self.y, z = self.z}, Vector3) end function Vector3.Distance(va, vb) return sqrt((va.x - vb.x)^2 + (va.y - vb.y)^2 + (va.z - vb.z)^2) end function Vector3.Dot(lhs, rhs) return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z end function Vector3.Lerp(from, to, t) t = clamp(t, 0, 1) return _new(from.x + (to.x - from.x) * t, from.y + (to.y - from.y) * t, from.z + (to.z - from.z) * t) end function Vector3:Magnitude() return sqrt(self.x * self.x + self.y * self.y + self.z * self.z) end function Vector3.Max(lhs, rhs) return _new(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z)) end function Vector3.Min(lhs, rhs) return _new(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z)) end function Vector3.Normalize(v) local x,y,z = v.x, v.y, v.z local num = sqrt(x * x + y * y + z * z) if num > 1e-5 then return setmetatable({x = x / num, y = y / num, z = z / num}, Vector3) end return setmetatable({x = 0, y = 0, z = 0}, Vector3) end function Vector3:SetNormalize() local num = sqrt(self.x * self.x + self.y * self.y + self.z * self.z) if num > 1e-5 then self.x = self.x / num self.y = self.y / num self.z = self.z /num else self.x = 0 self.y = 0 self.z = 0 end return self end function Vector3:SqrMagnitude() return self.x * self.x + self.y * self.y + self.z * self.z end local dot = Vector3.Dot function Vector3.Angle(from, to) return acos(clamp(dot(from:Normalize(), to:Normalize()), -1, 1)) * rad2Deg end function Vector3:ClampMagnitude(maxLength) if self:SqrMagnitude() > (maxLength * maxLength) then self:SetNormalize() self:Mul(maxLength) end return self end function Vector3.OrthoNormalize(va, vb, vc) va:SetNormalize() vb:Sub(vb:Project(va)) vb:SetNormalize() if vc == nil then return va, vb end vc:Sub(vc:Project(va)) vc:Sub(vc:Project(vb)) vc:SetNormalize() return va, vb, vc end function Vector3.MoveTowards(current, target, maxDistanceDelta) local delta = target - current local sqrDelta = delta:SqrMagnitude() local sqrDistance = maxDistanceDelta * maxDistanceDelta if sqrDelta > sqrDistance then local magnitude = sqrt(sqrDelta) if magnitude > 1e-6 then delta:Mul(maxDistanceDelta / magnitude) delta:Add(current) return delta else return current:Clone() end end return target:Clone() end function ClampedMove(lhs, rhs, clampedDelta) local delta = rhs - lhs if delta > 0 then return lhs + min(delta, clampedDelta) else return lhs - min(-delta, clampedDelta) end end local overSqrt2 = 0.7071067811865475244008443621048490 local function OrthoNormalVector(vec) local res = _new() if abs(vec.z) > overSqrt2 then local a = vec.y * vec.y + vec.z * vec.z local k = 1 / sqrt (a) res.x = 0 res.y = -vec.z * k res.z = vec.y * k else local a = vec.x * vec.x + vec.y * vec.y local k = 1 / sqrt (a) res.x = -vec.y * k res.y = vec.x * k res.z = 0 end return res end function Vector3.RotateTowards(current, target, maxRadiansDelta, maxMagnitudeDelta) local len1 = current:Magnitude() local len2 = target:Magnitude() if len1 > 1e-6 and len2 > 1e-6 then local from = current / len1 local to = target / len2 local cosom = dot(from, to) if cosom > 1 - 1e-6 then return Vector3.MoveTowards (current, target, maxMagnitudeDelta) elseif cosom < -1 + 1e-6 then local axis = OrthoNormalVector(from) local q = Quaternion.AngleAxis(maxRadiansDelta * rad2Deg, axis) local rotated = q:MulVec3(from) local delta = ClampedMove(len1, len2, maxMagnitudeDelta) rotated:Mul(delta) return rotated else local angle = acos(cosom) local axis = Vector3.Cross(from, to) axis:SetNormalize () local q = Quaternion.AngleAxis(min(maxRadiansDelta, angle) * rad2Deg, axis) local rotated = q:MulVec3(from) local delta = ClampedMove(len1, len2, maxMagnitudeDelta) rotated:Mul(delta) return rotated end end return Vector3.MoveTowards(current, target, maxMagnitudeDelta) end function Vector3.SmoothDamp(current, target, currentVelocity, smoothTime) local maxSpeed = Mathf.Infinity local deltaTime = Time.deltaTime smoothTime = max(0.0001, smoothTime) local num = 2 / smoothTime local num2 = num * deltaTime local num3 = 1 / (1 + num2 + 0.48 * num2 * num2 + 0.235 * num2 * num2 * num2) local vector2 = target:Clone() local maxLength = maxSpeed * smoothTime local vector = current - target vector:ClampMagnitude(maxLength) target = current - vector local vec3 = (currentVelocity + (vector * num)) * deltaTime currentVelocity = (currentVelocity - (vec3 * num)) * num3 local vector4 = target + (vector + vec3) * num3 if Vector3.Dot(vector2 - current, vector4 - vector2) > 0 then vector4 = vector2 currentVelocity:Set(0,0,0) end return vector4, currentVelocity end function Vector3.Scale(a, b) local x = a.x * b.x local y = a.y * b.y local z = a.z * b.z return _new(x, y, z) end function Vector3.Cross(lhs, rhs) local x = lhs.y * rhs.z - lhs.z * rhs.y local y = lhs.z * rhs.x - lhs.x * rhs.z local z = lhs.x * rhs.y - lhs.y * rhs.x return _new(x,y,z) end function Vector3:Equals(other) return self.x == other.x and self.y == other.y and self.z == other.z end function Vector3.Reflect(inDirection, inNormal) local num = -2 * dot(inNormal, inDirection) inNormal = inNormal * num inNormal:Add(inDirection) return inNormal end function Vector3.Project(vector, onNormal) local num = onNormal:SqrMagnitude() if num < 1.175494e-38 then return _new(0,0,0) end local num2 = dot(vector, onNormal) local v3 = onNormal:Clone() v3:Mul(num2/num) return v3 end function Vector3.ProjectOnPlane(vector, planeNormal) local v3 = Vector3.Project(vector, planeNormal) v3:Mul(-1) v3:Add(vector) return v3 end function Vector3.Slerp(from, to, t) local omega, sinom, scale0, scale1 if t <= 0 then return from:Clone() elseif t >= 1 then return to:Clone() end local v2 = to:Clone() local v1 = from:Clone() local len2 = to:Magnitude() local len1 = from:Magnitude() v2:Div(len2) v1:Div(len1) local len = (len2 - len1) * t + len1 local cosom = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z if cosom > 1 - 1e-6 then scale0 = 1 - t scale1 = t elseif cosom < -1 + 1e-6 then local axis = OrthoNormalVector(from) local q = Quaternion.AngleAxis(180.0 * t, axis) local v = q:MulVec3(from) v:Mul(len) return v else omega = acos(cosom) sinom = sin(omega) scale0 = sin((1 - t) * omega) / sinom scale1 = sin(t * omega) / sinom end v1:Mul(scale0) v2:Mul(scale1) v2:Add(v1) v2:Mul(len) return v2 end function Vector3:Mul(q) if type(q) == "number" then self.x = self.x * q self.y = self.y * q self.z = self.z * q else self:MulQuat(q) end return self end function Vector3:Div(d) self.x = self.x / d self.y = self.y / d self.z = self.z / d return self end function Vector3:Add(vb) self.x = self.x + vb.x self.y = self.y + vb.y self.z = self.z + vb.z return self end function Vector3:Sub(vb) self.x = self.x - vb.x self.y = self.y - vb.y self.z = self.z - vb.z return self end function Vector3:MulQuat(quat) local num = quat.x * 2 local num2 = quat.y * 2 local num3 = quat.z * 2 local num4 = quat.x * num local num5 = quat.y * num2 local num6 = quat.z * num3 local num7 = quat.x * num2 local num8 = quat.x * num3 local num9 = quat.y * num3 local num10 = quat.w * num local num11 = quat.w * num2 local num12 = quat.w * num3 local x = (((1 - (num5 + num6)) * self.x) + ((num7 - num12) * self.y)) + ((num8 + num11) * self.z) local y = (((num7 + num12) * self.x) + ((1 - (num4 + num6)) * self.y)) + ((num9 - num10) * self.z) local z = (((num8 - num11) * self.x) + ((num9 + num10) * self.y)) + ((1 - (num4 + num5)) * self.z) self:Set(x, y, z) return self end function Vector3.AngleAroundAxis (from, to, axis) from = from - Vector3.Project(from, axis) to = to - Vector3.Project(to, axis) local angle = Vector3.Angle (from, to) return angle * (Vector3.Dot (axis, Vector3.Cross (from, to)) < 0 and -1 or 1) end Vector3.__tostring = function(self) return "["..self.x..","..self.y..","..self.z.."]" end Vector3.__div = function(va, d) return _new(va.x / d, va.y / d, va.z / d) end Vector3.__mul = function(va, d) if type(d) == "number" then return _new(va.x * d, va.y * d, va.z * d) else local vec = va:Clone() vec:MulQuat(d) return vec end end Vector3.__add = function(va, vb) return _new(va.x + vb.x, va.y + vb.y, va.z + vb.z) end Vector3.__sub = function(va, vb) return _new(va.x - vb.x, va.y - vb.y, va.z - vb.z) end Vector3.__unm = function(va) return _new(-va.x, -va.y, -va.z) end Vector3.__eq = function(a,b) local v = a - b local delta = v:SqrMagnitude() return delta < 1e-10 end get.up = function() return _new(0,1,0) end get.down = function() return _new(0,-1,0) end get.right = function() return _new(1,0,0) end get.left = function() return _new(-1,0,0) end get.forward = function() return _new(0,0,1) end get.back = function() return _new(0,0,-1) end get.zero = function() return _new(0,0,0) end get.one = function() return _new(1,1,1) end get.magnitude = Vector3.Magnitude get.normalized = Vector3.Normalize get.sqrMagnitude= Vector3.SqrMagnitude UnityEngine.Vector3 = Vector3 setmetatable(Vector3, Vector3) return Vector3 ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Vector3.lua.meta ================================================ fileFormatVersion: 2 guid: 3697c841f98720444b380cc2756c17ea DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Vector4.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local clamp = Mathf.Clamp local sqrt = Mathf.Sqrt local min = Mathf.Min local max = Mathf.Max local setmetatable = setmetatable local rawget = rawget local Vector4 = {} local get = tolua.initget(Vector4) Vector4.__index = function(t,k) local var = rawget(Vector4, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var end Vector4.__call = function(t, x, y, z, w) return setmetatable({x = x or 0, y = y or 0, z = z or 0, w = w or 0}, Vector4) end function Vector4.New(x, y, z, w) return setmetatable({x = x or 0, y = y or 0, z = z or 0, w = w or 0}, Vector4) end function Vector4:Set(x,y,z,w) self.x = x or 0 self.y = y or 0 self.z = z or 0 self.w = w or 0 end function Vector4:Get() return self.x, self.y, self.z, self.w end function Vector4.Lerp(from, to, t) t = clamp(t, 0, 1) return Vector4.New(from.x + ((to.x - from.x) * t), from.y + ((to.y - from.y) * t), from.z + ((to.z - from.z) * t), from.w + ((to.w - from.w) * t)) end function Vector4.MoveTowards(current, target, maxDistanceDelta) local vector = target - current local magnitude = vector:Magnitude() if magnitude > maxDistanceDelta and magnitude ~= 0 then maxDistanceDelta = maxDistanceDelta / magnitude vector:Mul(maxDistanceDelta) vector:Add(current) return vector end return target end function Vector4.Scale(a, b) return Vector4.New(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w) end function Vector4:SetScale(scale) self.x = self.x * scale.x self.y = self.y * scale.y self.z = self.z * scale.z self.w = self.w * scale.w end function Vector4:Normalize() local v = vector4.New(self.x, self.y, self.z, self.w) return v:SetNormalize() end function Vector4:SetNormalize() local num = self:Magnitude() if num == 1 then return self elseif num > 1e-05 then self:Div(num) else self:Set(0,0,0,0) end return self end function Vector4:Div(d) self.x = self.x / d self.y = self.y / d self.z = self.z / d self.w = self.w / d return self end function Vector4:Mul(d) self.x = self.x * d self.y = self.y * d self.z = self.z * d self.w = self.w * d return self end function Vector4:Add(b) self.x = self.x + b.x self.y = self.y + b.y self.z = self.z + b.z self.w = self.w + b.w return self end function Vector4:Sub(b) self.x = self.x - b.x self.y = self.y - b.y self.z = self.z - b.z self.w = self.w - b.w return self end function Vector4.Dot(a, b) return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w end function Vector4.Project(a, b) local s = Vector4.Dot(a, b) / Vector4.Dot(b, b) return b * s end function Vector4.Distance(a, b) local v = a - b return Vector4.Magnitude(v) end function Vector4.Magnitude(a) return sqrt(a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w) end function Vector4.SqrMagnitude(a) return a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w end function Vector4.Min(lhs, rhs) return Vector4.New(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z), max(lhs.w, rhs.w)) end function Vector4.Max(lhs, rhs) return Vector4.New(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z), min(lhs.w, rhs.w)) end Vector4.__tostring = function(self) return string.format("[%f,%f,%f,%f]", self.x, self.y, self.z, self.w) end Vector4.__div = function(va, d) return Vector4.New(va.x / d, va.y / d, va.z / d, va.w / d) end Vector4.__mul = function(va, d) return Vector4.New(va.x * d, va.y * d, va.z * d, va.w * d) end Vector4.__add = function(va, vb) return Vector4.New(va.x + vb.x, va.y + vb.y, va.z + vb.z, va.w + vb.w) end Vector4.__sub = function(va, vb) return Vector4.New(va.x - vb.x, va.y - vb.y, va.z - vb.z, va.w - vb.w) end Vector4.__unm = function(va) return Vector4.New(-va.x, -va.y, -va.z, -va.w) end Vector4.__eq = function(va,vb) local v = va - vb local delta = Vector4.SqrMagnitude(v) return delta < 1e-10 end get.zero = function() return Vector4.New(0, 0, 0, 0) end get.one = function() return Vector4.New(1, 1, 1, 1) end get.magnitude = Vector4.Magnitude get.normalized = Vector4.Normalize get.sqrMagnitude = Vector4.SqrMagnitude UnityEngine.Vector4 = Vector4 setmetatable(Vector4, Vector4) return Vector4 ================================================ FILE: Assets/ToLua/Lua/UnityEngine/Vector4.lua.meta ================================================ fileFormatVersion: 2 guid: 7e294d4af7e55084dadac8ee7a76099d DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/UnityEngine.meta ================================================ fileFormatVersion: 2 guid: ec9654611f40bd64cb988c5f45494721 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/cjson/util.lua ================================================ local json = require "cjson" -- Various common routines used by the Lua CJSON package -- -- Mark Pulford -- Determine with a Lua table can be treated as an array. -- Explicitly returns "not an array" for very sparse arrays. -- Returns: -- -1 Not an array -- 0 Empty table -- >0 Highest index in the array local function is_array(table) local max = 0 local count = 0 for k, v in pairs(table) do if type(k) == "number" then if k > max then max = k end count = count + 1 else return -1 end end if max > count * 2 then return -1 end return max end local serialise_value local function serialise_table(value, indent, depth) local spacing, spacing2, indent2 if indent then spacing = "\n" .. indent spacing2 = spacing .. " " indent2 = indent .. " " else spacing, spacing2, indent2 = " ", " ", false end depth = depth + 1 if depth > 50 then return "Cannot serialise any further: too many nested tables" end local max = is_array(value) local comma = false local fragment = { "{" .. spacing2 } if max > 0 then -- Serialise array for i = 1, max do if comma then table.insert(fragment, "," .. spacing2) end table.insert(fragment, serialise_value(value[i], indent2, depth)) comma = true end elseif max < 0 then -- Serialise table for k, v in pairs(value) do if comma then table.insert(fragment, "," .. spacing2) end table.insert(fragment, ("[%s] = %s"):format(serialise_value(k, indent2, depth), serialise_value(v, indent2, depth))) comma = true end end table.insert(fragment, spacing .. "}") return table.concat(fragment) end function serialise_value(value, indent, depth) if indent == nil then indent = "" end if depth == nil then depth = 0 end if value == json.null then return "json.null" elseif type(value) == "string" then return ("%q"):format(value) elseif type(value) == "nil" or type(value) == "number" or type(value) == "boolean" then return tostring(value) elseif type(value) == "table" then return serialise_table(value, indent, depth) else return "\"<" .. type(value) .. ">\"" end end local function file_load(filename) local file if filename == nil then file = io.stdin else local err file, err = io.open(filename, "rb") if file == nil then error(("Unable to read '%s': %s"):format(filename, err)) end end local data = file:read("*a") if filename ~= nil then file:close() end if data == nil then error("Failed to read " .. filename) end return data end local function file_save(filename, data) local file if filename == nil then file = io.stdout else local err file, err = io.open(filename, "wb") if file == nil then error(("Unable to write '%s': %s"):format(filename, err)) end end file:write(data) if filename ~= nil then file:close() end end local function compare_values(val1, val2) local type1 = type(val1) local type2 = type(val2) if type1 ~= type2 then return false end -- Check for NaN if type1 == "number" and val1 ~= val1 and val2 ~= val2 then return true end if type1 ~= "table" then return val1 == val2 end -- check_keys stores all the keys that must be checked in val2 local check_keys = {} for k, _ in pairs(val1) do check_keys[k] = true end for k, v in pairs(val2) do if not check_keys[k] then return false end if not compare_values(val1[k], val2[k]) then return false end check_keys[k] = nil end for k, _ in pairs(check_keys) do -- Not the same if any keys from val1 were not found in val2 return false end return true end local test_count_pass = 0 local test_count_total = 0 local function run_test_summary() return test_count_pass, test_count_total end local function run_test(testname, func, input, should_work, output) local function status_line(name, status, value) local statusmap = { [true] = ":success", [false] = ":error" } if status ~= nil then name = name .. statusmap[status] end print(("[%s] %s"):format(name, serialise_value(value, false))) end local result = { pcall(func, unpack(input)) } local success = table.remove(result, 1) local correct = false if success == should_work and compare_values(result, output) then correct = true test_count_pass = test_count_pass + 1 end test_count_total = test_count_total + 1 local teststatus = { [true] = "PASS", [false] = "FAIL" } print(("==> Test [%d] %s: %s"):format(test_count_total, testname, teststatus[correct])) status_line("Input", nil, input) if not correct then status_line("Expected", should_work, output) end status_line("Received", success, result) print() return correct, result end local function run_test_group(tests) local function run_helper(name, func, input) if type(name) == "string" and #name > 0 then print("==> " .. name) end -- Not a protected call, these functions should never generate errors. func(unpack(input or {})) print() end for _, v in ipairs(tests) do -- Run the helper if "should_work" is missing if v[4] == nil then run_helper(unpack(v)) else run_test(unpack(v)) end end end -- Run a Lua script in a separate environment local function run_script(script, env) local env = env or {} local func -- Use setfenv() if it exists, otherwise assume Lua 5.2 load() exists if _G.setfenv then func = loadstring(script) if func then setfenv(func, env) end else func = load(script, nil, nil, env) end if func == nil then error("Invalid syntax.") end func() return env end -- Export functions return { serialise_value = serialise_value, file_load = file_load, file_save = file_save, compare_values = compare_values, run_test_summary = run_test_summary, run_test = run_test, run_test_group = run_test_group, run_script = run_script } -- vi:ai et sw=4 ts=4: ================================================ FILE: Assets/ToLua/Lua/cjson/util.lua.meta ================================================ fileFormatVersion: 2 guid: d6b21c50e0c10c840bb4965a6b03fdc1 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/cjson.meta ================================================ fileFormatVersion: 2 guid: 51fabff50886aea4ca5100ee3396939b folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/event.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local setmetatable = setmetatable local xpcall = xpcall local pcall = pcall local assert = assert local rawget = rawget local error = error local print = print local maxn = table.maxn local traceback = tolua.traceback local ilist = ilist local _xpcall = {} _xpcall.__call = function(self, ...) if jit then if nil == self.obj then return xpcall(self.func, traceback, ...) else return xpcall(self.func, traceback, self.obj, ...) end else local args = {...} if nil == self.obj then local func = function() self.func(unpack(args, 1, maxn(args))) end return xpcall(func, traceback) else local func = function() self.func(self.obj, unpack(args, 1, maxn(args))) end return xpcall(func, traceback) end end end _xpcall.__eq = function(lhs, rhs) return lhs.func == rhs.func and lhs.obj == rhs.obj end local function xfunctor(func, obj) return setmetatable({func = func, obj = obj}, _xpcall) end local _pcall = {} _pcall.__call = function(self, ...) if nil == self.obj then return pcall(self.func, ...) else return pcall(self.func, self.obj, ...) end end _pcall.__eq = function(lhs, rhs) return lhs.func == rhs.func and lhs.obj == rhs.obj end local function functor(func, obj) return setmetatable({func = func, obj = obj}, _pcall) end local _event = {} _event.__index = _event --废弃 function _event:Add(func, obj) assert(func) if self.keepSafe then func = xfunctor(func, obj) else func = functor(func, obj) end if self.lock then local node = {value = func, _prev = 0, _next = 0, removed = true} table.insert(self.opList, function() self.list:pushnode(node) end) return node else return self.list:push(func) end end --废弃 function _event:Remove(func, obj) for i, v in ilist(self.list) do if v.func == func and v.obj == obj then if self.lock then table.insert(self.opList, function() self.list:remove(i) end) else self.list:remove(i) end break end end end function _event:CreateListener(func, obj) if self.keepSafe then func = xfunctor(func, obj) else func = functor(func, obj) end return {value = func, _prev = 0, _next = 0, removed = true} end function _event:AddListener(handle) assert(handle) if self.lock then table.insert(self.opList, function() self.list:pushnode(handle) end) else self.list:pushnode(handle) end end function _event:RemoveListener(handle) assert(handle) if self.lock then table.insert(self.opList, function() self.list:remove(handle) end) else self.list:remove(handle) end end function _event:Count() return self.list.length end function _event:Clear() self.list:clear() self.opList = {} self.lock = false self.keepSafe = false self.current = nil end function _event:Dump() local count = 0 for _, v in ilist(self.list) do if v.obj then print("update function:", v.func, "object name:", v.obj.name) else print("update function: ", v.func) end count = count + 1 end print("all function is:", count) end _event.__call = function(self, ...) local _list = self.list self.lock = true local ilist = ilist for i, f in ilist(_list) do self.current = i local flag, msg = f(...) if not flag then _list:remove(i) self.lock = false error(msg) end end local opList = self.opList self.lock = false for i, op in ipairs(opList) do op() opList[i] = nil end end function event(name, safe) safe = safe or false return setmetatable({name = name, keepSafe = safe, lock = false, opList = {}, list = list:new()}, _event) end UpdateBeat = event("Update", true) LateUpdateBeat = event("LateUpdate", true) FixedUpdateBeat = event("FixedUpdate", true) CoUpdateBeat = event("CoUpdate") --只在协同使用 local Time = Time local UpdateBeat = UpdateBeat local LateUpdateBeat = LateUpdateBeat local FixedUpdateBeat = FixedUpdateBeat local CoUpdateBeat = CoUpdateBeat --逻辑update function Update(deltaTime, unscaledDeltaTime) Time:SetDeltaTime(deltaTime, unscaledDeltaTime) UpdateBeat() end function LateUpdate() LateUpdateBeat() CoUpdateBeat() Time:SetFrameCount() end --物理update function FixedUpdate(fixedDeltaTime) Time:SetFixedDelta(fixedDeltaTime) FixedUpdateBeat() end function PrintEvents() UpdateBeat:Dump() FixedUpdateBeat:Dump() end ================================================ FILE: Assets/ToLua/Lua/event.lua.meta ================================================ fileFormatVersion: 2 guid: 3cb3ad8be0f474f4c997acf1b791b133 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/jit/bc.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT bytecode listing module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module lists the bytecode of a Lua function. If it's loaded by -jbc -- it hooks into the parser and lists all functions of a chunk as they -- are parsed. -- -- Example usage: -- -- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)' -- luajit -jbc=- foo.lua -- luajit -jbc=foo.list foo.lua -- -- Default output is to stderr. To redirect the output to a file, pass a -- filename as an argument (use '-' for stdout) or set the environment -- variable LUAJIT_LISTFILE. The file is overwritten every time the module -- is started. -- -- This module can also be used programmatically: -- -- local bc = require("jit.bc") -- -- local function foo() print("hello") end -- -- bc.dump(foo) --> -- BYTECODE -- [...] -- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello" -- -- local out = { -- -- Do something with each line: -- write = function(t, ...) io.write(...) end, -- close = function(t) end, -- flush = function(t) end, -- } -- bc.dump(foo, out) -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local bit = require("bit") local sub, gsub, format = string.sub, string.gsub, string.format local byte, band, shr = string.byte, bit.band, bit.rshift local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck local funcuvname = jutil.funcuvname local bcnames = vmdef.bcnames local stdout, stderr = io.stdout, io.stderr ------------------------------------------------------------------------------ local function ctlsub(c) if c == "\n" then return "\\n" elseif c == "\r" then return "\\r" elseif c == "\t" then return "\\t" else return format("\\%03d", byte(c)) end end -- Return one bytecode line. local function bcline(func, pc, prefix, lineinfo) local ins, m, l = funcbc(func, pc, lineinfo and 1 or 0) if not ins then return end local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128) local a = band(shr(ins, 8), 0xff) local oidx = 6*band(ins, 0xff) local op = sub(bcnames, oidx+1, oidx+6) local s if lineinfo then s = format("%04d %7s %s %-6s %3s ", pc, "["..l.."]", prefix or " ", op, ma == 0 and "" or a) else s = format("%04d %s %-6s %3s ", pc, prefix or " ", op, ma == 0 and "" or a) end local d = shr(ins, 16) if mc == 13*128 then -- BCMjump return format("%s=> %04d\n", s, pc+d-0x7fff) end if mb ~= 0 then d = band(d, 0xff) elseif mc == 0 then return s.."\n" end local kc if mc == 10*128 then -- BCMstr kc = funck(func, -d-1) kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) elseif mc == 9*128 then -- BCMnum kc = funck(func, d) if op == "TSETM " then kc = kc - 2^52 end elseif mc == 12*128 then -- BCMfunc local fi = funcinfo(funck(func, -d-1)) if fi.ffid then kc = vmdef.ffnames[fi.ffid] else kc = fi.loc end elseif mc == 5*128 then -- BCMuv kc = funcuvname(func, d) end if ma == 5 then -- BCMuv local ka = funcuvname(func, a) if kc then kc = ka.." ; "..kc else kc = ka end end if mb ~= 0 then local b = shr(ins, 24) if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end return format("%s%3d %3d\n", s, b, d) end if kc then return format("%s%3d ; %s\n", s, d, kc) end if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits return format("%s%3d\n", s, d) end -- Collect branch targets of a function. local function bctargets(func) local target = {} for pc=1,1000000000 do local ins, m = funcbc(func, pc) if not ins then break end if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end end return target end -- Dump bytecode instructions of a function. local function bcdump(func, out, all, lineinfo) if not out then out = stdout end local fi = funcinfo(func) if all and fi.children then for n=-1,-1000000000,-1 do local k = funck(func, n) if not k then break end if type(k) == "proto" then bcdump(k, out, true, lineinfo) end end end out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined)) for n=-1,-1000000000,-1 do local kc = funck(func, n) if not kc then break end local typ = type(kc) if typ == "string" then kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) out:write(format("KGC %d %s\n", -(n + 1), kc)) elseif typ == "proto" then local fi = funcinfo(kc) if fi.ffid then kc = vmdef.ffnames[fi.ffid] else kc = fi.loc end out:write(format("KGC %d %s\n", -(n + 1), kc)) elseif typ == "table" then out:write(format("KGC %d table\n", -(n + 1))) else -- error("unknown KGC type: " .. typ) end end for n=1,1000000000 do local kc = funck(func, n) if not kc then break end if type(kc) == "number" then out:write(format("KN %d %s\n", n, kc)) end end local target = bctargets(func) for pc=1,1000000000 do local s = bcline(func, pc, target[pc] and "=>", lineinfo) if not s then break end out:write(s) end out:write("\n") out:flush() end ------------------------------------------------------------------------------ -- Active flag and output file handle. local active, out -- List handler. local function h_list(func) return bcdump(func, out) end -- Detach list handler. local function bclistoff() if active then active = false jit.attach(h_list) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach list handler. local function bcliston(outfile) if active then bclistoff() end if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stderr end jit.attach(h_list, "bc") active = true end -- Public module functions. return { line = bcline, dump = bcdump, targets = bctargets, on = bcliston, off = bclistoff, start = bcliston -- For -j command line option. } ================================================ FILE: Assets/ToLua/Lua/jit/bc.lua.meta ================================================ fileFormatVersion: 2 guid: 5f0b5eb903971c641845b50fec99cc42 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/bcsave.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT module to save/list bytecode. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module saves or lists the bytecode for an input file. -- It's run by the -b command line option. -- ------------------------------------------------------------------------------ local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local bit = require("bit") -- Symbol name prefix for LuaJIT bytecode. local LJBC_PREFIX = "luaJIT_BC_" ------------------------------------------------------------------------------ local function usage() io.stderr:write[[ Save LuaJIT bytecode: luajit -b[options] input output -l Only list bytecode. -L Only list bytecode with lineinfo. -s Strip debug info (default). -g Keep debug info. -n name Set module name (default: auto-detect from input name). -t type Set output file type (default: auto-detect from output name). -a arch Override architecture for object files (default: native). -o os Override OS for object files (default: native). -e chunk Use chunk string as input. -- Stop handling options. - Use stdin as input and/or stdout as output. File types: c h obj o raw (default) ]] os.exit(1) end local function check(ok, ...) if ok then return ok, ... end io.stderr:write("luajit: ", ...) io.stderr:write("\n") os.exit(1) end local function readfile(input) if type(input) == "function" then return input end if input == "-" then input = nil end return check(loadfile(input)) end local function savefile(name, mode) if name == "-" then return io.stdout end return check(io.open(name, mode)) end ------------------------------------------------------------------------------ local map_type = { raw = "raw", c = "c", h = "h", o = "obj", obj = "obj", } local map_arch = { x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true, ppc = true, mips = true, mipsel = true, } local map_os = { linux = true, windows = true, osx = true, freebsd = true, netbsd = true, openbsd = true, dragonfly = true, solaris = true, } local function checkarg(str, map, err) str = string.lower(str) local s = check(map[str], "unknown ", err) return s == true and str or s end local function detecttype(str) local ext = string.match(string.lower(str), "%.(%a+)$") return map_type[ext] or "raw" end local function checkmodname(str) check(string.match(str, "^[%w_.%-]+$"), "bad module name") return string.gsub(str, "[%.%-]", "_") end local function detectmodname(str) if type(str) == "string" then local tail = string.match(str, "[^/\\]+$") if tail then str = tail end local head = string.match(str, "^(.*)%.[^.]*$") if head then str = head end str = string.match(str, "^[%w_.%-]+") else str = nil end check(str, "cannot derive module name, use -n name") return string.gsub(str, "[%.%-]", "_") end ------------------------------------------------------------------------------ local function bcsave_tail(fp, output, s) local ok, err = fp:write(s) if ok and output ~= "-" then ok, err = fp:close() end check(ok, "cannot write ", output, ": ", err) end local function bcsave_raw(output, s) local fp = savefile(output, "wb") bcsave_tail(fp, output, s) end local function bcsave_c(ctx, output, s) local fp = savefile(output, "w") if ctx.type == "c" then fp:write(string.format([[ #ifdef _cplusplus extern "C" #endif #ifdef _WIN32 __declspec(dllexport) #endif const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname)) else fp:write(string.format([[ #define %s%s_SIZE %d static const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname)) end local t, n, m = {}, 0, 0 for i=1,#s do local b = tostring(string.byte(s, i)) m = m + #b + 1 if m > 78 then fp:write(table.concat(t, ",", 1, n), ",\n") n, m = 0, #b + 1 end n = n + 1 t[n] = b end bcsave_tail(fp, output, table.concat(t, ",", 1, n).."\n};\n") end local function bcsave_elfobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; uint16_t type, machine; uint32_t version; uint32_t entry, phofs, shofs; uint32_t flags; uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; } ELF32header; typedef struct { uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; uint16_t type, machine; uint32_t version; uint64_t entry, phofs, shofs; uint32_t flags; uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; } ELF64header; typedef struct { uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize; } ELF32sectheader; typedef struct { uint32_t name, type; uint64_t flags, addr, ofs, size; uint32_t link, info; uint64_t align, entsize; } ELF64sectheader; typedef struct { uint32_t name, value, size; uint8_t info, other; uint16_t sectidx; } ELF32symbol; typedef struct { uint32_t name; uint8_t info, other; uint16_t sectidx; uint64_t value, size; } ELF64symbol; typedef struct { ELF32header hdr; ELF32sectheader sect[6]; ELF32symbol sym[2]; uint8_t space[4096]; } ELF32obj; typedef struct { ELF64header hdr; ELF64sectheader sect[6]; ELF64symbol sym[2]; uint8_t space[4096]; } ELF64obj; ]] local symname = LJBC_PREFIX..ctx.modname local is64, isbe = false, false if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then is64 = true elseif ctx.arch == "ppc" or ctx.arch == "mips" then isbe = true end -- Handle different host/target endianess. local function f32(x) return x end local f16, fofs = f32, f32 if ffi.abi("be") ~= isbe then f32 = bit.bswap function f16(x) return bit.rshift(bit.bswap(x), 16) end if is64 then local two32 = ffi.cast("int64_t", 2^32) function fofs(x) return bit.bswap(x)*two32 end else fofs = f32 end end -- Create ELF object and fill in header. local o = ffi.new(is64 and "ELF64obj" or "ELF32obj") local hdr = o.hdr if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi. local bf = assert(io.open("/bin/ls", "rb")) local bs = bf:read(9) bf:close() ffi.copy(o, bs, 9) check(hdr.emagic[0] == 127, "no support for writing native object files") else hdr.emagic = "\127ELF" hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0 end hdr.eclass = is64 and 2 or 1 hdr.eendian = isbe and 2 or 1 hdr.eversion = 1 hdr.type = f16(1) hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch]) if ctx.arch == "mips" or ctx.arch == "mipsel" then hdr.flags = f32(0x50001006) end hdr.version = f32(1) hdr.shofs = fofs(ffi.offsetof(o, "sect")) hdr.ehsize = f16(ffi.sizeof(hdr)) hdr.shentsize = f16(ffi.sizeof(o.sect[0])) hdr.shnum = f16(6) hdr.shstridx = f16(2) -- Fill in sections and symbols. local sofs, ofs = ffi.offsetof(o, "space"), 1 for i,name in ipairs{ ".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack", } do local sect = o.sect[i] sect.align = fofs(1) sect.name = f32(ofs) ffi.copy(o.space+ofs, name) ofs = ofs + #name+1 end o.sect[1].type = f32(2) -- .symtab o.sect[1].link = f32(3) o.sect[1].info = f32(1) o.sect[1].align = fofs(8) o.sect[1].ofs = fofs(ffi.offsetof(o, "sym")) o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0])) o.sect[1].size = fofs(ffi.sizeof(o.sym)) o.sym[1].name = f32(1) o.sym[1].sectidx = f16(4) o.sym[1].size = fofs(#s) o.sym[1].info = 17 o.sect[2].type = f32(3) -- .shstrtab o.sect[2].ofs = fofs(sofs) o.sect[2].size = fofs(ofs) o.sect[3].type = f32(3) -- .strtab o.sect[3].ofs = fofs(sofs + ofs) o.sect[3].size = fofs(#symname+2) ffi.copy(o.space+ofs+1, symname) ofs = ofs + #symname + 2 o.sect[4].type = f32(1) -- .rodata o.sect[4].flags = fofs(2) o.sect[4].ofs = fofs(sofs + ofs) o.sect[4].size = fofs(#s) o.sect[5].type = f32(1) -- .note.GNU-stack o.sect[5].ofs = fofs(sofs + ofs + #s) -- Write ELF object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) bcsave_tail(fp, output, s) end local function bcsave_peobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint16_t arch, nsects; uint32_t time, symtabofs, nsyms; uint16_t opthdrsz, flags; } PEheader; typedef struct { char name[8]; uint32_t vsize, vaddr, size, ofs, relocofs, lineofs; uint16_t nreloc, nline; uint32_t flags; } PEsection; typedef struct __attribute((packed)) { union { char name[8]; uint32_t nameref[2]; }; uint32_t value; int16_t sect; uint16_t type; uint8_t scl, naux; } PEsym; typedef struct __attribute((packed)) { uint32_t size; uint16_t nreloc, nline; uint32_t cksum; uint16_t assoc; uint8_t comdatsel, unused[3]; } PEsymaux; typedef struct { PEheader hdr; PEsection sect[2]; // Must be an even number of symbol structs. PEsym sym0; PEsymaux sym0aux; PEsym sym1; PEsymaux sym1aux; PEsym sym2; PEsym sym3; uint32_t strtabsize; uint8_t space[4096]; } PEobj; ]] local symname = LJBC_PREFIX..ctx.modname local is64 = false if ctx.arch == "x86" then symname = "_"..symname elseif ctx.arch == "x64" then is64 = true end local symexport = " /EXPORT:"..symname..",DATA " -- The file format is always little-endian. Swap if the host is big-endian. local function f32(x) return x end local f16 = f32 if ffi.abi("be") then f32 = bit.bswap function f16(x) return bit.rshift(bit.bswap(x), 16) end end -- Create PE object and fill in header. local o = ffi.new("PEobj") local hdr = o.hdr hdr.arch = f16(({ x86=0x14c, x64=0x8664, arm=0x1c0, ppc=0x1f2, mips=0x366, mipsel=0x366 })[ctx.arch]) hdr.nsects = f16(2) hdr.symtabofs = f32(ffi.offsetof(o, "sym0")) hdr.nsyms = f32(6) -- Fill in sections and symbols. o.sect[0].name = ".drectve" o.sect[0].size = f32(#symexport) o.sect[0].flags = f32(0x00100a00) o.sym0.sect = f16(1) o.sym0.scl = 3 o.sym0.name = ".drectve" o.sym0.naux = 1 o.sym0aux.size = f32(#symexport) o.sect[1].name = ".rdata" o.sect[1].size = f32(#s) o.sect[1].flags = f32(0x40300040) o.sym1.sect = f16(2) o.sym1.scl = 3 o.sym1.name = ".rdata" o.sym1.naux = 1 o.sym1aux.size = f32(#s) o.sym2.sect = f16(2) o.sym2.scl = 2 o.sym2.nameref[1] = f32(4) o.sym3.sect = f16(-1) o.sym3.scl = 2 o.sym3.value = f32(1) o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant. ffi.copy(o.space, symname) local ofs = #symname + 1 o.strtabsize = f32(ofs + 4) o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs) ffi.copy(o.space + ofs, symexport) ofs = ofs + #symexport o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs) -- Write PE object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) bcsave_tail(fp, output, s) end local function bcsave_machobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags; } mach_header; typedef struct { mach_header; uint32_t reserved; } mach_header_64; typedef struct { uint32_t cmd, cmdsize; char segname[16]; uint32_t vmaddr, vmsize, fileoff, filesize; uint32_t maxprot, initprot, nsects, flags; } mach_segment_command; typedef struct { uint32_t cmd, cmdsize; char segname[16]; uint64_t vmaddr, vmsize, fileoff, filesize; uint32_t maxprot, initprot, nsects, flags; } mach_segment_command_64; typedef struct { char sectname[16], segname[16]; uint32_t addr, size; uint32_t offset, align, reloff, nreloc, flags; uint32_t reserved1, reserved2; } mach_section; typedef struct { char sectname[16], segname[16]; uint64_t addr, size; uint32_t offset, align, reloff, nreloc, flags; uint32_t reserved1, reserved2, reserved3; } mach_section_64; typedef struct { uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize; } mach_symtab_command; typedef struct { int32_t strx; uint8_t type, sect; int16_t desc; uint32_t value; } mach_nlist; typedef struct { uint32_t strx; uint8_t type, sect; uint16_t desc; uint64_t value; } mach_nlist_64; typedef struct { uint32_t magic, nfat_arch; } mach_fat_header; typedef struct { uint32_t cputype, cpusubtype, offset, size, align; } mach_fat_arch; typedef struct { struct { mach_header hdr; mach_segment_command seg; mach_section sec; mach_symtab_command sym; } arch[1]; mach_nlist sym_entry; uint8_t space[4096]; } mach_obj; typedef struct { struct { mach_header_64 hdr; mach_segment_command_64 seg; mach_section_64 sec; mach_symtab_command sym; } arch[1]; mach_nlist_64 sym_entry; uint8_t space[4096]; } mach_obj_64; typedef struct { mach_fat_header fat; mach_fat_arch fat_arch[2]; struct { mach_header hdr; mach_segment_command seg; mach_section sec; mach_symtab_command sym; } arch[2]; mach_nlist sym_entry; uint8_t space[4096]; } mach_fat_obj; ]] local symname = '_'..LJBC_PREFIX..ctx.modname local isfat, is64, align, mobj = false, false, 4, "mach_obj" if ctx.arch == "x64" then is64, align, mobj = true, 8, "mach_obj_64" elseif ctx.arch == "arm" then isfat, mobj = true, "mach_fat_obj" elseif ctx.arch == "arm64" then is64, align, isfat, mobj = true, 8, true, "mach_fat_obj" else check(ctx.arch == "x86", "unsupported architecture for OSX") end local function aligned(v, a) return bit.band(v+a-1, -a) end local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE. -- Create Mach-O object and fill in header. local o = ffi.new(mobj) local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align) local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch] local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch] if isfat then o.fat.magic = be32(0xcafebabe) o.fat.nfat_arch = be32(#cpusubtype) end -- Fill in sections and symbols. for i=0,#cpusubtype-1 do local ofs = 0 if isfat then local a = o.fat_arch[i] a.cputype = be32(cputype[i+1]) a.cpusubtype = be32(cpusubtype[i+1]) -- Subsequent slices overlap each other to share data. ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0]) a.offset = be32(ofs) a.size = be32(mach_size-ofs+#s) end local a = o.arch[i] a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface a.hdr.cputype = cputype[i+1] a.hdr.cpusubtype = cpusubtype[i+1] a.hdr.filetype = 1 a.hdr.ncmds = 2 a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym) a.seg.cmd = is64 and 0x19 or 0x1 a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec) a.seg.vmsize = #s a.seg.fileoff = mach_size-ofs a.seg.filesize = #s a.seg.maxprot = 1 a.seg.initprot = 1 a.seg.nsects = 1 ffi.copy(a.sec.sectname, "__data") ffi.copy(a.sec.segname, "__DATA") a.sec.size = #s a.sec.offset = mach_size-ofs a.sym.cmd = 2 a.sym.cmdsize = ffi.sizeof(a.sym) a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs a.sym.nsyms = 1 a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs a.sym.strsize = aligned(#symname+2, align) end o.sym_entry.type = 0xf o.sym_entry.sect = 1 o.sym_entry.strx = 1 ffi.copy(o.space+1, symname) -- Write Macho-O object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, mach_size)) bcsave_tail(fp, output, s) end local function bcsave_obj(ctx, output, s) local ok, ffi = pcall(require, "ffi") check(ok, "FFI library required to write this file type") if ctx.os == "windows" then return bcsave_peobj(ctx, output, s, ffi) elseif ctx.os == "osx" then return bcsave_machobj(ctx, output, s, ffi) else return bcsave_elfobj(ctx, output, s, ffi) end end ------------------------------------------------------------------------------ local function bclist(input, output, lineinfo) local f = readfile(input) require("jit.bc").dump(f, savefile(output, "w"), true, lineinfo) end local function bcsave(ctx, input, output) local f = readfile(input) local s = string.dump(f, ctx.strip) local t = ctx.type if not t then t = detecttype(output) ctx.type = t end if t == "raw" then bcsave_raw(output, s) else if not ctx.modname then ctx.modname = detectmodname(input) end if t == "obj" then bcsave_obj(ctx, output, s) else bcsave_c(ctx, output, s) end end end local function docmd(...) local arg = {...} local n = 1 local list = false local lineinfo = false local ctx = { strip = true, arch = jit.arch, os = string.lower(jit.os), type = false, modname = false, } while n <= #arg do local a = arg[n] if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then table.remove(arg, n) if a == "--" then break end for m=2,#a do local opt = string.sub(a, m, m) if opt == "l" then list = true elseif opt == "L" then list = true lineinfo = true elseif opt == "s" then ctx.strip = true elseif opt == "g" then ctx.strip = false else if arg[n] == nil or m ~= #a then usage() end if opt == "e" then if n ~= 1 then usage() end arg[1] = check(loadstring(arg[1])) elseif opt == "n" then ctx.modname = checkmodname(table.remove(arg, n)) elseif opt == "t" then ctx.type = checkarg(table.remove(arg, n), map_type, "file type") elseif opt == "a" then ctx.arch = checkarg(table.remove(arg, n), map_arch, "architecture") elseif opt == "o" then ctx.os = checkarg(table.remove(arg, n), map_os, "OS name") else usage() end end end else n = n + 1 end end if list then if #arg == 0 or #arg > 2 then usage() end bclist(arg[1], arg[2] or "-", lineinfo) else if #arg ~= 2 then usage() end bcsave(ctx, arg[1], arg[2]) end end ------------------------------------------------------------------------------ -- Public module functions. return { start = docmd -- Process -b command line option. } ================================================ FILE: Assets/ToLua/Lua/jit/bcsave.lua.meta ================================================ fileFormatVersion: 2 guid: c57519f5e4f846c459de1f2eaa13da69 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_arm.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles most user-mode ARMv7 instructions -- NYI: Advanced SIMD and VFP instructions. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Opcode maps ------------------------------------------------------------------------------ local map_loadc = { shift = 8, mask = 15, [10] = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "vmovFmDN", "vstmFNdr", _ = { shift = 21, mask = 1, [0] = "vstrFdl", { shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", } }, }, { shift = 23, mask = 3, [0] = "vmovFDNm", { shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", }, _ = { shift = 21, mask = 1, [0] = "vldrFdl", "vldmdbFNdr", }, }, }, [11] = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "vmovGmDN", "vstmGNdr", _ = { shift = 21, mask = 1, [0] = "vstrGdl", { shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", } }, }, { shift = 23, mask = 3, [0] = "vmovGDNm", { shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", }, _ = { shift = 21, mask = 1, [0] = "vldrGdl", "vldmdbGNdr", }, }, }, _ = { shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc. }, } local map_vfps = { shift = 6, mask = 0x2c001, [0] = "vmlaF.dnm", "vmlsF.dnm", [0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm", [0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm", [0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm", [0x20000] = "vdivF.dnm", [0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm", [0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm", [0x2c000] = "vmovF.dY", [0x2c001] = { shift = 7, mask = 0x1e01, [0] = "vmovF.dm", "vabsF.dm", [0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm", [0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm", [0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d", [0x0e01] = "vcvtG.dF.m", [0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm", [0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm", [0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm", }, } local map_vfpd = { shift = 6, mask = 0x2c001, [0] = "vmlaG.dnm", "vmlsG.dnm", [0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm", [0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm", [0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm", [0x20000] = "vdivG.dnm", [0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm", [0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm", [0x2c000] = "vmovG.dY", [0x2c001] = { shift = 7, mask = 0x1e01, [0] = "vmovG.dm", "vabsG.dm", [0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm", [0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm", [0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d", [0x0e01] = "vcvtF.dG.m", [0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm", [0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m", [0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m", }, } local map_datac = { shift = 24, mask = 1, [0] = { shift = 4, mask = 1, [0] = { shift = 8, mask = 15, [10] = map_vfps, [11] = map_vfpd, -- NYI cdp, mcr, mrc. }, { shift = 8, mask = 15, [10] = { shift = 20, mask = 15, [0] = "vmovFnD", "vmovFDn", [14] = "vmsrD", [15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", }, }, }, }, "svcT", } local map_loadcu = { shift = 0, mask = 0, -- NYI unconditional CP load/store. } local map_datacu = { shift = 0, mask = 0, -- NYI unconditional CP data. } local map_simddata = { shift = 0, mask = 0, -- NYI SIMD data. } local map_simdload = { shift = 0, mask = 0, -- NYI SIMD load/store, preload. } local map_preload = { shift = 0, mask = 0, -- NYI preload. } local map_media = { shift = 20, mask = 31, [0] = false, { --01 shift = 5, mask = 7, [0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM", "sadd8DNM", false, false, "ssub8DNM", }, { --02 shift = 5, mask = 7, [0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM", "qadd8DNM", false, false, "qsub8DNM", }, { --03 shift = 5, mask = 7, [0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM", "shadd8DNM", false, false, "shsub8DNM", }, false, { --05 shift = 5, mask = 7, [0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM", "uadd8DNM", false, false, "usub8DNM", }, { --06 shift = 5, mask = 7, [0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM", "uqadd8DNM", false, false, "uqsub8DNM", }, { --07 shift = 5, mask = 7, [0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM", "uhadd8DNM", false, false, "uhsub8DNM", }, { --08 shift = 5, mask = 7, [0] = "pkhbtDNMU", false, "pkhtbDNMU", { shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", }, "pkhbtDNMU", "selDNM", "pkhtbDNMU", }, false, { --0a shift = 5, mask = 7, [0] = "ssatDxMu", "ssat16DxM", "ssatDxMu", { shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", }, "ssatDxMu", false, "ssatDxMu", }, { --0b shift = 5, mask = 7, [0] = "ssatDxMu", "revDM", "ssatDxMu", { shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", }, "ssatDxMu", "rev16DM", "ssatDxMu", }, { --0c shift = 5, mask = 7, [3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", }, }, false, { --0e shift = 5, mask = 7, [0] = "usatDwMu", "usat16DwM", "usatDwMu", { shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", }, "usatDwMu", false, "usatDwMu", }, { --0f shift = 5, mask = 7, [0] = "usatDwMu", "rbitDM", "usatDwMu", { shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", }, "usatDwMu", "revshDM", "usatDwMu", }, { --10 shift = 12, mask = 15, [15] = { shift = 5, mask = 7, "smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS", }, _ = { shift = 5, mask = 7, [0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD", }, }, false, false, false, { --14 shift = 5, mask = 7, [0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS", }, { --15 shift = 5, mask = 7, [0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", }, { shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", }, false, false, false, false, "smmlsNMSD", "smmlsrNMSD", }, false, false, { --18 shift = 5, mask = 7, [0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", }, }, false, { --1a shift = 5, mask = 3, [2] = "sbfxDMvw", }, { --1b shift = 5, mask = 3, [2] = "sbfxDMvw", }, { --1c shift = 5, mask = 3, [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, }, { --1d shift = 5, mask = 3, [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, }, { --1e shift = 5, mask = 3, [2] = "ubfxDMvw", }, { --1f shift = 5, mask = 3, [2] = "ubfxDMvw", }, } local map_load = { shift = 21, mask = 9, { shift = 20, mask = 5, [0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL", }, _ = { shift = 20, mask = 5, [0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL", } } local map_load1 = { shift = 4, mask = 1, [0] = map_load, map_media, } local map_loadm = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "stmdaNR", "stmNR", { shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR", }, { shift = 23, mask = 3, [0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", }, "ldmdbNR", "ldmibNR", }, } local map_data = { shift = 21, mask = 15, [0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs", "addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs", "tstNP", "teqNP", "cmpNP", "cmnNP", "orrDNPs", "movDPs", "bicDNPs", "mvnDPs", } local map_mul = { shift = 21, mask = 7, [0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS", "umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs", } local map_sync = { shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd. [0] = "swpDMN", false, false, false, "swpbDMN", false, false, false, "strexDMN", "ldrexDN", "strexdDN", "ldrexdDN", "strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN", } local map_mulh = { shift = 21, mask = 3, [0] = { shift = 5, mask = 3, [0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", }, { shift = 5, mask = 3, [0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", }, { shift = 5, mask = 3, [0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", }, { shift = 5, mask = 3, [0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", }, } local map_misc = { shift = 4, mask = 7, -- NYI: decode PSR bits of msr. [0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", }, { shift = 21, mask = 3, "bxM", false, "clzDM", }, { shift = 21, mask = 3, "bxjM", }, { shift = 21, mask = 3, "blxM", }, false, { shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", }, false, { shift = 21, mask = 3, "bkptK", }, } local map_datar = { shift = 4, mask = 9, [9] = { shift = 5, mask = 3, [0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, }, { shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", }, { shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", }, { shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", }, }, _ = { shift = 20, mask = 25, [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, }, _ = { shift = 0, mask = 0xffffffff, [bor(0xe1a00000)] = "nop", _ = map_data, } }, } local map_datai = { shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12. [16] = "movwDW", [20] = "movtDW", [18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", }, [22] = "msrNW", _ = map_data, } local map_branch = { shift = 24, mask = 1, [0] = "bB", "blB" } local map_condins = { [0] = map_datar, map_datai, map_load, map_load1, map_loadm, map_branch, map_loadc, map_datac } -- NYI: setend. local map_uncondins = { [0] = false, map_simddata, map_simdload, map_preload, false, "blxB", map_loadcu, map_datacu, } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", } local map_cond = { [0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al", } local map_shift = { [0] = "lsl", "lsr", "asr", "ror", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then extra = "\t; 0x"..tohex(ctx.rel) end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-5s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-5s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end -- Format operand 2 of load/store opcodes. local function fmtload(ctx, op, pos) local base = map_gpr[band(rshift(op, 16), 15)] local x, ofs local ext = (band(op, 0x04000000) == 0) if not ext and band(op, 0x02000000) == 0 then ofs = band(op, 4095) if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end ofs = "#"..ofs elseif ext and band(op, 0x00400000) ~= 0 then ofs = band(op, 15) + band(rshift(op, 4), 0xf0) if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end ofs = "#"..ofs else ofs = map_gpr[band(op, 15)] if ext or band(op, 0xfe0) == 0 then elseif band(op, 0xfe0) == 0x60 then ofs = format("%s, rrx", ofs) else local sh = band(rshift(op, 7), 31) if sh == 0 then sh = 32 end ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh) end if band(op, 0x00800000) == 0 then ofs = "-"..ofs end end if ofs == "#0" then x = format("[%s]", base) elseif band(op, 0x01000000) == 0 then x = format("[%s], %s", base, ofs) else x = format("[%s, %s]", base, ofs) end if band(op, 0x01200000) == 0x01200000 then x = x.."!" end return x end -- Format operand 2 of vector load/store opcodes. local function fmtvload(ctx, op, pos) local base = map_gpr[band(rshift(op, 16), 15)] local ofs = band(op, 255)*4 if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end if ofs == 0 then return format("[%s]", base) else return format("[%s, #%d]", base, ofs) end end local function fmtvr(op, vr, sh0, sh1) if vr == "s" then return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1)) else return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16)) end end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) local operands = {} local suffix = "" local last, name, pat local vr ctx.op = op ctx.rel = nil local cond = rshift(op, 28) local opat if cond == 15 then opat = map_uncondins[band(rshift(op, 25), 7)] else if cond ~= 14 then suffix = map_cond[cond] end opat = map_condins[band(rshift(op, 25), 7)] end while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end name, pat = match(opat, "^([a-z0-9]*)(.*)") if sub(pat, 1, 1) == "." then local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") suffix = suffix..s2 pat = p2 end for p in gmatch(pat, ".") do local x = nil if p == "D" then x = map_gpr[band(rshift(op, 12), 15)] elseif p == "N" then x = map_gpr[band(rshift(op, 16), 15)] elseif p == "S" then x = map_gpr[band(rshift(op, 8), 15)] elseif p == "M" then x = map_gpr[band(op, 15)] elseif p == "d" then x = fmtvr(op, vr, 12, 22) elseif p == "n" then x = fmtvr(op, vr, 16, 7) elseif p == "m" then x = fmtvr(op, vr, 0, 5) elseif p == "P" then if band(op, 0x02000000) ~= 0 then x = ror(band(op, 255), 2*band(rshift(op, 8), 15)) else x = map_gpr[band(op, 15)] if band(op, 0xff0) ~= 0 then operands[#operands+1] = x local s = map_shift[band(rshift(op, 5), 3)] local r = nil if band(op, 0xf90) == 0 then if s == "ror" then s = "rrx" else r = "#32" end elseif band(op, 0x10) == 0 then r = "#"..band(rshift(op, 7), 31) else r = map_gpr[band(rshift(op, 8), 15)] end if name == "mov" then name = s; x = r elseif r then x = format("%s %s", s, r) else x = s end end end elseif p == "L" then x = fmtload(ctx, op, pos) elseif p == "l" then x = fmtvload(ctx, op, pos) elseif p == "B" then local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6) if cond == 15 then addr = addr + band(rshift(op, 23), 2) end ctx.rel = addr x = "0x"..tohex(addr) elseif p == "F" then vr = "s" elseif p == "G" then vr = "d" elseif p == "." then suffix = suffix..(vr == "s" and ".f32" or ".f64") elseif p == "R" then if band(op, 0x00200000) ~= 0 and #operands == 1 then operands[1] = operands[1].."!" end local t = {} for i=0,15 do if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end end x = "{"..concat(t, ", ").."}" elseif p == "r" then if band(op, 0x00200000) ~= 0 and #operands == 2 then operands[1] = operands[1].."!" end local s = tonumber(sub(last, 2)) local n = band(op, 255) if vr == "d" then n = rshift(n, 1) end operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1) elseif p == "W" then x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000) elseif p == "T" then x = "#0x"..tohex(band(op, 0x00ffffff), 6) elseif p == "U" then x = band(rshift(op, 7), 31) if x == 0 then x = nil end elseif p == "u" then x = band(rshift(op, 7), 31) if band(op, 0x40) == 0 then if x == 0 then x = nil else x = "lsl #"..x end else if x == 0 then x = "asr #32" else x = "asr #"..x end end elseif p == "v" then x = band(rshift(op, 7), 31) elseif p == "w" then x = band(rshift(op, 16), 31) elseif p == "x" then x = band(rshift(op, 16), 31) + 1 elseif p == "X" then x = band(rshift(op, 16), 31) - last + 1 elseif p == "Y" then x = band(rshift(op, 12), 0xf0) + band(op, 0x0f) elseif p == "K" then x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4) elseif p == "s" then if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end else assert(false) end if x then last = x if type(x) == "number" then x = "#"..x end operands[#operands+1] = x end end return putop(ctx, name..suffix, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ctx.pos = ofs ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 16 then return map_gpr[r] end return "d"..(r-16) end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Assets/ToLua/Lua/jit/dis_arm.lua.meta ================================================ fileFormatVersion: 2 guid: 0ca08f899c4b9e9468fe93edcef60270 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_arm64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM64 disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h -- -- Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com. -- Sponsored by Cisco Systems, Inc. ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles most user-mode AArch64 instructions. -- NYI: Advanced SIMD and VFP instructions. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") local band, bor, bxor, tohex = bit.band, bit.bor, bit.bxor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift local ror = bit.ror ------------------------------------------------------------------------------ -- Opcode maps ------------------------------------------------------------------------------ local map_adr = { -- PC-relative addressing. shift = 31, mask = 1, [0] = "adrDBx", "adrpDBx" } local map_addsubi = { -- Add/subtract immediate. shift = 29, mask = 3, [0] = "add|movDNIg", "adds|cmnD0NIg", "subDNIg", "subs|cmpD0NIg", } local map_logi = { -- Logical immediate. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig" }, false -- unallocated }, { shift = 29, mask = 3, [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig" } } local map_movwi = { -- Move wide immediate. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg" }, false -- unallocated }, { shift = 29, mask = 3, [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg" }, } local map_bitf = { -- Bitfield. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12w", "bfm|bfi|bfxilDN13w", "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12w" } }, { shift = 22, mask = 1, { shift = 29, mask = 3, [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12x", "bfm|bfi|bfxilDN13x", "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12x" } } } local map_datai = { -- Data processing - immediate. shift = 23, mask = 7, [0] = map_adr, map_adr, map_addsubi, false, map_logi, map_movwi, map_bitf, { shift = 15, mask = 0x1c0c1, [0] = "extr|rorDNM4w", [0x10080] = "extr|rorDNM4x", [0x10081] = "extr|rorDNM4x" } } local map_logsr = { -- Logical, shifted register. shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 29, mask = 3, [0] = { shift = 21, mask = 7, [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg" }, { shift = 21, mask = 7, [0] ="orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg" }, { shift = 21, mask = 7, [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg" }, { shift = 21, mask = 7, [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg" } }, false -- unallocated }, { shift = 29, mask = 3, [0] = { shift = 21, mask = 7, [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg" }, { shift = 21, mask = 7, [0] = "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg" }, { shift = 21, mask = 7, [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg" }, { shift = 21, mask = 7, [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg" } } } local map_assh = { shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 29, mask = 3, [0] = { shift = 22, mask = 3, [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg" }, { shift = 22, mask = 3, [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMg" }, { shift = 22, mask = 3, [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg" }, { shift = 22, mask = 3, [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg" }, }, false -- unallocated }, { shift = 29, mask = 3, [0] = { shift = 22, mask = 3, [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg" }, { shift = 22, mask = 3, [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMg" }, { shift = 22, mask = 3, [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg" }, { shift = 22, mask = 3, [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg" } } } local map_addsubsh = { -- Add/subtract, shifted register. shift = 22, mask = 3, [0] = map_assh, map_assh, map_assh } local map_addsubex = { -- Add/subtract, extended register. shift = 22, mask = 3, [0] = { shift = 29, mask = 3, [0] = "addDNMXg", "adds|cmnD0NMXg", "subDNMXg", "subs|cmpD0NMzXg", } } local map_addsubc = { -- Add/subtract, with carry. shift = 10, mask = 63, [0] = { shift = 29, mask = 3, [0] = "adcDNMg", "adcsDNMg", "sbc|ngcDN0Mg", "sbcs|ngcsDN0Mg", } } local map_ccomp = { shift = 4, mask = 1, [0] = { shift = 10, mask = 3, [0] = { -- Conditional compare register. shift = 29, mask = 3, "ccmnNMVCg", false, "ccmpNMVCg", }, [2] = { -- Conditional compare immediate. shift = 29, mask = 3, "ccmnN5VCg", false, "ccmpN5VCg", } } } local map_csel = { -- Conditional select. shift = 11, mask = 1, [0] = { shift = 10, mask = 1, [0] = { shift = 29, mask = 3, [0] = "cselDNMzCg", false, "csinv|cinv|csetmDNMcg", false, }, { shift = 29, mask = 3, [0] = "csinc|cinc|csetDNMcg", false, "csneg|cnegDNMcg", false, } } } local map_data1s = { -- Data processing, 1 source. shift = 29, mask = 1, [0] = { shift = 31, mask = 1, [0] = { shift = 10, mask = 0x7ff, [0] = "rbitDNg", "rev16DNg", "revDNw", false, "clzDNg", "clsDNg" }, { shift = 10, mask = 0x7ff, [0] = "rbitDNg", "rev16DNg", "rev32DNx", "revDNx", "clzDNg", "clsDNg" } } } local map_data2s = { -- Data processing, 2 sources. shift = 29, mask = 1, [0] = { shift = 10, mask = 63, false, "udivDNMg", "sdivDNMg", false, false, false, false, "lslDNMg", "lsrDNMg", "asrDNMg", "rorDNMg" } } local map_data3s = { -- Data processing, 3 sources. shift = 29, mask = 7, [0] = { shift = 21, mask = 7, [0] = { shift = 15, mask = 1, [0] = "madd|mulDNMA0g", "msub|mnegDNMA0g" } }, false, false, false, { shift = 15, mask = 1, [0] = { shift = 21, mask = 7, [0] = "madd|mulDNMA0g", "smaddl|smullDxNMwA0x", "smulhDNMx", false, false, "umaddl|umullDxNMwA0x", "umulhDNMx" }, { shift = 21, mask = 7, [0] = "msub|mnegDNMA0g", "smsubl|smneglDxNMwA0x", false, false, false, "umsubl|umneglDxNMwA0x" } } } local map_datar = { -- Data processing, register. shift = 28, mask = 1, [0] = { shift = 24, mask = 1, [0] = map_logsr, { shift = 21, mask = 1, [0] = map_addsubsh, map_addsubex } }, { shift = 21, mask = 15, [0] = map_addsubc, false, map_ccomp, false, map_csel, false, { shift = 30, mask = 1, [0] = map_data2s, map_data1s }, false, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s } } local map_lrl = { -- Load register, literal. shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = "ldrDwB", "ldrDxB", "ldrswDxB" }, { shift = 30, mask = 3, [0] = "ldrDsB", "ldrDdB" } } local map_lsriind = { -- Load/store register, immediate pre/post-indexed. shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strbDwzL", "ldrbDwzL", "ldrsbDxzL", "ldrsbDwzL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strhDwzL", "ldrhDwzL", "ldrshDxzL", "ldrshDwzL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strDwzL", "ldrDwzL", "ldrswDxzL" }, { shift = 22, mask = 3, [0] = "strDszL", "ldrDszL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strDxzL", "ldrDxzL" }, { shift = 22, mask = 3, [0] = "strDdzL", "ldrDdzL" } } } local map_lsriro = { shift = 21, mask = 1, [0] = { -- Load/store register immediate. shift = 10, mask = 3, [0] = { -- Unscaled immediate. shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "sturbDwK", "ldurbDwK" }, { shift = 22, mask = 3, [0] = "sturhDwK", "ldurhDwK" }, { shift = 22, mask = 3, [0] = "sturDwK", "ldurDwK" }, { shift = 22, mask = 3, [0] = "sturDxK", "ldurDxK" } } }, map_lsriind, false, map_lsriind }, { -- Load/store register, register offset. shift = 10, mask = 3, [2] = { shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "strbDwO", "ldrbDwO", "ldrsbDxO", "ldrsbDwO" }, { shift = 22, mask = 3, [0] = "strhDwO", "ldrhDwO", "ldrshDxO", "ldrshDwO" }, { shift = 22, mask = 3, [0] = "strDwO", "ldrDwO", "ldrswDxO" }, { shift = 22, mask = 3, [0] = "strDxO", "ldrDxO" } }, { shift = 30, mask = 3, [2] = { shift = 22, mask = 3, [0] = "strDsO", "ldrDsO" }, [3] = { shift = 22, mask = 3, [0] = "strDdO", "ldrDdO" } } } } } local map_lsp = { -- Load/store register pair, offset. shift = 22, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = "stpDzAzwP", "stpDzAzsP", }, { shift = 26, mask = 1, "stpDzAzdP" }, { shift = 26, mask = 1, [0] = "stpDzAzxP" } }, { shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = "ldpDzAzwP", "ldpDzAzsP", }, { shift = 26, mask = 1, [0] = "ldpswDAxP", "ldpDzAzdP" }, { shift = 26, mask = 1, [0] = "ldpDzAzxP" } } } local map_ls = { -- Loads and stores. shift = 24, mask = 0x31, [0x10] = map_lrl, [0x30] = map_lsriro, [0x20] = { shift = 23, mask = 3, map_lsp, map_lsp, map_lsp }, [0x21] = { shift = 23, mask = 3, map_lsp, map_lsp, map_lsp }, [0x31] = { shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "strbDwzU", "ldrbDwzU" }, { shift = 22, mask = 3, [0] = "strhDwzU", "ldrhDwzU" }, { shift = 22, mask = 3, [0] = "strDwzU", "ldrDwzU" }, { shift = 22, mask = 3, [0] = "strDxzU", "ldrDxzU" } }, { shift = 30, mask = 3, [2] = { shift = 22, mask = 3, [0] = "strDszU", "ldrDszU" }, [3] = { shift = 22, mask = 3, [0] = "strDdzU", "ldrDdzU" } } }, } local map_datafp = { -- Data processing, SIMD and FP. shift = 28, mask = 7, { -- 001 shift = 24, mask = 1, [0] = { shift = 21, mask = 1, { shift = 10, mask = 3, [0] = { shift = 12, mask = 1, [0] = { shift = 13, mask = 1, [0] = { shift = 14, mask = 1, [0] = { shift = 15, mask = 1, [0] = { -- FP/int conversion. shift = 31, mask = 1, [0] = { shift = 16, mask = 0xff, [0x20] = "fcvtnsDwNs", [0x21] = "fcvtnuDwNs", [0x22] = "scvtfDsNw", [0x23] = "ucvtfDsNw", [0x24] = "fcvtasDwNs", [0x25] = "fcvtauDwNs", [0x26] = "fmovDwNs", [0x27] = "fmovDsNw", [0x28] = "fcvtpsDwNs", [0x29] = "fcvtpuDwNs", [0x30] = "fcvtmsDwNs", [0x31] = "fcvtmuDwNs", [0x38] = "fcvtzsDwNs", [0x39] = "fcvtzuDwNs", [0x60] = "fcvtnsDwNd", [0x61] = "fcvtnuDwNd", [0x62] = "scvtfDdNw", [0x63] = "ucvtfDdNw", [0x64] = "fcvtasDwNd", [0x65] = "fcvtauDwNd", [0x68] = "fcvtpsDwNd", [0x69] = "fcvtpuDwNd", [0x70] = "fcvtmsDwNd", [0x71] = "fcvtmuDwNd", [0x78] = "fcvtzsDwNd", [0x79] = "fcvtzuDwNd" }, { shift = 16, mask = 0xff, [0x20] = "fcvtnsDxNs", [0x21] = "fcvtnuDxNs", [0x22] = "scvtfDsNx", [0x23] = "ucvtfDsNx", [0x24] = "fcvtasDxNs", [0x25] = "fcvtauDxNs", [0x28] = "fcvtpsDxNs", [0x29] = "fcvtpuDxNs", [0x30] = "fcvtmsDxNs", [0x31] = "fcvtmuDxNs", [0x38] = "fcvtzsDxNs", [0x39] = "fcvtzuDxNs", [0x60] = "fcvtnsDxNd", [0x61] = "fcvtnuDxNd", [0x62] = "scvtfDdNx", [0x63] = "ucvtfDdNx", [0x64] = "fcvtasDxNd", [0x65] = "fcvtauDxNd", [0x66] = "fmovDxNd", [0x67] = "fmovDdNx", [0x68] = "fcvtpsDxNd", [0x69] = "fcvtpuDxNd", [0x70] = "fcvtmsDxNd", [0x71] = "fcvtmuDxNd", [0x78] = "fcvtzsDxNd", [0x79] = "fcvtzuDxNd" } } }, { -- FP data-processing, 1 source. shift = 31, mask = 1, [0] = { shift = 22, mask = 3, [0] = { shift = 15, mask = 63, [0] = "fmovDNf", "fabsDNf", "fnegDNf", "fsqrtDNf", false, "fcvtDdNs", false, false, "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf", "frintaDNf", false, "frintxDNf", "frintiDNf", }, { shift = 15, mask = 63, [0] = "fmovDNf", "fabsDNf", "fnegDNf", "fsqrtDNf", "fcvtDsNd", false, false, false, "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf", "frintaDNf", false, "frintxDNf", "frintiDNf", } } } }, { -- FP compare. shift = 31, mask = 1, [0] = { shift = 14, mask = 3, [0] = { shift = 23, mask = 1, [0] = { shift = 0, mask = 31, [0] = "fcmpNMf", [8] = "fcmpNZf", [16] = "fcmpeNMf", [24] = "fcmpeNZf", } } } } }, { -- FP immediate. shift = 31, mask = 1, [0] = { shift = 5, mask = 31, [0] = { shift = 23, mask = 1, [0] = "fmovDFf" } } } }, { -- FP conditional compare. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = { shift = 4, mask = 1, [0] = "fccmpNMVCf", "fccmpeNMVCf" } } }, { -- FP data-processing, 2 sources. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = { shift = 12, mask = 15, [0] = "fmulDNMf", "fdivDNMf", "faddDNMf", "fsubDNMf", "fmaxDNMf", "fminDNMf", "fmaxnmDNMf", "fminnmDNMf", "fnmulDNMf" } } }, { -- FP conditional select. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = "fcselDNMCf" } } } }, { -- FP data-processing, 3 sources. shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 21, mask = 5, [0] = "fmaddDNMAf", "fnmaddDNMAf" }, { shift = 21, mask = 5, [0] = "fmsubDNMAf", "fnmsubDNMAf" } } } } } local map_br = { -- Branches, exception generating and system instructions. shift = 29, mask = 7, [0] = "bB", { -- Compare & branch, immediate. shift = 24, mask = 3, [0] = "cbzDBg", "cbnzDBg", "tbzDTBw", "tbnzDTBw" }, { -- Conditional branch, immediate. shift = 24, mask = 3, [0] = { shift = 4, mask = 1, [0] = { shift = 0, mask = 15, [0] = "beqB", "bneB", "bhsB", "bloB", "bmiB", "bplB", "bvsB", "bvcB", "bhiB", "blsB", "bgeB", "bltB", "bgtB", "bleB", "balB" } } }, false, "blB", { -- Compare & branch, immediate. shift = 24, mask = 3, [0] = "cbzDBg", "cbnzDBg", "tbzDTBx", "tbnzDTBx" }, { shift = 24, mask = 3, [0] = { -- Exception generation. shift = 0, mask = 0xe0001f, [0x200000] = "brkW" }, { -- System instructions. shift = 0, mask = 0x3fffff, [0x03201f] = "nop" }, { -- Unconditional branch, register. shift = 0, mask = 0xfffc1f, [0x1f0000] = "brNx", [0x3f0000] = "blrNx", [0x5f0000] = "retNx" }, } } local map_init = { shift = 25, mask = 15, [0] = false, false, false, false, map_ls, map_datar, map_ls, map_datafp, map_datai, map_datai, map_br, map_br, map_ls, map_datar, map_ls, map_datafp } ------------------------------------------------------------------------------ local map_regs = { x = {}, w = {}, d = {}, s = {} } for i=0,30 do map_regs.x[i] = "x"..i map_regs.w[i] = "w"..i map_regs.d[i] = "d"..i map_regs.s[i] = "s"..i end map_regs.x[31] = "sp" map_regs.w[31] = "wsp" map_regs.d[31] = "d31" map_regs.s[31] = "s31" local map_cond = { [0] = "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al", } local map_shift = { [0] = "lsl", "lsr", "asr", } local map_extend = { [0] = "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-5s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-5s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end local function match_reg(p, pat, regnum) return map_regs[match(pat, p.."%w-([xwds])")][regnum] end local function fmt_hex32(x) if x < 0 then return tohex(x) else return format("%x", x) end end local imm13_rep = { 0x55555555, 0x11111111, 0x01010101, 0x00010001, 0x00000001 } local function decode_imm13(op) local imms = band(rshift(op, 10), 63) local immr = band(rshift(op, 16), 63) if band(op, 0x00400000) == 0 then local len = 5 if imms >= 56 then if imms >= 60 then len = 1 else len = 2 end elseif imms >= 48 then len = 3 elseif imms >= 32 then len = 4 end local l = lshift(1, len)-1 local s = band(imms, l) local r = band(immr, l) local imm = ror(rshift(-1, 31-s), r) if len ~= 5 then imm = band(imm, lshift(1, l)-1) + rshift(imm, 31-l) end imm = imm * imm13_rep[len] local ix = fmt_hex32(imm) if rshift(op, 31) ~= 0 then return ix..tohex(imm) else return ix end else local lo, hi = -1, 0 if imms < 32 then lo = rshift(-1, 31-imms) else hi = rshift(-1, 63-imms) end if immr ~= 0 then lo, hi = ror(lo, immr), ror(hi, immr) local x = immr == 32 and 0 or band(bxor(lo, hi), lshift(-1, 32-immr)) lo, hi = bxor(lo, x), bxor(hi, x) if immr >= 32 then lo, hi = hi, lo end end if hi ~= 0 then return fmt_hex32(hi)..tohex(lo) else return fmt_hex32(lo) end end end local function parse_immpc(op, name) if name == "b" or name == "bl" then return arshift(lshift(op, 6), 4) elseif name == "adr" or name == "adrp" then local immlo = band(rshift(op, 29), 3) local immhi = lshift(arshift(lshift(op, 8), 13), 2) return bor(immhi, immlo) elseif name == "tbz" or name == "tbnz" then return lshift(arshift(lshift(op, 13), 18), 2) else return lshift(arshift(lshift(op, 8), 13), 2) end end local function parse_fpimm8(op) local sign = band(op, 0x100000) == 0 and 1 or -1 local exp = bxor(rshift(arshift(lshift(op, 12), 5), 24), 0x80) - 131 local frac = 16+band(rshift(op, 13), 15) return sign * frac * 2^exp end local function prefer_bfx(sf, uns, imms, immr) if imms < immr or imms == 31 or imms == 63 then return false end if immr == 0 then if sf == 0 and (imms == 7 or imms == 15) then return false end if sf ~= 0 and uns == 0 and (imms == 7 or imms == 15 or imms == 31) then return false end end return true end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) local operands = {} local suffix = "" local last, name, pat local map_reg ctx.op = op ctx.rel = nil last = nil local opat opat = map_init[band(rshift(op, 25), 15)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end name, pat = match(opat, "^([a-z0-9]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") if altname then pat = pat2 end if sub(pat, 1, 1) == "." then local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") suffix = suffix..s2 pat = p2 end local rt = match(pat, "[gf]") if rt then if rt == "g" then map_reg = band(op, 0x80000000) ~= 0 and map_regs.x or map_regs.w else map_reg = band(op, 0x400000) ~= 0 and map_regs.d or map_regs.s end end local second0, immr for p in gmatch(pat, ".") do local x = nil if p == "D" then local regnum = band(op, 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "N" then local regnum = band(rshift(op, 5), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "M" then local regnum = band(rshift(op, 16), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "A" then local regnum = band(rshift(op, 10), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "B" then local addr = ctx.addr + pos + parse_immpc(op, name) ctx.rel = addr x = "0x"..tohex(addr) elseif p == "T" then x = bor(band(rshift(op, 26), 32), band(rshift(op, 19), 31)) elseif p == "V" then x = band(op, 15) elseif p == "C" then x = map_cond[band(rshift(op, 12), 15)] elseif p == "c" then local rn = band(rshift(op, 5), 31) local rm = band(rshift(op, 16), 31) local cond = band(rshift(op, 12), 15) local invc = bxor(cond, 1) x = map_cond[cond] if altname and cond ~= 14 and cond ~= 15 then local a1, a2 = match(altname, "([^|]*)|(.*)") if rn == rm then local n = #operands operands[n] = nil x = map_cond[invc] if rn ~= 31 then if a1 then name = a1 else name = altname end else operands[n-1] = nil name = a2 end end end elseif p == "W" then x = band(rshift(op, 5), 0xffff) elseif p == "Y" then x = band(rshift(op, 5), 0xffff) local hw = band(rshift(op, 21), 3) if altname and (hw == 0 or x ~= 0) then name = altname end elseif p == "L" then local rn = map_regs.x[band(rshift(op, 5), 31)] local imm9 = arshift(lshift(op, 11), 23) if band(op, 0x800) ~= 0 then x = "["..rn..", #"..imm9.."]!" else x = "["..rn.."], #"..imm9 end elseif p == "U" then local rn = map_regs.x[band(rshift(op, 5), 31)] local sz = band(rshift(op, 30), 3) local imm12 = lshift(arshift(lshift(op, 10), 20), sz) if imm12 ~= 0 then x = "["..rn..", #"..imm12.."]" else x = "["..rn.."]" end elseif p == "K" then local rn = map_regs.x[band(rshift(op, 5), 31)] local imm9 = arshift(lshift(op, 11), 23) if imm9 ~= 0 then x = "["..rn..", #"..imm9.."]" else x = "["..rn.."]" end elseif p == "O" then local rn, rm = map_regs.x[band(rshift(op, 5), 31)] local m = band(rshift(op, 13), 1) if m == 0 then rm = map_regs.w[band(rshift(op, 16), 31)] else rm = map_regs.x[band(rshift(op, 16), 31)] end x = "["..rn..", "..rm local opt = band(rshift(op, 13), 7) local s = band(rshift(op, 12), 1) local sz = band(rshift(op, 30), 3) -- extension to be applied if opt == 3 then if s == 0 then x = x.."]" else x = x..", lsl #"..sz.."]" end elseif opt == 2 or opt == 6 or opt == 7 then if s == 0 then x = x..", "..map_extend[opt].."]" else x = x..", "..map_extend[opt].." #"..sz.."]" end else x = x.."]" end elseif p == "P" then local opcv, sh = rshift(op, 26), 2 if opcv >= 0x2a then sh = 4 elseif opcv >= 0x1b then sh = 3 end local imm7 = lshift(arshift(lshift(op, 10), 25), sh) local rn = map_regs.x[band(rshift(op, 5), 31)] local ind = band(rshift(op, 23), 3) if ind == 1 then x = "["..rn.."], #"..imm7 elseif ind == 2 then if imm7 == 0 then x = "["..rn.."]" else x = "["..rn..", #"..imm7.."]" end elseif ind == 3 then x = "["..rn..", #"..imm7.."]!" end elseif p == "I" then local shf = band(rshift(op, 22), 3) local imm12 = band(rshift(op, 10), 0x0fff) local rn, rd = band(rshift(op, 5), 31), band(op, 31) if altname == "mov" and shf == 0 and imm12 == 0 and (rn == 31 or rd == 31) then name = altname x = nil elseif shf == 0 then x = imm12 elseif shf == 1 then x = imm12..", lsl #12" end elseif p == "i" then x = "#0x"..decode_imm13(op) elseif p == "1" then immr = band(rshift(op, 16), 63) x = immr elseif p == "2" then x = band(rshift(op, 10), 63) if altname then local a1, a2, a3, a4, a5, a6 = match(altname, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|(.*)") local sf = band(rshift(op, 26), 32) local uns = band(rshift(op, 30), 1) if prefer_bfx(sf, uns, x, immr) then name = a2 x = x - immr + 1 elseif immr == 0 and x == 7 then local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] name = a6 x = nil elseif immr == 0 and x == 15 then local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] name = a5 x = nil elseif x == 31 or x == 63 then if x == 31 and immr == 0 and name == "sbfm" then name = a4 local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] else name = a3 end x = nil elseif band(x, 31) ~= 31 and immr == x+1 and name == "ubfm" then name = a4 last = "#"..(sf+32 - immr) operands[#operands] = last x = nil elseif x < immr then name = a1 last = "#"..(sf+32 - immr) operands[#operands] = last x = x + 1 end end elseif p == "3" then x = band(rshift(op, 10), 63) if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if x < immr then name = a1 local sf = band(rshift(op, 26), 32) last = "#"..(sf+32 - immr) operands[#operands] = last x = x + 1 elseif x >= immr then name = a2 x = x - immr + 1 end end elseif p == "4" then x = band(rshift(op, 10), 63) local rn = band(rshift(op, 5), 31) local rm = band(rshift(op, 16), 31) if altname and rn == rm then local n = #operands operands[n] = nil last = operands[n-1] name = altname end elseif p == "5" then x = band(rshift(op, 16), 31) elseif p == "S" then x = band(rshift(op, 10), 63) if x == 0 then x = nil else x = map_shift[band(rshift(op, 22), 3)].." #"..x end elseif p == "X" then local opt = band(rshift(op, 13), 7) -- Width specifier . if opt ~= 3 and opt ~= 7 then last = map_regs.w[band(rshift(op, 16), 31)] operands[#operands] = last end x = band(rshift(op, 10), 7) -- Extension. if opt == 2 + band(rshift(op, 31), 1) and band(rshift(op, second0 and 5 or 0), 31) == 31 then if x == 0 then x = nil else x = "lsl #"..x end else if x == 0 then x = map_extend[band(rshift(op, 13), 7)] else x = map_extend[band(rshift(op, 13), 7)].." #"..x end end elseif p == "R" then x = band(rshift(op,21), 3) if x == 0 then x = nil else x = "lsl #"..x*16 end elseif p == "z" then local n = #operands if operands[n] == "sp" then operands[n] = "xzr" elseif operands[n] == "wsp" then operands[n] = "wzr" end elseif p == "Z" then x = 0 elseif p == "F" then x = parse_fpimm8(op) elseif p == "g" or p == "f" or p == "x" or p == "w" or p == "d" or p == "s" then -- These are handled in D/N/M/A. elseif p == "0" then if last == "sp" or last == "wsp" then local n = #operands operands[n] = nil last = operands[n-1] if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if not a1 then name = altname elseif second0 then name, altname = a2, a1 else name, altname = a1, a2 end end end second0 = true else assert(false) end if x then last = x if type(x) == "number" then x = "#"..x end operands[#operands+1] = x end end return putop(ctx, name..suffix, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ctx.pos = ofs ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_regs.x[r] end return map_regs.d[r-32] end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Assets/ToLua/Lua/jit/dis_arm64.lua.meta ================================================ fileFormatVersion: 2 guid: b4d4c9abbcac24849b38a339a3bf4529 timeCreated: 1494052836 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_arm64be.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM64BE disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- ARM64 instructions are always little-endian. So just forward to the -- common ARM64 disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ return require((string.match(..., ".*%.") or "").."dis_arm64") ================================================ FILE: Assets/ToLua/Lua/jit/dis_arm64be.lua.meta ================================================ fileFormatVersion: 2 guid: 9743f232842733e4c9e3b478b8adbffd timeCreated: 1494052836 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_mips.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles all standard MIPS32R1/R2 instructions. -- Default mode is big-endian, but see: dis_mipsel.lua ------------------------------------------------------------------------------ local type = type local byte, format = string.byte, string.format local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Primary and extended opcode maps ------------------------------------------------------------------------------ local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", } local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", } local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", } local map_special = { shift = 0, mask = 63, [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" }, map_movci, map_srl, "sraDTA", "sllvDTS", false, map_srlv, "sravDTS", "jrS", "jalrD1S", "movzDST", "movnDST", "syscallY", "breakY", false, "sync", "mfhiD", "mthiS", "mfloD", "mtloS", "dsllvDST", false, "dsrlvDST", "dsravDST", "multST", "multuST", "divST", "divuST", "dmultST", "dmultuST", "ddivST", "ddivuST", "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", "andDST", "or|moveDST0", "xorDST", "nor|notDST0", false, false, "sltDST", "sltuDST", "daddDST", "dadduDST", "dsubDST", "dsubuDST", "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", "teqSTZ", false, "tneSTZ", false, "dsllDTA", false, "dsrlDTA", "dsraDTA", "dsll32DTA", false, "dsrl32DTA", "dsra32DTA", } local map_special2 = { shift = 0, mask = 63, [0] = "maddST", "madduST", "mulDST", false, "msubST", "msubuST", [32] = "clzDS", [33] = "cloDS", [63] = "sdbbpY", } local map_bshfl = { shift = 6, mask = 31, [2] = "wsbhDT", [16] = "sebDT", [24] = "sehDT", } local map_dbshfl = { shift = 6, mask = 31, [2] = "dsbhDT", [5] = "dshdDT", } local map_special3 = { shift = 0, mask = 63, [0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK", [4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL", [32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD", } local map_regimm = { shift = 16, mask = 31, [0] = "bltzSB", "bgezSB", "bltzlSB", "bgezlSB", false, false, false, false, "tgeiSI", "tgeiuSI", "tltiSI", "tltiuSI", "teqiSI", false, "tneiSI", false, "bltzalSB", "bgezalSB", "bltzallSB", "bgezallSB", false, false, false, false, false, false, false, false, false, false, false, "synciSO", } local map_cop0 = { shift = 25, mask = 1, [0] = { shift = 21, mask = 15, [0] = "mfc0TDW", [4] = "mtc0TDW", [10] = "rdpgprDT", [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", }, [14] = "wrpgprDT", }, { shift = 0, mask = 63, [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp", [24] = "eret", [31] = "deret", [32] = "wait", }, } local map_cop1s = { shift = 0, mask = 63, [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH", "sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG", "round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG", "round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG", false, { shift = 16, mask = 1, [0] = "movf.sFGC", "movt.sFGC" }, "movz.sFGT", "movn.sFGT", false, "recip.sFG", "rsqrt.sFG", false, false, false, false, false, false, false, false, false, false, "cvt.d.sFG", false, false, "cvt.w.sFG", "cvt.l.sFG", "cvt.ps.sFGH", false, false, false, false, false, false, false, false, false, "c.f.sVGH", "c.un.sVGH", "c.eq.sVGH", "c.ueq.sVGH", "c.olt.sVGH", "c.ult.sVGH", "c.ole.sVGH", "c.ule.sVGH", "c.sf.sVGH", "c.ngle.sVGH", "c.seq.sVGH", "c.ngl.sVGH", "c.lt.sVGH", "c.nge.sVGH", "c.le.sVGH", "c.ngt.sVGH", } local map_cop1d = { shift = 0, mask = 63, [0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH", "sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG", "round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG", "round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG", false, { shift = 16, mask = 1, [0] = "movf.dFGC", "movt.dFGC" }, "movz.dFGT", "movn.dFGT", false, "recip.dFG", "rsqrt.dFG", false, false, false, false, false, false, false, false, false, "cvt.s.dFG", false, false, false, "cvt.w.dFG", "cvt.l.dFG", false, false, false, false, false, false, false, false, false, false, "c.f.dVGH", "c.un.dVGH", "c.eq.dVGH", "c.ueq.dVGH", "c.olt.dVGH", "c.ult.dVGH", "c.ole.dVGH", "c.ule.dVGH", "c.df.dVGH", "c.ngle.dVGH", "c.deq.dVGH", "c.ngl.dVGH", "c.lt.dVGH", "c.nge.dVGH", "c.le.dVGH", "c.ngt.dVGH", } local map_cop1ps = { shift = 0, mask = 63, [0] = "add.psFGH", "sub.psFGH", "mul.psFGH", false, false, "abs.psFG", "mov.psFG", "neg.psFG", false, false, false, false, false, false, false, false, false, { shift = 16, mask = 1, [0] = "movf.psFGC", "movt.psFGC" }, "movz.psFGT", "movn.psFGT", false, false, false, false, false, false, false, false, false, false, false, false, "cvt.s.puFG", false, false, false, false, false, false, false, "cvt.s.plFG", false, false, false, "pll.psFGH", "plu.psFGH", "pul.psFGH", "puu.psFGH", "c.f.psVGH", "c.un.psVGH", "c.eq.psVGH", "c.ueq.psVGH", "c.olt.psVGH", "c.ult.psVGH", "c.ole.psVGH", "c.ule.psVGH", "c.psf.psVGH", "c.ngle.psVGH", "c.pseq.psVGH", "c.ngl.psVGH", "c.lt.psVGH", "c.nge.psVGH", "c.le.psVGH", "c.ngt.psVGH", } local map_cop1w = { shift = 0, mask = 63, [32] = "cvt.s.wFG", [33] = "cvt.d.wFG", } local map_cop1l = { shift = 0, mask = 63, [32] = "cvt.s.lFG", [33] = "cvt.d.lFG", } local map_cop1bc = { shift = 16, mask = 3, [0] = "bc1fCB", "bc1tCB", "bc1flCB", "bc1tlCB", } local map_cop1 = { shift = 21, mask = 31, [0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG", "mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG", map_cop1bc, false, false, false, false, false, false, false, map_cop1s, map_cop1d, false, false, map_cop1w, map_cop1l, map_cop1ps, } local map_cop1x = { shift = 0, mask = 63, [0] = "lwxc1FSX", "ldxc1FSX", false, false, false, "luxc1FSX", false, false, "swxc1FSX", "sdxc1FSX", false, false, false, "suxc1FSX", false, "prefxMSX", false, false, false, false, false, false, false, false, false, false, false, false, false, false, "alnv.psFGHS", false, "madd.sFRGH", "madd.dFRGH", false, false, false, false, "madd.psFRGH", false, "msub.sFRGH", "msub.dFRGH", false, false, false, false, "msub.psFRGH", false, "nmadd.sFRGH", "nmadd.dFRGH", false, false, false, false, "nmadd.psFRGH", false, "nmsub.sFRGH", "nmsub.dFRGH", false, false, false, false, "nmsub.psFRGH", false, } local map_pri = { [0] = map_special, map_regimm, "jJ", "jalJ", "beq|beqz|bST00B", "bne|bnezST0B", "blezSB", "bgtzSB", "addiTSI", "addiu|liTS0I", "sltiTSI", "sltiuTSI", "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU", map_cop0, map_cop1, false, map_cop1x, "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB", "daddiTSI", "daddiuTSI", false, false, map_special2, "jalxJ", false, map_special3, "lbTSO", "lhTSO", "lwlTSO", "lwTSO", "lbuTSO", "lhuTSO", "lwrTSO", false, "sbTSO", "shTSO", "swlTSO", "swTSO", false, false, "swrTSO", "cacheNSO", "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO", false, "ldc1HSO", "ldc2TSO", "ldTSO", "scTSO", "swc1HSO", "swc2TSO", false, false, "sdc1HSO", "sdc2TSO", "sdTSO", } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "sp", "r30", "ra", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-7s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-7s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end local function get_be(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) return bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) end local function get_le(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) end -- Disassemble a single instruction. local function disass_ins(ctx) local op = ctx:get() local operands = {} local last = nil ctx.op = op ctx.rel = nil local opat = map_pri[rshift(op, 26)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") if altname then pat = pat2 end for p in gmatch(pat, ".") do local x = nil if p == "S" then x = map_gpr[band(rshift(op, 21), 31)] elseif p == "T" then x = map_gpr[band(rshift(op, 16), 31)] elseif p == "D" then x = map_gpr[band(rshift(op, 11), 31)] elseif p == "F" then x = "f"..band(rshift(op, 6), 31) elseif p == "G" then x = "f"..band(rshift(op, 11), 31) elseif p == "H" then x = "f"..band(rshift(op, 16), 31) elseif p == "R" then x = "f"..band(rshift(op, 21), 31) elseif p == "A" then x = band(rshift(op, 6), 31) elseif p == "E" then x = band(rshift(op, 6), 31) + 32 elseif p == "M" then x = band(rshift(op, 11), 31) elseif p == "N" then x = band(rshift(op, 16), 31) elseif p == "C" then x = band(rshift(op, 18), 7) if x == 0 then x = nil end elseif p == "K" then x = band(rshift(op, 11), 31) + 1 elseif p == "P" then x = band(rshift(op, 11), 31) + 33 elseif p == "L" then x = band(rshift(op, 11), 31) - last + 1 elseif p == "Q" then x = band(rshift(op, 11), 31) - last + 33 elseif p == "I" then x = arshift(lshift(op, 16), 16) elseif p == "U" then x = band(op, 0xffff) elseif p == "O" then local disp = arshift(lshift(op, 16), 16) operands[#operands] = format("%d(%s)", disp, last) elseif p == "X" then local index = map_gpr[band(rshift(op, 16), 31)] operands[#operands] = format("%s(%s)", index, last) elseif p == "B" then x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4 ctx.rel = x x = format("0x%08x", x) elseif p == "J" then local a = ctx.addr + ctx.pos x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4 ctx.rel = x x = format("0x%08x", x) elseif p == "V" then x = band(rshift(op, 8), 7) if x == 0 then x = nil end elseif p == "W" then x = band(op, 7) if x == 0 then x = nil end elseif p == "Y" then x = band(rshift(op, 6), 0x000fffff) if x == 0 then x = nil end elseif p == "Z" then x = band(rshift(op, 6), 1023) if x == 0 then x = nil end elseif p == "0" then if last == "r0" or last == 0 then local n = #operands operands[n] = nil last = operands[n-1] if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if a1 then name, altname = a1, a2 else name = altname end end end elseif p == "1" then if last == "ra" then operands[#operands] = nil end else assert(false) end if x then operands[#operands+1] = x; last = x end end return putop(ctx, name, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code stop = stop - stop % 4 ctx.pos = ofs - ofs % 4 ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 ctx.get = get_be return ctx end local function create_el(code, addr, out) local ctx = create(code, addr, out) ctx.get = get_le return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end local function disass_el(code, addr, out) create_el(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_gpr[r] end return "f"..(r-32) end -- Public module functions. return { create = create, create_el = create_el, disass = disass, disass_el = disass_el, regname = regname } ================================================ FILE: Assets/ToLua/Lua/jit/dis_mips.lua.meta ================================================ fileFormatVersion: 2 guid: 24d7d1c35dd3f7b4e8b37409571d4a8d timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_mips64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS64 disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the big-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create, disass = dis_mips.disass, regname = dis_mips.regname } ================================================ FILE: Assets/ToLua/Lua/jit/dis_mips64.lua.meta ================================================ fileFormatVersion: 2 guid: 45cd531eacd4e694585cb017ffc7df14 timeCreated: 1494052836 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_mips64el.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS64EL disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the little-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create_el, disass = dis_mips.disass_el, regname = dis_mips.regname } ================================================ FILE: Assets/ToLua/Lua/jit/dis_mips64el.lua.meta ================================================ fileFormatVersion: 2 guid: c933838018073f44d8b9cb738c3ef6f8 timeCreated: 1494052836 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_mipsel.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPSEL disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the little-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create_el, disass = dis_mips.disass_el, regname = dis_mips.regname } ================================================ FILE: Assets/ToLua/Lua/jit/dis_mipsel.lua.meta ================================================ fileFormatVersion: 2 guid: 7b8e829ec84bb8e4f8b56474c9812d02 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_ppc.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT PPC disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles all common, non-privileged 32/64 bit PowerPC instructions -- plus the e500 SPE instructions and some Cell/Xenon extensions. -- -- NYI: VMX, VMX128 ------------------------------------------------------------------------------ local type = type local byte, format = string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Primary and extended opcode maps ------------------------------------------------------------------------------ local map_crops = { shift = 1, mask = 1023, [0] = "mcrfXX", [33] = "crnor|crnotCCC=", [129] = "crandcCCC", [193] = "crxor|crclrCCC%", [225] = "crnandCCC", [257] = "crandCCC", [289] = "creqv|crsetCCC%", [417] = "crorcCCC", [449] = "cror|crmoveCCC=", [16] = "b_lrKB", [528] = "b_ctrKB", [150] = "isync", } local map_rlwinm = setmetatable({ shift = 0, mask = -1, }, { __index = function(t, x) local rot = band(rshift(x, 11), 31) local mb = band(rshift(x, 6), 31) local me = band(rshift(x, 1), 31) if mb == 0 and me == 31-rot then return "slwiRR~A." elseif me == 31 and mb == 32-rot then return "srwiRR~-A." else return "rlwinmRR~AAA." end end }) local map_rld = { shift = 2, mask = 7, [0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.", { shift = 1, mask = 1, [0] = "rldclRR~RM.", "rldcrRR~RM.", }, } local map_ext = setmetatable({ shift = 1, mask = 1023, [0] = "cmp_YLRR", [32] = "cmpl_YLRR", [4] = "twARR", [68] = "tdARR", [8] = "subfcRRR.", [40] = "subfRRR.", [104] = "negRR.", [136] = "subfeRRR.", [200] = "subfzeRR.", [232] = "subfmeRR.", [520] = "subfcoRRR.", [552] = "subfoRRR.", [616] = "negoRR.", [648] = "subfeoRRR.", [712] = "subfzeoRR.", [744] = "subfmeoRR.", [9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.", [457] = "divduRRR.", [489] = "divdRRR.", [745] = "mulldoRRR.", [969] = "divduoRRR.", [1001] = "divdoRRR.", [10] = "addcRRR.", [138] = "addeRRR.", [202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.", [522] = "addcoRRR.", [650] = "addeoRRR.", [714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.", [11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.", [459] = "divwuRRR.", [491] = "divwRRR.", [747] = "mullwoRRR.", [971] = "divwouRRR.", [1003] = "divwoRRR.", [15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR", [144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", }, [19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", }, [371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", }, [339] = { shift = 11, mask = 1023, [32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR", }, [467] = { shift = 11, mask = 1023, [32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR", }, [20] = "lwarxRR0R", [84] = "ldarxRR0R", [21] = "ldxRR0R", [53] = "lduxRRR", [149] = "stdxRR0R", [181] = "stduxRRR", [341] = "lwaxRR0R", [373] = "lwauxRRR", [23] = "lwzxRR0R", [55] = "lwzuxRRR", [87] = "lbzxRR0R", [119] = "lbzuxRRR", [151] = "stwxRR0R", [183] = "stwuxRRR", [215] = "stbxRR0R", [247] = "stbuxRRR", [279] = "lhzxRR0R", [311] = "lhzuxRRR", [343] = "lhaxRR0R", [375] = "lhauxRRR", [407] = "sthxRR0R", [439] = "sthuxRRR", [54] = "dcbst-R0R", [86] = "dcbf-R0R", [150] = "stwcxRR0R.", [214] = "stdcxRR0R.", [246] = "dcbtst-R0R", [278] = "dcbt-R0R", [310] = "eciwxRR0R", [438] = "ecowxRR0R", [470] = "dcbi-RR", [598] = { shift = 21, mask = 3, [0] = "sync", "lwsync", "ptesync", }, [758] = "dcba-RR", [854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R", [26] = "cntlzwRR~", [58] = "cntlzdRR~", [122] = "popcntbRR~", [154] = "prtywRR~", [186] = "prtydRR~", [28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.", [284] = "eqvRR~R.", [316] = "xorRR~R.", [412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.", [508] = "cmpbRR~R", [512] = "mcrxrX", [532] = "ldbrxRR0R", [660] = "stdbrxRR0R", [533] = "lswxRR0R", [597] = "lswiRR0A", [661] = "stswxRR0R", [725] = "stswiRR0A", [534] = "lwbrxRR0R", [662] = "stwbrxRR0R", [790] = "lhbrxRR0R", [918] = "sthbrxRR0R", [535] = "lfsxFR0R", [567] = "lfsuxFRR", [599] = "lfdxFR0R", [631] = "lfduxFRR", [663] = "stfsxFR0R", [695] = "stfsuxFRR", [727] = "stfdxFR0R", [759] = "stfduxFR0R", [855] = "lfiwaxFR0R", [983] = "stfiwxFR0R", [24] = "slwRR~R.", [27] = "sldRR~R.", [536] = "srwRR~R.", [792] = "srawRR~R.", [824] = "srawiRR~A.", [794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.", [922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.", [539] = "srdRR~R.", }, { __index = function(t, x) if band(x, 31) == 15 then return "iselRRRC" end end }) local map_ld = { shift = 0, mask = 3, [0] = "ldRRE", "lduRRE", "lwaRRE", } local map_std = { shift = 0, mask = 3, [0] = "stdRRE", "stduRRE", } local map_fps = { shift = 5, mask = 1, { shift = 1, mask = 15, [0] = false, false, "fdivsFFF.", false, "fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false, "fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false, "fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.", } } local map_fpd = { shift = 5, mask = 1, [0] = { shift = 1, mask = 1023, [0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX", [38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>", [8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.", [136] = "fnabsF-F.", [264] = "fabsF-F.", [12] = "frspF-F.", [14] = "fctiwF-F.", [15] = "fctiwzF-F.", [583] = "mffsF.", [711] = "mtfsfZF.", [392] = "frinF-F.", [424] = "frizF-F.", [456] = "fripF-F.", [488] = "frimF-F.", [814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.", }, { shift = 1, mask = 15, [0] = false, false, "fdivFFF.", false, "fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.", "freF-F.", "fmulFF-F.", "frsqrteF-F.", false, "fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.", } } local map_spe = { shift = 0, mask = 2047, [512] = "evaddwRRR", [514] = "evaddiwRAR~", [516] = "evsubwRRR~", [518] = "evsubiwRAR~", [520] = "evabsRR", [521] = "evnegRR", [522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR", [525] = "evcntlzwRR", [526] = "evcntlswRR", [527] = "brincRRR", [529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR", [535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=", [537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR", [544] = "evsrwuRRR", [545] = "evsrwsRRR", [546] = "evsrwiuRRA", [547] = "evsrwisRRA", [548] = "evslwRRR", [550] = "evslwiRRA", [552] = "evrlwRRR", [553] = "evsplatiRS", [554] = "evrlwiRRA", [555] = "evsplatfiRS", [556] = "evmergehiRRR", [557] = "evmergeloRRR", [558] = "evmergehiloRRR", [559] = "evmergelohiRRR", [560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR", [562] = "evcmpltuYRR", [563] = "evcmpltsYRR", [564] = "evcmpeqYRR", [632] = "evselRRR", [633] = "evselRRRW", [634] = "evselRRRW", [635] = "evselRRRW", [636] = "evselRRRW", [637] = "evselRRRW", [638] = "evselRRRW", [639] = "evselRRRW", [640] = "evfsaddRRR", [641] = "evfssubRRR", [644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR", [648] = "evfsmulRRR", [649] = "evfsdivRRR", [652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR", [656] = "evfscfuiR-R", [657] = "evfscfsiR-R", [658] = "evfscfufR-R", [659] = "evfscfsfR-R", [660] = "evfsctuiR-R", [661] = "evfsctsiR-R", [662] = "evfsctufR-R", [663] = "evfsctsfR-R", [664] = "evfsctuizR-R", [666] = "evfsctsizR-R", [668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR", [704] = "efsaddRRR", [705] = "efssubRRR", [708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR", [712] = "efsmulRRR", [713] = "efsdivRRR", [716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR", [719] = "efscfdR-R", [720] = "efscfuiR-R", [721] = "efscfsiR-R", [722] = "efscfufR-R", [723] = "efscfsfR-R", [724] = "efsctuiR-R", [725] = "efsctsiR-R", [726] = "efsctufR-R", [727] = "efsctsfR-R", [728] = "efsctuizR-R", [730] = "efsctsizR-R", [732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR", [736] = "efdaddRRR", [737] = "efdsubRRR", [738] = "efdcfuidR-R", [739] = "efdcfsidR-R", [740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR", [744] = "efdmulRRR", [745] = "efddivRRR", [746] = "efdctuidzR-R", [747] = "efdctsidzR-R", [748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR", [751] = "efdcfsR-R", [752] = "efdcfuiR-R", [753] = "efdcfsiR-R", [754] = "efdcfufR-R", [755] = "efdcfsfR-R", [756] = "efdctuiR-R", [757] = "efdctsiR-R", [758] = "efdctufR-R", [759] = "efdctsfR-R", [760] = "efdctuizR-R", [762] = "efdctsizR-R", [764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR", [768] = "evlddxRR0R", [769] = "evlddRR8", [770] = "evldwxRR0R", [771] = "evldwRR8", [772] = "evldhxRR0R", [773] = "evldhRR8", [776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2", [780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2", [782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2", [784] = "evlwhexRR0R", [785] = "evlwheRR4", [788] = "evlwhouxRR0R", [789] = "evlwhouRR4", [790] = "evlwhosxRR0R", [791] = "evlwhosRR4", [792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4", [796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4", [800] = "evstddxRR0R", [801] = "evstddRR8", [802] = "evstdwxRR0R", [803] = "evstdwRR8", [804] = "evstdhxRR0R", [805] = "evstdhRR8", [816] = "evstwhexRR0R", [817] = "evstwheRR4", [820] = "evstwhoxRR0R", [821] = "evstwhoRR4", [824] = "evstwwexRR0R", [825] = "evstwweRR4", [828] = "evstwwoxRR0R", [829] = "evstwwoRR4", [1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR", [1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR", [1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR", [1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR", [1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR", [1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR", [1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR", [1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR", [1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR", [1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR", [1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR", [1147] = "evmwsmfaRRR", [1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR", [1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR", [1220] = "evmraRR", [1222] = "evdivwsRRR", [1223] = "evdivwuRRR", [1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR", [1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR", [1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR", [1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR", [1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR", [1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR", [1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR", [1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR", [1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR", [1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR", [1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR", [1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR", [1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR", [1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR", [1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR", [1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR", [1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR", [1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR", [1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR", [1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR", [1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR", [1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR", [1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR", [1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR", [1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR", [1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR", [1491] = "evmwssfanRRR", [1496] = "evmwumianRRR", [1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR", } local map_pri = { [0] = false, false, "tdiARI", "twiARI", map_spe, false, false, "mulliRRI", "subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI", "addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I", "b_KBJ", "sc", "bKJ", map_crops, "rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.", "oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U", "andi.RR~U", "andis.RR~U", map_rld, map_ext, "lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD", "stwRRD", "stwuRRD", "stbRRD", "stbuRRD", "lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD", "sthRRD", "sthuRRD", "lmwRRD", "stmwRRD", "lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD", "stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD", false, false, map_ld, map_fps, false, false, map_std, map_fpd, } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", } local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", } -- Format a condition bit. local function condfmt(cond) if cond <= 3 then return map_cond[band(cond, 3)] else return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)]) end end ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-7s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-7s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) local operands = {} local last = nil local rs = 21 ctx.op = op ctx.rel = nil local opat = map_pri[rshift(b0, 2)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] end local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)") if altname then pat = pat2 end for p in gmatch(pat, ".") do local x = nil if p == "R" then x = map_gpr[band(rshift(op, rs), 31)] rs = rs - 5 elseif p == "F" then x = "f"..band(rshift(op, rs), 31) rs = rs - 5 elseif p == "A" then x = band(rshift(op, rs), 31) rs = rs - 5 elseif p == "S" then x = arshift(lshift(op, 27-rs), 27) rs = rs - 5 elseif p == "I" then x = arshift(lshift(op, 16), 16) elseif p == "U" then x = band(op, 0xffff) elseif p == "D" or p == "E" then local disp = arshift(lshift(op, 16), 16) if p == "E" then disp = band(disp, -4) end if last == "r0" then last = "0" end operands[#operands] = format("%d(%s)", disp, last) elseif p >= "2" and p <= "8" then local disp = band(rshift(op, rs), 31) * p if last == "r0" then last = "0" end operands[#operands] = format("%d(%s)", disp, last) elseif p == "H" then x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4) rs = rs - 5 elseif p == "M" then x = band(rshift(op, rs), 31) + band(op, 0x20) elseif p == "C" then x = condfmt(band(rshift(op, rs), 31)) rs = rs - 5 elseif p == "B" then local bo = rshift(op, 21) local cond = band(rshift(op, 16), 31) local cn = "" rs = rs - 10 if band(bo, 4) == 0 then cn = band(bo, 2) == 0 and "dnz" or "dz" if band(bo, 0x10) == 0 then cn = cn..(band(bo, 8) == 0 and "f" or "t") end if band(bo, 0x10) == 0 then x = condfmt(cond) end name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") elseif band(bo, 0x10) == 0 then cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)] if cond > 3 then x = "cr"..rshift(cond, 2) end name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") end name = gsub(name, "_", cn) elseif p == "J" then x = arshift(lshift(op, 27-rs), 29-rs)*4 if band(op, 2) == 0 then x = ctx.addr + pos + x end ctx.rel = x x = "0x"..tohex(x) elseif p == "K" then if band(op, 1) ~= 0 then name = name.."l" end if band(op, 2) ~= 0 then name = name.."a" end elseif p == "X" or p == "Y" then x = band(rshift(op, rs+2), 7) if x == 0 and p == "Y" then x = nil else x = "cr"..x end rs = rs - 5 elseif p == "W" then x = "cr"..band(op, 7) elseif p == "Z" then x = band(rshift(op, rs-4), 255) rs = rs - 10 elseif p == ">" then operands[#operands] = rshift(operands[#operands], 1) elseif p == "0" then if last == "r0" then operands[#operands] = nil if altname then name = altname end end elseif p == "L" then name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w") elseif p == "." then if band(op, 1) == 1 then name = name.."." end elseif p == "N" then if op == 0x60000000 then name = "nop"; break end elseif p == "~" then local n = #operands operands[n-1], operands[n] = operands[n], operands[n-1] elseif p == "=" then local n = #operands if last == operands[n-1] then operands[n] = nil name = altname end elseif p == "%" then local n = #operands if last == operands[n-1] and last == operands[n-2] then operands[n] = nil operands[n-1] = nil name = altname end elseif p == "-" then rs = rs - 5 else assert(false) end if x then operands[#operands+1] = x; last = x end end return putop(ctx, name, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code stop = stop - stop % 4 ctx.pos = ofs - ofs % 4 ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_gpr[r] end return "f"..(r-32) end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Assets/ToLua/Lua/jit/dis_ppc.lua.meta ================================================ fileFormatVersion: 2 guid: 1231975d3fb5f1b4995c9112ea3537f4 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_x64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT x64 disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the 64 bit functions from the combined -- x86/x64 disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86") return { create = dis_x86.create64, disass = dis_x86.disass64, regname = dis_x86.regname64 } ================================================ FILE: Assets/ToLua/Lua/jit/dis_x64.lua.meta ================================================ fileFormatVersion: 2 guid: b9997149317d8a6458002e31b320c212 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dis_x86.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT x86/x64 disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- Sending small code snippets to an external disassembler and mixing the -- output with our own stuff was too fragile. So I had to bite the bullet -- and write yet another x86 disassembler. Oh well ... -- -- The output format is very similar to what ndisasm generates. But it has -- been developed independently by looking at the opcode tables from the -- Intel and AMD manuals. The supported instruction set is quite extensive -- and reflects what a current generation Intel or AMD CPU implements in -- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3, -- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor -- (VMX/SVM) instructions. -- -- Notes: -- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported. -- * No attempt at optimization has been made -- it's fast enough for my needs. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local lower, rep = string.lower, string.rep local bit = require("bit") local tohex = bit.tohex -- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on. local map_opc1_32 = { --0x [0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es", "orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*", --1x "adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss", "sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds", --2x "andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa", "subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das", --3x "xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa", "cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas", --4x "incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR", "decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR", --5x "pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR", "popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR", --6x "sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr", "fs:seg","gs:seg","o16:","a16", "pushUi","imulVrmi","pushBs","imulVrms", "insb","insVS","outsb","outsVS", --7x "joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj", "jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj", --8x "arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms", "testBmr","testVmr","xchgBrm","xchgVrm", "movBmr","movVmr","movBrm","movVrm", "movVmg","leaVrm","movWgm","popUm", --9x "nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR", "xchgVaR","xchgVaR","xchgVaR","xchgVaR", "sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait", "sz*pushfw,pushf","sz*popfw,popf","sahf","lahf", --Ax "movBao","movVao","movBoa","movVoa", "movsb","movsVS","cmpsb","cmpsVS", "testBai","testVai","stosb","stosVS", "lodsb","lodsVS","scasb","scasVS", --Bx "movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi", "movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI", --Cx "shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi", "enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS", --Dx "shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb", "fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7", --Ex "loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj", "inBau","inVau","outBua","outVua", "callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda", --Fx "lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm", "clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm", } assert(#map_opc1_32 == 255) -- Map for 1st opcode byte in 64 bit mode (overrides only). local map_opc1_64 = setmetatable({ [0x06]=false, [0x07]=false, [0x0e]=false, [0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false, [0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false, [0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:", [0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb", [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb", [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb", [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb", [0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false, [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false, }, { __index = map_opc1_32 }) -- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you. -- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2 local map_opc2 = { --0x [0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret", "invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu", --1x "movupsXrm|movssXrvm|movupdXrm|movsdXrvm", "movupsXmr|movssXmvr|movupdXmr|movsdXmvr", "movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", "movlpsXmr||movlpdXmr", "unpcklpsXrvm||unpcklpdXrvm", "unpckhpsXrvm||unpckhpdXrvm", "movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm", "movhpsXmr||movhpdXmr", "$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm", "hintnopVm","hintnopVm","hintnopVm","hintnopVm", --2x "movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil, "movapsXrm||movapdXrm", "movapsXmr||movapdXmr", "cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt", "movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr", "cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm", "cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm", "ucomissXrm||ucomisdXrm", "comissXrm||comisdXrm", --3x "wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec", "opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil, --4x "cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm", "cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm", "cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm", "cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm", --5x "movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm", "rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm", "andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm", "orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm", "addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm", "cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm", "cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm", "subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm", "divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm", --6x "punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm", "pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm", "punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm", "||punpcklqdqXrvm","||punpckhqdqXrvm", "movPrVSm","movqMrm|movdquXrm|movdqaXrm", --7x "pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu", "pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu", "pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|", "vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$", nil,nil, "||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm", "movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr", --8x "joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj", "jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj", --9x "setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm", "setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm", --Ax "push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil, "push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm", --Bx "cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr", "$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt", "|popcntVrm","ud2Dp","bt!Vmu","btcVmr", "bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt", --Cx "xaddBmr","xaddVmr", "cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|", "pinsrwPrvWmu","pextrwDrPmu", "shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp", "bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR", --Dx "||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm", "paddqPrvm","pmullwPrvm", "|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm", "psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm", "paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm", --Ex "pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm", "pmulhuwPrvm","pmulhwPrvm", "|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr", "psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm", "paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm", --Fx "|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm", "pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$", "psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm", "paddbPrvm","paddwPrvm","padddPrvm","ud", } assert(map_opc2[255] == "ud") -- Map for three-byte opcodes. Can't wait for their next invention. local map_opc3 = { ["38"] = { -- [66] 0f 38 xx --0x [0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm", "pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm", "psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm", "||permilpsXrvm","||permilpdXrvm",nil,nil, --1x "||pblendvbXrma",nil,nil,nil, "||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm", "||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil, "pabsbPrm","pabswPrm","pabsdPrm",nil, --2x "||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm", "||pmovsxwqXrm","||pmovsxdqXrm",nil,nil, "||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm", "||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr", --3x "||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm", "||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm", "||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm", "||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm", --4x "||pmulddXrvm","||phminposuwXrm",nil,nil, nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm", --5x [0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm", [0x5a] = "||broadcasti128XrlXm", --7x [0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm", --8x [0x8c] = "||pmaskmovXrvVSm", [0x8e] = "||pmaskmovVSmXvr", --9x [0x96] = "||fmaddsub132pHXrvm",[0x97] = "||fmsubadd132pHXrvm", [0x98] = "||fmadd132pHXrvm",[0x99] = "||fmadd132sHXrvm", [0x9a] = "||fmsub132pHXrvm",[0x9b] = "||fmsub132sHXrvm", [0x9c] = "||fnmadd132pHXrvm",[0x9d] = "||fnmadd132sHXrvm", [0x9e] = "||fnmsub132pHXrvm",[0x9f] = "||fnmsub132sHXrvm", --Ax [0xa6] = "||fmaddsub213pHXrvm",[0xa7] = "||fmsubadd213pHXrvm", [0xa8] = "||fmadd213pHXrvm",[0xa9] = "||fmadd213sHXrvm", [0xaa] = "||fmsub213pHXrvm",[0xab] = "||fmsub213sHXrvm", [0xac] = "||fnmadd213pHXrvm",[0xad] = "||fnmadd213sHXrvm", [0xae] = "||fnmsub213pHXrvm",[0xaf] = "||fnmsub213sHXrvm", --Bx [0xb6] = "||fmaddsub231pHXrvm",[0xb7] = "||fmsubadd231pHXrvm", [0xb8] = "||fmadd231pHXrvm",[0xb9] = "||fmadd231sHXrvm", [0xba] = "||fmsub231pHXrvm",[0xbb] = "||fmsub231sHXrvm", [0xbc] = "||fnmadd231pHXrvm",[0xbd] = "||fnmadd231sHXrvm", [0xbe] = "||fnmsub231pHXrvm",[0xbf] = "||fnmsub231sHXrvm", --Dx [0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm", [0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm", --Fx [0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt", [0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv", }, ["3a"] = { -- [66] 0f 3a xx --0x [0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil, "||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil, "||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu", "||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu", --1x nil,nil,nil,nil, "||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru", "||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil, nil,nil,nil,nil, --2x "||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil, --3x [0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru", --4x [0x40] = "||dppsXrvmu", [0x41] = "||dppdXrvmu", [0x42] = "||mpsadbwXrvmu", [0x44] = "||pclmulqdqXrvmu", [0x46] = "||perm2i128Xrvmu", [0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb", [0x4c] = "||pblendvbXrvmb", --6x [0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu", [0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu", [0xdf] = "||aeskeygenassistXrmu", --Fx [0xf0] = "||| rorxVrmu", }, } -- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands). local map_opcvm = { [0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff", [0xc8]="monitor",[0xc9]="mwait", [0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave", [0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga", [0xf8]="swapgs",[0xf9]="rdtscp", } -- Map for FP opcodes. And you thought stack machines are simple? local map_opcfp = { -- D8-DF 00-BF: opcodes with a memory operand. -- D8 [0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm", "fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm", -- DA "fiaddDm","fimulDm","ficomDm","ficompDm", "fisubDm","fisubrDm","fidivDm","fidivrDm", -- DB "fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp", -- DC "faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm", -- DD "fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm", -- DE "fiaddWm","fimulWm","ficomWm","ficompWm", "fisubWm","fisubrWm","fidivWm","fidivrWm", -- DF "fildWm","fisttpWm","fistWm","fistpWm", "fbld twordFmp","fildQm","fbstp twordFmp","fistpQm", -- xx C0-FF: opcodes with a pseudo-register operand. -- D8 "faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf", -- D9 "fldFf","fxchFf",{"fnop"},nil, {"fchs","fabs",nil,nil,"ftst","fxam"}, {"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"}, {"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"}, {"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"}, -- DA "fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil, -- DB "fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf", {nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil, -- DC "fadd toFf","fmul toFf",nil,nil, "fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf", -- DD "ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil, -- DE "faddpFf","fmulpFf",nil,{nil,"fcompp"}, "fsubrpFf","fsubpFf","fdivrpFf","fdivpFf", -- DF nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil, } assert(map_opcfp[126] == "fcomipFf") -- Map for opcode groups. The subkey is sp from the ModRM byte. local map_opcgroup = { arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" }, shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" }, testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" }, testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" }, incb = { "inc", "dec" }, incd = { "inc", "dec", "callUmp", "$call farDmp", "jmpUmp", "$jmp farDmp", "pushUm" }, sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" }, sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt", "smsw", nil, "lmsw", "vm*$invlpg" }, bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" }, cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil, nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" }, pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" }, pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" }, pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" }, pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" }, fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr", nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" }, prefetch = { "prefetch", "prefetchw" }, prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" }, } ------------------------------------------------------------------------------ -- Maps for register names. local map_regs = { B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" }, D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" }, Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }, M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext! X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" }, Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" }, } local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" } -- Maps for size names. local map_sz2n = { B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32, } local map_sz2prefix = { B = "byte", W = "word", D = "dword", Q = "qword", M = "qword", X = "xword", Y = "yword", F = "dword", G = "qword", -- No need for sizes/register names for these two. } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local code, pos, hex = ctx.code, ctx.pos, "" local hmax = ctx.hexdump if hmax > 0 then for i=ctx.start,pos-1 do hex = hex..format("%02X", byte(code, i, i)) end if #hex > hmax then hex = sub(hex, 1, hmax)..". " else hex = hex..rep(" ", hmax-#hex+2) end end if operands then text = text.." "..operands end if ctx.o16 then text = "o16 "..text; ctx.o16 = false end if ctx.a32 then text = "a32 "..text; ctx.a32 = false end if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end if ctx.rex then local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "").. (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "").. (ctx.vexl and "l" or "") if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "") elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rex = false; ctx.vexl = false; ctx.vexv = false end if ctx.seg then local text2, n = gsub(text, "%[", "["..ctx.seg..":") if n == 0 then text = ctx.seg.." "..text else text = text2 end ctx.seg = false end if ctx.lock then text = "lock "..text; ctx.lock = false end local imm = ctx.imm if imm then local sym = ctx.symtab[imm] if sym then text = text.."\t->"..sym end end ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text)) ctx.mrm = false ctx.vexv = false ctx.start = pos ctx.imm = nil end -- Clear all prefix flags. local function clearprefixes(ctx) ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rex = false; ctx.a32 = false; ctx.vexl = false end -- Fallback for incomplete opcodes at the end. local function incomplete(ctx) ctx.pos = ctx.stop+1 clearprefixes(ctx) return putop(ctx, "(incomplete)") end -- Fallback for unknown opcodes. local function unknown(ctx) clearprefixes(ctx) return putop(ctx, "(unknown)") end -- Return an immediate of the specified size. local function getimm(ctx, pos, n) if pos+n-1 > ctx.stop then return incomplete(ctx) end local code = ctx.code if n == 1 then local b1 = byte(code, pos, pos) return b1 elseif n == 2 then local b1, b2 = byte(code, pos, pos+1) return b1+b2*256 else local b1, b2, b3, b4 = byte(code, pos, pos+3) local imm = b1+b2*256+b3*65536+b4*16777216 ctx.imm = imm return imm end end -- Process pattern string and generate the operands. local function putpat(ctx, name, pat) local operands, regs, sz, mode, sp, rm, sc, rx, sdisp local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl -- Chars used: 1DFGHIMPQRSTUVWXYabcdfgijlmoprstuvwxyz for p in gmatch(pat, ".") do local x = nil if p == "V" or p == "U" then if ctx.rexw then sz = "Q"; ctx.rexw = false elseif ctx.o16 then sz = "W"; ctx.o16 = false elseif p == "U" and ctx.x64 then sz = "Q" else sz = "D" end regs = map_regs[sz] elseif p == "T" then if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end regs = map_regs[sz] elseif p == "B" then sz = "B" regs = ctx.rex and map_regs.B64 or map_regs.B elseif match(p, "[WDQMXYFG]") then sz = p if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end regs = map_regs[sz] elseif p == "P" then sz = ctx.o16 and "X" or "M"; ctx.o16 = false if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end regs = map_regs[sz] elseif p == "H" then name = name..(ctx.rexw and "d" or "s") ctx.rexw = false elseif p == "S" then name = name..lower(sz) elseif p == "s" then local imm = getimm(ctx, pos, 1); if not imm then return end x = imm <= 127 and format("+0x%02x", imm) or format("-0x%02x", 256-imm) pos = pos+1 elseif p == "u" then local imm = getimm(ctx, pos, 1); if not imm then return end x = format("0x%02x", imm) pos = pos+1 elseif p == "b" then local imm = getimm(ctx, pos, 1); if not imm then return end x = regs[imm/16+1] pos = pos+1 elseif p == "w" then local imm = getimm(ctx, pos, 2); if not imm then return end x = format("0x%x", imm) pos = pos+2 elseif p == "o" then -- [offset] if ctx.x64 then local imm1 = getimm(ctx, pos, 4); if not imm1 then return end local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end x = format("[0x%08x%08x]", imm2, imm1) pos = pos+8 else local imm = getimm(ctx, pos, 4); if not imm then return end x = format("[0x%08x]", imm) pos = pos+4 end elseif p == "i" or p == "I" then local n = map_sz2n[sz] if n == 8 and ctx.x64 and p == "I" then local imm1 = getimm(ctx, pos, 4); if not imm1 then return end local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end x = format("0x%08x%08x", imm2, imm1) else if n == 8 then n = 4 end local imm = getimm(ctx, pos, n); if not imm then return end if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then imm = (0xffffffff+1)-imm x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm) else x = format(imm > 65535 and "0x%08x" or "0x%x", imm) end end pos = pos+n elseif p == "j" then local n = map_sz2n[sz] if n == 8 then n = 4 end local imm = getimm(ctx, pos, n); if not imm then return end if sz == "B" and imm > 127 then imm = imm-256 elseif imm > 2147483647 then imm = imm-4294967296 end pos = pos+n imm = imm + pos + ctx.addr if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end ctx.imm = imm if sz == "W" then x = format("word 0x%04x", imm%65536) elseif ctx.x64 then local lo = imm % 0x1000000 x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo) else x = "0x"..tohex(imm) end elseif p == "R" then local r = byte(code, pos-1, pos-1)%8 if ctx.rexb then r = r + 8; ctx.rexb = false end x = regs[r+1] elseif p == "a" then x = regs[1] elseif p == "c" then x = "cl" elseif p == "d" then x = "dx" elseif p == "1" then x = "1" else if not mode then mode = ctx.mrm if not mode then if pos > stop then return incomplete(ctx) end mode = byte(code, pos, pos) pos = pos+1 end rm = mode%8; mode = (mode-rm)/8 sp = mode%8; mode = (mode-sp)/8 sdisp = "" if mode < 3 then if rm == 4 then if pos > stop then return incomplete(ctx) end sc = byte(code, pos, pos) pos = pos+1 rm = sc%8; sc = (sc-rm)/8 rx = sc%8; sc = (sc-rx)/8 if ctx.rexx then rx = rx + 8; ctx.rexx = false end if rx == 4 then rx = nil end end if mode > 0 or rm == 5 then local dsz = mode if dsz ~= 1 then dsz = 4 end local disp = getimm(ctx, pos, dsz); if not disp then return end if mode == 0 then rm = nil end if rm or rx or (not sc and ctx.x64 and not ctx.a32) then if dsz == 1 and disp > 127 then sdisp = format("-0x%x", 256-disp) elseif disp >= 0 and disp <= 0x7fffffff then sdisp = format("+0x%x", disp) else sdisp = format("-0x%x", (0xffffffff+1)-disp) end else sdisp = format(ctx.x64 and not ctx.a32 and not (disp >= 0 and disp <= 0x7fffffff) and "0xffffffff%08x" or "0x%08x", disp) end pos = pos+dsz end end if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end if ctx.rexr then sp = sp + 8; ctx.rexr = false end end if p == "m" then if mode == 3 then x = regs[rm+1] else local aregs = ctx.a32 and map_regs.D or ctx.aregs local srm, srx = "", "" if rm then srm = aregs[rm+1] elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end ctx.a32 = false if rx then if rm then srm = srm.."+" end srx = aregs[rx+1] if sc > 0 then srx = srx.."*"..(2^sc) end end x = format("[%s%s%s]", srm, srx, sdisp) end if mode < 3 and (not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck. x = map_sz2prefix[sz].." "..x end elseif p == "r" then x = regs[sp+1] elseif p == "g" then x = map_segregs[sp+1] elseif p == "p" then -- Suppress prefix. elseif p == "f" then x = "st"..rm elseif p == "x" then if sp == 0 and ctx.lock and not ctx.x64 then x = "CR8"; ctx.lock = false else x = "CR"..sp end elseif p == "v" then if ctx.vexv then x = regs[ctx.vexv+1]; ctx.vexv = false end elseif p == "y" then x = "DR"..sp elseif p == "z" then x = "TR"..sp elseif p == "l" then vexl = false elseif p == "t" then else error("bad pattern `"..pat.."'") end end if x then operands = operands and operands..", "..x or x end end ctx.pos = pos return putop(ctx, name, operands) end -- Forward declaration. local map_act -- Fetch and cache MRM byte. local function getmrm(ctx) local mrm = ctx.mrm if not mrm then local pos = ctx.pos if pos > ctx.stop then return nil end mrm = byte(ctx.code, pos, pos) ctx.pos = pos+1 ctx.mrm = mrm end return mrm end -- Dispatch to handler depending on pattern. local function dispatch(ctx, opat, patgrp) if not opat then return unknown(ctx) end if match(opat, "%|") then -- MMX/SSE variants depending on prefix. local p if ctx.rep then p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)" ctx.rep = false elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false else p = "^[^%|]*" end opat = match(opat, p) if not opat then return unknown(ctx) end -- ctx.rep = false; ctx.o16 = false --XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi] --XXX remove in branches? end if match(opat, "%$") then -- reg$mem variants. local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)") if opat == "" then return unknown(ctx) end end if opat == "" then return unknown(ctx) end local name, pat = match(opat, "^([a-z0-9 ]*)(.*)") if pat == "" and patgrp then pat = patgrp end return map_act[sub(pat, 1, 1)](ctx, name, pat) end -- Get a pattern from an opcode map and dispatch to handler. local function dispatchmap(ctx, opcmap) local pos = ctx.pos local opat = opcmap[byte(ctx.code, pos, pos)] pos = pos + 1 ctx.pos = pos return dispatch(ctx, opat) end -- Map for action codes. The key is the first char after the name. map_act = { -- Simple opcodes without operands. [""] = function(ctx, name, pat) return putop(ctx, name) end, -- Operand size chars fall right through. B = putpat, W = putpat, D = putpat, Q = putpat, V = putpat, U = putpat, T = putpat, M = putpat, X = putpat, P = putpat, F = putpat, G = putpat, Y = putpat, H = putpat, -- Collect prefixes. [":"] = function(ctx, name, pat) ctx[pat == ":" and name or sub(pat, 2)] = name if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes. end, -- Chain to special handler specified by name. ["*"] = function(ctx, name, pat) return map_act[name](ctx, name, sub(pat, 2)) end, -- Use named subtable for opcode group. ["!"] = function(ctx, name, pat) local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2)) end, -- o16,o32[,o64] variants. sz = function(ctx, name, pat) if ctx.o16 then ctx.o16 = false else pat = match(pat, ",(.*)") if ctx.rexw then local p = match(pat, ",(.*)") if p then pat = p; ctx.rexw = false end end end pat = match(pat, "^[^,]*") return dispatch(ctx, pat) end, -- Two-byte opcode dispatch. opc2 = function(ctx, name, pat) return dispatchmap(ctx, map_opc2) end, -- Three-byte opcode dispatch. opc3 = function(ctx, name, pat) return dispatchmap(ctx, map_opc3[pat]) end, -- VMX/SVM dispatch. vm = function(ctx, name, pat) return dispatch(ctx, map_opcvm[ctx.mrm]) end, -- Floating point opcode dispatch. fp = function(ctx, name, pat) local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end local rm = mrm%8 local idx = pat*8 + ((mrm-rm)/8)%8 if mrm >= 192 then idx = idx + 64 end local opat = map_opcfp[idx] if type(opat) == "table" then opat = opat[rm+1] end return dispatch(ctx, opat) end, -- REX prefix. rex = function(ctx, name, pat) if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. for p in gmatch(pat, ".") do ctx["rex"..p] = true end ctx.rex = "rex" end, -- VEX prefix. vex = function(ctx, name, pat) if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. ctx.rex = "vex" local pos = ctx.pos if ctx.mrm then ctx.mrm = nil pos = pos-1 end local b = byte(ctx.code, pos, pos) if not b then return incomplete(ctx) end pos = pos+1 if b < 128 then ctx.rexr = true end local m = 1 if pat == "3" then m = b%32; b = (b-m)/32 local nb = b%2; b = (b-nb)/2 if nb == 0 then ctx.rexb = true end local nx = b%2 if nx == 0 then ctx.rexx = true end b = byte(ctx.code, pos, pos) if not b then return incomplete(ctx) end pos = pos+1 if b >= 128 then ctx.rexw = true end end ctx.pos = pos local map if m == 1 then map = map_opc2 elseif m == 2 then map = map_opc3["38"] elseif m == 3 then map = map_opc3["3a"] else return unknown(ctx) end local p = b%4; b = (b-p)/4 if p == 1 then ctx.o16 = "o16" elseif p == 2 then ctx.rep = "rep" elseif p == 3 then ctx.rep = "repne" end local l = b%2; b = (b-l)/2 if l ~= 0 then ctx.vexl = true end ctx.vexv = (-1-b)%16 return dispatchmap(ctx, map) end, -- Special case for nop with REX prefix. nop = function(ctx, name, pat) return dispatch(ctx, ctx.rex and pat or "nop") end, -- Special case for 0F 77. emms = function(ctx, name, pat) if ctx.rex ~= "vex" then return putop(ctx, "emms") elseif ctx.vexl then ctx.vexl = false return putop(ctx, "zeroall") else return putop(ctx, "zeroupper") end end, } ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ofs = ofs + 1 ctx.start = ofs ctx.pos = ofs ctx.stop = stop ctx.imm = nil ctx.mrm = false clearprefixes(ctx) while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end if ctx.pos ~= ctx.start then incomplete(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = (addr or 0) - 1 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 16 ctx.x64 = false ctx.map1 = map_opc1_32 ctx.aregs = map_regs.D return ctx end local function create64(code, addr, out) local ctx = create(code, addr, out) ctx.x64 = true ctx.map1 = map_opc1_64 ctx.aregs = map_regs.Q return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end local function disass64(code, addr, out) create64(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 8 then return map_regs.D[r+1] end return map_regs.X[r-7] end local function regname64(r) if r < 16 then return map_regs.Q[r+1] end return map_regs.X[r-15] end -- Public module functions. return { create = create, create64 = create64, disass = disass, disass64 = disass64, regname = regname, regname64 = regname64 } ================================================ FILE: Assets/ToLua/Lua/jit/dis_x86.lua.meta ================================================ fileFormatVersion: 2 guid: 3244c54564aeae24daa6a81b810b9d3f timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/dump.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT compiler dump module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module can be used to debug the JIT compiler itself. It dumps the -- code representations and structures used in various compiler stages. -- -- Example usage: -- -- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)" -- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R -- luajit -jdump=is myapp.lua | less -R -- luajit -jdump=-b myapp.lua -- luajit -jdump=+aH,myapp.html myapp.lua -- luajit -jdump=ixT,myapp.dump myapp.lua -- -- The first argument specifies the dump mode. The second argument gives -- the output file name. Default output is to stdout, unless the environment -- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the -- module is started. -- -- Different features can be turned on or off with the dump mode. If the -- mode starts with a '+', the following features are added to the default -- set of features; a '-' removes them. Otherwise the features are replaced. -- -- The following dump features are available (* marks the default): -- -- * t Print a line for each started, ended or aborted trace (see also -jv). -- * b Dump the traced bytecode. -- * i Dump the IR (intermediate representation). -- r Augment the IR with register/stack slots. -- s Dump the snapshot map. -- * m Dump the generated machine code. -- x Print each taken trace exit. -- X Print each taken trace exit and the contents of all registers. -- a Print the IR of aborted traces, too. -- -- The output format can be set with the following characters: -- -- T Plain text output. -- A ANSI-colored text output -- H Colorized HTML + CSS output. -- -- The default output format is plain text. It's set to ANSI-colored text -- if the COLORTERM variable is set. Note: this is independent of any output -- redirection, which is actually considered a feature. -- -- You probably want to use less -R to enjoy viewing ANSI-colored text from -- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R" -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr local bit = require("bit") local band, shr, tohex = bit.band, bit.rshift, bit.tohex local sub, gsub, format = string.sub, string.gsub, string.format local byte, rep = string.byte, string.rep local type, tostring = type, tostring local stdout, stderr = io.stdout, io.stderr -- Load other modules on-demand. local bcline, disass -- Active flag, output file handle and dump mode. local active, out, dumpmode ------------------------------------------------------------------------------ local symtabmt = { __index = false } local symtab = {} local nexitsym = 0 -- Fill nested symbol table with per-trace exit stub addresses. local function fillsymtab_tr(tr, nexit) local t = {} symtabmt.__index = t if jit.arch:sub(1, 4) == "mips" then t[traceexitstub(tr, 0)] = "exit" return end for i=0,nexit-1 do local addr = traceexitstub(tr, i) if addr < 0 then addr = addr + 2^32 end t[addr] = tostring(i) end local addr = traceexitstub(tr, nexit) if addr then t[addr] = "stack_check" end end -- Fill symbol table with trace exit stub addresses. local function fillsymtab(tr, nexit) local t = symtab if nexitsym == 0 then local ircall = vmdef.ircall for i=0,#ircall do local addr = ircalladdr(i) if addr ~= 0 then if addr < 0 then addr = addr + 2^32 end t[addr] = ircall[i] end end end if nexitsym == 1000000 then -- Per-trace exit stubs. fillsymtab_tr(tr, nexit) elseif nexit > nexitsym then -- Shared exit stubs. for i=nexitsym,nexit-1 do local addr = traceexitstub(i) if addr == nil then -- Fall back to per-trace exit stubs. fillsymtab_tr(tr, nexit) setmetatable(symtab, symtabmt) nexit = 1000000 break end if addr < 0 then addr = addr + 2^32 end t[addr] = tostring(i) end nexitsym = nexit end return t end local function dumpwrite(s) out:write(s) end -- Disassemble machine code. local function dump_mcode(tr) local info = traceinfo(tr) if not info then return end local mcode, addr, loop = tracemc(tr) if not mcode then return end if not disass then disass = require("jit.dis_"..jit.arch) end if addr < 0 then addr = addr + 2^32 end out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") local ctx = disass.create(mcode, addr, dumpwrite) ctx.hexdump = 0 ctx.symtab = fillsymtab(tr, info.nexit) if loop ~= 0 then symtab[addr+loop] = "LOOP" ctx:disass(0, loop) out:write("->LOOP:\n") ctx:disass(loop, #mcode-loop) symtab[addr+loop] = nil else ctx:disass(0, #mcode) end end ------------------------------------------------------------------------------ local irtype_text = { [0] = "nil", "fal", "tru", "lud", "str", "p32", "thr", "pro", "fun", "p64", "cdt", "tab", "udt", "flt", "num", "i8 ", "u8 ", "i16", "u16", "int", "u32", "i64", "u64", "sfp", } local colortype_ansi = { [0] = "%s", "%s", "%s", "\027[36m%s\027[m", "\027[32m%s\027[m", "%s", "\027[1m%s\027[m", "%s", "\027[1m%s\027[m", "%s", "\027[33m%s\027[m", "\027[31m%s\027[m", "\027[36m%s\027[m", "\027[34m%s\027[m", "\027[34m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", } local function colorize_text(s) return s end local function colorize_ansi(s, t) return format(colortype_ansi[t], s) end local irtype_ansi = setmetatable({}, { __index = function(tab, t) local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end }) local html_escape = { ["<"] = "<", [">"] = ">", ["&"] = "&", } local function colorize_html(s, t) s = gsub(s, "[<>&]", html_escape) return format('%s', irtype_text[t], s) end local irtype_html = setmetatable({}, { __index = function(tab, t) local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end }) local header_html = [[ ]] local colorize, irtype -- Lookup tables to convert some literals into names. local litname = { ["SLOAD "] = setmetatable({}, { __index = function(t, mode) local s = "" if band(mode, 1) ~= 0 then s = s.."P" end if band(mode, 2) ~= 0 then s = s.."F" end if band(mode, 4) ~= 0 then s = s.."T" end if band(mode, 8) ~= 0 then s = s.."C" end if band(mode, 16) ~= 0 then s = s.."R" end if band(mode, 32) ~= 0 then s = s.."I" end t[mode] = s return s end}), ["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", }, ["CONV "] = setmetatable({}, { __index = function(t, mode) local s = irtype[band(mode, 31)] s = irtype[band(shr(mode, 5), 31)].."."..s if band(mode, 0x800) ~= 0 then s = s.." sext" end local c = shr(mode, 14) if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end t[mode] = s return s end}), ["FLOAD "] = vmdef.irfield, ["FREF "] = vmdef.irfield, ["FPMATH"] = vmdef.irfpm, ["BUFHDR"] = { [0] = "RESET", "APPEND" }, ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, } local function ctlsub(c) if c == "\n" then return "\\n" elseif c == "\r" then return "\\r" elseif c == "\t" then return "\\t" else return format("\\%03d", byte(c)) end end local function fmtfunc(func, pc) local fi = funcinfo(func, pc) if fi.loc then return fi.loc elseif fi.ffid then return vmdef.ffnames[fi.ffid] elseif fi.addr then return format("C:%x", fi.addr) else return "(?)" end end local function formatk(tr, idx, sn) local k, t, slot = tracek(tr, idx) local tn = type(k) local s if tn == "number" then if band(sn or 0, 0x30000) ~= 0 then s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz" elseif k == 2^52+2^51 then s = "bias" else s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k) end elseif tn == "string" then s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) elseif tn == "function" then s = fmtfunc(k) elseif tn == "table" then s = format("{%p}", k) elseif tn == "userdata" then if t == 12 then s = format("userdata:%p", k) else s = format("[%p]", k) if s == "[NULL]" then s = "NULL" end end elseif t == 21 then -- int64_t s = sub(tostring(k), 1, -3) if sub(s, 1, 1) ~= "-" then s = "+"..s end elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL) return "----" -- Special case for LJ_FR2 slot 1. else s = tostring(k) -- For primitives. end s = colorize(format("%-4s", s), t) if slot then s = format("%s @%d", s, slot) end return s end local function printsnap(tr, snap) local n = 2 for s=0,snap[1]-1 do local sn = snap[n] if shr(sn, 24) == s then n = n + 1 local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS if ref < 0 then out:write(formatk(tr, ref, sn)) elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM out:write(colorize(format("%04d/%04d", ref, ref+1), 14)) else local m, ot, op1, op2 = traceir(tr, ref) out:write(colorize(format("%04d", ref), band(ot, 31))) end out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME else out:write("---- ") end end out:write("]\n") end -- Dump snapshots (not interleaved with IR). local function dump_snap(tr) out:write("---- TRACE ", tr, " snapshots\n") for i=0,1000000000 do local snap = tracesnap(tr, i) if not snap then break end out:write(format("#%-3d %04d [ ", i, snap[0])) printsnap(tr, snap) end end -- Return a register name or stack slot for a rid/sp location. local function ridsp_name(ridsp, ins) if not disass then disass = require("jit.dis_"..jit.arch) end local rid, slot = band(ridsp, 0xff), shr(ridsp, 8) if rid == 253 or rid == 254 then return (slot == 0 or slot == 255) and " {sink" or format(" {%04d", ins-slot) end if ridsp > 255 then return format("[%x]", slot*4) end if rid < 128 then return disass.regname(rid) end return "" end -- Dump CALL* function ref and return optional ctype. local function dumpcallfunc(tr, ins) local ctype if ins > 0 then local m, ot, op1, op2 = traceir(tr, ins) if band(ot, 31) == 0 then -- nil type means CARG(func, ctype). ins = op1 ctype = formatk(tr, op2) end end if ins < 0 then out:write(format("[0x%x](", tonumber((tracek(tr, ins))))) else out:write(format("%04d (", ins)) end return ctype end -- Recursively gather CALL* args and dump them. local function dumpcallargs(tr, ins) if ins < 0 then out:write(formatk(tr, ins)) else local m, ot, op1, op2 = traceir(tr, ins) local oidx = 6*shr(ot, 8) local op = sub(vmdef.irnames, oidx+1, oidx+6) if op == "CARG " then dumpcallargs(tr, op1) if op2 < 0 then out:write(" ", formatk(tr, op2)) else out:write(" ", format("%04d", op2)) end else out:write(format("%04d", ins)) end end end -- Dump IR and interleaved snapshots. local function dump_ir(tr, dumpsnap, dumpreg) local info = traceinfo(tr) if not info then return end local nins = info.nins out:write("---- TRACE ", tr, " IR\n") local irnames = vmdef.irnames local snapref = 65536 local snap, snapno if dumpsnap then snap = tracesnap(tr, 0) snapref = snap[0] snapno = 0 end for ins=1,nins do if ins >= snapref then if dumpreg then out:write(format(".... SNAP #%-3d [ ", snapno)) else out:write(format(".... SNAP #%-3d [ ", snapno)) end printsnap(tr, snap) snapno = snapno + 1 snap = tracesnap(tr, snapno) snapref = snap and snap[0] or 65536 end local m, ot, op1, op2, ridsp = traceir(tr, ins) local oidx, t = 6*shr(ot, 8), band(ot, 31) local op = sub(irnames, oidx+1, oidx+6) if op == "LOOP " then if dumpreg then out:write(format("%04d ------------ LOOP ------------\n", ins)) else out:write(format("%04d ------ LOOP ------------\n", ins)) end elseif op ~= "NOP " and op ~= "CARG " and (dumpreg or op ~= "RENAME") then local rid = band(ridsp, 255) if dumpreg then out:write(format("%04d %-6s", ins, ridsp_name(ridsp, ins))) else out:write(format("%04d ", ins)) end out:write(format("%s%s %s %s ", (rid == 254 or rid == 253) and "}" or (band(ot, 128) == 0 and " " or ">"), band(ot, 64) == 0 and " " or "+", irtype[t], op)) local m1, m2 = band(m, 3), band(m, 3*4) if sub(op, 1, 4) == "CALL" then local ctype if m2 == 1*4 then -- op2 == IRMlit out:write(format("%-10s (", vmdef.ircall[op2])) else ctype = dumpcallfunc(tr, op2) end if op1 ~= -1 then dumpcallargs(tr, op1) end out:write(")") if ctype then out:write(" ctype ", ctype) end elseif op == "CNEW " and op2 == -1 then out:write(formatk(tr, op1)) elseif m1 ~= 3 then -- op1 != IRMnone if op1 < 0 then out:write(formatk(tr, op1)) else out:write(format(m1 == 0 and "%04d" or "#%-3d", op1)) end if m2 ~= 3*4 then -- op2 != IRMnone if m2 == 1*4 then -- op2 == IRMlit local litn = litname[op] if litn and litn[op2] then out:write(" ", litn[op2]) elseif op == "UREFO " or op == "UREFC " then out:write(format(" #%-3d", shr(op2, 8))) else out:write(format(" #%-3d", op2)) end elseif op2 < 0 then out:write(" ", formatk(tr, op2)) else out:write(format(" %04d", op2)) end end end out:write("\n") end end if snap then if dumpreg then out:write(format(".... SNAP #%-3d [ ", snapno)) else out:write(format(".... SNAP #%-3d [ ", snapno)) end printsnap(tr, snap) end end ------------------------------------------------------------------------------ local recprefix = "" local recdepth = 0 -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err end -- Dump trace states. local function dump_trace(what, tr, func, pc, otr, oex) if what == "stop" or (what == "abort" and dumpmode.a) then if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop") elseif dumpmode.s then dump_snap(tr) end if dumpmode.m then dump_mcode(tr) end end if what == "start" then if dumpmode.H then out:write('
\n') end
    out:write("---- TRACE ", tr, " ", what)
    if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
    out:write(" ", fmtfunc(func, pc), "\n")
  elseif what == "stop" or what == "abort" then
    out:write("---- TRACE ", tr, " ", what)
    if what == "abort" then
      out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
    else
      local info = traceinfo(tr)
      local link, ltype = info.link, info.linktype
      if link == tr or link == 0 then
	out:write(" -> ", ltype, "\n")
      elseif ltype == "root" then
	out:write(" -> ", link, "\n")
      else
	out:write(" -> ", link, " ", ltype, "\n")
      end
    end
    if dumpmode.H then out:write("
\n\n") else out:write("\n") end else if what == "flush" then symtab, nexitsym = {}, 0 end out:write("---- TRACE ", what, "\n\n") end out:flush() end -- Dump recorded bytecode. local function dump_record(tr, func, pc, depth, callee) if depth ~= recdepth then recdepth = depth recprefix = rep(" .", depth) end local line if pc >= 0 then line = bcline(func, pc, recprefix) if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end if pc > 0 then line = sub(line, 1, -2) .. " (" .. fmtfunc(func, pc) .. ")\n" end else line = "0000 "..recprefix.." FUNCC \n" callee = func end if pc <= 0 then out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n") else out:write(line) end if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond. end end ------------------------------------------------------------------------------ -- Dump taken trace exits. local function dump_texit(tr, ex, ngpr, nfpr, ...) out:write("---- TRACE ", tr, " exit ", ex, "\n") if dumpmode.X then local regs = {...} if jit.arch == "x64" then for i=1,ngpr do out:write(format(" %016x", regs[i])) if i % 4 == 0 then out:write("\n") end end else for i=1,ngpr do out:write(" ", tohex(regs[i])) if i % 8 == 0 then out:write("\n") end end end if jit.arch == "mips" or jit.arch == "mipsel" then for i=1,nfpr,2 do out:write(format(" %+17.14g", regs[ngpr+i])) if i % 8 == 7 then out:write("\n") end end else for i=1,nfpr do out:write(format(" %+17.14g", regs[ngpr+i])) if i % 4 == 0 then out:write("\n") end end end end end ------------------------------------------------------------------------------ -- Detach dump handlers. local function dumpoff() if active then active = false jit.attach(dump_texit) jit.attach(dump_record) jit.attach(dump_trace) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach dump handlers. local function dumpon(opt, outfile) if active then dumpoff() end local term = os.getenv("TERM") local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T" if opt then opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end) end local m = { t=true, b=true, i=true, m=true, } if opt and opt ~= "" then local o = sub(opt, 1, 1) if o ~= "+" and o ~= "-" then m = {} end for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end end dumpmode = m if m.t or m.b or m.i or m.s or m.m then jit.attach(dump_trace, "trace") end if m.b then jit.attach(dump_record, "record") if not bcline then bcline = require("jit.bc").line end end if m.x or m.X then jit.attach(dump_texit, "texit") end if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stdout end m[colormode] = true if colormode == "A" then colorize = colorize_ansi irtype = irtype_ansi elseif colormode == "H" then colorize = colorize_html irtype = irtype_html out:write(header_html) else colorize = colorize_text irtype = irtype_text end active = true end -- Public module functions. return { on = dumpon, off = dumpoff, start = dumpon -- For -j command line option. } ================================================ FILE: Assets/ToLua/Lua/jit/dump.lua.meta ================================================ fileFormatVersion: 2 guid: 4d03e3137c36cc2468b3fbc7d489f17e timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/p.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT profiler. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module is a simple command line interface to the built-in -- low-overhead profiler of LuaJIT. -- -- The lower-level API of the profiler is accessible via the "jit.profile" -- module or the luaJIT_profile_* C API. -- -- Example usage: -- -- luajit -jp myapp.lua -- luajit -jp=s myapp.lua -- luajit -jp=-s myapp.lua -- luajit -jp=vl myapp.lua -- luajit -jp=G,profile.txt myapp.lua -- -- The following dump features are available: -- -- f Stack dump: function name, otherwise module:line. Default mode. -- F Stack dump: ditto, but always prepend module. -- l Stack dump: module:line. -- stack dump depth (callee < caller). Default: 1. -- - Inverse stack dump depth (caller > callee). -- s Split stack dump after first stack level. Implies abs(depth) >= 2. -- p Show full path for module names. -- v Show VM states. Can be combined with stack dumps, e.g. vf or fv. -- z Show zones. Can be combined with stack dumps, e.g. zf or fz. -- r Show raw sample counts. Default: show percentages. -- a Annotate excerpts from source code files. -- A Annotate complete source code files. -- G Produce raw output suitable for graphical tools (e.g. flame graphs). -- m Minimum sample percentage to be shown. Default: 3. -- i Sampling interval in milliseconds. Default: 10. -- ---------------------------------------------------------------------------- -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local profile = require("jit.profile") local vmdef = require("jit.vmdef") local math = math local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor local sort, format = table.sort, string.format local stdout = io.stdout local zone -- Load jit.zone module on demand. -- Output file handle. local out ------------------------------------------------------------------------------ local prof_ud local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth local prof_ann, prof_count1, prof_count2, prof_samples local map_vmmode = { N = "Compiled", I = "Interpreted", C = "C code", G = "Garbage Collector", J = "JIT Compiler", } -- Profiler callback. local function prof_cb(th, samples, vmmode) prof_samples = prof_samples + samples local key_stack, key_stack2, key_state -- Collect keys for sample. if prof_states then if prof_states == "v" then key_state = map_vmmode[vmmode] or vmmode else key_state = zone:get() or "(none)" end end if prof_fmt then key_stack = profile.dumpstack(th, prof_fmt, prof_depth) key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x) return vmdef.ffnames[tonumber(x)] end) if prof_split == 2 then local k1, k2 = key_stack:match("(.-) [<>] (.*)") if k2 then key_stack, key_stack2 = k1, k2 end elseif prof_split == 3 then key_stack2 = profile.dumpstack(th, "l", 1) end end -- Order keys. local k1, k2 if prof_split == 1 then if key_state then k1 = key_state if key_stack then k2 = key_stack end end elseif key_stack then k1 = key_stack if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end end -- Coalesce samples in one or two levels. if k1 then local t1 = prof_count1 t1[k1] = (t1[k1] or 0) + samples if k2 then local t2 = prof_count2 local t3 = t2[k1] if not t3 then t3 = {}; t2[k1] = t3 end t3[k2] = (t3[k2] or 0) + samples end end end ------------------------------------------------------------------------------ -- Show top N list. local function prof_top(count1, count2, samples, indent) local t, n = {}, 0 for k in pairs(count1) do n = n + 1 t[n] = k end sort(t, function(a, b) return count1[a] > count1[b] end) for i=1,n do local k = t[i] local v = count1[k] local pct = floor(v*100/samples + 0.5) if pct < prof_min then break end if not prof_raw then out:write(format("%s%2d%% %s\n", indent, pct, k)) elseif prof_raw == "r" then out:write(format("%s%5d %s\n", indent, v, k)) else out:write(format("%s %d\n", k, v)) end if count2 then local r = count2[k] if r then prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or (prof_depth < 0 and " -> " or " <- ")) end end end end -- Annotate source code local function prof_annotate(count1, samples) local files = {} local ms = 0 for k, v in pairs(count1) do local pct = floor(v*100/samples + 0.5) ms = math.max(ms, v) if pct >= prof_min then local file, line = k:match("^(.*):(%d+)$") if not file then file = k; line = 0 end local fl = files[file] if not fl then fl = {}; files[file] = fl; files[#files+1] = file end line = tonumber(line) fl[line] = prof_raw and v or pct end end sort(files) local fmtv, fmtn = " %3d%% | %s\n", " | %s\n" if prof_raw then local n = math.max(5, math.ceil(math.log10(ms))) fmtv = "%"..n.."d | %s\n" fmtn = (" "):rep(n).." | %s\n" end local ann = prof_ann for _, file in ipairs(files) do local f0 = file:byte() if f0 == 40 or f0 == 91 then out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file)) break end local fp, err = io.open(file) if not fp then out:write(format("====== ERROR: %s: %s\n", file, err)) break end out:write(format("\n====== %s ======\n", file)) local fl = files[file] local n, show = 1, false if ann ~= 0 then for i=1,ann do if fl[i] then show = true; out:write("@@ 1 @@\n"); break end end end for line in fp:lines() do if line:byte() == 27 then out:write("[Cannot annotate bytecode file]\n") break end local v = fl[n] if ann ~= 0 then local v2 = fl[n+ann] if show then if v2 then show = n+ann elseif v then show = n elseif show+ann < n then show = false end elseif v2 then show = n+ann out:write(format("@@ %d @@\n", n)) end if not show then goto next end end if v then out:write(format(fmtv, v, line)) else out:write(format(fmtn, line)) end ::next:: n = n + 1 end fp:close() end end ------------------------------------------------------------------------------ -- Finish profiling and dump result. local function prof_finish() if prof_ud then profile.stop() local samples = prof_samples if samples == 0 then if prof_raw ~= true then out:write("[No samples collected]\n") end return end if prof_ann then prof_annotate(prof_count1, samples) else prof_top(prof_count1, prof_count2, samples, "") end prof_count1 = nil prof_count2 = nil prof_ud = nil end end -- Start profiling. local function prof_start(mode) local interval = "" mode = mode:gsub("i%d*", function(s) interval = s; return "" end) prof_min = 3 mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end) prof_depth = 1 mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end) local m = {} for c in mode:gmatch(".") do m[c] = c end prof_states = m.z or m.v if prof_states == "z" then zone = require("jit.zone") end local scope = m.l or m.f or m.F or (prof_states and "" or "f") local flags = (m.p or "") prof_raw = m.r if m.s then prof_split = 2 if prof_depth == -1 or m["-"] then prof_depth = -2 elseif prof_depth == 1 then prof_depth = 2 end elseif mode:find("[fF].*l") then scope = "l" prof_split = 3 else prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0 end prof_ann = m.A and 0 or (m.a and 3) if prof_ann then scope = "l" prof_fmt = "pl" prof_split = 0 prof_depth = 1 elseif m.G and scope ~= "" then prof_fmt = flags..scope.."Z;" prof_depth = -100 prof_raw = true prof_min = 0 elseif scope == "" then prof_fmt = false else local sc = prof_split == 3 and m.f or m.F or scope prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ") end prof_count1 = {} prof_count2 = {} prof_samples = 0 profile.start(scope:lower()..interval, prof_cb) prof_ud = newproxy(true) getmetatable(prof_ud).__gc = prof_finish end ------------------------------------------------------------------------------ local function start(mode, outfile) if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stdout end prof_start(mode or "f") end -- Public module functions. return { start = start, -- For -j command line option. stop = prof_finish } ================================================ FILE: Assets/ToLua/Lua/jit/p.lua.meta ================================================ fileFormatVersion: 2 guid: 413d3a4d59c39ea48b62dbb8f1b361c3 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/v.lua ================================================ ---------------------------------------------------------------------------- -- Verbose mode of the LuaJIT compiler. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module shows verbose information about the progress of the -- JIT compiler. It prints one line for each generated trace. This module -- is useful to see which code has been compiled or where the compiler -- punts and falls back to the interpreter. -- -- Example usage: -- -- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end" -- luajit -jv=myapp.out myapp.lua -- -- Default output is to stderr. To redirect the output to a file, pass a -- filename as an argument (use '-' for stdout) or set the environment -- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the -- module is started. -- -- The output from the first example should look like this: -- -- [TRACE 1 (command line):1 loop] -- [TRACE 2 (1/3) (command line):1 -> 1] -- -- The first number in each line is the internal trace number. Next are -- the file name ('(command line)') and the line number (':1') where the -- trace has started. Side traces also show the parent trace number and -- the exit number where they are attached to in parentheses ('(1/3)'). -- An arrow at the end shows where the trace links to ('-> 1'), unless -- it loops to itself. -- -- In this case the inner loop gets hot and is traced first, generating -- a root trace. Then the last exit from the 1st trace gets hot, too, -- and triggers generation of the 2nd trace. The side trace follows the -- path along the outer loop and *around* the inner loop, back to its -- start, and then links to the 1st trace. Yes, this may seem unusual, -- if you know how traditional compilers work. Trace compilers are full -- of surprises like this -- have fun! :-) -- -- Aborted traces are shown like this: -- -- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50] -- -- Don't worry -- trace aborts are quite common, even in programs which -- can be fully compiled. The compiler may retry several times until it -- finds a suitable trace. -- -- Of course this doesn't work with features that are not-yet-implemented -- (NYI error messages). The VM simply falls back to the interpreter. This -- may not matter at all if the particular trace is not very high up in -- the CPU usage profile. Oh, and the interpreter is quite fast, too. -- -- Also check out the -jdump module, which prints all the gory details. -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo local type, format = type, string.format local stdout, stderr = io.stdout, io.stderr -- Active flag and output file handle. local active, out ------------------------------------------------------------------------------ local startloc, startex local function fmtfunc(func, pc) local fi = funcinfo(func, pc) if fi.loc then return fi.loc elseif fi.ffid then return vmdef.ffnames[fi.ffid] elseif fi.addr then return format("C:%x", fi.addr) else return "(?)" end end -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err end -- Dump trace states. local function dump_trace(what, tr, func, pc, otr, oex) if what == "start" then startloc = fmtfunc(func, pc) startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or "" else if what == "abort" then local loc = fmtfunc(func, pc) if loc ~= startloc then out:write(format("[TRACE --- %s%s -- %s at %s]\n", startex, startloc, fmterr(otr, oex), loc)) else out:write(format("[TRACE --- %s%s -- %s]\n", startex, startloc, fmterr(otr, oex))) end elseif what == "stop" then local info = traceinfo(tr) local link, ltype = info.link, info.linktype if ltype == "interpreter" then out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n", tr, startex, startloc)) elseif ltype == "stitch" then out:write(format("[TRACE %3s %s%s %s %s]\n", tr, startex, startloc, ltype, fmtfunc(func, pc))) elseif link == tr or link == 0 then out:write(format("[TRACE %3s %s%s %s]\n", tr, startex, startloc, ltype)) elseif ltype == "root" then out:write(format("[TRACE %3s %s%s -> %d]\n", tr, startex, startloc, link)) else out:write(format("[TRACE %3s %s%s -> %d %s]\n", tr, startex, startloc, link, ltype)) end else out:write(format("[TRACE %s]\n", what)) end out:flush() end end ------------------------------------------------------------------------------ -- Detach dump handlers. local function dumpoff() if active then active = false jit.attach(dump_trace) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach dump handlers. local function dumpon(outfile) if active then dumpoff() end if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stderr end jit.attach(dump_trace, "trace") active = true end -- Public module functions. return { on = dumpon, off = dumpoff, start = dumpon -- For -j command line option. } ================================================ FILE: Assets/ToLua/Lua/jit/v.lua.meta ================================================ fileFormatVersion: 2 guid: e83d256a881de8f4ab20afb40ff611f7 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit/zone.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT profiler zones. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module implements a simple hierarchical zone model. -- -- Example usage: -- -- local zone = require("jit.zone") -- zone("AI") -- ... -- zone("A*") -- ... -- print(zone:get()) --> "A*" -- ... -- zone() -- ... -- print(zone:get()) --> "AI" -- ... -- zone() -- ---------------------------------------------------------------------------- local remove = table.remove return setmetatable({ flush = function(t) for i=#t,1,-1 do t[i] = nil end end, get = function(t) return t[#t] end }, { __call = function(t, zone) if zone then t[#t+1] = zone else return (assert(remove(t), "empty zone stack")) end end }) ================================================ FILE: Assets/ToLua/Lua/jit/zone.lua.meta ================================================ fileFormatVersion: 2 guid: af44e752354375746813d50c6d26b867 timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/jit.meta ================================================ fileFormatVersion: 2 guid: 7b8761c25aba4304482c7fd87688285a folderAsset: yes timeCreated: 1492692752 licenseType: Pro DefaultImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/list.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local setmetatable = setmetatable local list = {} list.__index = list function list:new() local t = {length = 0, _prev = 0, _next = 0} t._prev = t t._next = t return setmetatable(t, list) end function list:clear() self._next = self self._prev = self self.length = 0 end function list:push(value) --assert(value) local node = {value = value, _prev = 0, _next = 0, removed = false} self._prev._next = node node._next = self node._prev = self._prev self._prev = node self.length = self.length + 1 return node end function list:pushnode(node) if not node.removed then return end self._prev._next = node node._next = self node._prev = self._prev self._prev = node node.removed = false self.length = self.length + 1 end function list:pop() local _prev = self._prev self:remove(_prev) return _prev.value end function list:unshift(v) local node = {value = v, _prev = 0, _next = 0, removed = false} self._next._prev = node node._prev = self node._next = self._next self._next = node self.length = self.length + 1 return node end function list:shift() local _next = self._next self:remove(_next) return _next.value end function list:remove(iter) if iter.removed then return end local _prev = iter._prev local _next = iter._next _next._prev = _prev _prev._next = _next self.length = math.max(0, self.length - 1) iter.removed = true end function list:find(v, iter) iter = iter or self repeat if v == iter.value then return iter else iter = iter._next end until iter == self return nil end function list:findlast(v, iter) iter = iter or self repeat if v == iter.value then return iter end iter = iter._prev until iter == self return nil end function list:next(iter) local _next = iter._next if _next ~= self then return _next, _next.value end return nil end function list:prev(iter) local _prev = iter._prev if _prev ~= self then return _prev, _prev.value end return nil end function list:erase(v) local iter = self:find(v) if iter then self:remove(iter) end end function list:insert(v, iter) if not iter then return self:push(v) end local node = {value = v, _next = 0, _prev = 0, removed = false} if iter._next then iter._next._prev = node node._next = iter._next else self.last = node end node._prev = iter iter._next = node self.length = self.length + 1 return node end function list:head() return self._next.value end function list:tail() return self._prev.value end function list:clone() local t = list:new() for i, v in list.next, self, self do t:push(v) end return t end ilist = function(_list) return list.next, _list, _list end rilist = function(_list) return list.prev, _list, _list end setmetatable(list, {__call = list.new}) return list ================================================ FILE: Assets/ToLua/Lua/list.lua.meta ================================================ fileFormatVersion: 2 guid: f0d0ca55b7df3414aafaf11a39c13378 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/lpeg/re.lua ================================================ -- $Id: re.lua,v 1.44 2013/03/26 20:11:40 roberto Exp $ -- imported functions and modules local tonumber, type, print, error = tonumber, type, print, error local setmetatable = setmetatable local m = require"lpeg" -- 'm' will be used to parse expressions, and 'mm' will be used to -- create expressions; that is, 're' runs on 'm', creating patterns -- on 'mm' local mm = m -- pattern's metatable local mt = getmetatable(mm.P(0)) -- No more global accesses after this point local version = _VERSION if version == "Lua 5.2" then _ENV = nil end local any = m.P(1) -- Pre-defined names local Predef = { nl = m.P"\n" } local mem local fmem local gmem local function updatelocale () mm.locale(Predef) Predef.a = Predef.alpha Predef.c = Predef.cntrl Predef.d = Predef.digit Predef.g = Predef.graph Predef.l = Predef.lower Predef.p = Predef.punct Predef.s = Predef.space Predef.u = Predef.upper Predef.w = Predef.alnum Predef.x = Predef.xdigit Predef.A = any - Predef.a Predef.C = any - Predef.c Predef.D = any - Predef.d Predef.G = any - Predef.g Predef.L = any - Predef.l Predef.P = any - Predef.p Predef.S = any - Predef.s Predef.U = any - Predef.u Predef.W = any - Predef.w Predef.X = any - Predef.x mem = {} -- restart memoization fmem = {} gmem = {} local mt = {__mode = "v"} setmetatable(mem, mt) setmetatable(fmem, mt) setmetatable(gmem, mt) end updatelocale() local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end) local function getdef (id, defs) local c = defs and defs[id] if not c then error("undefined name: " .. id) end return c end local function patt_error (s, i) local msg = (#s < i + 20) and s:sub(i) or s:sub(i,i+20) .. "..." msg = ("pattern error near '%s'"):format(msg) error(msg, 2) end local function mult (p, n) local np = mm.P(true) while n >= 1 do if n%2 >= 1 then np = np * p end p = p * p n = n/2 end return np end local function equalcap (s, i, c) if type(c) ~= "string" then return nil end local e = #c + i if s:sub(i, e - 1) == c then return e else return nil end end local S = (Predef.space + "--" * (any - Predef.nl)^0)^0 local name = m.R("AZ", "az", "__") * m.R("AZ", "az", "__", "09")^0 local arrow = S * "<-" local seq_follow = m.P"/" + ")" + "}" + ":}" + "~}" + "|}" + (name * arrow) + -1 name = m.C(name) -- a defined name only have meaning in a given environment local Def = name * m.Carg(1) local num = m.C(m.R"09"^1) * S / tonumber local String = "'" * m.C((any - "'")^0) * "'" + '"' * m.C((any - '"')^0) * '"' local defined = "%" * Def / function (c,Defs) local cat = Defs and Defs[c] or Predef[c] if not cat then error ("name '" .. c .. "' undefined") end return cat end local Range = m.Cs(any * (m.P"-"/"") * (any - "]")) / mm.R local item = defined + Range + m.C(any) local Class = "[" * (m.C(m.P"^"^-1)) -- optional complement symbol * m.Cf(item * (item - "]")^0, mt.__add) / function (c, p) return c == "^" and any - p or p end * "]" local function adddef (t, k, exp) if t[k] then error("'"..k.."' already defined as a rule") else t[k] = exp end return t end local function firstdef (n, r) return adddef({n}, n, r) end local function NT (n, b) if not b then error("rule '"..n.."' used outside a grammar") else return mm.V(n) end end local exp = m.P{ "Exp", Exp = S * ( m.V"Grammar" + m.Cf(m.V"Seq" * ("/" * S * m.V"Seq")^0, mt.__add) ); Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix"^0 , mt.__mul) * (#seq_follow + patt_error); Prefix = "&" * S * m.V"Prefix" / mt.__len + "!" * S * m.V"Prefix" / mt.__unm + m.V"Suffix"; Suffix = m.Cf(m.V"Primary" * S * ( ( m.P"+" * m.Cc(1, mt.__pow) + m.P"*" * m.Cc(0, mt.__pow) + m.P"?" * m.Cc(-1, mt.__pow) + "^" * ( m.Cg(num * m.Cc(mult)) + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow)) ) + "->" * S * ( m.Cg((String + num) * m.Cc(mt.__div)) + m.P"{}" * m.Cc(nil, m.Ct) + m.Cg(Def / getdef * m.Cc(mt.__div)) ) + "=>" * S * m.Cg(Def / getdef * m.Cc(m.Cmt)) ) * S )^0, function (a,b,f) return f(a,b) end ); Primary = "(" * m.V"Exp" * ")" + String / mm.P + Class + defined + "{:" * (name * ":" + m.Cc(nil)) * m.V"Exp" * ":}" / function (n, p) return mm.Cg(p, n) end + "=" * name / function (n) return mm.Cmt(mm.Cb(n), equalcap) end + m.P"{}" / mm.Cp + "{~" * m.V"Exp" * "~}" / mm.Cs + "{|" * m.V"Exp" * "|}" / mm.Ct + "{" * m.V"Exp" * "}" / mm.C + m.P"." * m.Cc(any) + (name * -arrow + "<" * name * ">") * m.Cb("G") / NT; Definition = name * arrow * m.V"Exp"; Grammar = m.Cg(m.Cc(true), "G") * m.Cf(m.V"Definition" / firstdef * m.Cg(m.V"Definition")^0, adddef) / mm.P } local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error) local function compile (p, defs) if mm.type(p) == "pattern" then return p end -- already compiled local cp = pattern:match(p, 1, defs) if not cp then error("incorrect pattern", 3) end return cp end local function match (s, p, i) local cp = mem[p] if not cp then cp = compile(p) mem[p] = cp end return cp:match(s, i or 1) end local function find (s, p, i) local cp = fmem[p] if not cp then cp = compile(p) / 0 cp = mm.P{ mm.Cp() * cp * mm.Cp() + 1 * mm.V(1) } fmem[p] = cp end local i, e = cp:match(s, i or 1) if i then return i, e - 1 else return i end end local function gsub (s, p, rep) local g = gmem[p] or {} -- ensure gmem[p] is not collected while here gmem[p] = g local cp = g[rep] if not cp then cp = compile(p) cp = mm.Cs((cp / rep + 1)^0) g[rep] = cp end return cp:match(s) end -- exported names local re = { compile = compile, match = match, find = find, gsub = gsub, updatelocale = updatelocale, } if version == "Lua 5.1" then --I need this to work with strict.lua, sorry for breaking compatibility. --_G.re = re end return re ================================================ FILE: Assets/ToLua/Lua/lpeg/re.lua.meta ================================================ fileFormatVersion: 2 guid: b7e8b1ba4c06a4d4db879ad831cb62f1 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/lpeg.meta ================================================ fileFormatVersion: 2 guid: 58143f62c40fa4143903b5b1abc707fe folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/ltn12.lua ================================================ ----------------------------------------------------------------------------- -- LTN12 - Filters, sources, sinks and pumps. -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module ----------------------------------------------------------------------------- local string = require("string") local table = require("table") local unpack = unpack or table.unpack local base = _G local _M = {} if module then -- heuristic for exporting a global package table ltn12 = _M end local filter,source,sink,pump = {},{},{},{} _M.filter = filter _M.source = source _M.sink = sink _M.pump = pump local unpack = unpack or table.unpack local select = base.select -- 2048 seems to be better in windows... _M.BLOCKSIZE = 2048 _M._VERSION = "LTN12 1.0.3" ----------------------------------------------------------------------------- -- Filter stuff ----------------------------------------------------------------------------- -- returns a high level filter that cycles a low-level filter function filter.cycle(low, ctx, extra) base.assert(low) return function(chunk) local ret ret, ctx = low(ctx, chunk, extra) return ret end end -- chains a bunch of filters together -- (thanks to Wim Couwenberg) function filter.chain(...) local arg = {...} local n = base.select('#',...) local top, index = 1, 1 local retry = "" return function(chunk) retry = chunk and retry while true do if index == top then chunk = arg[index](chunk) if chunk == "" or top == n then return chunk elseif chunk then index = index + 1 else top = top+1 index = top end else chunk = arg[index](chunk or "") if chunk == "" then index = index - 1 chunk = retry elseif chunk then if index == n then return chunk else index = index + 1 end else base.error("filter returned inappropriate nil") end end end end end ----------------------------------------------------------------------------- -- Source stuff ----------------------------------------------------------------------------- -- create an empty source local function empty() return nil end function source.empty() return empty end -- returns a source that just outputs an error function source.error(err) return function() return nil, err end end -- creates a file source function source.file(handle, io_err) if handle then return function() local chunk = handle:read(_M.BLOCKSIZE) if not chunk then handle:close() end return chunk end else return source.error(io_err or "unable to open file") end end -- turns a fancy source into a simple source function source.simplify(src) base.assert(src) return function() local chunk, err_or_new = src() src = err_or_new or src if not chunk then return nil, err_or_new else return chunk end end end -- creates string source function source.string(s) if s then local i = 1 return function() local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1) i = i + _M.BLOCKSIZE if chunk ~= "" then return chunk else return nil end end else return source.empty() end end -- creates rewindable source function source.rewind(src) base.assert(src) local t = {} return function(chunk) if not chunk then chunk = table.remove(t) if not chunk then return src() else return chunk end else table.insert(t, chunk) end end end -- chains a source with one or several filter(s) function source.chain(src, f, ...) if ... then f=filter.chain(f, ...) end base.assert(src and f) local last_in, last_out = "", "" local state = "feeding" local err return function() if not last_out then base.error('source is empty!', 2) end while true do if state == "feeding" then last_in, err = src() if err then return nil, err end last_out = f(last_in) if not last_out then if last_in then base.error('filter returned inappropriate nil') else return nil end elseif last_out ~= "" then state = "eating" if last_in then last_in = "" end return last_out end else last_out = f(last_in) if last_out == "" then if last_in == "" then state = "feeding" else base.error('filter returned ""') end elseif not last_out then if last_in then base.error('filter returned inappropriate nil') else return nil end else return last_out end end end end end -- creates a source that produces contents of several sources, one after the -- other, as if they were concatenated -- (thanks to Wim Couwenberg) function source.cat(...) local arg = {...} local src = table.remove(arg, 1) return function() while src do local chunk, err = src() if chunk then return chunk end if err then return nil, err end src = table.remove(arg, 1) end end end ----------------------------------------------------------------------------- -- Sink stuff ----------------------------------------------------------------------------- -- creates a sink that stores into a table function sink.table(t) t = t or {} local f = function(chunk, err) if chunk then table.insert(t, chunk) end return 1 end return f, t end -- turns a fancy sink into a simple sink function sink.simplify(snk) base.assert(snk) return function(chunk, err) local ret, err_or_new = snk(chunk, err) if not ret then return nil, err_or_new end snk = err_or_new or snk return 1 end end -- creates a file sink function sink.file(handle, io_err) if handle then return function(chunk, err) if not chunk then handle:close() return 1 else return handle:write(chunk) end end else return sink.error(io_err or "unable to open file") end end -- creates a sink that discards data local function null() return 1 end function sink.null() return null end -- creates a sink that just returns an error function sink.error(err) return function() return nil, err end end -- chains a sink with one or several filter(s) function sink.chain(f, snk, ...) if ... then local args = { f, snk, ... } snk = table.remove(args, #args) f = filter.chain(unpack(args)) end base.assert(f and snk) return function(chunk, err) if chunk ~= "" then local filtered = f(chunk) local done = chunk and "" while true do local ret, snkerr = snk(filtered, err) if not ret then return nil, snkerr end if filtered == done then return 1 end filtered = f(done) end else return 1 end end end ----------------------------------------------------------------------------- -- Pump stuff ----------------------------------------------------------------------------- -- pumps one chunk from the source to the sink function pump.step(src, snk) local chunk, src_err = src() local ret, snk_err = snk(chunk, src_err) if chunk and ret then return 1 else return nil, src_err or snk_err end end -- pumps all data from a source to a sink, using a step function function pump.all(src, snk, step) base.assert(src and snk) step = step or pump.step while true do local ret, err = step(src, snk) if not ret then if err then return nil, err else return 1 end end end end return _M ================================================ FILE: Assets/ToLua/Lua/ltn12.lua.meta ================================================ fileFormatVersion: 2 guid: 6f6ae256ba8bd244692e687b1b0ece95 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/mime.lua ================================================ ----------------------------------------------------------------------------- -- MIME support for the Lua language. -- Author: Diego Nehab -- Conforming to RFCs 2045-2049 ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module and import dependencies ----------------------------------------------------------------------------- local base = _G local ltn12 = require("ltn12") local mime = require("mime.core") local io = require("io") local string = require("string") local _M = mime -- encode, decode and wrap algorithm tables local encodet, decodet, wrapt = {},{},{} _M.encodet = encodet _M.decodet = decodet _M.wrapt = wrapt -- creates a function that chooses a filter by name from a given table local function choose(table) return function(name, opt1, opt2) if base.type(name) ~= "string" then name, opt1, opt2 = "default", name, opt1 end local f = table[name or "nil"] if not f then base.error("unknown key (" .. base.tostring(name) .. ")", 3) else return f(opt1, opt2) end end end -- define the encoding filters encodet['base64'] = function() return ltn12.filter.cycle(_M.b64, "") end encodet['quoted-printable'] = function(mode) return ltn12.filter.cycle(_M.qp, "", (mode == "binary") and "=0D=0A" or "\r\n") end -- define the decoding filters decodet['base64'] = function() return ltn12.filter.cycle(_M.unb64, "") end decodet['quoted-printable'] = function() return ltn12.filter.cycle(_M.unqp, "") end local function format(chunk) if chunk then if chunk == "" then return "''" else return string.len(chunk) end else return "nil" end end -- define the line-wrap filters wrapt['text'] = function(length) length = length or 76 return ltn12.filter.cycle(_M.wrp, length, length) end wrapt['base64'] = wrapt['text'] wrapt['default'] = wrapt['text'] wrapt['quoted-printable'] = function() return ltn12.filter.cycle(_M.qpwrp, 76, 76) end -- function that choose the encoding, decoding or wrap algorithm _M.encode = choose(encodet) _M.decode = choose(decodet) _M.wrap = choose(wrapt) -- define the end-of-line normalization filter function _M.normalize(marker) return ltn12.filter.cycle(_M.eol, 0, marker) end -- high level stuffing filter function _M.stuff() return ltn12.filter.cycle(_M.dot, 2) end return _M ================================================ FILE: Assets/ToLua/Lua/mime.lua.meta ================================================ fileFormatVersion: 2 guid: 78de065ed4e50984eba196a41070d017 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/misc/functions.lua ================================================ local require = require local string = string local table = table int64.zero = int64.new(0,0) uint64.zero = uint64.new(0,0) function string.split(input, delimiter) input = tostring(input) delimiter = tostring(delimiter) if (delimiter=='') then return false end local pos,arr = 0, {} -- for each divider found for st,sp in function() return string.find(input, delimiter, pos, true) end do table.insert(arr, string.sub(input, pos, st - 1)) pos = sp + 1 end table.insert(arr, string.sub(input, pos)) return arr end function import(moduleName, currentModuleName) local currentModuleNameParts local moduleFullName = moduleName local offset = 1 while true do if string.byte(moduleName, offset) ~= 46 then -- . moduleFullName = string.sub(moduleName, offset) if currentModuleNameParts and #currentModuleNameParts > 0 then moduleFullName = table.concat(currentModuleNameParts, ".") .. "." .. moduleFullName end break end offset = offset + 1 if not currentModuleNameParts then if not currentModuleName then local n,v = debug.getlocal(3, 1) currentModuleName = v end currentModuleNameParts = string.split(currentModuleName, ".") end table.remove(currentModuleNameParts, #currentModuleNameParts) end return require(moduleFullName) end --重新require一个lua文件,替代系统文件。 function reimport(name) local package = package package.loaded[name] = nil package.preload[name] = nil return require(name) end ================================================ FILE: Assets/ToLua/Lua/misc/functions.lua.meta ================================================ fileFormatVersion: 2 guid: 7ad071edc48d0d8469028957a2df9c67 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/misc/strict.lua ================================================ -- -- strict.lua -- checks uses of undeclared global variables -- All global variables must be 'declared' through a regular assignment -- (even assigning nil will do) in a main chunk before being used -- anywhere or assigned to inside a function. -- -- modified for better compatibility with LuaJIT, see: -- http://www.freelists.org/post/luajit/strictlua-with-stripped-bytecode local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget local mt = getmetatable(_G) if mt == nil then mt = {} setmetatable(_G, mt) end mt.__declared = {} mt.__newindex = function (t, n, v) if not mt.__declared[n] then local info = getinfo(2, "S") if info and info.linedefined > 0 then error("assign to undeclared variable '"..n.."'", 2) end mt.__declared[n] = true end rawset(t, n, v) end mt.__index = function (t, n) if not mt.__declared[n] then local info = getinfo(2, "S") if info and info.linedefined > 0 then error("variable '"..n.."' is not declared", 2) end end return rawget(t, n) end ================================================ FILE: Assets/ToLua/Lua/misc/strict.lua.meta ================================================ fileFormatVersion: 2 guid: 4df6e3671aafc8e4d82fee6a2cf5948e DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/misc/utf8.lua ================================================ local utf8 = {} --byte index of the next char after the char at byte index i, followed by a valid flag for the char at byte index i. --nil if not found. invalid characters are iterated as 1-byte chars. function utf8.next_raw(s, i) if not i then if #s == 0 then return nil end return 1, true --fake flag (doesn't matter since this flag is not to be taken as full validation) end if i > #s then return end local c = s:byte(i) if c >= 0x00 and c <= 0x7F then i = i + 1 elseif c >= 0xC2 and c <= 0xDF then i = i + 2 elseif c >= 0xE0 and c <= 0xEF then i = i + 3 elseif c >= 0xF0 and c <= 0xF4 then i = i + 4 else --invalid return i + 1, false end if i > #s then return end return i, true end --next() is the generic iterator and can be replaced for different semantics. next_raw() must preserve its semantics. utf8.next = utf8.next_raw --iterate chars, returning the byte index where each char starts function utf8.byte_indices(s, previ) return utf8.next, s, previ end --number of chars in string function utf8.len(s) assert(s, "bad argument #1 to 'len' (string expected, got nil)") local len = 0 for _ in utf8.byte_indices(s) do len = len + 1 end return len end --byte index given char index. nil if the index is outside the string. function utf8.byte_index(s, target_ci) if target_ci < 1 then return end local ci = 0 for i in utf8.byte_indices(s) do ci = ci + 1 if ci == target_ci then return i end end assert(target_ci > ci, "invalid index") end --char index given byte index. nil if the index is outside the string. function utf8.char_index(s, target_i) if target_i < 1 or target_i > #s then return end local ci = 0 for i in utf8.byte_indices(s) do ci = ci + 1 if i == target_i then return ci end end error("invalid index") end --byte index of the prev. char before the char at byte index i, which defaults to #s + 1. --nil if the index is outside the 2..#s+1 range. --NOTE: unlike next(), this is a O(N) operation! function utf8.prev(s, nexti) nexti = nexti or #s + 1 if nexti <= 1 or nexti > #s + 1 then return end local lasti, lastvalid = utf8.next(s) for i, valid in utf8.byte_indices(s) do if i == nexti then return lasti, lastvalid end lasti, lastvalid = i, valid end if nexti == #s + 1 then return lasti, lastvalid end error("invalid index") end --iterate chars in reverse order, returning the byte index where each char starts. function utf8.byte_indices_reverse(s, nexti) if #s < 200 then --using prev() is a O(N^2/2) operation, ok for small strings (200 chars need 40,000 iterations) return utf8.prev, s, nexti else --store byte indices in a table and iterate them in reverse. --this is 40x slower than byte_indices() but still fast at 2mil chars/second (but eats RAM and makes garbage). local t = {} for i in utf8.byte_indices(s) do if nexti and i >= nexti then break end table.insert(t, i) end local i = #t + 1 return function() i = i - 1 return t[i] end end end --sub based on char indices, which, unlike with standard string.sub(), can't be negative. --start_ci can be 1..inf and end_ci can be 0..inf. end_ci can be nil meaning last char. --if start_ci is out of range or end_ci < start_ci, the empty string is returned. --if end_ci is out of range, it is considered to be the last position in the string. function utf8.sub(s, start_ci, end_ci) --assert for positive indices because we might implement negative indices in the future. assert(start_ci >= 1) assert(not end_ci or end_ci >= 0) local ci = 0 local start_i, end_i for i in utf8.byte_indices(s) do ci = ci + 1 if ci == start_ci then start_i = i end if ci == end_ci then end_i = i end end if not start_i then assert(start_ci > ci, 'invalid index') return '' end if end_ci and not end_i then if end_ci < start_ci then return '' end assert(end_ci > ci, 'invalid index') end return s:sub(start_i, end_i and end_i - 1) end --check if a string contains a substring at byte index i without making garbage. --nil if the index is out of range. true if searching for the empty string. function utf8.contains(s, i, sub) if i < 1 or i > #s then return nil end for si = 1, #sub do if s:byte(i + si - 1) ~= sub:byte(si) then return false end end return true end --count the number of occurences of a substring in a string. the substring cannot be the empty string. function utf8.count(s, sub) assert(#sub > 0) local count = 0 local i = 1 while i do if utf8.contains(s, i, sub) then count = count + 1 i = i + #sub if i > #s then break end else i = utf8.next(s, i) end end return count end --utf8 validation and sanitization --check if there's a valid utf8 codepoint at byte index i. valid ranges for each utf8 byte are: -- byte 1 2 3 4 -------------------------------------------- -- 00 - 7F -- C2 - DF 80 - BF -- E0 A0 - BF 80 - BF -- E1 - EC 80 - BF 80 - BF -- ED 80 - 9F 80 - BF -- EE - EF 80 - BF 80 - BF -- F0 90 - BF 80 - BF 80 - BF -- F1 - F3 80 - BF 80 - BF 80 - BF -- F4 80 - 8F 80 - BF 80 - BF function utf8.isvalid(s, i) local c = s:byte(i) if not c then return false elseif c >= 0x00 and c <= 0x7F then return true elseif c >= 0xC2 and c <= 0xDF then local c2 = s:byte(i + 1) return c2 and c2 >= 0x80 and c2 <= 0xBF elseif c >= 0xE0 and c <= 0xEF then local c2 = s:byte(i + 1) local c3 = s:byte(i + 2) if c == 0xE0 then return c2 and c3 and c2 >= 0xA0 and c2 <= 0xBF and c3 >= 0x80 and c3 <= 0xBF elseif c >= 0xE1 and c <= 0xEC then return c2 and c3 and c2 >= 0x80 and c2 <= 0xBF and c3 >= 0x80 and c3 <= 0xBF elseif c == 0xED then return c2 and c3 and c2 >= 0x80 and c2 <= 0x9F and c3 >= 0x80 and c3 <= 0xBF elseif c >= 0xEE and c <= 0xEF then if c == 0xEF and c2 == 0xBF and (c3 == 0xBE or c3 == 0xBF) then return false --uFFFE and uFFFF non-characters end return c2 and c3 and c2 >= 0x80 and c2 <= 0xBF and c3 >= 0x80 and c3 <= 0xBF end elseif c >= 0xF0 and c <= 0xF4 then local c2 = s:byte(i + 1) local c3 = s:byte(i + 2) local c4 = s:byte(i + 3) if c == 0xF0 then return c2 and c3 and c4 and c2 >= 0x90 and c2 <= 0xBF and c3 >= 0x80 and c3 <= 0xBF and c4 >= 0x80 and c4 <= 0xBF elseif c >= 0xF1 and c <= 0xF3 then return c2 and c3 and c4 and c2 >= 0x80 and c2 <= 0xBF and c3 >= 0x80 and c3 <= 0xBF and c4 >= 0x80 and c4 <= 0xBF elseif c == 0xF4 then return c2 and c3 and c4 and c2 >= 0x80 and c2 <= 0x8F and c3 >= 0x80 and c3 <= 0xBF and c4 >= 0x80 and c4 <= 0xBF end end return false end --byte index of the next valid utf8 char after the char at byte index i. --nil if indices go out of range. invalid characters are skipped. function utf8.next_valid(s, i) local valid i, valid = utf8.next_raw(s, i) while i and (not valid or not utf8.isvalid(s, i)) do i, valid = utf8.next(s, i) end return i end --iterate valid chars, returning the byte index where each char starts function utf8.valid_byte_indices(s) return utf8.next_valid, s end --assert that a string only contains valid utf8 characters function utf8.validate(s) for i, valid in utf8.byte_indices(s) do if not valid or not utf8.isvalid(s, i) then error(string.format('invalid utf8 char at #%d', i)) end end end local function table_lookup(s, i, j, t) return t[s:sub(i, j)] end --replace characters in string based on a function f(s, i, j, ...) -> replacement_string | nil function utf8.replace(s, f, ...) if type(f) == 'table' then return utf8.replace(s, table_lookup, f) end if s == '' then return s end local t = {} local lasti = 1 for i in utf8.byte_indices(s) do local nexti = utf8.next(s, i) or #s + 1 local repl = f(s, i, nexti - 1, ...) if repl then table.insert(t, s:sub(lasti, i - 1)) table.insert(t, repl) lasti = nexti end end table.insert(t, s:sub(lasti)) return table.concat(t) end local function replace_invalid(s, i, j, repl_char) if not utf8.isvalid(s, i) then return repl_char end end --replace invalid utf8 chars with a replacement char function utf8.sanitize(s, repl_char) repl_char = repl_char or '�' --\uFFFD return utf8.replace(s, replace_invalid, repl_char) end return utf8 ================================================ FILE: Assets/ToLua/Lua/misc/utf8.lua.meta ================================================ fileFormatVersion: 2 guid: c7ac60fc5e653564588e60deb91863ee DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/misc.meta ================================================ fileFormatVersion: 2 guid: 08e54c61aaaa7c545b03c37c12e41df1 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/pbc.meta ================================================ fileFormatVersion: 2 guid: b90e9a8a37d474c4fa8fdcf856eeb7e8 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: ================================================ FILE: Assets/ToLua/Lua/protobuf/containers.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: containers.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- -- COMPANY: NetEase -- CREATED: 2010年08月02日 16时15分42秒 CST -------------------------------------------------------------------------------- -- local setmetatable = setmetatable local table = table local rawset = rawset local error = error module "protobuf.containers" local _RCFC_meta = { add = function(self) local value = self._message_descriptor._concrete_class() local listener = self._listener rawset(self, #self + 1, value) value:_SetListener(listener) if listener.dirty == false then listener:Modified() end return value end, remove = function(self, key) local listener = self._listener table.remove(self, key) listener:Modified() end, __newindex = function(self, key, value) error("RepeatedCompositeFieldContainer Can't set value directly") end } _RCFC_meta.__index = _RCFC_meta function RepeatedCompositeFieldContainer(listener, message_descriptor) local o = { _listener = listener, _message_descriptor = message_descriptor } return setmetatable(o, _RCFC_meta) end local _RSFC_meta = { append = function(self, value) self._type_checker(value) rawset(self, #self + 1, value) self._listener:Modified() end, remove = function(self, key) table.remove(self, key) self._listener:Modified() end, __newindex = function(self, key, value) error("RepeatedCompositeFieldContainer Can't set value directly") end } _RSFC_meta.__index = _RSFC_meta function RepeatedScalarFieldContainer(listener, type_checker) local o = {} o._listener = listener o._type_checker = type_checker return setmetatable(o, _RSFC_meta) end ================================================ FILE: Assets/ToLua/Lua/protobuf/containers.lua.meta ================================================ fileFormatVersion: 2 guid: b091e6d28e2ea5b469fa0ef87c372f3a DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/decoder.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: decoder.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- -- COMPANY: NetEase -- CREATED: 2010年07月29日 19时30分51秒 CST -------------------------------------------------------------------------------- -- local string = string local table = table local assert = assert local ipairs = ipairs local error = error local print = print local pb = require "pb" local encoder = require "protobuf.encoder" local wire_format = require "protobuf.wire_format" module "protobuf.decoder" local _DecodeVarint = pb.varint_decoder local _DecodeSignedVarint = pb.signed_varint_decoder local _DecodeVarint32 = pb.varint_decoder local _DecodeSignedVarint32 = pb.signed_varint_decoder local _DecodeVarint64 = pb.varint_decoder64 local _DecodeSignedVarint64 = pb.signed_varint_decoder64 ReadTag = pb.read_tag local function _SimpleDecoder(wire_type, decode_value) return function(field_number, is_repeated, is_packed, key, new_default) if is_packed then local DecodeVarint = _DecodeVarint return function (buffer, pos, pend, message, field_dict) local value = field_dict[key] if value == nil then value = new_default(message) field_dict[key] = value end local endpoint endpoint, pos = DecodeVarint(buffer, pos) endpoint = endpoint + pos if endpoint > pend then error('Truncated message.') end local element while pos < endpoint do element, pos = decode_value(buffer, pos) value[#value + 1] = element end if pos > endpoint then value:remove(#value) error('Packed element was truncated.') end return pos end elseif is_repeated then local tag_bytes = encoder.TagBytes(field_number, wire_type) local tag_len = #tag_bytes local sub = string.sub return function(buffer, pos, pend, message, field_dict) local value = field_dict[key] if value == nil then value = new_default(message) field_dict[key] = value end while 1 do local element, new_pos = decode_value(buffer, pos) value:append(element) pos = new_pos + tag_len if sub(buffer, new_pos+1, pos) ~= tag_bytes or new_pos >= pend then if new_pos > pend then error('Truncated message.') end return new_pos end end end else return function (buffer, pos, pend, message, field_dict) field_dict[key], pos = decode_value(buffer, pos) if pos > pend then field_dict[key] = nil error('Truncated message.') end return pos end end end end local function _ModifiedDecoder(wire_type, decode_value, modify_value) local InnerDecode = function (buffer, pos) local result, new_pos = decode_value(buffer, pos) return modify_value(result), new_pos end return _SimpleDecoder(wire_type, InnerDecode) end local function _StructPackDecoder(wire_type, value_size, format) local struct_unpack = pb.struct_unpack function InnerDecode(buffer, pos) local new_pos = pos + value_size local result = struct_unpack(format, buffer, pos) return result, new_pos end return _SimpleDecoder(wire_type, InnerDecode) end local function _Boolean(value) return value ~= 0 end Int32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32) EnumDecoder = Int32Decoder Int64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint64) UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint64) SInt32Decoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode32) SInt64Decoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint64, wire_format.ZigZagDecode64) Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('I')) Fixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('Q')) SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('i')) SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('q')) FloatDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('f')) DoubleDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('d')) BoolDecoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint, _Boolean) function StringDecoder(field_number, is_repeated, is_packed, key, new_default) local DecodeVarint = _DecodeVarint local sub = string.sub -- local unicode = unicode assert(not is_packed) if is_repeated then local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local tag_len = #tag_bytes return function (buffer, pos, pend, message, field_dict) local value = field_dict[key] if value == nil then value = new_default(message) field_dict[key] = value end while 1 do local size, new_pos size, pos = DecodeVarint(buffer, pos) new_pos = pos + size if new_pos > pend then error('Truncated string.') end value:append(sub(buffer, pos+1, new_pos)) pos = new_pos + tag_len if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then return new_pos end end end else return function (buffer, pos, pend, message, field_dict) local size, new_pos size, pos = DecodeVarint(buffer, pos) new_pos = pos + size if new_pos > pend then error('Truncated string.') end field_dict[key] = sub(buffer, pos + 1, new_pos) return new_pos end end end function BytesDecoder(field_number, is_repeated, is_packed, key, new_default) local DecodeVarint = _DecodeVarint local sub = string.sub assert(not is_packed) if is_repeated then local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local tag_len = #tag_bytes return function (buffer, pos, pend, message, field_dict) local value = field_dict[key] if value == nil then value = new_default(message) field_dict[key] = value end while 1 do local size, new_pos size, pos = DecodeVarint(buffer, pos) new_pos = pos + size if new_pos > pend then error('Truncated string.') end value:append(sub(buffer, pos + 1, new_pos)) pos = new_pos + tag_len if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then return new_pos end end end else return function(buffer, pos, pend, message, field_dict) local size, new_pos size, pos = DecodeVarint(buffer, pos) new_pos = pos + size if new_pos > pend then error('Truncated string.') end field_dict[key] = sub(buffer, pos + 1, new_pos) return new_pos end end end function MessageDecoder(field_number, is_repeated, is_packed, key, new_default) local DecodeVarint = _DecodeVarint local sub = string.sub assert(not is_packed) if is_repeated then local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local tag_len = #tag_bytes return function (buffer, pos, pend, message, field_dict) local value = field_dict[key] if value == nil then value = new_default(message) field_dict[key] = value end while 1 do local size, new_pos size, pos = DecodeVarint(buffer, pos) new_pos = pos + size if new_pos > pend then error('Truncated message.') end if value:add():_InternalParse(buffer, pos, new_pos) ~= new_pos then error('Unexpected end-group tag.') end pos = new_pos + tag_len if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then return new_pos end end end else return function (buffer, pos, pend, message, field_dict) local value = field_dict[key] if value == nil then value = new_default(message) field_dict[key] = value end local size, new_pos size, pos = DecodeVarint(buffer, pos) new_pos = pos + size if new_pos > pend then error('Truncated message.') end if value:_InternalParse(buffer, pos, new_pos) ~= new_pos then error('Unexpected end-group tag.') end return new_pos end end end function _SkipVarint(buffer, pos, pend) local value value, pos = _DecodeVarint(buffer, pos) return pos end function _SkipFixed64(buffer, pos, pend) pos = pos + 8 if pos > pend then error('Truncated message.') end return pos end function _SkipLengthDelimited(buffer, pos, pend) local size size, pos = _DecodeVarint(buffer, pos) pos = pos + size if pos > pend then error('Truncated message.') end return pos end function _SkipFixed32(buffer, pos, pend) pos = pos + 4 if pos > pend then error('Truncated message.') end return pos end function _RaiseInvalidWireType(buffer, pos, pend) error('Tag had invalid wire type.') end function _FieldSkipper() WIRETYPE_TO_SKIPPER = { _SkipVarint, _SkipFixed64, _SkipLengthDelimited, _SkipGroup, _EndGroup, _SkipFixed32, _RaiseInvalidWireType, _RaiseInvalidWireType, } -- wiretype_mask = wire_format.TAG_TYPE_MASK local ord = string.byte local sub = string.sub return function (buffer, pos, pend, tag_bytes) local wire_type = ord(sub(tag_bytes, 1, 1)) % 8 + 1 return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, pend) end end SkipField = _FieldSkipper() ================================================ FILE: Assets/ToLua/Lua/protobuf/decoder.lua.meta ================================================ fileFormatVersion: 2 guid: 99e0d332d92e1c44ca56267a2b3bdcf9 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/descriptor.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: descriptor.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- -- COMPANY: NetEase -- CREATED: 2010年08月11日 18时45分43秒 CST -------------------------------------------------------------------------------- -- module "protobuf.descriptor" FieldDescriptor = { TYPE_DOUBLE = 1, TYPE_FLOAT = 2, TYPE_INT64 = 3, TYPE_UINT64 = 4, TYPE_INT32 = 5, TYPE_FIXED64 = 6, TYPE_FIXED32 = 7, TYPE_BOOL = 8, TYPE_STRING = 9, TYPE_GROUP = 10, TYPE_MESSAGE = 11, TYPE_BYTES = 12, TYPE_UINT32 = 13, TYPE_ENUM = 14, TYPE_SFIXED32 = 15, TYPE_SFIXED64 = 16, TYPE_SINT32 = 17, TYPE_SINT64 = 18, MAX_TYPE = 18, -- Must be consistent with C++ FieldDescriptor::CppType enum in -- descriptor.h. -- CPPTYPE_INT32 = 1, CPPTYPE_INT64 = 2, CPPTYPE_UINT32 = 3, CPPTYPE_UINT64 = 4, CPPTYPE_DOUBLE = 5, CPPTYPE_FLOAT = 6, CPPTYPE_BOOL = 7, CPPTYPE_ENUM = 8, CPPTYPE_STRING = 9, CPPTYPE_MESSAGE = 10, MAX_CPPTYPE = 10, -- Must be consistent with C++ FieldDescriptor::Label enum in -- descriptor.h. -- LABEL_OPTIONAL = 1, LABEL_REQUIRED = 2, LABEL_REPEATED = 3, MAX_LABEL = 3 } ================================================ FILE: Assets/ToLua/Lua/protobuf/descriptor.lua.meta ================================================ fileFormatVersion: 2 guid: ec5270fc0e79e1140be77c303c4874c4 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/encoder.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: encoder.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- -- COMPANY: NetEase -- CREATED: 2010年07月29日 19时30分46秒 CST -------------------------------------------------------------------------------- -- local string = string local table = table local ipairs = ipairs local assert =assert local pb = require "pb" local wire_format = require "protobuf.wire_format" module "protobuf.encoder" function _VarintSize(value) if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end if value <= 0x7ffffffff then return 5 end if value <= 0x3ffffffffff then return 6 end if value <= 0x1ffffffffffff then return 7 end if value <= 0xffffffffffffff then return 8 end if value <= 0x7fffffffffffffff then return 9 end return 10 end function _SignedVarintSize(value) if value < 0 then return 10 end if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end if value <= 0x7ffffffff then return 5 end if value <= 0x3ffffffffff then return 6 end if value <= 0x1ffffffffffff then return 7 end if value <= 0xffffffffffffff then return 8 end if value <= 0x7fffffffffffffff then return 9 end return 10 end function _TagSize(field_number) return _VarintSize(wire_format.PackTag(field_number, 0)) end function _SimpleSizer(compute_value_size) return function(field_number, is_repeated, is_packed) local tag_size = _TagSize(field_number) if is_packed then local VarintSize = _VarintSize return function(value) local result = 0 for _, element in ipairs(value) do result = result + compute_value_size(element) end return result + VarintSize(result) + tag_size end elseif is_repeated then return function(value) local result = tag_size * #value for _, element in ipairs(value) do result = result + compute_value_size(element) end return result end else return function (value) return tag_size + compute_value_size(value) end end end end function _ModifiedSizer(compute_value_size, modify_value) return function (field_number, is_repeated, is_packed) local tag_size = _TagSize(field_number) if is_packed then local VarintSize = _VarintSize return function (value) local result = 0 for _, element in ipairs(value) do result = result + compute_value_size(modify_value(element)) end return result + VarintSize(result) + tag_size end elseif is_repeated then return function (value) local result = tag_size * #value for _, element in ipairs(value) do result = result + compute_value_size(modify_value(element)) end return result end else return function (value) return tag_size + compute_value_size(modify_value(value)) end end end end function _FixedSizer(value_size) return function (field_number, is_repeated, is_packed) local tag_size = _TagSize(field_number) if is_packed then local VarintSize = _VarintSize return function (value) local result = #value * value_size return result + VarintSize(result) + tag_size end elseif is_repeated then local element_size = value_size + tag_size return function(value) return #value * element_size end else local field_size = value_size + tag_size return function (value) return field_size end end end end Int32Sizer = _SimpleSizer(_SignedVarintSize) Int64Sizer = _SimpleSizer(pb.signed_varint_size) EnumSizer = Int32Sizer UInt32Sizer = _SimpleSizer(_VarintSize) UInt64Sizer = _SimpleSizer(pb.varint_size) SInt32Sizer = _ModifiedSizer(_SignedVarintSize, wire_format.ZigZagEncode32) SInt64Sizer = SInt32Sizer Fixed32Sizer = _FixedSizer(4) SFixed32Sizer = Fixed32Sizer FloatSizer = Fixed32Sizer Fixed64Sizer = _FixedSizer(8) SFixed64Sizer = Fixed64Sizer DoubleSizer = Fixed64Sizer BoolSizer = _FixedSizer(1) function StringSizer(field_number, is_repeated, is_packed) local tag_size = _TagSize(field_number) local VarintSize = _VarintSize assert(not is_packed) if is_repeated then return function(value) local result = tag_size * #value for _, element in ipairs(value) do local l = #element result = result + VarintSize(l) + l end return result end else return function(value) local l = #value return tag_size + VarintSize(l) + l end end end function BytesSizer(field_number, is_repeated, is_packed) local tag_size = _TagSize(field_number) local VarintSize = _VarintSize assert(not is_packed) if is_repeated then return function (value) local result = tag_size * #value for _,element in ipairs(value) do local l = #element result = result + VarintSize(l) + l end return result end else return function (value) local l = #value return tag_size + VarintSize(l) + l end end end function MessageSizer(field_number, is_repeated, is_packed) local tag_size = _TagSize(field_number) local VarintSize = _VarintSize assert(not is_packed) if is_repeated then return function(value) local result = tag_size * #value for _,element in ipairs(value) do local l = element:ByteSize() result = result + VarintSize(l) + l end return result end else return function (value) local l = value:ByteSize() return tag_size + VarintSize(l) + l end end end -- ==================================================================== -- Encoders! local _EncodeVarint = pb.varint_encoder local _EncodeSignedVarint = pb.signed_varint_encoder local _EncodeVarint64 = pb.varint_encoder64 local _EncodeSignedVarint64 = pb.signed_varint_encoder64 function _VarintBytes(value) local out = {} local write = function(value) out[#out + 1 ] = value end _EncodeSignedVarint(write, value) return table.concat(out) end function TagBytes(field_number, wire_type) return _VarintBytes(wire_format.PackTag(field_number, wire_type)) end function _SimpleEncoder(wire_type, encode_value, compute_value_size) return function(field_number, is_repeated, is_packed) if is_packed then local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local EncodeVarint = _EncodeVarint return function(write, value) write(tag_bytes) local size = 0 for _, element in ipairs(value) do size = size + compute_value_size(element) end EncodeVarint(write, size) for element in value do encode_value(write, element) end end elseif is_repeated then local tag_bytes = TagBytes(field_number, wire_type) return function(write, value) for _, element in ipairs(value) do write(tag_bytes) encode_value(write, element) end end else local tag_bytes = TagBytes(field_number, wire_type) return function(write, value) write(tag_bytes) encode_value(write, value) end end end end function _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value) return function (field_number, is_repeated, is_packed) if is_packed then local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local EncodeVarint = _EncodeVarint return function (write, value) write(tag_bytes) local size = 0 for _, element in ipairs(value) do size = size + compute_value_size(modify_value(element)) end EncodeVarint(write, size) for _, element in ipairs(value) do encode_value(write, modify_value(element)) end end elseif is_repeated then local tag_bytes = TagBytes(field_number, wire_type) return function (write, value) for _, element in ipairs(value) do write(tag_bytes) encode_value(write, modify_value(element)) end end else local tag_bytes = TagBytes(field_number, wire_type) return function (write, value) write(tag_bytes) encode_value(write, modify_value(value)) end end end end function _StructPackEncoder(wire_type, value_size, format) return function(field_number, is_repeated, is_packed) local struct_pack = pb.struct_pack if is_packed then local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local EncodeVarint = _EncodeVarint return function (write, value) write(tag_bytes) EncodeVarint(write, #value * value_size) for _, element in ipairs(value) do struct_pack(write, format, element) end end elseif is_repeated then local tag_bytes = TagBytes(field_number, wire_type) return function (write, value) for _, element in ipairs(value) do write(tag_bytes) struct_pack(write, format, element) end end else local tag_bytes = TagBytes(field_number, wire_type) return function (write, value) write(tag_bytes) struct_pack(write, format, value) end end end end Int32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize) Int64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint64, _SignedVarintSize) EnumEncoder = Int32Encoder UInt32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize) UInt64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize) SInt32Encoder = _ModifiedEncoder( wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize, wire_format.ZigZagEncode32) SInt64Encoder = _ModifiedEncoder( wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize, wire_format.ZigZagEncode64) Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('I')) Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('Q')) SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('i')) SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('q')) FloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('f')) DoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('d')) function BoolEncoder(field_number, is_repeated, is_packed) local false_byte = '\0' local true_byte = '\1' if is_packed then local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local EncodeVarint = _EncodeVarint return function (write, value) write(tag_bytes) EncodeVarint(write, #value) for _, element in ipairs(value) do if element then write(true_byte) else write(false_byte) end end end elseif is_repeated then local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) return function(write, value) for _, element in ipairs(value) do write(tag_bytes) if element then write(true_byte) else write(false_byte) end end end else local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) return function (write, value) write(tag_bytes) if value then return write(true_byte) end return write(false_byte) end end end function StringEncoder(field_number, is_repeated, is_packed) local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local EncodeVarint = _EncodeVarint assert(not is_packed) if is_repeated then return function (write, value) for _, element in ipairs(value) do -- encoded = element.encode('utf-8') write(tag) EncodeVarint(write, #element) write(element) end end else return function (write, value) -- local encoded = value.encode('utf-8') write(tag) EncodeVarint(write, #value) return write(value) end end end function BytesEncoder(field_number, is_repeated, is_packed) local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local EncodeVarint = _EncodeVarint assert(not is_packed) if is_repeated then return function (write, value) for _, element in ipairs(value) do write(tag) EncodeVarint(write, #element) write(element) end end else return function(write, value) write(tag) EncodeVarint(write, #value) return write(value) end end end function MessageEncoder(field_number, is_repeated, is_packed) local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local EncodeVarint = _EncodeVarint assert(not is_packed) if is_repeated then return function(write, value) for _, element in ipairs(value) do write(tag) EncodeVarint(write, element:ByteSize()) element:_InternalSerialize(write) end end else return function (write, value) write(tag) EncodeVarint(write, value:ByteSize()) return value:_InternalSerialize(write) end end end ================================================ FILE: Assets/ToLua/Lua/protobuf/encoder.lua.meta ================================================ fileFormatVersion: 2 guid: 59c27d5459f0dfc4ab1077ce6f391ea9 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/listener.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: listener.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- -- COMPANY: NetEase -- CREATED: 2010年08月02日 17时35分25秒 CST -------------------------------------------------------------------------------- -- local setmetatable = setmetatable module "protobuf.listener" local _null_listener = { Modified = function() end } function NullMessageListener() return _null_listener end local _listener_meta = { Modified = function(self) if self.dirty then return end if self._parent_message then self._parent_message:_Modified() end end } _listener_meta.__index = _listener_meta function Listener(parent_message) local o = {} o.__mode = "v" o._parent_message = parent_message o.dirty = false return setmetatable(o, _listener_meta) end ================================================ FILE: Assets/ToLua/Lua/protobuf/listener.lua.meta ================================================ fileFormatVersion: 2 guid: 7778f4f6aeddbee43984c5da8cc06953 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/protobuf.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: protobuf.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- -- COMPANY: NetEase -- CREATED: 2010年07月29日 14时30分02秒 CST -------------------------------------------------------------------------------- -- local setmetatable = setmetatable local rawset = rawset local rawget = rawget local error = error local ipairs = ipairs local pairs = pairs local print = print local table = table local string = string local tostring = tostring local type = type local pb = require "pb" local wire_format = require "protobuf.wire_format" local type_checkers = require "protobuf.type_checkers" local encoder = require "protobuf.encoder" local decoder = require "protobuf.decoder" local listener_mod = require "protobuf.listener" local containers = require "protobuf.containers" local descriptor = require "protobuf.descriptor" local FieldDescriptor = descriptor.FieldDescriptor local text_format = require "protobuf.text_format" module("protobuf.protobuf") local function make_descriptor(name, descriptor, usable_key) local meta = { __newindex = function(self, key, value) if usable_key[key] then rawset(self, key, value) else error("error key: "..key) end end }; meta.__index = meta meta.__call = function() return setmetatable({}, meta) end _M[name] = setmetatable(descriptor, meta); end make_descriptor("Descriptor", {}, { name = true, full_name = true, filename = true, containing_type = true, fields = true, nested_types = true, enum_types = true, extensions = true, options = true, is_extendable = true, extension_ranges = true, }) make_descriptor("FieldDescriptor", FieldDescriptor, { name = true, full_name = true, index = true, number = true, type = true, cpp_type = true, label = true, has_default_value = true, default_value = true, containing_type = true, message_type = true, enum_type = true, is_extension = true, extension_scope = true, }) make_descriptor("EnumDescriptor", {}, { name = true, full_name = true, values = true, containing_type = true, options = true }) make_descriptor("EnumValueDescriptor", {}, { name = true, index = true, number = true, type = true, options = true }) -- Maps from field type to expected wiretype. local FIELD_TYPE_TO_WIRE_TYPE = { [FieldDescriptor.TYPE_DOUBLE] = wire_format.WIRETYPE_FIXED64, [FieldDescriptor.TYPE_FLOAT] = wire_format.WIRETYPE_FIXED32, [FieldDescriptor.TYPE_INT64] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_UINT64] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_INT32] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_FIXED64] = wire_format.WIRETYPE_FIXED64, [FieldDescriptor.TYPE_FIXED32] = wire_format.WIRETYPE_FIXED32, [FieldDescriptor.TYPE_BOOL] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_STRING] = wire_format.WIRETYPE_LENGTH_DELIMITED, [FieldDescriptor.TYPE_GROUP] = wire_format.WIRETYPE_START_GROUP, [FieldDescriptor.TYPE_MESSAGE] = wire_format.WIRETYPE_LENGTH_DELIMITED, [FieldDescriptor.TYPE_BYTES] = wire_format.WIRETYPE_LENGTH_DELIMITED, [FieldDescriptor.TYPE_UINT32] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_ENUM] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_SFIXED32] = wire_format.WIRETYPE_FIXED32, [FieldDescriptor.TYPE_SFIXED64] = wire_format.WIRETYPE_FIXED64, [FieldDescriptor.TYPE_SINT32] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_SINT64] = wire_format.WIRETYPE_VARINT } local NON_PACKABLE_TYPES = { [FieldDescriptor.TYPE_STRING] = true, [FieldDescriptor.TYPE_GROUP] = true, [FieldDescriptor.TYPE_MESSAGE] = true, [FieldDescriptor.TYPE_BYTES] = true } local _VALUE_CHECKERS = { [FieldDescriptor.CPPTYPE_INT32] = type_checkers.Int32ValueChecker(), [FieldDescriptor.CPPTYPE_INT64] = type_checkers.TypeChecker({string = true, number = true}), [FieldDescriptor.CPPTYPE_UINT32] = type_checkers.Uint32ValueChecker(), [FieldDescriptor.CPPTYPE_UINT64] = type_checkers.TypeChecker({string = true, number = true}), [FieldDescriptor.CPPTYPE_DOUBLE] = type_checkers.TypeChecker({number = true}), [FieldDescriptor.CPPTYPE_FLOAT] = type_checkers.TypeChecker({number = true}), [FieldDescriptor.CPPTYPE_BOOL] = type_checkers.TypeChecker({boolean = true, bool = true, int=true}), [FieldDescriptor.CPPTYPE_ENUM] = type_checkers.Int32ValueChecker(), [FieldDescriptor.CPPTYPE_STRING] = type_checkers.TypeChecker({string = true}) } local TYPE_TO_BYTE_SIZE_FN = { [FieldDescriptor.TYPE_DOUBLE] = wire_format.DoubleByteSize, [FieldDescriptor.TYPE_FLOAT] = wire_format.FloatByteSize, [FieldDescriptor.TYPE_INT64] = wire_format.Int64ByteSize, [FieldDescriptor.TYPE_UINT64] = wire_format.UInt64ByteSize, [FieldDescriptor.TYPE_INT32] = wire_format.Int32ByteSize, [FieldDescriptor.TYPE_FIXED64] = wire_format.Fixed64ByteSize, [FieldDescriptor.TYPE_FIXED32] = wire_format.Fixed32ByteSize, [FieldDescriptor.TYPE_BOOL] = wire_format.BoolByteSize, [FieldDescriptor.TYPE_STRING] = wire_format.StringByteSize, [FieldDescriptor.TYPE_GROUP] = wire_format.GroupByteSize, [FieldDescriptor.TYPE_MESSAGE] = wire_format.MessageByteSize, [FieldDescriptor.TYPE_BYTES] = wire_format.BytesByteSize, [FieldDescriptor.TYPE_UINT32] = wire_format.UInt32ByteSize, [FieldDescriptor.TYPE_ENUM] = wire_format.EnumByteSize, [FieldDescriptor.TYPE_SFIXED32] = wire_format.SFixed32ByteSize, [FieldDescriptor.TYPE_SFIXED64] = wire_format.SFixed64ByteSize, [FieldDescriptor.TYPE_SINT32] = wire_format.SInt32ByteSize, [FieldDescriptor.TYPE_SINT64] = wire_format.SInt64ByteSize } local TYPE_TO_ENCODER = { [FieldDescriptor.TYPE_DOUBLE] = encoder.DoubleEncoder, [FieldDescriptor.TYPE_FLOAT] = encoder.FloatEncoder, [FieldDescriptor.TYPE_INT64] = encoder.Int64Encoder, [FieldDescriptor.TYPE_UINT64] = encoder.UInt64Encoder, [FieldDescriptor.TYPE_INT32] = encoder.Int32Encoder, [FieldDescriptor.TYPE_FIXED64] = encoder.Fixed64Encoder, [FieldDescriptor.TYPE_FIXED32] = encoder.Fixed32Encoder, [FieldDescriptor.TYPE_BOOL] = encoder.BoolEncoder, [FieldDescriptor.TYPE_STRING] = encoder.StringEncoder, [FieldDescriptor.TYPE_GROUP] = encoder.GroupEncoder, [FieldDescriptor.TYPE_MESSAGE] = encoder.MessageEncoder, [FieldDescriptor.TYPE_BYTES] = encoder.BytesEncoder, [FieldDescriptor.TYPE_UINT32] = encoder.UInt32Encoder, [FieldDescriptor.TYPE_ENUM] = encoder.EnumEncoder, [FieldDescriptor.TYPE_SFIXED32] = encoder.SFixed32Encoder, [FieldDescriptor.TYPE_SFIXED64] = encoder.SFixed64Encoder, [FieldDescriptor.TYPE_SINT32] = encoder.SInt32Encoder, [FieldDescriptor.TYPE_SINT64] = encoder.SInt64Encoder } local TYPE_TO_SIZER = { [FieldDescriptor.TYPE_DOUBLE] = encoder.DoubleSizer, [FieldDescriptor.TYPE_FLOAT] = encoder.FloatSizer, [FieldDescriptor.TYPE_INT64] = encoder.Int64Sizer, [FieldDescriptor.TYPE_UINT64] = encoder.UInt64Sizer, [FieldDescriptor.TYPE_INT32] = encoder.Int32Sizer, [FieldDescriptor.TYPE_FIXED64] = encoder.Fixed64Sizer, [FieldDescriptor.TYPE_FIXED32] = encoder.Fixed32Sizer, [FieldDescriptor.TYPE_BOOL] = encoder.BoolSizer, [FieldDescriptor.TYPE_STRING] = encoder.StringSizer, [FieldDescriptor.TYPE_GROUP] = encoder.GroupSizer, [FieldDescriptor.TYPE_MESSAGE] = encoder.MessageSizer, [FieldDescriptor.TYPE_BYTES] = encoder.BytesSizer, [FieldDescriptor.TYPE_UINT32] = encoder.UInt32Sizer, [FieldDescriptor.TYPE_ENUM] = encoder.EnumSizer, [FieldDescriptor.TYPE_SFIXED32] = encoder.SFixed32Sizer, [FieldDescriptor.TYPE_SFIXED64] = encoder.SFixed64Sizer, [FieldDescriptor.TYPE_SINT32] = encoder.SInt32Sizer, [FieldDescriptor.TYPE_SINT64] = encoder.SInt64Sizer } local TYPE_TO_DECODER = { [FieldDescriptor.TYPE_DOUBLE] = decoder.DoubleDecoder, [FieldDescriptor.TYPE_FLOAT] = decoder.FloatDecoder, [FieldDescriptor.TYPE_INT64] = decoder.Int64Decoder, [FieldDescriptor.TYPE_UINT64] = decoder.UInt64Decoder, [FieldDescriptor.TYPE_INT32] = decoder.Int32Decoder, [FieldDescriptor.TYPE_FIXED64] = decoder.Fixed64Decoder, [FieldDescriptor.TYPE_FIXED32] = decoder.Fixed32Decoder, [FieldDescriptor.TYPE_BOOL] = decoder.BoolDecoder, [FieldDescriptor.TYPE_STRING] = decoder.StringDecoder, [FieldDescriptor.TYPE_GROUP] = decoder.GroupDecoder, [FieldDescriptor.TYPE_MESSAGE] = decoder.MessageDecoder, [FieldDescriptor.TYPE_BYTES] = decoder.BytesDecoder, [FieldDescriptor.TYPE_UINT32] = decoder.UInt32Decoder, [FieldDescriptor.TYPE_ENUM] = decoder.EnumDecoder, [FieldDescriptor.TYPE_SFIXED32] = decoder.SFixed32Decoder, [FieldDescriptor.TYPE_SFIXED64] = decoder.SFixed64Decoder, [FieldDescriptor.TYPE_SINT32] = decoder.SInt32Decoder, [FieldDescriptor.TYPE_SINT64] = decoder.SInt64Decoder } local FIELD_TYPE_TO_WIRE_TYPE = { [FieldDescriptor.TYPE_DOUBLE] = wire_format.WIRETYPE_FIXED64, [FieldDescriptor.TYPE_FLOAT] = wire_format.WIRETYPE_FIXED32, [FieldDescriptor.TYPE_INT64] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_UINT64] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_INT32] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_FIXED64] = wire_format.WIRETYPE_FIXED64, [FieldDescriptor.TYPE_FIXED32] = wire_format.WIRETYPE_FIXED32, [FieldDescriptor.TYPE_BOOL] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_STRING] = wire_format.WIRETYPE_LENGTH_DELIMITED, [FieldDescriptor.TYPE_GROUP] = wire_format.WIRETYPE_START_GROUP, [FieldDescriptor.TYPE_MESSAGE] = wire_format.WIRETYPE_LENGTH_DELIMITED, [FieldDescriptor.TYPE_BYTES] = wire_format.WIRETYPE_LENGTH_DELIMITED, [FieldDescriptor.TYPE_UINT32] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_ENUM] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_SFIXED32] = wire_format.WIRETYPE_FIXED32, [FieldDescriptor.TYPE_SFIXED64] = wire_format.WIRETYPE_FIXED64, [FieldDescriptor.TYPE_SINT32] = wire_format.WIRETYPE_VARINT, [FieldDescriptor.TYPE_SINT64] = wire_format.WIRETYPE_VARINT } local function IsTypePackable(field_type) return NON_PACKABLE_TYPES[field_type] == nil end local function GetTypeChecker(cpp_type, field_type) if (cpp_type == FieldDescriptor.CPPTYPE_STRING and field_type == FieldDescriptor.TYPE_STRING) then return type_checkers.UnicodeValueChecker() end return _VALUE_CHECKERS[cpp_type] end local function _DefaultValueConstructorForField(field) if field.label == FieldDescriptor.LABEL_REPEATED then if type(field.default_value) ~= "table" or #(field.default_value) ~= 0 then error('Repeated field default value not empty list:' .. tostring(field.default_value)) end if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then local message_type = field.message_type return function (message) return containers.RepeatedCompositeFieldContainer(message._listener_for_children, message_type) end else local type_checker = GetTypeChecker(field.cpp_type, field.type) return function (message) return containers.RepeatedScalarFieldContainer(message._listener_for_children, type_checker) end end end if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then local message_type = field.message_type return function (message) result = message_type._concrete_class() result._SetListener(message._listener_for_children) return result end end return function (message) return field.default_value end end local function _AttachFieldHelpers(message_meta, field_descriptor) local is_repeated = (field_descriptor.label == FieldDescriptor.LABEL_REPEATED) local is_packed = (field_descriptor.has_options and field_descriptor.GetOptions().packed) rawset(field_descriptor, "_encoder", TYPE_TO_ENCODER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed)) rawset(field_descriptor, "_sizer", TYPE_TO_SIZER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed)) rawset(field_descriptor, "_default_constructor", _DefaultValueConstructorForField(field_descriptor)) local AddDecoder = function(wiretype, is_packed) local tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) message_meta._decoders_by_tag[tag_bytes] = TYPE_TO_DECODER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed, field_descriptor, field_descriptor._default_constructor) end AddDecoder(FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], False) if is_repeated and IsTypePackable(field_descriptor.type) then AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) end end local function _AddEnumValues(descriptor, message_meta) for _, enum_type in ipairs(descriptor.enum_types) do for _, enum_value in ipairs(enum_type.values) do message_meta._member[enum_value.name] = enum_value.number end end end local function _InitMethod(message_meta) return function() local self = {} self._cached_byte_size = 0 self._cached_byte_size_dirty = false self._fields = {} self._is_present_in_parent = false self._listener = listener_mod.NullMessageListener() self._listener_for_children = listener_mod.Listener(self) return setmetatable(self, message_meta) end end local function _AddPropertiesForRepeatedField(field, message_meta) local property_name = field.name message_meta._getter[property_name] = function(self) local field_value = self._fields[field] if field_value == nil then field_value = field._default_constructor(self) self._fields[field] = field_value if not self._cached_byte_size_dirty then message_meta._member._Modified(self) end end return field_value end message_meta._setter[property_name] = function(self) error('Assignment not allowed to repeated field "' .. property_name .. '" in protocol message object.') end end local function _AddPropertiesForNonRepeatedCompositeField(field, message_meta) local property_name = field.name local message_type = field.message_type message_meta._getter[property_name] = function(self) local field_value = self._fields[field] if field_value == nil then field_value = message_type._concrete_class() field_value:_SetListener(self._listener_for_children) self._fields[field] = field_value if not self._cached_byte_size_dirty then message_meta._member._Modified(self) end end return field_value end message_meta._setter[property_name] = function(self, new_value) error('Assignment not allowed to composite field' .. property_name .. 'in protocol message object.' ) end end local function _AddPropertiesForNonRepeatedScalarField(field, message) local property_name = field.name local type_checker = GetTypeChecker(field.cpp_type, field.type) local default_value = field.default_value message._getter[property_name] = function(self) local value = self._fields[field] if value ~= nil then return self._fields[field] else return default_value end end message._setter[property_name] = function(self, new_value) type_checker(new_value) self._fields[field] = new_value if not self._cached_byte_size_dirty then message._member._Modified(self) end end end local function _AddPropertiesForField(field, message_meta) constant_name = field.name:upper() .. "_FIELD_NUMBER" message_meta._member[constant_name] = field.number if field.label == FieldDescriptor.LABEL_REPEATED then _AddPropertiesForRepeatedField(field, message_meta) elseif field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then _AddPropertiesForNonRepeatedCompositeField(field, message_meta) else _AddPropertiesForNonRepeatedScalarField(field, message_meta) end end local _ED_meta = { __index = function(self, extension_handle) local _extended_message = rawget(self, "_extended_message") local value = _extended_message._fields[extension_handle] if value ~= nil then return value end if extension_handle.label == FieldDescriptor.LABEL_REPEATED then value = extension_handle._default_constructor(self._extended_message) elseif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then value = extension_handle.message_type._concrete_class() value:_SetListener(_extended_message._listener_for_children) else return extension_handle.default_value end _extended_message._fields[extension_handle] = value return value end, __newindex = function(self, extension_handle, value) local _extended_message = rawget(self, "_extended_message") if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE) then error('Cannot assign to extension "'.. extension_handle.full_name .. '" because it is a repeated or composite type.') end local type_checker = GetTypeChecker(extension_handle.cpp_type, extension_handle.type) type_checker.CheckValue(value) _extended_message._fields[extension_handle] = value _extended_message._Modified() end } local function _ExtensionDict(message) local o = {} o._extended_message = message return setmetatable(o, _ED_meta) end local function _AddPropertiesForFields(descriptor, message_meta) for _, field in ipairs(descriptor.fields) do _AddPropertiesForField(field, message_meta) end if descriptor.is_extendable then message_meta._getter.Extensions = function(self) return _ExtensionDict(self) end end end local function _AddPropertiesForExtensions(descriptor, message_meta) local extension_dict = descriptor._extensions_by_name for extension_name, extension_field in pairs(extension_dict) do local constant_name = string.upper(extension_name) .. "_FIELD_NUMBER" message_meta._member[constant_name] = extension_field.number end end local function _AddStaticMethods(message_meta) message_meta._member.RegisterExtension = function(extension_handle) extension_handle.containing_type = message_meta._descriptor _AttachFieldHelpers(message_meta, extension_handle) if message_meta._extensions_by_number[extension_handle.number] == nil then message_meta._extensions_by_number[extension_handle.number] = extension_handle else error( string.format('Extensions "%s" and "%s" both try to extend message type "%s" with field number %d.', extension_handle.full_name, actual_handle.full_name, message_meta._descriptor.full_name, extension_handle.number)) end message_meta._extensions_by_name[extension_handle.full_name] = extension_handle end message_meta._member.FromString = function(s) local message = message_meta._member.__call() message.MergeFromString(s) return message end end local function _IsPresent(descriptor, value) if descriptor.label == FieldDescriptor.LABEL_REPEATED then return value elseif descriptor.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then return value._is_present_in_parent else return true end end function sortFunc(a, b) return a.index < b.index end function pairsByKeys (t, f) local a = {} for n in pairs(t) do table.insert(a, n) end table.sort(a, f) local i = 0 -- iterator variable local iter = function () -- iterator function i = i + 1 if a[i] == nil then return nil else return a[i], t[a[i]] end end return iter end local function _AddListFieldsMethod(message_descriptor, message_meta) message_meta._member.ListFields = function (self) local list_field = function(fields) --local f, s, v = pairs(self._fields) local f,s,v = pairsByKeys(self._fields, sortFunc) local iter = function(a, i) while true do local descriptor, value = f(a, i) if descriptor == nil then return elseif _IsPresent(descriptor, value) then return descriptor, value end end end return iter, s, v end return list_field(self._fields) end end local function _AddHasFieldMethod(message_descriptor, message_meta) local singular_fields = {} for _, field in ipairs(message_descriptor.fields) do if field.label ~= FieldDescriptor.LABEL_REPEATED then singular_fields[field.name] = field end end message_meta._member.HasField = function (self, field_name) field = singular_fields[field_name] if field == nil then error('Protocol message has no singular "'.. field_name.. '" field.') end if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then value = self._fields[field] return value ~= nil and value._is_present_in_parent else local valueTmp = self._fields[field] return valueTmp ~= nil end end end local function _AddClearFieldMethod(message_descriptor, message_meta) local singular_fields = {} for _, field in ipairs(message_descriptor.fields) do if field.label ~= FieldDescriptor.LABEL_REPEATED then singular_fields[field.name] = field end end message_meta._member.ClearField = function(self, field_name) field = singular_fields[field_name] if field == nil then error('Protocol message has no singular "'.. field_name.. '" field.') end if self._fields[field] then self._fields[field] = nil end message_meta._member._Modified(self) end end local function _AddClearExtensionMethod(message_meta) message_meta._member.ClearExtension = function(self, extension_handle) if self._fields[extension_handle] == nil then self._fields[extension_handle] = nil end message_meta._member._Modified(self) end end local function _AddClearMethod(message_descriptor, message_meta) message_meta._member.Clear = function(self) self._fields = {} message_meta._member._Modified(self) end end local function _AddStrMethod(message_meta) local format = text_format.msg_format message_meta.__tostring = function(self) return format(self) end end local function _AddHasExtensionMethod(message_meta) message_meta._member.HasExtension = function(self, extension_handle) if extension_handle.label == FieldDescriptor.LABEL_REPEATED then error(extension_handle.full_name .. ' is repeated.') end if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then value = self._fields[extension_handle] return value ~= nil and value._is_present_in_parent else return self._fields[extension_handle] end end end local function _AddSetListenerMethod(message_meta) message_meta._member._SetListener = function(self, listener) if listener ~= nil then self._listener = listener_mod.NullMessageListener() else self._listener = listener end end end local function _AddByteSizeMethod(message_descriptor, message_meta) message_meta._member.ByteSize = function(self) --kaiser --bug:这里在Repeat字段的结构体如果第一个字段不是int变量会产生_cached_byte_size_dirty为false而导致byte size为0 --如果bytesize为0让它强制计算byte size if not self._cached_byte_size_dirty and self._cached_byte_size > 0 then return self._cached_byte_size end local size = 0 for field_descriptor, field_value in message_meta._member.ListFields(self) do size = field_descriptor._sizer(field_value) + size end self._cached_byte_size = size self._cached_byte_size_dirty = false self._listener_for_children.dirty = false return size end end local function _AddSerializeToStringMethod(message_descriptor, message_meta) message_meta._member.SerializeToString = function(self) if not message_meta._member.IsInitialized(self) then error('Message is missing required fields: ' .. table.concat(message_meta._member.FindInitializationErrors(self), ',')) end return message_meta._member.SerializePartialToString(self) end message_meta._member.SerializeToIOString = function(self, iostring) if not message_meta._member.IsInitialized(self) then error('Message is missing required fields: ' .. table.concat(message_meta._member.FindInitializationErrors(self), ',')) end return message_meta._member.SerializePartialToIOString(self, iostring) end end local function _AddSerializePartialToStringMethod(message_descriptor, message_meta) local concat = table.concat local _internal_serialize = function(self, write_bytes) for field_descriptor, field_value in message_meta._member.ListFields(self) do field_descriptor._encoder(write_bytes, field_value) end end local _serialize_partial_to_iostring = function(self, iostring) local w = iostring.write local write = function(value) w(iostring, value) end _internal_serialize(self, write) return end local _serialize_partial_to_string = function(self) local out = {} local write = function(value) out[#out + 1] = value end _internal_serialize(self, write) return concat(out) end message_meta._member._InternalSerialize = _internal_serialize message_meta._member.SerializePartialToIOString = _serialize_partial_to_iostring message_meta._member.SerializePartialToString = _serialize_partial_to_string end local function _AddMergeFromStringMethod(message_descriptor, message_meta) local ReadTag = decoder.ReadTag local SkipField = decoder.SkipField local decoders_by_tag = message_meta._decoders_by_tag local _internal_parse = function(self, buffer, pos, pend) message_meta._member._Modified(self) local field_dict = self._fields local tag_bytes, new_pos local field_decoder while pos ~= pend do tag_bytes, new_pos = ReadTag(buffer, pos) field_decoder = decoders_by_tag[tag_bytes] if field_decoder == nil then new_pos = SkipField(buffer, new_pos, pend, tag_bytes) if new_pos == -1 then return pos end pos = new_pos else pos = field_decoder(buffer, new_pos, pend, self, field_dict) end end return pos end message_meta._member._InternalParse = _internal_parse local merge_from_string = function(self, serialized) local length = #serialized if _internal_parse(self, serialized, 0, length) ~= length then error('Unexpected end-group tag.') end return length end message_meta._member.MergeFromString = merge_from_string message_meta._member.ParseFromString = function(self, serialized) message_meta._member.Clear(self) merge_from_string(self, serialized) end end local function _AddIsInitializedMethod(message_descriptor, message_meta) local required_fields = {} for _, field in ipairs(message_descriptor.fields) do if field.label == FieldDescriptor.LABEL_REQUIRED then required_fields[#required_fields + 1] = field end end message_meta._member.IsInitialized = function(self, errors) for _, field in ipairs(required_fields) do if self._fields[field] == nil or (field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE and not self._fields[field]._is_present_in_parent) then if errors ~= nil then errors[#errors + 1] = message_meta._member.FindInitializationErrors(self) end return false end end for field, value in pairs(self._fields) do if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then if field.label == FieldDescriptor.LABEL_REPEATED then for _, element in ipairs(value) do if not element:IsInitialized() then if errors ~= nil then errors[#errors + 1] = message_meta._member.FindInitializationErrors(self) end return false end end elseif value._is_present_in_parent and not value:IsInitialized() then if errors ~= nil then errors[#errors + 1] = message_meta._member.FindInitializationErrors(self) end return false end end end return true end message_meta._member.FindInitializationErrors = function(self) local errors = {} for _,field in ipairs(required_fields) do if not message_meta._member.HasField(self, field.name) then errors[#errors + 1] = field.name end end for field, value in message_meta._member.ListFields(self) do if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then if field.is_extension then name = string.format("(%s)", field.full_name) else name = field.name end if field.label == FieldDescriptor.LABEL_REPEATED then for i, element in ipairs(value) do prefix = string.format("%s[%d].", name, i) sub_errors = element:FindInitializationErrors() for _, e in ipairs(sub_errors) do errors[#errors + 1] = prefix .. e end end else prefix = name .. "." sub_errors = value:FindInitializationErrors() for _, e in ipairs(sub_errors) do errors[#errors + 1] = prefix .. e end end end end return errors end end local function _AddMergeFromMethod(message_meta) local LABEL_REPEATED = FieldDescriptor.LABEL_REPEATED local CPPTYPE_MESSAGE = FieldDescriptor.CPPTYPE_MESSAGE message_meta._member.MergeFrom = function (self, msg) assert(msg ~= self) message_meta._member._Modified(self) local fields = self._fields for field, value in pairs(msg._fields) do if field.label == LABEL_REPEATED or field.cpp_type == CPPTYPE_MESSAGE then field_value = fields[field] if field_value == nil then field_value = field._default_constructor(self) fields[field] = field_value end field_value:MergeFrom(value) else self._fields[field] = value end end end end local function _AddMessageMethods(message_descriptor, message_meta) _AddListFieldsMethod(message_descriptor, message_meta) _AddHasFieldMethod(message_descriptor, message_meta) _AddClearFieldMethod(message_descriptor, message_meta) if message_descriptor.is_extendable then _AddClearExtensionMethod(message_meta) _AddHasExtensionMethod(message_meta) end _AddClearMethod(message_descriptor, message_meta) -- _AddEqualsMethod(message_descriptor, message_meta) _AddStrMethod(message_meta) _AddSetListenerMethod(message_meta) _AddByteSizeMethod(message_descriptor, message_meta) _AddSerializeToStringMethod(message_descriptor, message_meta) _AddSerializePartialToStringMethod(message_descriptor, message_meta) _AddMergeFromStringMethod(message_descriptor, message_meta) _AddIsInitializedMethod(message_descriptor, message_meta) _AddMergeFromMethod(message_meta) end local function _AddPrivateHelperMethods(message_meta) local Modified = function (self) if not self._cached_byte_size_dirty then self._cached_byte_size_dirty = true self._listener_for_children.dirty = true self._is_present_in_parent = true self._listener:Modified() end end message_meta._member._Modified = Modified message_meta._member.SetInParent = Modified end local function property_getter(message_meta) local getter = message_meta._getter local member = message_meta._member return function (self, property) local g = getter[property] if g then return g(self) else return member[property] end end end local function property_setter(message_meta) local setter = message_meta._setter return function (self, property, value) local s = setter[property] if s then s(self, value) else error(property .. " not found") end end end function _AddClassAttributesForNestedExtensions(descriptor, message_meta) local extension_dict = descriptor._extensions_by_name for extension_name, extension_field in pairs(extension_dict) do message_meta._member[extension_name] = extension_field end end local function Message(descriptor) local message_meta = {} message_meta._decoders_by_tag = {} rawset(descriptor, "_extensions_by_name", {}) for _, k in ipairs(descriptor.extensions) do descriptor._extensions_by_name[k.name] = k end rawset(descriptor, "_extensions_by_number", {}) for _, k in ipairs(descriptor.extensions) do descriptor._extensions_by_number[k.number] = k end message_meta._descriptor = descriptor message_meta._extensions_by_name = {} message_meta._extensions_by_number = {} message_meta._getter = {} message_meta._setter = {} message_meta._member = {} -- message_meta._name = descriptor.full_name local ns = setmetatable({}, message_meta._member) message_meta._member.__call = _InitMethod(message_meta) message_meta._member.__index = message_meta._member message_meta._member.type = ns if rawget(descriptor, "_concrete_class") == nil then rawset(descriptor, "_concrete_class", ns) for k, field in ipairs(descriptor.fields) do _AttachFieldHelpers(message_meta, field) end end _AddEnumValues(descriptor, message_meta) _AddClassAttributesForNestedExtensions(descriptor, message_meta) _AddPropertiesForFields(descriptor, message_meta) _AddPropertiesForExtensions(descriptor, message_meta) _AddStaticMethods(message_meta) _AddMessageMethods(descriptor, message_meta) _AddPrivateHelperMethods(message_meta) message_meta.__index = property_getter(message_meta) message_meta.__newindex = property_setter(message_meta) return ns end _M.Message = Message ================================================ FILE: Assets/ToLua/Lua/protobuf/protobuf.lua.meta ================================================ fileFormatVersion: 2 guid: afc64cedbe4a843499e187d95d272f06 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/text_format.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: text_format.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- COMPANY: NetEase -- CREATED: 2010年08月05日 15时14分13秒 CST -------------------------------------------------------------------------------- -- local string = string local math = math local print = print local getmetatable = getmetatable local table = table local ipairs = ipairs local tostring = tostring local descriptor = require "protobuf.descriptor" module "protobuf.text_format" function format(buffer) local len = string.len( buffer ) for i = 1, len, 16 do local text = "" for j = i, math.min( i + 16 - 1, len ) do text = string.format( "%s %02x", text, string.byte( buffer, j ) ) end print( text ) end end local FieldDescriptor = descriptor.FieldDescriptor msg_format_indent = function(write, msg, indent) for field, value in msg:ListFields() do local print_field = function(field_value) local name = field.name write(string.rep(" ", indent)) if field.type == FieldDescriptor.TYPE_MESSAGE then local extensions = getmetatable(msg)._extensions_by_name if extensions[field.full_name] then write("[" .. name .. "] {\n") else write(name .. " {\n") end msg_format_indent(write, field_value, indent + 4) write(string.rep(" ", indent)) write("}\n") else write(string.format("%s: %s\n", name, tostring(field_value))) end end if field.label == FieldDescriptor.LABEL_REPEATED then for _, k in ipairs(value) do print_field(k) end else print_field(value) end end end function msg_format(msg) local out = {} local write = function(value) out[#out + 1] = value end msg_format_indent(write, msg, 0) return table.concat(out) end ================================================ FILE: Assets/ToLua/Lua/protobuf/text_format.lua.meta ================================================ fileFormatVersion: 2 guid: 11ebbcbb210e532448bcc1440a557d8f DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/type_checkers.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: type_checkers.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- -- COMPANY: NetEase -- CREATED: 2010年07月29日 19时30分37秒 CST -------------------------------------------------------------------------------- -- local type = type local error = error local string = string module "protobuf.type_checkers" function TypeChecker(acceptable_types) local acceptable_types = acceptable_types return function(proposed_value) local t = type(proposed_value) if acceptable_types[type(proposed_value)] == nil then error(string.format('%s has type %s, but expected one of: %s', proposed_value, type(proposed_value), acceptable_types)) end end end function Int32ValueChecker() local _MIN = -2147483648 local _MAX = 2147483647 return function(proposed_value) if type(proposed_value) ~= 'number' then error(string.format('%s has type %s, but expected one of: number', proposed_value, type(proposed_value))) end if _MIN > proposed_value or proposed_value > _MAX then error('Value out of range: ' .. proposed_value) end end end function Uint32ValueChecker(IntValueChecker) local _MIN = 0 local _MAX = 0xffffffff return function(proposed_value) if type(proposed_value) ~= 'number' then error(string.format('%s has type %s, but expected one of: number', proposed_value, type(proposed_value))) end if _MIN > proposed_value or proposed_value > _MAX then error('Value out of range: ' .. proposed_value) end end end function UnicodeValueChecker() return function (proposed_value) if type(proposed_value) ~= 'string' then error(string.format('%s has type %s, but expected one of: string', proposed_value, type(proposed_value))) end end end ================================================ FILE: Assets/ToLua/Lua/protobuf/type_checkers.lua.meta ================================================ fileFormatVersion: 2 guid: 38d553dac9a25c84c9c7d74608783a1b DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf/wire_format.lua ================================================ -- -------------------------------------------------------------------------------- -- FILE: wire_format.lua -- DESCRIPTION: protoc-gen-lua -- Google's Protocol Buffers project, ported to lua. -- https://code.google.com/p/protoc-gen-lua/ -- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com -- All rights reserved. -- -- Use, modification and distribution are subject to the "New BSD License" -- as listed at . -- COMPANY: NetEase -- CREATED: 2010年07月30日 15时59分53秒 CST -------------------------------------------------------------------------------- -- local pb = require "pb" module "protobuf.wire_format" WIRETYPE_VARINT = 0 WIRETYPE_FIXED64 = 1 WIRETYPE_LENGTH_DELIMITED = 2 WIRETYPE_START_GROUP = 3 WIRETYPE_END_GROUP = 4 WIRETYPE_FIXED32 = 5 _WIRETYPE_MAX = 5 -- yeah, we don't need uint64 local function _VarUInt64ByteSizeNoTag(uint64) if uint64 <= 0x7f then return 1 end if uint64 <= 0x3fff then return 2 end if uint64 <= 0x1fffff then return 3 end if uint64 <= 0xfffffff then return 4 end return 5 end function PackTag(field_number, wire_type) return field_number * 8 + wire_type end function UnpackTag(tag) local wire_type = tag % 8 return (tag - wire_type) / 8, wire_type end ZigZagEncode32 = pb.zig_zag_encode32 ZigZagDecode32 = pb.zig_zag_decode32 ZigZagEncode64 = pb.zig_zag_encode64 ZigZagDecode64 = pb.zig_zag_decode64 function Int32ByteSize(field_number, int32) return Int64ByteSize(field_number, int32) end function Int32ByteSizeNoTag(int32) return _VarUInt64ByteSizeNoTag(int32) end function Int64ByteSize(field_number, int64) return UInt64ByteSize(field_number, int64) end function UInt32ByteSize(field_number, uint32) return UInt64ByteSize(field_number, uint32) end function UInt64ByteSize(field_number, uint64) return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) end function SInt32ByteSize(field_number, int32) return UInt32ByteSize(field_number, ZigZagEncode(int32)) end function SInt64ByteSize(field_number, int64) return UInt64ByteSize(field_number, ZigZagEncode(int64)) end function Fixed32ByteSize(field_number, fixed32) return TagByteSize(field_number) + 4 end function Fixed64ByteSize(field_number, fixed64) return TagByteSize(field_number) + 8 end function SFixed32ByteSize(field_number, sfixed32) return TagByteSize(field_number) + 4 end function SFixed64ByteSize(field_number, sfixed64) return TagByteSize(field_number) + 8 end function FloatByteSize(field_number, flt) return TagByteSize(field_number) + 4 end function DoubleByteSize(field_number, double) return TagByteSize(field_number) + 8 end function BoolByteSize(field_number, b) return TagByteSize(field_number) + 1 end function EnumByteSize(field_number, enum) return UInt32ByteSize(field_number, enum) end function StringByteSize(field_number, string) return BytesByteSize(field_number, string) end function BytesByteSize(field_number, b) return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(#b) + #b end function MessageByteSize(field_number, message) return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(message.ByteSize()) + message.ByteSize() end function MessageSetItemByteSize(field_number, msg) local total_size = 2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3) total_size = total_size + _VarUInt64ByteSizeNoTag(field_number) local message_size = msg.ByteSize() total_size = total_size + _VarUInt64ByteSizeNoTag(message_size) total_size = total_size + message_size return total_size end function TagByteSize(field_number) return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) end ================================================ FILE: Assets/ToLua/Lua/protobuf/wire_format.lua.meta ================================================ fileFormatVersion: 2 guid: 02ba9c90e50e89e4da2ee869851300a0 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/protobuf.meta ================================================ fileFormatVersion: 2 guid: 588f81265fa730e41a5371957a46eb61 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/slot.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local setmetatable = setmetatable local _slot = {} setmetatable(_slot, _slot) _slot.__call = function(self, ...) if nil == self.obj then return self.func(...) else return self.func(self.obj, ...) end end _slot.__eq = function (lhs, rhs) return lhs.func == rhs.func and lhs.obj == rhs.obj end --可用于 Timer 定时器回调函数. 例如Timer.New(slot(self.func, self)) function slot(func, obj) return setmetatable({func = func, obj = obj}, _slot) end ================================================ FILE: Assets/ToLua/Lua/slot.lua.meta ================================================ fileFormatVersion: 2 guid: 5040eeedfb5e1bf4b8a5294bba19ca0b DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket/ftp.lua ================================================ ----------------------------------------------------------------------------- -- FTP support for the Lua language -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module and import dependencies ----------------------------------------------------------------------------- local base = _G local table = require("table") local string = require("string") local math = require("math") local socket = require("socket") local url = require("socket.url") local tp = require("socket.tp") local ltn12 = require("ltn12") socket.ftp = {} local _M = socket.ftp ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -- timeout in seconds before the program gives up on a connection _M.TIMEOUT = 60 -- default port for ftp service local PORT = 21 -- this is the default anonymous password. used when no password is -- provided in url. should be changed to your e-mail. _M.USER = "ftp" _M.PASSWORD = "anonymous@anonymous.org" ----------------------------------------------------------------------------- -- Low level FTP API ----------------------------------------------------------------------------- local metat = { __index = {} } function _M.open(server, port, create) local tp = socket.try(tp.connect(server, port or PORT, _M.TIMEOUT, create)) local f = base.setmetatable({ tp = tp }, metat) -- make sure everything gets closed in an exception f.try = socket.newtry(function() f:close() end) return f end function metat.__index:portconnect() self.try(self.server:settimeout(_M.TIMEOUT)) self.data = self.try(self.server:accept()) self.try(self.data:settimeout(_M.TIMEOUT)) end function metat.__index:pasvconnect() self.data = self.try(socket.tcp()) self.try(self.data:settimeout(_M.TIMEOUT)) self.try(self.data:connect(self.pasvt.address, self.pasvt.port)) end function metat.__index:login(user, password) self.try(self.tp:command("user", user or _M.USER)) local code, reply = self.try(self.tp:check{"2..", 331}) if code == 331 then self.try(self.tp:command("pass", password or _M.PASSWORD)) self.try(self.tp:check("2..")) end return 1 end function metat.__index:pasv() self.try(self.tp:command("pasv")) local code, reply = self.try(self.tp:check("2..")) local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern)) self.try(a and b and c and d and p1 and p2, reply) self.pasvt = { address = string.format("%d.%d.%d.%d", a, b, c, d), port = p1*256 + p2 } if self.server then self.server:close() self.server = nil end return self.pasvt.address, self.pasvt.port end function metat.__index:epsv() self.try(self.tp:command("epsv")) local code, reply = self.try(self.tp:check("229")) local pattern = "%((.)(.-)%1(.-)%1(.-)%1%)" local d, prt, address, port = string.match(reply, pattern) self.try(port, "invalid epsv response") self.pasvt = { address = self.tp:getpeername(), port = port } if self.server then self.server:close() self.server = nil end return self.pasvt.address, self.pasvt.port end function metat.__index:port(address, port) self.pasvt = nil if not address then address, port = self.try(self.tp:getsockname()) self.server = self.try(socket.bind(address, 0)) address, port = self.try(self.server:getsockname()) self.try(self.server:settimeout(_M.TIMEOUT)) end local pl = port % 256 local ph = (port - pl)/256 local arg = string.gsub(string.format("%s,%d,%d", address, ph, pl), "%.", ",") self.try(self.tp:command("port", arg)) self.try(self.tp:check("2..")) return 1 end function metat.__index:eprt(family, address, port) self.pasvt = nil if not address then address, port = self.try(self.tp:getsockname()) self.server = self.try(socket.bind(address, 0)) address, port = self.try(self.server:getsockname()) self.try(self.server:settimeout(_M.TIMEOUT)) end local arg = string.format("|%s|%s|%d|", family, address, port) self.try(self.tp:command("eprt", arg)) self.try(self.tp:check("2..")) return 1 end function metat.__index:send(sendt) self.try(self.pasvt or self.server, "need port or pasv first") -- if there is a pasvt table, we already sent a PASV command -- we just get the data connection into self.data if self.pasvt then self:pasvconnect() end -- get the transfer argument and command local argument = sendt.argument or url.unescape(string.gsub(sendt.path or "", "^[/\\]", "")) if argument == "" then argument = nil end local command = sendt.command or "stor" -- send the transfer command and check the reply self.try(self.tp:command(command, argument)) local code, reply = self.try(self.tp:check{"2..", "1.."}) -- if there is not a pasvt table, then there is a server -- and we already sent a PORT command if not self.pasvt then self:portconnect() end -- get the sink, source and step for the transfer local step = sendt.step or ltn12.pump.step local readt = { self.tp } local checkstep = function(src, snk) -- check status in control connection while downloading local readyt = socket.select(readt, nil, 0) if readyt[tp] then code = self.try(self.tp:check("2..")) end return step(src, snk) end local sink = socket.sink("close-when-done", self.data) -- transfer all data and check error self.try(ltn12.pump.all(sendt.source, sink, checkstep)) if string.find(code, "1..") then self.try(self.tp:check("2..")) end -- done with data connection self.data:close() -- find out how many bytes were sent local sent = socket.skip(1, self.data:getstats()) self.data = nil return sent end function metat.__index:receive(recvt) self.try(self.pasvt or self.server, "need port or pasv first") if self.pasvt then self:pasvconnect() end local argument = recvt.argument or url.unescape(string.gsub(recvt.path or "", "^[/\\]", "")) if argument == "" then argument = nil end local command = recvt.command or "retr" self.try(self.tp:command(command, argument)) local code,reply = self.try(self.tp:check{"1..", "2.."}) if (code >= 200) and (code <= 299) then recvt.sink(reply) return 1 end if not self.pasvt then self:portconnect() end local source = socket.source("until-closed", self.data) local step = recvt.step or ltn12.pump.step self.try(ltn12.pump.all(source, recvt.sink, step)) if string.find(code, "1..") then self.try(self.tp:check("2..")) end self.data:close() self.data = nil return 1 end function metat.__index:cwd(dir) self.try(self.tp:command("cwd", dir)) self.try(self.tp:check(250)) return 1 end function metat.__index:type(type) self.try(self.tp:command("type", type)) self.try(self.tp:check(200)) return 1 end function metat.__index:greet() local code = self.try(self.tp:check{"1..", "2.."}) if string.find(code, "1..") then self.try(self.tp:check("2..")) end return 1 end function metat.__index:quit() self.try(self.tp:command("quit")) self.try(self.tp:check("2..")) return 1 end function metat.__index:close() if self.data then self.data:close() end if self.server then self.server:close() end return self.tp:close() end ----------------------------------------------------------------------------- -- High level FTP API ----------------------------------------------------------------------------- local function override(t) if t.url then local u = url.parse(t.url) for i,v in base.pairs(t) do u[i] = v end return u else return t end end local function tput(putt) putt = override(putt) socket.try(putt.host, "missing hostname") local f = _M.open(putt.host, putt.port, putt.create) f:greet() f:login(putt.user, putt.password) if putt.type then f:type(putt.type) end f:epsv() local sent = f:send(putt) f:quit() f:close() return sent end local default = { path = "/", scheme = "ftp" } local function genericform(u) local t = socket.try(url.parse(u, default)) socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'") socket.try(t.host, "missing hostname") local pat = "^type=(.)$" if t.params then t.type = socket.skip(2, string.find(t.params, pat)) socket.try(t.type == "a" or t.type == "i", "invalid type '" .. t.type .. "'") end return t end _M.genericform = genericform local function sput(u, body) local putt = genericform(u) putt.source = ltn12.source.string(body) return tput(putt) end _M.put = socket.protect(function(putt, body) if base.type(putt) == "string" then return sput(putt, body) else return tput(putt) end end) local function tget(gett) gett = override(gett) socket.try(gett.host, "missing hostname") local f = _M.open(gett.host, gett.port, gett.create) f:greet() f:login(gett.user, gett.password) if gett.type then f:type(gett.type) end f:epsv() f:receive(gett) f:quit() return f:close() end local function sget(u) local gett = genericform(u) local t = {} gett.sink = ltn12.sink.table(t) tget(gett) return table.concat(t) end _M.command = socket.protect(function(cmdt) cmdt = override(cmdt) socket.try(cmdt.host, "missing hostname") socket.try(cmdt.command, "missing command") local f = _M.open(cmdt.host, cmdt.port, cmdt.create) f:greet() f:login(cmdt.user, cmdt.password) if type(cmdt.command) == "table" then local argument = cmdt.argument or {} local check = cmdt.check or {} for i,cmd in ipairs(cmdt.command) do f.try(f.tp:command(cmd, argument[i])) if check[i] then f.try(f.tp:check(check[i])) end end else f.try(f.tp:command(cmdt.command, cmdt.argument)) if cmdt.check then f.try(f.tp:check(cmdt.check)) end end f:quit() return f:close() end) _M.get = socket.protect(function(gett) if base.type(gett) == "string" then return sget(gett) else return tget(gett) end end) return _M ================================================ FILE: Assets/ToLua/Lua/socket/ftp.lua.meta ================================================ fileFormatVersion: 2 guid: 7d703a862f37cfb42a2937b6f2cc9df6 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket/headers.lua ================================================ ----------------------------------------------------------------------------- -- Canonic header field capitalization -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- local socket = require("socket") socket.headers = {} local _M = socket.headers _M.canonic = { ["accept"] = "Accept", ["accept-charset"] = "Accept-Charset", ["accept-encoding"] = "Accept-Encoding", ["accept-language"] = "Accept-Language", ["accept-ranges"] = "Accept-Ranges", ["action"] = "Action", ["alternate-recipient"] = "Alternate-Recipient", ["age"] = "Age", ["allow"] = "Allow", ["arrival-date"] = "Arrival-Date", ["authorization"] = "Authorization", ["bcc"] = "Bcc", ["cache-control"] = "Cache-Control", ["cc"] = "Cc", ["comments"] = "Comments", ["connection"] = "Connection", ["content-description"] = "Content-Description", ["content-disposition"] = "Content-Disposition", ["content-encoding"] = "Content-Encoding", ["content-id"] = "Content-ID", ["content-language"] = "Content-Language", ["content-length"] = "Content-Length", ["content-location"] = "Content-Location", ["content-md5"] = "Content-MD5", ["content-range"] = "Content-Range", ["content-transfer-encoding"] = "Content-Transfer-Encoding", ["content-type"] = "Content-Type", ["cookie"] = "Cookie", ["date"] = "Date", ["diagnostic-code"] = "Diagnostic-Code", ["dsn-gateway"] = "DSN-Gateway", ["etag"] = "ETag", ["expect"] = "Expect", ["expires"] = "Expires", ["final-log-id"] = "Final-Log-ID", ["final-recipient"] = "Final-Recipient", ["from"] = "From", ["host"] = "Host", ["if-match"] = "If-Match", ["if-modified-since"] = "If-Modified-Since", ["if-none-match"] = "If-None-Match", ["if-range"] = "If-Range", ["if-unmodified-since"] = "If-Unmodified-Since", ["in-reply-to"] = "In-Reply-To", ["keywords"] = "Keywords", ["last-attempt-date"] = "Last-Attempt-Date", ["last-modified"] = "Last-Modified", ["location"] = "Location", ["max-forwards"] = "Max-Forwards", ["message-id"] = "Message-ID", ["mime-version"] = "MIME-Version", ["original-envelope-id"] = "Original-Envelope-ID", ["original-recipient"] = "Original-Recipient", ["pragma"] = "Pragma", ["proxy-authenticate"] = "Proxy-Authenticate", ["proxy-authorization"] = "Proxy-Authorization", ["range"] = "Range", ["received"] = "Received", ["received-from-mta"] = "Received-From-MTA", ["references"] = "References", ["referer"] = "Referer", ["remote-mta"] = "Remote-MTA", ["reply-to"] = "Reply-To", ["reporting-mta"] = "Reporting-MTA", ["resent-bcc"] = "Resent-Bcc", ["resent-cc"] = "Resent-Cc", ["resent-date"] = "Resent-Date", ["resent-from"] = "Resent-From", ["resent-message-id"] = "Resent-Message-ID", ["resent-reply-to"] = "Resent-Reply-To", ["resent-sender"] = "Resent-Sender", ["resent-to"] = "Resent-To", ["retry-after"] = "Retry-After", ["return-path"] = "Return-Path", ["sender"] = "Sender", ["server"] = "Server", ["smtp-remote-recipient"] = "SMTP-Remote-Recipient", ["status"] = "Status", ["subject"] = "Subject", ["te"] = "TE", ["to"] = "To", ["trailer"] = "Trailer", ["transfer-encoding"] = "Transfer-Encoding", ["upgrade"] = "Upgrade", ["user-agent"] = "User-Agent", ["vary"] = "Vary", ["via"] = "Via", ["warning"] = "Warning", ["will-retry-until"] = "Will-Retry-Until", ["www-authenticate"] = "WWW-Authenticate", ["x-mailer"] = "X-Mailer", } return _M ================================================ FILE: Assets/ToLua/Lua/socket/headers.lua.meta ================================================ fileFormatVersion: 2 guid: 62876db61c32bf6499db08ea59ccff1f DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket/http.lua ================================================ ----------------------------------------------------------------------------- -- HTTP/1.1 client support for the Lua language. -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module and import dependencies ------------------------------------------------------------------------------- local socket = require("socket") local url = require("socket.url") local ltn12 = require("ltn12") local mime = require("mime") local string = require("string") local headers = require("socket.headers") local base = _G local table = require("table") socket.http = {} local _M = socket.http ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -- connection timeout in seconds _M.TIMEOUT = 60 -- user agent field sent in request _M.USERAGENT = socket._VERSION -- supported schemes local SCHEMES = { ["http"] = true } -- default port for document retrieval local PORT = 80 ----------------------------------------------------------------------------- -- Reads MIME headers from a connection, unfolding where needed ----------------------------------------------------------------------------- local function receiveheaders(sock, headers) local line, name, value, err headers = headers or {} -- get first line line, err = sock:receive() if err then return nil, err end -- headers go until a blank line is found while line ~= "" do -- get field-name and value name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)")) if not (name and value) then return nil, "malformed reponse headers" end name = string.lower(name) -- get next line (value might be folded) line, err = sock:receive() if err then return nil, err end -- unfold any folded values while string.find(line, "^%s") do value = value .. line line = sock:receive() if err then return nil, err end end -- save pair in table if headers[name] then headers[name] = headers[name] .. ", " .. value else headers[name] = value end end return headers end ----------------------------------------------------------------------------- -- Extra sources and sinks ----------------------------------------------------------------------------- socket.sourcet["http-chunked"] = function(sock, headers) return base.setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function() -- get chunk size, skip extention local line, err = sock:receive() if err then return nil, err end local size = base.tonumber(string.gsub(line, ";.*", ""), 16) if not size then return nil, "invalid chunk size" end -- was it the last chunk? if size > 0 then -- if not, get chunk and skip terminating CRLF local chunk, err, part = sock:receive(size) if chunk then sock:receive() end return chunk, err else -- if it was, read trailers into headers table headers, err = receiveheaders(sock, headers) if not headers then return nil, err end end end }) end socket.sinkt["http-chunked"] = function(sock) return base.setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function(self, chunk, err) if not chunk then return sock:send("0\r\n\r\n") end local size = string.format("%X\r\n", string.len(chunk)) return sock:send(size .. chunk .. "\r\n") end }) end ----------------------------------------------------------------------------- -- Low level HTTP API ----------------------------------------------------------------------------- local metat = { __index = {} } function _M.open(host, port, create) -- create socket with user connect function, or with default local c = socket.try((create or socket.tcp)()) local h = base.setmetatable({ c = c }, metat) -- create finalized try h.try = socket.newtry(function() h:close() end) -- set timeout before connecting h.try(c:settimeout(_M.TIMEOUT)) h.try(c:connect(host, port or PORT)) -- here everything worked return h end function metat.__index:sendrequestline(method, uri) local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri) return self.try(self.c:send(reqline)) end function metat.__index:sendheaders(tosend) local canonic = headers.canonic local h = "\r\n" for f, v in base.pairs(tosend) do h = (canonic[f] or f) .. ": " .. v .. "\r\n" .. h end self.try(self.c:send(h)) return 1 end function metat.__index:sendbody(headers, source, step) source = source or ltn12.source.empty() step = step or ltn12.pump.step -- if we don't know the size in advance, send chunked and hope for the best local mode = "http-chunked" if headers["content-length"] then mode = "keep-open" end return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step)) end function metat.__index:receivestatusline() local status = self.try(self.c:receive(5)) -- identify HTTP/0.9 responses, which do not contain a status line -- this is just a heuristic, but is what the RFC recommends if status ~= "HTTP/" then return nil, status end -- otherwise proceed reading a status line status = self.try(self.c:receive("*l", status)) local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) return self.try(base.tonumber(code), status) end function metat.__index:receiveheaders() return self.try(receiveheaders(self.c)) end function metat.__index:receivebody(headers, sink, step) sink = sink or ltn12.sink.null() step = step or ltn12.pump.step local length = base.tonumber(headers["content-length"]) local t = headers["transfer-encoding"] -- shortcut local mode = "default" -- connection close if t and t ~= "identity" then mode = "http-chunked" elseif base.tonumber(headers["content-length"]) then mode = "by-length" end return self.try(ltn12.pump.all(socket.source(mode, self.c, length), sink, step)) end function metat.__index:receive09body(status, sink, step) local source = ltn12.source.rewind(socket.source("until-closed", self.c)) source(status) return self.try(ltn12.pump.all(source, sink, step)) end function metat.__index:close() return self.c:close() end ----------------------------------------------------------------------------- -- High level HTTP API ----------------------------------------------------------------------------- local function adjusturi(reqt) local u = reqt -- if there is a proxy, we need the full url. otherwise, just a part. if not reqt.proxy and not _M.PROXY then u = { path = socket.try(reqt.path, "invalid path 'nil'"), params = reqt.params, query = reqt.query, fragment = reqt.fragment } end return url.build(u) end local function adjustproxy(reqt) local proxy = reqt.proxy or _M.PROXY if proxy then proxy = url.parse(proxy) return proxy.host, proxy.port or 3128 else return reqt.host, reqt.port end end local function adjustheaders(reqt) -- default headers local host = string.gsub(reqt.authority, "^.-@", "") local lower = { ["user-agent"] = _M.USERAGENT, ["host"] = host, ["connection"] = "close, TE", ["te"] = "trailers" } -- if we have authentication information, pass it along if reqt.user and reqt.password then lower["authorization"] = "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password)) end -- if we have proxy authentication information, pass it along local proxy = reqt.proxy or _M.PROXY if proxy then proxy = url.parse(proxy) if proxy.user and proxy.password then lower["proxy-authorization"] = "Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password)) end end -- override with user headers for i,v in base.pairs(reqt.headers or lower) do lower[string.lower(i)] = v end return lower end -- default url parts local default = { host = "", port = PORT, path ="/", scheme = "http" } local function adjustrequest(reqt) -- parse url if provided local nreqt = reqt.url and url.parse(reqt.url, default) or {} -- explicit components override url for i,v in base.pairs(reqt) do nreqt[i] = v end if nreqt.port == "" then nreqt.port = PORT end if not (nreqt.host and nreqt.host ~= "") then socket.try(nil, "invalid host '" .. base.tostring(nreqt.host) .. "'") end -- compute uri if user hasn't overriden nreqt.uri = reqt.uri or adjusturi(nreqt) -- adjust headers in request nreqt.headers = adjustheaders(nreqt) -- ajust host and port if there is a proxy nreqt.host, nreqt.port = adjustproxy(nreqt) return nreqt end local function shouldredirect(reqt, code, headers) local location = headers.location if not location then return false end location = string.gsub(location, "%s", "") if location == "" then return false end local scheme = string.match(location, "^([%w][%w%+%-%.]*)%:") if scheme and not SCHEMES[scheme] then return false end return (reqt.redirect ~= false) and (code == 301 or code == 302 or code == 303 or code == 307) and (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD") and (not reqt.nredirects or reqt.nredirects < 5) end local function shouldreceivebody(reqt, code) if reqt.method == "HEAD" then return nil end if code == 204 or code == 304 then return nil end if code >= 100 and code < 200 then return nil end return 1 end -- forward declarations local trequest, tredirect --[[local]] function tredirect(reqt, location) local result, code, headers, status = trequest { -- the RFC says the redirect URL has to be absolute, but some -- servers do not respect that url = url.absolute(reqt.url, location), source = reqt.source, sink = reqt.sink, headers = reqt.headers, proxy = reqt.proxy, nredirects = (reqt.nredirects or 0) + 1, create = reqt.create } -- pass location header back as a hint we redirected headers = headers or {} headers.location = headers.location or location return result, code, headers, status end --[[local]] function trequest(reqt) -- we loop until we get what we want, or -- until we are sure there is no way to get it local nreqt = adjustrequest(reqt) local h = _M.open(nreqt.host, nreqt.port, nreqt.create) -- send request line and headers h:sendrequestline(nreqt.method, nreqt.uri) h:sendheaders(nreqt.headers) -- if there is a body, send it if nreqt.source then h:sendbody(nreqt.headers, nreqt.source, nreqt.step) end local code, status = h:receivestatusline() -- if it is an HTTP/0.9 server, simply get the body and we are done if not code then h:receive09body(status, nreqt.sink, nreqt.step) return 1, 200 end local headers -- ignore any 100-continue messages while code == 100 do headers = h:receiveheaders() code, status = h:receivestatusline() end headers = h:receiveheaders() -- at this point we should have a honest reply from the server -- we can't redirect if we already used the source, so we report the error if shouldredirect(nreqt, code, headers) and not nreqt.source then h:close() return tredirect(reqt, headers.location) end -- here we are finally done if shouldreceivebody(nreqt, code) then h:receivebody(headers, nreqt.sink, nreqt.step) end h:close() return 1, code, headers, status end -- turns an url and a body into a generic request local function genericform(u, b) local t = {} local reqt = { url = u, sink = ltn12.sink.table(t), target = t } if b then reqt.source = ltn12.source.string(b) reqt.headers = { ["content-length"] = string.len(b), ["content-type"] = "application/x-www-form-urlencoded" } reqt.method = "POST" end return reqt end _M.genericform = genericform local function srequest(u, b) local reqt = genericform(u, b) local _, code, headers, status = trequest(reqt) return table.concat(reqt.target), code, headers, status end _M.request = socket.protect(function(reqt, body) if base.type(reqt) == "string" then return srequest(reqt, body) else return trequest(reqt) end end) return _M ================================================ FILE: Assets/ToLua/Lua/socket/http.lua.meta ================================================ fileFormatVersion: 2 guid: 209e83764932d974287e82cda5febaf7 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket/mbox.lua ================================================ local _M = {} if module then mbox = _M end function _M.split_message(message_s) local message = {} message_s = string.gsub(message_s, "\r\n", "\n") string.gsub(message_s, "^(.-\n)\n", function (h) message.headers = h end) string.gsub(message_s, "^.-\n\n(.*)", function (b) message.body = b end) if not message.body then string.gsub(message_s, "^\n(.*)", function (b) message.body = b end) end if not message.headers and not message.body then message.headers = message_s end return message.headers or "", message.body or "" end function _M.split_headers(headers_s) local headers = {} headers_s = string.gsub(headers_s, "\r\n", "\n") headers_s = string.gsub(headers_s, "\n[ ]+", " ") string.gsub("\n" .. headers_s, "\n([^\n]+)", function (h) table.insert(headers, h) end) return headers end function _M.parse_header(header_s) header_s = string.gsub(header_s, "\n[ ]+", " ") header_s = string.gsub(header_s, "\n+", "") local _, __, name, value = string.find(header_s, "([^%s:]-):%s*(.*)") return name, value end function _M.parse_headers(headers_s) local headers_t = _M.split_headers(headers_s) local headers = {} for i = 1, #headers_t do local name, value = _M.parse_header(headers_t[i]) if name then name = string.lower(name) if headers[name] then headers[name] = headers[name] .. ", " .. value else headers[name] = value end end end return headers end function _M.parse_from(from) local _, __, name, address = string.find(from, "^%s*(.-)%s*%<(.-)%>") if not address then _, __, address = string.find(from, "%s*(.+)%s*") end name = name or "" address = address or "" if name == "" then name = address end name = string.gsub(name, '"', "") return name, address end function _M.split_mbox(mbox_s) local mbox = {} mbox_s = string.gsub(mbox_s, "\r\n", "\n") .."\n\nFrom \n" local nj, i, j = 1, 1, 1 while 1 do i, nj = string.find(mbox_s, "\n\nFrom .-\n", j) if not i then break end local message = string.sub(mbox_s, j, i-1) table.insert(mbox, message) j = nj+1 end return mbox end function _M.parse(mbox_s) local mbox = _M.split_mbox(mbox_s) for i = 1, #mbox do mbox[i] = _M.parse_message(mbox[i]) end return mbox end function _M.parse_message(message_s) local message = {} message.headers, message.body = _M.split_message(message_s) message.headers = _M.parse_headers(message.headers) return message end return _M ================================================ FILE: Assets/ToLua/Lua/socket/mbox.lua.meta ================================================ fileFormatVersion: 2 guid: b179323d673f3f04996fc0b22c0817bb DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket/smtp.lua ================================================ ----------------------------------------------------------------------------- -- SMTP client support for the Lua language. -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module and import dependencies ----------------------------------------------------------------------------- local base = _G local coroutine = require("coroutine") local string = require("string") local math = require("math") local os = require("os") local socket = require("socket") local tp = require("socket.tp") local ltn12 = require("ltn12") local headers = require("socket.headers") local mime = require("mime") socket.smtp = {} local _M = socket.smtp ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -- timeout for connection _M.TIMEOUT = 60 -- default server used to send e-mails _M.SERVER = "localhost" -- default port _M.PORT = 25 -- domain used in HELO command and default sendmail -- If we are under a CGI, try to get from environment _M.DOMAIN = os.getenv("SERVER_NAME") or "localhost" -- default time zone (means we don't know) _M.ZONE = "-0000" --------------------------------------------------------------------------- -- Low level SMTP API ----------------------------------------------------------------------------- local metat = { __index = {} } function metat.__index:greet(domain) self.try(self.tp:check("2..")) self.try(self.tp:command("EHLO", domain or _M.DOMAIN)) return socket.skip(1, self.try(self.tp:check("2.."))) end function metat.__index:mail(from) self.try(self.tp:command("MAIL", "FROM:" .. from)) return self.try(self.tp:check("2..")) end function metat.__index:rcpt(to) self.try(self.tp:command("RCPT", "TO:" .. to)) return self.try(self.tp:check("2..")) end function metat.__index:data(src, step) self.try(self.tp:command("DATA")) self.try(self.tp:check("3..")) self.try(self.tp:source(src, step)) self.try(self.tp:send("\r\n.\r\n")) return self.try(self.tp:check("2..")) end function metat.__index:quit() self.try(self.tp:command("QUIT")) return self.try(self.tp:check("2..")) end function metat.__index:close() return self.tp:close() end function metat.__index:login(user, password) self.try(self.tp:command("AUTH", "LOGIN")) self.try(self.tp:check("3..")) self.try(self.tp:send(mime.b64(user) .. "\r\n")) self.try(self.tp:check("3..")) self.try(self.tp:send(mime.b64(password) .. "\r\n")) return self.try(self.tp:check("2..")) end function metat.__index:plain(user, password) local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password) self.try(self.tp:command("AUTH", auth)) return self.try(self.tp:check("2..")) end function metat.__index:auth(user, password, ext) if not user or not password then return 1 end if string.find(ext, "AUTH[^\n]+LOGIN") then return self:login(user, password) elseif string.find(ext, "AUTH[^\n]+PLAIN") then return self:plain(user, password) else self.try(nil, "authentication not supported") end end -- send message or throw an exception function metat.__index:send(mailt) self:mail(mailt.from) if base.type(mailt.rcpt) == "table" then for i,v in base.ipairs(mailt.rcpt) do self:rcpt(v) end else self:rcpt(mailt.rcpt) end self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) end function _M.open(server, port, create) local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT, _M.TIMEOUT, create)) local s = base.setmetatable({tp = tp}, metat) -- make sure tp is closed if we get an exception s.try = socket.newtry(function() s:close() end) return s end -- convert headers to lowercase local function lower_headers(headers) local lower = {} for i,v in base.pairs(headers or lower) do lower[string.lower(i)] = v end return lower end --------------------------------------------------------------------------- -- Multipart message source ----------------------------------------------------------------------------- -- returns a hopefully unique mime boundary local seqno = 0 local function newboundary() seqno = seqno + 1 return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'), math.random(0, 99999), seqno) end -- send_message forward declaration local send_message -- yield the headers all at once, it's faster local function send_headers(tosend) local canonic = headers.canonic local h = "\r\n" for f,v in base.pairs(tosend) do h = (canonic[f] or f) .. ': ' .. v .. "\r\n" .. h end coroutine.yield(h) end -- yield multipart message body from a multipart message table local function send_multipart(mesgt) -- make sure we have our boundary and send headers local bd = newboundary() local headers = lower_headers(mesgt.headers or {}) headers['content-type'] = headers['content-type'] or 'multipart/mixed' headers['content-type'] = headers['content-type'] .. '; boundary="' .. bd .. '"' send_headers(headers) -- send preamble if mesgt.body.preamble then coroutine.yield(mesgt.body.preamble) coroutine.yield("\r\n") end -- send each part separated by a boundary for i, m in base.ipairs(mesgt.body) do coroutine.yield("\r\n--" .. bd .. "\r\n") send_message(m) end -- send last boundary coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n") -- send epilogue if mesgt.body.epilogue then coroutine.yield(mesgt.body.epilogue) coroutine.yield("\r\n") end end -- yield message body from a source local function send_source(mesgt) -- make sure we have a content-type local headers = lower_headers(mesgt.headers or {}) headers['content-type'] = headers['content-type'] or 'text/plain; charset="iso-8859-1"' send_headers(headers) -- send body from source while true do local chunk, err = mesgt.body() if err then coroutine.yield(nil, err) elseif chunk then coroutine.yield(chunk) else break end end end -- yield message body from a string local function send_string(mesgt) -- make sure we have a content-type local headers = lower_headers(mesgt.headers or {}) headers['content-type'] = headers['content-type'] or 'text/plain; charset="iso-8859-1"' send_headers(headers) -- send body from string coroutine.yield(mesgt.body) end -- message source function send_message(mesgt) if base.type(mesgt.body) == "table" then send_multipart(mesgt) elseif base.type(mesgt.body) == "function" then send_source(mesgt) else send_string(mesgt) end end -- set defaul headers local function adjust_headers(mesgt) local lower = lower_headers(mesgt.headers) lower["date"] = lower["date"] or os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE) lower["x-mailer"] = lower["x-mailer"] or socket._VERSION -- this can't be overriden lower["mime-version"] = "1.0" return lower end function _M.message(mesgt) mesgt.headers = adjust_headers(mesgt) -- create and return message source local co = coroutine.create(function() send_message(mesgt) end) return function() local ret, a, b = coroutine.resume(co) if ret then return a, b else return nil, a end end end --------------------------------------------------------------------------- -- High level SMTP API ----------------------------------------------------------------------------- _M.send = socket.protect(function(mailt) local s = _M.open(mailt.server, mailt.port, mailt.create) local ext = s:greet(mailt.domain) s:auth(mailt.user, mailt.password, ext) s:send(mailt) s:quit() return s:close() end) return _M ================================================ FILE: Assets/ToLua/Lua/socket/smtp.lua.meta ================================================ fileFormatVersion: 2 guid: 5fb16f8ece254ef4d9c196242b49a8ae DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket/tp.lua ================================================ ----------------------------------------------------------------------------- -- Unified SMTP/FTP subsystem -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module and import dependencies ----------------------------------------------------------------------------- local base = _G local string = require("string") local socket = require("socket") local ltn12 = require("ltn12") socket.tp = {} local _M = socket.tp ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- _M.TIMEOUT = 60 ----------------------------------------------------------------------------- -- Implementation ----------------------------------------------------------------------------- -- gets server reply (works for SMTP and FTP) local function get_reply(c) local code, current, sep local line, err = c:receive() local reply = line if err then return nil, err end code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) if not code then return nil, "invalid server reply" end if sep == "-" then -- reply is multiline repeat line, err = c:receive() if err then return nil, err end current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) reply = reply .. "\n" .. line -- reply ends with same code until code == current and sep == " " end return code, reply end -- metatable for sock object local metat = { __index = {} } function metat.__index:getpeername() return self.c:getpeername() end function metat.__index:getsockname() return self.c:getpeername() end function metat.__index:check(ok) local code, reply = get_reply(self.c) if not code then return nil, reply end if base.type(ok) ~= "function" then if base.type(ok) == "table" then for i, v in base.ipairs(ok) do if string.find(code, v) then return base.tonumber(code), reply end end return nil, reply else if string.find(code, ok) then return base.tonumber(code), reply else return nil, reply end end else return ok(base.tonumber(code), reply) end end function metat.__index:command(cmd, arg) cmd = string.upper(cmd) if arg then return self.c:send(cmd .. " " .. arg.. "\r\n") else return self.c:send(cmd .. "\r\n") end end function metat.__index:sink(snk, pat) local chunk, err = self.c:receive(pat) return snk(chunk, err) end function metat.__index:send(data) return self.c:send(data) end function metat.__index:receive(pat) return self.c:receive(pat) end function metat.__index:getfd() return self.c:getfd() end function metat.__index:dirty() return self.c:dirty() end function metat.__index:getcontrol() return self.c end function metat.__index:source(source, step) local sink = socket.sink("keep-open", self.c) local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step) return ret, err end -- closes the underlying c function metat.__index:close() self.c:close() return 1 end -- connect with server and return c object function _M.connect(host, port, timeout, create) local c, e = (create or socket.tcp)() if not c then return nil, e end c:settimeout(timeout or _M.TIMEOUT) local r, e = c:connect(host, port) if not r then c:close() return nil, e end return base.setmetatable({c = c}, metat) end return _M ================================================ FILE: Assets/ToLua/Lua/socket/tp.lua.meta ================================================ fileFormatVersion: 2 guid: f81b525c8aa6ab6408db2989c91556cc DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket/url.lua ================================================ ----------------------------------------------------------------------------- -- URI parsing, composition and relative URL resolution -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module ----------------------------------------------------------------------------- local string = require("string") local base = _G local table = require("table") local socket = require("socket") socket.url = {} local _M = socket.url ----------------------------------------------------------------------------- -- Module version ----------------------------------------------------------------------------- _M._VERSION = "URL 1.0.3" ----------------------------------------------------------------------------- -- Encodes a string into its escaped hexadecimal representation -- Input -- s: binary string to be encoded -- Returns -- escaped representation of string binary ----------------------------------------------------------------------------- function _M.escape(s) return (string.gsub(s, "([^A-Za-z0-9_])", function(c) return string.format("%%%02x", string.byte(c)) end)) end ----------------------------------------------------------------------------- -- Protects a path segment, to prevent it from interfering with the -- url parsing. -- Input -- s: binary string to be encoded -- Returns -- escaped representation of string binary ----------------------------------------------------------------------------- local function make_set(t) local s = {} for i,v in base.ipairs(t) do s[t[i]] = 1 end return s end -- these are allowed withing a path segment, along with alphanum -- other characters must be escaped local segment_set = make_set { "-", "_", ".", "!", "~", "*", "'", "(", ")", ":", "@", "&", "=", "+", "$", ",", } local function protect_segment(s) return string.gsub(s, "([^A-Za-z0-9_])", function (c) if segment_set[c] then return c else return string.format("%%%02x", string.byte(c)) end end) end ----------------------------------------------------------------------------- -- Encodes a string into its escaped hexadecimal representation -- Input -- s: binary string to be encoded -- Returns -- escaped representation of string binary ----------------------------------------------------------------------------- function _M.unescape(s) return (string.gsub(s, "%%(%x%x)", function(hex) return string.char(base.tonumber(hex, 16)) end)) end ----------------------------------------------------------------------------- -- Builds a path from a base path and a relative path -- Input -- base_path -- relative_path -- Returns -- corresponding absolute path ----------------------------------------------------------------------------- local function absolute_path(base_path, relative_path) if string.sub(relative_path, 1, 1) == "/" then return relative_path end local path = string.gsub(base_path, "[^/]*$", "") path = path .. relative_path path = string.gsub(path, "([^/]*%./)", function (s) if s ~= "./" then return s else return "" end end) path = string.gsub(path, "/%.$", "/") local reduced while reduced ~= path do reduced = path path = string.gsub(reduced, "([^/]*/%.%./)", function (s) if s ~= "../../" then return "" else return s end end) end path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) if s ~= "../.." then return "" else return s end end) return path end ----------------------------------------------------------------------------- -- Parses a url and returns a table with all its parts according to RFC 2396 -- The following grammar describes the names given to the URL parts -- ::= :///;?# -- ::= @: -- ::= [:] -- :: = {/} -- Input -- url: uniform resource locator of request -- default: table with default values for each field -- Returns -- table with the following fields, where RFC naming conventions have -- been preserved: -- scheme, authority, userinfo, user, password, host, port, -- path, params, query, fragment -- Obs: -- the leading '/' in {/} is considered part of ----------------------------------------------------------------------------- function _M.parse(url, default) -- initialize default parameters local parsed = {} for i,v in base.pairs(default or parsed) do parsed[i] = v end -- empty url is parsed to nil if not url or url == "" then return nil, "invalid url" end -- remove whitespace -- url = string.gsub(url, "%s", "") -- get fragment url = string.gsub(url, "#(.*)$", function(f) parsed.fragment = f return "" end) -- get scheme url = string.gsub(url, "^([%w][%w%+%-%.]*)%:", function(s) parsed.scheme = s; return "" end) -- get authority url = string.gsub(url, "^//([^/]*)", function(n) parsed.authority = n return "" end) -- get query string url = string.gsub(url, "%?(.*)", function(q) parsed.query = q return "" end) -- get params url = string.gsub(url, "%;(.*)", function(p) parsed.params = p return "" end) -- path is whatever was left if url ~= "" then parsed.path = url end local authority = parsed.authority if not authority then return parsed end authority = string.gsub(authority,"^([^@]*)@", function(u) parsed.userinfo = u; return "" end) authority = string.gsub(authority, ":([^:%]]*)$", function(p) parsed.port = p; return "" end) if authority ~= "" then -- IPv6? parsed.host = string.match(authority, "^%[(.+)%]$") or authority end local userinfo = parsed.userinfo if not userinfo then return parsed end userinfo = string.gsub(userinfo, ":([^:]*)$", function(p) parsed.password = p; return "" end) parsed.user = userinfo return parsed end ----------------------------------------------------------------------------- -- Rebuilds a parsed URL from its components. -- Components are protected if any reserved or unallowed characters are found -- Input -- parsed: parsed URL, as returned by parse -- Returns -- a stringing with the corresponding URL ----------------------------------------------------------------------------- function _M.build(parsed) local ppath = _M.parse_path(parsed.path or "") local url = _M.build_path(ppath) if parsed.params then url = url .. ";" .. parsed.params end if parsed.query then url = url .. "?" .. parsed.query end local authority = parsed.authority if parsed.host then authority = parsed.host if string.find(authority, ":") then -- IPv6? authority = "[" .. authority .. "]" end if parsed.port then authority = authority .. ":" .. parsed.port end local userinfo = parsed.userinfo if parsed.user then userinfo = parsed.user if parsed.password then userinfo = userinfo .. ":" .. parsed.password end end if userinfo then authority = userinfo .. "@" .. authority end end if authority then url = "//" .. authority .. url end if parsed.scheme then url = parsed.scheme .. ":" .. url end if parsed.fragment then url = url .. "#" .. parsed.fragment end -- url = string.gsub(url, "%s", "") return url end ----------------------------------------------------------------------------- -- Builds a absolute URL from a base and a relative URL according to RFC 2396 -- Input -- base_url -- relative_url -- Returns -- corresponding absolute url ----------------------------------------------------------------------------- function _M.absolute(base_url, relative_url) local base_parsed if base.type(base_url) == "table" then base_parsed = base_url base_url = _M.build(base_parsed) else base_parsed = _M.parse(base_url) end local relative_parsed = _M.parse(relative_url) if not base_parsed then return relative_url elseif not relative_parsed then return base_url elseif relative_parsed.scheme then return relative_url else relative_parsed.scheme = base_parsed.scheme if not relative_parsed.authority then relative_parsed.authority = base_parsed.authority if not relative_parsed.path then relative_parsed.path = base_parsed.path if not relative_parsed.params then relative_parsed.params = base_parsed.params if not relative_parsed.query then relative_parsed.query = base_parsed.query end end else relative_parsed.path = absolute_path(base_parsed.path or "", relative_parsed.path) end end return _M.build(relative_parsed) end end ----------------------------------------------------------------------------- -- Breaks a path into its segments, unescaping the segments -- Input -- path -- Returns -- segment: a table with one entry per segment ----------------------------------------------------------------------------- function _M.parse_path(path) local parsed = {} path = path or "" --path = string.gsub(path, "%s", "") string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) for i = 1, #parsed do parsed[i] = _M.unescape(parsed[i]) end if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end return parsed end ----------------------------------------------------------------------------- -- Builds a path component from its segments, escaping protected characters. -- Input -- parsed: path segments -- unsafe: if true, segments are not protected before path is built -- Returns -- path: corresponding path stringing ----------------------------------------------------------------------------- function _M.build_path(parsed, unsafe) local path = "" local n = #parsed if unsafe then for i = 1, n-1 do path = path .. parsed[i] path = path .. "/" end if n > 0 then path = path .. parsed[n] if parsed.is_directory then path = path .. "/" end end else for i = 1, n-1 do path = path .. protect_segment(parsed[i]) path = path .. "/" end if n > 0 then path = path .. protect_segment(parsed[n]) if parsed.is_directory then path = path .. "/" end end end if parsed.is_absolute then path = "/" .. path end return path end return _M ================================================ FILE: Assets/ToLua/Lua/socket/url.lua.meta ================================================ fileFormatVersion: 2 guid: f52d8d21085d51c42b5e27aca557bcd9 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket.lua ================================================ ----------------------------------------------------------------------------- -- LuaSocket helper module -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module and import dependencies ----------------------------------------------------------------------------- local base = _G local string = require("string") local math = require("math") local socket = require("socket.core") local _M = socket ----------------------------------------------------------------------------- -- Exported auxiliar functions ----------------------------------------------------------------------------- function _M.connect4(address, port, laddress, lport) return socket.connect(address, port, laddress, lport, "inet") end function _M.connect6(address, port, laddress, lport) return socket.connect(address, port, laddress, lport, "inet6") end function _M.bind(host, port, backlog) if host == "*" then host = "0.0.0.0" end local addrinfo, err = socket.dns.getaddrinfo(host); if not addrinfo then return nil, err end local sock, res err = "no info on address" for i, alt in base.ipairs(addrinfo) do if alt.family == "inet" then sock, err = socket.tcp4() else sock, err = socket.tcp6() end if not sock then return nil, err end sock:setoption("reuseaddr", true) res, err = sock:bind(alt.addr, port) if not res then sock:close() else res, err = sock:listen(backlog) if not res then sock:close() else return sock end end end return nil, err end _M.try = _M.newtry() function _M.choose(table) return function(name, opt1, opt2) if base.type(name) ~= "string" then name, opt1, opt2 = "default", name, opt1 end local f = table[name or "nil"] if not f then base.error("unknown key (".. base.tostring(name) ..")", 3) else return f(opt1, opt2) end end end ----------------------------------------------------------------------------- -- Socket sources and sinks, conforming to LTN12 ----------------------------------------------------------------------------- -- create namespaces inside LuaSocket namespace local sourcet, sinkt = {}, {} _M.sourcet = sourcet _M.sinkt = sinkt _M.BLOCKSIZE = 2048 sinkt["close-when-done"] = function(sock) return base.setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function(self, chunk, err) if not chunk then sock:close() return 1 else return sock:send(chunk) end end }) end sinkt["keep-open"] = function(sock) return base.setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function(self, chunk, err) if chunk then return sock:send(chunk) else return 1 end end }) end sinkt["default"] = sinkt["keep-open"] _M.sink = _M.choose(sinkt) sourcet["by-length"] = function(sock, length) return base.setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function() if length <= 0 then return nil end local size = math.min(socket.BLOCKSIZE, length) local chunk, err = sock:receive(size) if err then return nil, err end length = length - string.len(chunk) return chunk end }) end sourcet["until-closed"] = function(sock) local done return base.setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function() if done then return nil end local chunk, err, partial = sock:receive(socket.BLOCKSIZE) if not err then return chunk elseif err == "closed" then sock:close() done = 1 return partial else return nil, err end end }) end sourcet["default"] = sourcet["until-closed"] _M.source = _M.choose(sourcet) return _M ================================================ FILE: Assets/ToLua/Lua/socket.lua.meta ================================================ fileFormatVersion: 2 guid: 63c3bb6af007b6344af9a86ef0b7e225 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/socket.meta ================================================ fileFormatVersion: 2 guid: d809aad390df7d54a95d719367731993 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/tolua.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- if jit then if jit.opt then jit.opt.start(3) end print("ver"..jit.version_num.." jit: ", jit.status()) print(string.format("os: %s, arch: %s", jit.os, jit.arch)) end if DebugServerIp then require("mobdebug").start(DebugServerIp) end require "misc.functions" Mathf = require "UnityEngine.Mathf" Vector3 = require "UnityEngine.Vector3" Quaternion = require "UnityEngine.Quaternion" Vector2 = require "UnityEngine.Vector2" Vector4 = require "UnityEngine.Vector4" Color = require "UnityEngine.Color" Color32 = require "UnityEngine.Color32" Ray = require "UnityEngine.Ray" Bounds = require "UnityEngine.Bounds" RaycastHit = require "UnityEngine.RaycastHit" Touch = require "UnityEngine.Touch" LayerMask = require "UnityEngine.LayerMask" Plane = require "UnityEngine.Plane" Time = reimport "UnityEngine.Time" list = require "list" utf8 = require "misc.utf8" require "event" require "typeof" require "slot" require "System.Timer" require "System.coroutine" require "System.ValueType" require "System.Reflection.BindingFlags" --require "misc.strict" ================================================ FILE: Assets/ToLua/Lua/tolua.lua.meta ================================================ fileFormatVersion: 2 guid: 2dab8762e884a1c469dd11f6d2044a0f DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua/typeof.lua ================================================ -------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local type = type local types = {} local _typeof = tolua.typeof local _findtype = tolua.findtype function typeof(obj) local t = type(obj) local ret = nil if t == "table" then ret = types[obj] if ret == nil then ret = _typeof(obj) types[obj] = ret end elseif t == "string" then ret = types[obj] if ret == nil then ret = _findtype(obj) types[obj] = ret end else error(debug.traceback("attemp to call typeof on type "..t)) end return ret end ================================================ FILE: Assets/ToLua/Lua/typeof.lua.meta ================================================ fileFormatVersion: 2 guid: a7edd4f2975d3f54f8396b61d8b34944 DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Lua.meta ================================================ fileFormatVersion: 2 guid: 9b3be0814bb45e640973aea4f6303a33 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Misc/LuaClient.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System.Collections.Generic; using LuaInterface; using System.Collections; using System.IO; using System; #if UNITY_5_4_OR_NEWER using UnityEngine.SceneManagement; #endif public class LuaClient : MonoBehaviour { public static LuaClient Instance { get; protected set; } protected LuaState luaState = null; protected LuaLooper loop = null; protected LuaFunction levelLoaded = null; protected bool openLuaSocket = false; protected bool beZbStart = false; protected virtual LuaFileUtils InitLoader() { return LuaFileUtils.Instance; } protected virtual void LoadLuaFiles() { OnLoadFinished(); } protected virtual void OpenLibs() { luaState.OpenLibs(LuaDLL.luaopen_pb); luaState.OpenLibs(LuaDLL.luaopen_struct); luaState.OpenLibs(LuaDLL.luaopen_lpeg); #if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX luaState.OpenLibs(LuaDLL.luaopen_bit); #endif if (LuaConst.openLuaSocket) { OpenLuaSocket(); } if (LuaConst.openLuaDebugger) { OpenZbsDebugger(); } } public void OpenZbsDebugger(string ip = "localhost") { if (!Directory.Exists(LuaConst.zbsDir)) { Debugger.LogWarning("ZeroBraneStudio not install or LuaConst.zbsDir not right"); return; } if (!LuaConst.openLuaSocket) { OpenLuaSocket(); } if (!string.IsNullOrEmpty(LuaConst.zbsDir)) { luaState.AddSearchPath(LuaConst.zbsDir); } luaState.LuaDoString(string.Format("DebugServerIp = '{0}'", ip), "@LuaClient.cs"); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LuaOpen_Socket_Core(IntPtr L) { return LuaDLL.luaopen_socket_core(L); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LuaOpen_Mime_Core(IntPtr L) { return LuaDLL.luaopen_mime_core(L); } protected void OpenLuaSocket() { LuaConst.openLuaSocket = true; luaState.BeginPreLoad(); luaState.RegFunction("socket.core", LuaOpen_Socket_Core); luaState.RegFunction("mime.core", LuaOpen_Mime_Core); luaState.EndPreLoad(); } //cjson 比较特殊,只new了一个table,没有注册库,这里注册一下 protected void OpenCJson() { luaState.LuaGetField(LuaIndexes.LUA_REGISTRYINDEX, "_LOADED"); luaState.OpenLibs(LuaDLL.luaopen_cjson); luaState.LuaSetField(-2, "cjson"); luaState.OpenLibs(LuaDLL.luaopen_cjson_safe); luaState.LuaSetField(-2, "cjson.safe"); } protected virtual void CallMain() { LuaFunction main = luaState.GetFunction("Main"); main.Call(); main.Dispose(); main = null; } protected virtual void StartMain() { luaState.DoFile("Main.lua"); levelLoaded = luaState.GetFunction("OnLevelWasLoaded"); CallMain(); } protected void StartLooper() { loop = gameObject.AddComponent(); loop.luaState = luaState; } protected virtual void Bind() { LuaBinder.Bind(luaState); DelegateFactory.Init(); LuaCoroutine.Register(luaState, this); } protected void Init() { InitLoader(); luaState = new LuaState(); OpenLibs(); luaState.LuaSetTop(0); Bind(); LoadLuaFiles(); } protected void Awake() { Instance = this; Init(); #if UNITY_5_4_OR_NEWER SceneManager.sceneLoaded += OnSceneLoaded; #endif } protected virtual void OnLoadFinished() { luaState.Start(); StartLooper(); StartMain(); } void OnLevelLoaded(int level) { if (levelLoaded != null) { levelLoaded.BeginPCall(); levelLoaded.Push(level); levelLoaded.PCall(); levelLoaded.EndPCall(); } if (luaState != null) { luaState.RefreshDelegateMap(); } } #if UNITY_5_4_OR_NEWER void OnSceneLoaded(Scene scene, LoadSceneMode mode) { OnLevelLoaded(scene.buildIndex); } #else protected void OnLevelWasLoaded(int level) { OnLevelLoaded(level); } #endif public virtual void Destroy() { if (luaState != null) { #if UNITY_5_4_OR_NEWER SceneManager.sceneLoaded -= OnSceneLoaded; #endif luaState.Call("OnApplicationQuit", false); DetachProfiler(); LuaState state = luaState; luaState = null; if (levelLoaded != null) { levelLoaded.Dispose(); levelLoaded = null; } if (loop != null) { loop.Destroy(); loop = null; } state.Dispose(); Instance = null; } } protected void OnDestroy() { Destroy(); } protected void OnApplicationQuit() { Destroy(); } public static LuaState GetMainState() { return Instance.luaState; } public LuaLooper GetLooper() { return loop; } LuaTable profiler = null; public void AttachProfiler() { if (profiler == null) { profiler = luaState.Require("UnityEngine.Profiler"); profiler.Call("start", profiler); } } public void DetachProfiler() { if (profiler != null) { profiler.Call("stop", profiler); profiler.Dispose(); LuaProfiler.Clear(); } } } ================================================ FILE: Assets/ToLua/Misc/LuaClient.cs.meta ================================================ fileFormatVersion: 2 guid: 3d41d4486c02e3e4ca1c1f12f7a48a95 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Misc/LuaCoroutine.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using LuaInterface; using System; using System.Collections; public static class LuaCoroutine { private static MonoBehaviour mb = null; private static string strCo = @" local _WaitForSeconds, _WaitForFixedUpdate, _WaitForEndOfFrame, _Yield, _StopCoroutine = WaitForSeconds, WaitForFixedUpdate, WaitForEndOfFrame, Yield, StopCoroutine local error = error local debug = debug local coroutine = coroutine local comap = {} setmetatable(comap, {__mode = 'k'}) function _resume(co) if comap[co] then comap[co] = nil local flag, msg = coroutine.resume(co) if not flag then msg = debug.traceback(co, msg) error(msg) end end end function WaitForSeconds(t) local co = coroutine.running() local resume = function() _resume(co) end comap[co] = _WaitForSeconds(t, resume) return coroutine.yield() end function WaitForFixedUpdate() local co = coroutine.running() local resume = function() _resume(co) end comap[co] = _WaitForFixedUpdate(resume) return coroutine.yield() end function WaitForEndOfFrame() local co = coroutine.running() local resume = function() _resume(co) end comap[co] = _WaitForEndOfFrame(resume) return coroutine.yield() end function Yield(o) local co = coroutine.running() local resume = function() _resume(co) end comap[co] = _Yield(o, resume) return coroutine.yield() end function StartCoroutine(func) local co = coroutine.create(func) local flag, msg = coroutine.resume(co) if not flag then msg = debug.traceback(co, msg) error(msg) end return co end function StopCoroutine(co) local _co = comap[co] if _co == nil then return end comap[co] = nil _StopCoroutine(_co) end "; public static void Register(LuaState state, MonoBehaviour behaviour) { state.BeginModule(null); state.RegFunction("WaitForSeconds", _WaitForSeconds); state.RegFunction("WaitForFixedUpdate", WaitForFixedUpdate); state.RegFunction("WaitForEndOfFrame", WaitForEndOfFrame); state.RegFunction("Yield", Yield); state.RegFunction("StopCoroutine", StopCoroutine); state.RegFunction("WrapLuaCoroutine", WrapLuaCoroutine); state.EndModule(); state.LuaDoString(strCo, "LuaCoroutine.cs"); mb = behaviour; } //另一种方式,非脚本回调方式(用脚本方式更好,可避免lua_yield异常出现在c#函数中) /*[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int WaitForSeconds(IntPtr L) { try { LuaState state = LuaState.Get(L); LuaDLL.lua_pushthread(L); LuaThread thread = ToLua.ToLuaThread(L, -1); float sec = (float)LuaDLL.luaL_checknumber(L, 1); mb.StartCoroutine(CoWaitForSeconds(sec, thread)); return LuaDLL.lua_yield(L, 0); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } static IEnumerator CoWaitForSeconds(float sec, LuaThread thread) { yield return new WaitForSeconds(sec); thread.Resume(); }*/ [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] private static int _WaitForSeconds(IntPtr L) { try { float sec = (float)LuaDLL.luaL_checknumber(L, 1); LuaFunction func = ToLua.ToLuaFunction(L, 2); Coroutine co = mb.StartCoroutine(CoWaitForSeconds(sec, func)); ToLua.PushSealed(L, co); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } private static IEnumerator CoWaitForSeconds(float sec, LuaFunction func) { yield return new WaitForSeconds(sec); func.Call(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] private static int WaitForFixedUpdate(IntPtr L) { try { LuaFunction func = ToLua.ToLuaFunction(L, 1); Coroutine co = mb.StartCoroutine(CoWaitForFixedUpdate(func)); ToLua.PushSealed(L, co); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } private static IEnumerator CoWaitForFixedUpdate(LuaFunction func) { yield return new WaitForFixedUpdate(); func.Call(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] private static int WaitForEndOfFrame(IntPtr L) { try { LuaFunction func = ToLua.ToLuaFunction(L, 1); Coroutine co = mb.StartCoroutine(CoWaitForEndOfFrame(func)); ToLua.PushSealed(L, co); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } private static IEnumerator CoWaitForEndOfFrame(LuaFunction func) { yield return new WaitForEndOfFrame(); func.Call(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] private static int Yield(IntPtr L) { try { object o = ToLua.ToVarObject(L, 1); LuaFunction func = ToLua.ToLuaFunction(L, 2); Coroutine co = mb.StartCoroutine(CoYield(o, func)); ToLua.PushSealed(L, co); return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } private static IEnumerator CoYield(object o, LuaFunction func) { if (o is IEnumerator) { yield return mb.StartCoroutine((IEnumerator)o); } else { yield return o; } func.Call(); } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] private static int StopCoroutine(IntPtr L) { try { Coroutine co = (Coroutine)ToLua.CheckObject(L, 1, typeof(Coroutine)); mb.StopCoroutine(co); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] private static int WrapLuaCoroutine(IntPtr L) { LuaFunction func = ToLua.ToLuaFunction(L, 1); IEnumerator enumerator = CoWrap(func); ToLua.Push(L, enumerator); return 1; } private static IEnumerator CoWrap(LuaFunction func) { if (func == null) { yield break; } while (func.Invoke()) { yield return null; } } } ================================================ FILE: Assets/ToLua/Misc/LuaCoroutine.cs.meta ================================================ fileFormatVersion: 2 guid: 61c0f3aff91dfbd4097181bfb8c99d7f MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Misc/LuaLooper.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using UnityEngine; using LuaInterface; public class LuaLooper : MonoBehaviour { public LuaBeatEvent UpdateEvent { get; private set; } public LuaBeatEvent LateUpdateEvent { get; private set; } public LuaBeatEvent FixedUpdateEvent { get; private set; } public LuaState luaState = null; void Start() { try { UpdateEvent = GetEvent("UpdateBeat"); LateUpdateEvent = GetEvent("LateUpdateBeat"); FixedUpdateEvent = GetEvent("FixedUpdateBeat"); } catch (Exception e) { Destroy(this); throw e; } } LuaBeatEvent GetEvent(string name) { LuaTable table = luaState.GetTable(name); if (table == null) { throw new LuaException(string.Format("Lua table {0} not exists", name)); } LuaBeatEvent e = new LuaBeatEvent(table); table.Dispose(); table = null; return e; } void ThrowException() { string error = luaState.LuaToString(-1); luaState.LuaPop(2); throw new LuaException(error, LuaException.GetLastError()); } void Update() { #if UNITY_EDITOR if (luaState == null) { return; } #endif if (luaState.LuaUpdate(Time.deltaTime, Time.unscaledDeltaTime) != 0) { ThrowException(); } luaState.LuaPop(1); luaState.Collect(); #if UNITY_EDITOR luaState.CheckTop(); #endif } void LateUpdate() { #if UNITY_EDITOR if (luaState == null) { return; } #endif if (luaState.LuaLateUpdate() != 0) { ThrowException(); } luaState.StepCollect(); luaState.LuaPop(1); } void FixedUpdate() { #if UNITY_EDITOR if (luaState == null) { return; } #endif if (luaState.LuaFixedUpdate(Time.fixedDeltaTime) != 0) { ThrowException(); } luaState.LuaPop(1); } public void Destroy() { if (luaState != null) { if (UpdateEvent != null) { UpdateEvent.Dispose(); UpdateEvent = null; } if (LateUpdateEvent != null) { LateUpdateEvent.Dispose(); LateUpdateEvent = null; } if (FixedUpdateEvent != null) { FixedUpdateEvent.Dispose(); FixedUpdateEvent = null; } luaState = null; } } void OnDestroy() { if (luaState != null) { Destroy(); } } } ================================================ FILE: Assets/ToLua/Misc/LuaLooper.cs.meta ================================================ fileFormatVersion: 2 guid: d56dbfed903b80e498bb872845c17e7e MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: -10 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Misc/LuaProfiler.cs ================================================ using System.Collections.Generic; using UnityEngine; #if UNITY_5_5_OR_NEWER using UnityEngine.Profiling; #endif public static class LuaProfiler { public static List list = new List(); public static void Clear() { list.Clear(); } public static int GetID(string name) { int id = list.Count; list.Add(name); return id; } public static void BeginSample(int id) { string name = list[id]; Profiler.BeginSample(name); } public static void EndSample() { Profiler.EndSample(); } } ================================================ FILE: Assets/ToLua/Misc/LuaProfiler.cs.meta ================================================ fileFormatVersion: 2 guid: 29c635f2321c2dc48aea28e8e6accb7e MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Misc/LuaResLoader.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ //优先读取persistentDataPath/系统/Lua 目录下的文件(默认下载目录) //未找到文件怎读取 Resources/Lua 目录下文件(仍没有使用LuaFileUtil读取) using UnityEngine; using LuaInterface; using System.IO; using System.Text; public class LuaResLoader : LuaFileUtils { public LuaResLoader() { instance = this; beZip = false; } public override byte[] ReadFile(string fileName) { #if !UNITY_EDITOR byte[] buffer = ReadDownLoadFile(fileName); if (buffer == null) { buffer = ReadResourceFile(fileName); } if (buffer == null) { buffer = base.ReadFile(fileName); } #else byte[] buffer = base.ReadFile(fileName); if (buffer == null) { buffer = ReadResourceFile(fileName); } if (buffer == null) { buffer = ReadDownLoadFile(fileName); } #endif return buffer; } public override string FindFileError(string fileName) { if (Path.IsPathRooted(fileName)) { return fileName; } if (Path.GetExtension(fileName) == ".lua") { fileName = fileName.Substring(0, fileName.Length - 4); } using (CString.Block()) { CString sb = CString.Alloc(512); for (int i = 0; i < searchPaths.Count; i++) { sb.Append("\n\tno file '").Append(searchPaths[i]).Append('\''); } sb.Append("\n\tno file './Resources/").Append(fileName).Append(".lua'") .Append("\n\tno file '").Append(LuaConst.luaResDir).Append('/') .Append(fileName).Append(".lua'"); sb = sb.Replace("?", fileName); return sb.ToString(); } } byte[] ReadResourceFile(string fileName) { if (!fileName.EndsWith(".lua")) { fileName += ".lua"; } byte[] buffer = null; string path = "Lua/" + fileName; TextAsset text = Resources.Load(path, typeof(TextAsset)) as TextAsset; if (text != null) { buffer = text.bytes; Resources.UnloadAsset(text); } return buffer; } byte[] ReadDownLoadFile(string fileName) { if (!fileName.EndsWith(".lua")) { fileName += ".lua"; } string path = fileName; if (!Path.IsPathRooted(fileName)) { path = string.Format("{0}/{1}", LuaConst.luaResDir, fileName); } if (File.Exists(path)) { #if !UNITY_WEBPLAYER return File.ReadAllBytes(path); #else throw new LuaException("can't run in web platform, please switch to other platform"); #endif } return null; } } ================================================ FILE: Assets/ToLua/Misc/LuaResLoader.cs.meta ================================================ fileFormatVersion: 2 guid: 61b6ccc77a2cfc341963b08eb6cb4dfc MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Misc.meta ================================================ fileFormatVersion: 2 guid: 4ec2002202db97649bcdffe1705c0bdc folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/Reflection/LuaConstructor.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using System.Globalization; using System.Reflection; namespace LuaInterface { public sealed class LuaConstructor { ConstructorInfo method = null; List list = null; [NoToLuaAttribute] public LuaConstructor(ConstructorInfo func, Type[] types) { method = func; if (types != null) { list = new List(types); } } public int Call(IntPtr L) { object[] args = null; ToLua.CheckArgsCount(L, list.Count + 1); if (list.Count > 0) { args = new object[list.Count]; for (int i = 0; i < list.Count; i++) { bool isRef = list[i].IsByRef; Type t0 = isRef ? list[i].GetElementType() : list[i]; object o = ToLua.CheckVarObject(L, i + 2, t0); args[i] = o; } } object ret = method.Invoke(args); int count = 1; ToLua.Push(L, ret); for (int i = 0; i < list.Count; i++) { if (list[i].IsByRef) { ++count; ToLua.Push(L, args[i]); } } return count; } public void Destroy() { method = null; list.Clear(); } } } ================================================ FILE: Assets/ToLua/Reflection/LuaConstructor.cs.meta ================================================ fileFormatVersion: 2 guid: 5f277531b56c0944fb5d9af67defed02 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Reflection/LuaField.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Globalization; using System.Reflection; namespace LuaInterface { //代表一个反射属性 public sealed class LuaField { FieldInfo field = null; Type kclass = null; [NoToLuaAttribute] public LuaField(FieldInfo info, Type t) { field = info; kclass = t; } public int Get(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); object arg0 = ToLua.CheckObject(L, 2, kclass); object o = field.GetValue(arg0); if (o == null) { if (typeof(System.MulticastDelegate).IsAssignableFrom(field.FieldType)) { o = DelegateFactory.CreateDelegate(field.FieldType, null); ToLua.Push(L, (Delegate)o); } else { LuaDLL.lua_pushnil(L); } } else { ToLua.Push(L, o); } return 1; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } public int Set(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 3) { object arg0 = ToLua.CheckVarObject(L, 2, kclass); object arg1 = ToLua.ToVarObject(L, 3); if (arg1 != null) arg1 = TypeChecker.ChangeType(arg1, field.FieldType); field.SetValue(arg0, arg1); return 0; } else if (count == 6) { object arg0 = ToLua.CheckVarObject(L, 2, kclass); object arg1 = ToLua.ToVarObject(L, 3); if (arg1 != null) arg1 = TypeChecker.ChangeType(arg1, field.FieldType); BindingFlags arg2 = (BindingFlags)LuaDLL.luaL_checknumber(L, 4); Binder arg3 = (Binder)ToLua.CheckObject(L, 5, typeof(Binder)); CultureInfo arg4 = (CultureInfo)ToLua.CheckObject(L, 6, typeof(CultureInfo)); field.SetValue(arg0, arg1, arg2, arg3, arg4); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: LuaField.Set"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } } } ================================================ FILE: Assets/ToLua/Reflection/LuaField.cs.meta ================================================ fileFormatVersion: 2 guid: ac0dd1f9fec2afa4e96fc2f583688c5a MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Reflection/LuaMethod.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using System.Reflection; namespace LuaInterface { //代表一个反射函数 public sealed class LuaMethod { MethodInfo method = null; List list = new List(); Type kclass = null; [NoToLuaAttribute] public LuaMethod(MethodInfo md, Type t, Type[] types) { method = md; kclass = t; if (types != null) { list.AddRange(types); } } public int Call(IntPtr L) { object[] args = null; object obj = null; int offset = 1; if (!method.IsStatic) { offset += 1; obj = ToLua.CheckObject(L, 2, kclass); } ToLua.CheckArgsCount(L, list.Count + offset); if (list.Count > 0) { args = new object[list.Count]; offset += 1; for (int i = 0; i < list.Count; i++) { bool isRef = list[i].IsByRef; Type t0 = isRef ? list[i].GetElementType() : list[i]; object o = ToLua.CheckVarObject(L, i + offset, t0); args[i] = o; } } object ret = method.Invoke(obj, args); int count = 0; if (method.ReturnType != typeof(void)) { ++count; ToLua.Push(L, ret); } for (int i = 0; i < list.Count; i++) { if (list[i].IsByRef) { ++count; ToLua.Push(L, args[i]); } } return count; } public void Destroy() { method = null; list.Clear(); } } } ================================================ FILE: Assets/ToLua/Reflection/LuaMethod.cs.meta ================================================ fileFormatVersion: 2 guid: e50f0b4cc54866649975adb5d9801a3d MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Reflection/LuaProperty.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Globalization; using System.Reflection; namespace LuaInterface { //代表一个反射属性 public sealed class LuaProperty { PropertyInfo property = null; Type kclass = null; [NoToLuaAttribute] public LuaProperty(PropertyInfo prop, Type t) { property = prop; kclass = t; } public int Get(IntPtr L) { int count = LuaDLL.lua_gettop(L); if (count == 3) { object arg0 = ToLua.CheckVarObject(L, 2, kclass); object[] arg1 = ToLua.CheckObjectArray(L, 3); object o = property.GetValue(arg0, arg1); ToLua.Push(L, o); return 1; } else if (count == 6) { object arg0 = ToLua.CheckVarObject(L, 2, kclass); BindingFlags arg1 = (BindingFlags)LuaDLL.luaL_checknumber(L, 3); Binder arg2 = (Binder)ToLua.CheckObject(L, 4, typeof(Binder)); object[] arg3 = ToLua.CheckObjectArray(L, 5); CultureInfo arg4 = (CultureInfo)ToLua.CheckObject(L, 6, typeof(CultureInfo)); object o = property.GetValue(arg0, arg1, arg2, arg3, arg4); ToLua.Push(L, o); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: LuaInterface.LuaProperty.Get"); } } public int Set(IntPtr L) { int count = LuaDLL.lua_gettop(L); if (count == 4) { object arg0 = ToLua.CheckVarObject(L, 2, kclass); object arg1 = ToLua.ToVarObject(L, 3); if (arg1 != null) arg1 = TypeChecker.ChangeType(arg1, property.PropertyType); object[] arg2 = ToLua.CheckObjectArray(L, 4); property.SetValue(arg0, arg1, arg2); return 0; } else if (count == 7) { object arg0 = ToLua.CheckVarObject(L, 2, kclass); object arg1 = ToLua.ToVarObject(L, 3); if (arg1 != null) arg1 = TypeChecker.ChangeType(arg1, property.PropertyType); BindingFlags arg2 = (BindingFlags)LuaDLL.luaL_checknumber(L, 4); Binder arg3 = (Binder)ToLua.CheckObject(L, 5, typeof(Binder)); object[] arg4 = ToLua.CheckObjectArray(L, 6); CultureInfo arg5 = (CultureInfo)ToLua.CheckObject(L, 7, typeof(CultureInfo)); property.SetValue(arg0, arg1, arg2, arg3, arg4, arg5); return 0; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: LuaInterface.LuaProperty.Set"); } } } } ================================================ FILE: Assets/ToLua/Reflection/LuaProperty.cs.meta ================================================ fileFormatVersion: 2 guid: 26952c90fb22bda4dbe945f2fa2224ff MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Reflection/LuaReflection.cs ================================================ /* Copyright (c) 2015-2017 topameng(topameng@qq.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using System.Reflection; namespace LuaInterface { public class LuaReflection : IDisposable { public List list = new List(); #if !MULTI_STATE private static LuaReflection _reflection = null; #endif public LuaReflection() { #if !MULTI_STATE _reflection = this; #endif LoadAssembly("mscorlib"); LoadAssembly("UnityEngine"); //注释避免放在插件目录无法加载,需要可从lua代码loadassembly //LoadAssembly("Assembly-CSharp"); } public static void OpenLibs(IntPtr L) { LuaDLL.lua_getglobal(L, "tolua"); LuaDLL.lua_pushstring(L, "findtype"); LuaDLL.lua_pushcfunction(L, FindType); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "loadassembly"); LuaDLL.tolua_pushcfunction(L, LoadAssembly); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "getmethod"); LuaDLL.tolua_pushcfunction(L, GetMethod); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "getconstructor"); LuaDLL.tolua_pushcfunction(L, GetConstructor); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "gettypemethod"); LuaDLL.tolua_pushcfunction(L, GetTypeMethod); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "getfield"); LuaDLL.tolua_pushcfunction(L, GetField); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "getproperty"); LuaDLL.tolua_pushcfunction(L, GetProperty); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pushstring(L, "createinstance"); LuaDLL.tolua_pushcfunction(L, CreateInstance); LuaDLL.lua_rawset(L, -3); LuaDLL.lua_pop(L, 1); LuaState state = LuaState.Get(L); state.BeginPreLoad(); state.AddPreLoad("tolua.reflection", OpenReflectionLibs); state.EndPreLoad(); } public static LuaReflection Get(IntPtr L) { #if !MULTI_STATE return _reflection; #else return LuaState.GetReflection(L); #endif } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int OpenReflectionLibs(IntPtr L) { try { LuaState state = LuaState.Get(L); state.BeginModule(null); state.BeginModule("LuaInterface"); LuaInterface_LuaMethodWrap.Register(state); LuaInterface_LuaPropertyWrap.Register(state); LuaInterface_LuaFieldWrap.Register(state); LuaInterface_LuaConstructorWrap.Register(state); state.EndModule(); state.EndModule(); return 0; } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int FindType(IntPtr L) { string name = ToLua.CheckString(L, 1); LuaReflection reflection = LuaReflection.Get(L); List list = reflection.list; Type t = null; for (int i = 0; i < list.Count; i++) { t = list[i].GetType(name); if (t != null) { break; } } ToLua.Push(L, t); return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int LoadAssembly(IntPtr L) { try { LuaReflection reflection = LuaReflection.Get(L); string name = ToLua.CheckString(L, 1); LuaDLL.lua_pushboolean(L, reflection.LoadAssembly(name)); } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } return 1; } static void PushLuaMethod(IntPtr L, MethodInfo md, Type t, Type[] types) { if (md != null) { LuaMethod lm = new LuaMethod(md, t, types); ToLua.PushSealed(L, lm); } else { LuaDLL.lua_pushnil(L); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetMethod(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type t = ToLua.CheckMonoType(L, 1); string name = ToLua.CheckString(L, 2); Type[] types = null; if (count > 2) { types = new Type[count - 2]; for (int i = 3; i <= count; i++) { Type ti = ToLua.CheckMonoType(L, i); if (ti == null) LuaDLL.luaL_typerror(L, i, "Type"); types[i - 3] = ti; } } MethodInfo md = null; if (types == null) { md = t.GetMethod(name); } else { md = t.GetMethod(name, types); } PushLuaMethod(L, md, t, types); } catch(Exception e) { return LuaDLL.toluaL_exception(L, e); } return 1; } static void PushLuaConstructor(IntPtr L, ConstructorInfo func, Type[] types) { if (func != null) { LuaConstructor lm = new LuaConstructor(func, types); ToLua.PushSealed(L, lm); } else { LuaDLL.lua_pushnil(L); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetConstructor(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); Type t = (Type)ToLua.CheckObject(L, 1, typeof(Type)); Type[] types = null; if (count > 1) { types = new Type[count - 1]; for (int i = 2; i <= count; i++) { Type ti = ToLua.CheckMonoType(L, i); if (ti == null) LuaDLL.luaL_typerror(L, i, "Type"); types[i - 2] = ti; } } ConstructorInfo ret = t.GetConstructor(types); PushLuaConstructor(L, ret, types); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 1; } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetTypeMethod(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); MethodInfo o = obj.GetMethod(arg0); PushLuaMethod(L, o, obj, null); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); Type[] arg1 = ToLua.ToObjectArray(L, 3); MethodInfo o = obj.GetMethod(arg0, arg1); PushLuaMethod(L, o, obj, arg1); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); BindingFlags arg1 = (BindingFlags)LuaDLL.lua_tonumber(L, 3); MethodInfo o = obj.GetMethod(arg0, arg1); PushLuaMethod(L, o, obj, null); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); Type[] arg1 = ToLua.ToObjectArray(L, 3); ParameterModifier[] arg2 = ToLua.ToStructArray(L, 4); MethodInfo o = obj.GetMethod(arg0, arg1, arg2); PushLuaMethod(L, o, obj, arg1); return 1; } else if (count == 6 && TypeChecker.CheckTypes (L, 1)) { System.Type obj = (System.Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); BindingFlags arg1 = (BindingFlags)LuaDLL.lua_tonumber(L, 3); Binder arg2 = (Binder)ToLua.ToObject(L, 4); Type[] arg3 = ToLua.ToObjectArray(L, 5); ParameterModifier[] arg4 = ToLua.ToStructArray(L, 6); MethodInfo o = obj.GetMethod(arg0, arg1, arg2, arg3, arg4); PushLuaMethod(L, o, obj, arg3); return 1; } else if (count == 7 && TypeChecker.CheckTypes (L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); BindingFlags arg1 = (BindingFlags)LuaDLL.lua_tonumber(L, 3); Binder arg2 = (Binder)ToLua.ToObject(L, 4); CallingConventions arg3 = (CallingConventions)ToLua.ToObject(L, 5); Type[] arg4 = ToLua.ToObjectArray(L, 6); ParameterModifier[] arg5 = ToLua.ToStructArray(L, 7); MethodInfo o = obj.GetMethod(arg0, arg1, arg2, arg3, arg4, arg5); PushLuaMethod(L, o, obj, arg4); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: tolua.gettypemethod"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } static void PushLuaProperty(IntPtr L, PropertyInfo p, Type t) { if (p != null) { LuaProperty lp = new LuaProperty(p, t); ToLua.PushSealed(L, lp); } else { LuaDLL.lua_pushnil(L); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetProperty(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); PropertyInfo o = obj.GetProperty(arg0); PushLuaProperty(L, o, obj); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); Type[] arg1 = ToLua.ToObjectArray(L, 3); PropertyInfo o = obj.GetProperty(arg0, arg1); PushLuaProperty(L, o, obj); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); Type arg1 = (Type)ToLua.ToObject(L, 3); PropertyInfo o = obj.GetProperty(arg0, arg1); PushLuaProperty(L, o, obj); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); BindingFlags arg1 = (BindingFlags)LuaDLL.lua_tonumber(L, 3); PropertyInfo o = obj.GetProperty(arg0, arg1); PushLuaProperty(L, o, obj); return 1; } else if (count == 4 && TypeChecker.CheckTypes(L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); Type arg1 = (Type)ToLua.ToObject(L, 3); Type[] arg2 = ToLua.ToObjectArray(L, 4); PropertyInfo o = obj.GetProperty(arg0, arg1, arg2); PushLuaProperty(L, o, obj); return 1; } else if (count == 5 && TypeChecker.CheckTypes (L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); Type arg1 = (Type)ToLua.ToObject(L, 3); Type[] arg2 = ToLua.ToObjectArray(L, 4); ParameterModifier[] arg3 = ToLua.ToStructArray(L, 5); PropertyInfo o = obj.GetProperty(arg0, arg1, arg2, arg3); PushLuaProperty(L, o, obj); return 1; } else if (count == 7 && TypeChecker.CheckTypes (L, 1)) { Type obj = (Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); BindingFlags arg1 = (BindingFlags)LuaDLL.lua_tonumber(L, 3); Binder arg2 = (Binder)ToLua.ToObject(L, 4); Type arg3 = (Type)ToLua.ToObject(L, 5); Type[] arg4 = ToLua.ToObjectArray(L, 6); ParameterModifier[] arg5 = ToLua.ToStructArray(L, 7); PropertyInfo o = obj.GetProperty(arg0, arg1, arg2, arg3, arg4, arg5); PushLuaProperty(L, o, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: tolua.getproperty"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } static void PushLuaField(IntPtr L, FieldInfo f, Type t) { if (f != null) { LuaField lp = new LuaField(f, t); ToLua.PushSealed(L, lp); } else { LuaDLL.lua_pushnil(L); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int GetField(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes(L, 1)) { Type obj = (System.Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); FieldInfo o = obj.GetField(arg0); PushLuaField(L, o, obj); return 1; } else if (count == 3 && TypeChecker.CheckTypes(L, 1)) { Type obj = (System.Type)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); BindingFlags arg1 = (BindingFlags)LuaDLL.lua_tonumber(L, 3); FieldInfo o = obj.GetField(arg0, arg1); PushLuaField(L, o, obj); return 1; } else { return LuaDLL.luaL_throw(L, "invalid arguments to method: tolua.getfield"); } } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } } [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] static int CreateInstance(IntPtr L) { try { Type t = ToLua.CheckMonoType(L, 1); if (t == null) LuaDLL.luaL_typerror(L, 1, "Type"); int count = LuaDLL.lua_gettop(L); object obj = null; if (count == 1) { obj = Activator.CreateInstance(t); } else { object[] args = new object[count - 1]; for (int i = 2; i <= count; i++) { args[i - 2] = ToLua.ToVarObject(L, i); } obj = Activator.CreateInstance(t, args); } ToLua.Push(L, obj); } catch (Exception e) { return LuaDLL.toluaL_exception(L, e); } return 1; } bool LoadAssembly(string name) { for (int i = 0; i < list.Count; i++) { if (list[i].GetName().Name == name) { return true; } } Assembly assembly = Assembly.Load(name); if (assembly == null) { assembly = Assembly.Load(AssemblyName.GetAssemblyName(name)); } if (assembly != null && !list.Contains(assembly)) { list.Add(assembly); } return assembly != null; } public void Dispose() { list.Clear(); } } } ================================================ FILE: Assets/ToLua/Reflection/LuaReflection.cs.meta ================================================ fileFormatVersion: 2 guid: 3faee4f867484814bb3f76d4a798219d MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Assets/ToLua/Reflection.meta ================================================ fileFormatVersion: 2 guid: fcd2662a23826114e86e7828b55342b7 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/ToLua/readme.txt ================================================ tolua# git地址: https://github.com/topameng/tolua bug 反馈群: 286510803 如果你想在手机上测试,首先点击菜单Lua/Copy lua files to Resources, 之后再build 如果在mac上发布ios,删除x86和x86_64目录 更新插件之前,请先执行Lua/Clear wrap files,更新后再重新生成wrap文件。 1.01 - FIX: 5.x AssetBundle.Load函数废弃问题. - FIX: 修正模版类导出命名空间问题 - FIX: pblua protobuf协议tostring卡死问题 - FIX: Array index 不再检测null参数 - FIX: LuaInteger64 重载函数匹配检测问题 - NEW: 指定RenderSettings为静态类 - NEW: LuaFunction转委托函数支持可变参数列表 - NEW: Wrap函数出错同时附加c#异常堆栈 1.02 - New: c# event +=和-=操作支持 - New: 添加 mac 和 ios 运行库 - Opt: 优化list双向链表 1.0.3(需要重新导出Wrap文件) - FIX: 在mac unity5 luac协同异常后,unity追踪堆栈(一般是log类函数)不崩溃。(luac与unity配合问题) - FIX: ios发布mono版本编译问题 - FIX: 模拟unity协同在使用过程中发生协同被gc的bug. 加入StartCoroutine 和 StopCoroutine 来启动或者停止这种协同 - FIX: LuaFunction递归调用自身问题 - NEW: 出错后能反映两端正确的堆栈(并且格式与unity相同,无论是c#异常还是lua异常!) - NEW: 从LuaClient拆分出LuaLooper(负责update驱动分发) - NEW: Lua API 接口按照lua头文件方式排序,加入所有的Lua API函数(无法兼容的除非,部分被改写来) - NEW: 重写大量可发生异常的Lua API(native异常转换为C#异常)。 - NEW: lua 全双工协同加入 coroutine.stop 函数,请跟 coroutine.start 配合使用 - NEW: Event 改为小写 event, 增加 c# 端委托 +- LuaFunction - NEW: Add utf-8 libs and examples - NEW: Add cjson libs and examples - NEW: CustomSettings.cs 加入新的静态类,以及out类链表(默认不在为每个类加.out属性, 除非out列表有这个类型) - NEW: 加入LuaConst, 可以自定义Lua文件目录,设置后让例子环境正常运行 1.0.4 (需要重新导出Wrap文件,即使下载过这个版本也要重新导出) - FIX: 修复遗漏的TrackedReference问题(导出问题) - FIX: 导出wrap文件时当一个ref类型在其他非系统dll中也能正确找到。 - FIX: abstrace class 作为基类不再自动导出(默认跳过),如果需要导出,请加入到导出列表 - FIX: 如果函数名字与属性名相同(如get_Name 函数与 Name 属性),可以正确产生重载函数。 - FIX: char[] 转换问题 - FIX: int64.tonum2 符号位不对问题,int64加入范围检测 - NEW: int64 使用字符串赋值时加入溢出检查 - NEW: 修改proto-gen-lua库,使之支持int64, uint64。fixed64, ufixed64等等 - NEW: CheckTypes系列函数放入TypeChecker类 - NEW: 加入预加载库功能,预加载的库通过require类型延迟导入, 比如 require "UnityEngine.GameObject"。严格区分.与/。使用目录切勿用. - NEW: LuaConst加入ZeroBraneStudio路径设置,可以通过LuaClient.OpenZbsDebugger启动ZeroBraneStudio调试 - NEW: print 编辑器下可以打印所在的lua文件名和位置 - NEW: this操作符增加this属性,可以通过get和set操作, 在get_Item有重载函数,并且重载函数折叠掉this属性函数可以使用 - NEW: 增加LuaByteBufferAttribute, 加上这个标记的委托类型,在压入byte[]时作为lua string压入,而不是System.Array - Opt: 优化update系列函数速度 1.0.5 (需要重新生成库文件,重新导出wrap文件) - NEW: loader 遵从 lua 方式,c# loader 兼容package path路径方式 - NEW: 加入静态反射,使用方法见例子22_Reflection - NEW: 修改require, module 对于使用.和/不会作为不同文件加载。推荐用. - NEW: 支持c# 基础类型out修饰符。需要require 'tolua.out' 来加载。 - NEW: 加入LuaRenameAttribute元属性, 对于重载折叠掉的函数,可以使用这个属性设置一个新的函数名字从而实现单独导出 - NEW: 使用一个没有require的preloading库会触发一次警告,push 没有wrap的类型,做为注册过的基类类型存入(最差是System.Object) - NEW: 补齐一些极少用到的数组类型(如bool[]极少见)或者param数组(param string[](一般用param object[]))类型参数 - NEW: 导出支持增加扩展类型导出相应的扩展函数,支持可预知参数类型的模版函数导出。通过配置CustomSetting即可导出DoTween类库 - NEW: 支持ZeroBrandStudio调试 - NEW: luajit2.1 beta1 升级为 luajit2.1 beta2 - New: 打包lua文件名小写和u5.x一致,加入u5.x打包代码。 - FIX: 修改LuaSocket使用 git 上最新的LuaSocket版本,而不是之前的修改版 - FIX: 导出的数组支持c#所有数组函数,而不是只有[]和length - FIX: 去掉Type类一些无法使用的函数,使用静态反射方案替代 - FIX: luaref 默认值设置为-1,调用不存在或者未初始化的的函数出错信息同lua一致 - FIX: 修改AddSearchPath方式,c#查找文件方式与lua相同,并且兼容lua修改package.path,c#与c loader搜索目录不在重叠 - FIX: 清除LuaFunction 记录堆栈数据的gc alloc - FIX: int64作为object push check 问题 - FIX: LuaTable int key c#不做判断,按照lua标准执行或者报错 - FIX: 一些小的导出问题 1.0.6 (需要重新生成库文件,需要Clear all, 重新导出wrap) - NEW: 加入LuaStatePtr最为LuaDLL函数简单封装层 - NEW: LuaState ToLuaException 更名为 ThrowLuaException - NEW: Debugger 放入到 LuaInterface namespace - NEW: module.name 如果.name不存在,可以自动进行preloading操作,相当于 require "module.name" - NEW: 在控制台窗口点击print打印的lua log, 将会自动打开lua文件,或者跳转到设置的cs文件中 - NEW: 支持int64和uint64. c# 端long做为int64压入,ulong作为uint64压入 - NEW: 支持list和dictionary的通用导出 - NEW: list 支持数组操作符,如果Dictionary key 为int也支持,非int key 继续使用get_Item函数 - NEW: 支持委托转换LuaFunction函数,附带self。即System.Action(self.func, self), 这样转换可自动作为:调用 - FIX: tolua_pushcclosure 调整为 tolua_pushcfunction - FIX: userdata 访问__newindex不能存在的属性不创建peer表。如需peer表请主动创建 - FIX: 委托自动适配lua函数时,支持out参数。- 委托操作,支持自动转换函数。 - FIX: 部分GetHashCode函数可能潜在的问题 - FIX: CheckInteger64 更名为 CheckLong - FIX: DefaultMember("ItemOf")类导出问题 - FIX: 5.6部分编辑器函数或参数导出问题 - FIX:Object新的Instantiate函数导出问题 - FIX: int64反向计算问题 - FIX: 枚举唯一性问题 - Fix: LuaArrayTable LuaDictTable 迭代中break问题 1.0.7 (需要重新生成库文件,需要Clear all, 重新导出wrap) - NEW: LuaState增加直接调用一个lua函数,不生成临时的LuaFunction - NEW: LuaTable增加直接调用一个lua函数,不生成临时的LuaFunction - NEW: 通用模板支持, LuaFunction可以写简短调用方式,LuaTable 增加Get RawGet等无GC获取 - NEW: LuaFunction可转换为DelegateFactory中注册的委托 - NEW: CheckType采用模板形式,提高了重载函数匹配速度 - NEW: 优化了Physics.RayCast调用速度, 以及Check数组优化速度外加扩充 - NEW: 增加了struct类型自行扩展机制,通过自行扩展注入到tolua系统,快速无GC转换c#类型到lua table - NEW: luajit 升级为2.1b3, 并且极大减小在安卓上jit失败情况。 - NEW: 重载速度提升,相同参数个数,类型相同位置延迟参数类型检查 - NEW: 支持导出带有默认值的函数 - FIX: luajit不再因64位分配内存地址报not enough memory. 错误函数调用不在此列。参考http://luajit.org/status.html - FIX: 安卓上jit失败造成卡机问题 - FIX: 在系统中Instantis对象上的脚本Awake调用LuaFunction失败,通过LuaState.ThrowLuaException时堆栈错误上报出错问题 - FIX: 修正一些lua脚本中的书写错误 - FIX: 作为object PushLayerMask问题 ================================================ FILE: Assets/ToLua/readme.txt.meta ================================================ fileFormatVersion: 2 guid: c85b2c9de573bc54881ca0c2427016cd TextScriptImporter: userData: ================================================ FILE: Assets/ToLua.meta ================================================ fileFormatVersion: 2 guid: 032822da3092a2543aabbd58c5697222 folderAsset: yes DefaultImporter: userData: ================================================ FILE: Assets/link.xml ================================================  ================================================ FILE: Assets/link.xml.meta ================================================ fileFormatVersion: 2 guid: c8d0eb461ac328347a86a1727144872e timeCreated: 1498812386 licenseType: Pro TextScriptImporter: userData: assetBundleName: assetBundleVariant: ================================================ FILE: LICENSE-tolua ================================================ The MIT License (MIT) Copyright (c) 2015 topameng Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Luajit/Build.bat ================================================ @echo off cd /d %~dp0 if not exist jit (mkdir jit) if not exist Out (mkdir Out) xcopy /Y /D ..\..\..\Luajit\jit jit setlocal enabledelayedexpansion for /r %%i in (*.lua) do ( set v=%%~dpi call :loop set v=!v:%~dp0=! if not exist %~dp0out\!v! (mkdir %~dp0Out\!v!) ) for /r %%i in (*.lua) do ( set v=%%i set v=!v:%~dp0=! call :loop ..\..\..\Luajit\luajit32.exe -b -g !v! Out\!v!.bytes ) rd /s/q jit rd /s/q .\Out\jit\ setlocal disabledelayedexpansion :loop if "!v:~-1!"==" " set "v=!v:~0,-1!" & goto loop ================================================ FILE: Luajit/jit/bc.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT bytecode listing module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module lists the bytecode of a Lua function. If it's loaded by -jbc -- it hooks into the parser and lists all functions of a chunk as they -- are parsed. -- -- Example usage: -- -- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)' -- luajit -jbc=- foo.lua -- luajit -jbc=foo.list foo.lua -- -- Default output is to stderr. To redirect the output to a file, pass a -- filename as an argument (use '-' for stdout) or set the environment -- variable LUAJIT_LISTFILE. The file is overwritten every time the module -- is started. -- -- This module can also be used programmatically: -- -- local bc = require("jit.bc") -- -- local function foo() print("hello") end -- -- bc.dump(foo) --> -- BYTECODE -- [...] -- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello" -- -- local out = { -- -- Do something with each line: -- write = function(t, ...) io.write(...) end, -- close = function(t) end, -- flush = function(t) end, -- } -- bc.dump(foo, out) -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local bit = require("bit") local sub, gsub, format = string.sub, string.gsub, string.format local byte, band, shr = string.byte, bit.band, bit.rshift local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck local funcuvname = jutil.funcuvname local bcnames = vmdef.bcnames local stdout, stderr = io.stdout, io.stderr ------------------------------------------------------------------------------ local function ctlsub(c) if c == "\n" then return "\\n" elseif c == "\r" then return "\\r" elseif c == "\t" then return "\\t" else return format("\\%03d", byte(c)) end end -- Return one bytecode line. local function bcline(func, pc, prefix, lineinfo) local ins, m, l = funcbc(func, pc, lineinfo and 1 or 0) if not ins then return end local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128) local a = band(shr(ins, 8), 0xff) local oidx = 6*band(ins, 0xff) local op = sub(bcnames, oidx+1, oidx+6) local s if lineinfo then s = format("%04d %7s %s %-6s %3s ", pc, "["..l.."]", prefix or " ", op, ma == 0 and "" or a) else s = format("%04d %s %-6s %3s ", pc, prefix or " ", op, ma == 0 and "" or a) end local d = shr(ins, 16) if mc == 13*128 then -- BCMjump return format("%s=> %04d\n", s, pc+d-0x7fff) end if mb ~= 0 then d = band(d, 0xff) elseif mc == 0 then return s.."\n" end local kc if mc == 10*128 then -- BCMstr kc = funck(func, -d-1) kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) elseif mc == 9*128 then -- BCMnum kc = funck(func, d) if op == "TSETM " then kc = kc - 2^52 end elseif mc == 12*128 then -- BCMfunc local fi = funcinfo(funck(func, -d-1)) if fi.ffid then kc = vmdef.ffnames[fi.ffid] else kc = fi.loc end elseif mc == 5*128 then -- BCMuv kc = funcuvname(func, d) end if ma == 5 then -- BCMuv local ka = funcuvname(func, a) if kc then kc = ka.." ; "..kc else kc = ka end end if mb ~= 0 then local b = shr(ins, 24) if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end return format("%s%3d %3d\n", s, b, d) end if kc then return format("%s%3d ; %s\n", s, d, kc) end if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits return format("%s%3d\n", s, d) end -- Collect branch targets of a function. local function bctargets(func) local target = {} for pc=1,1000000000 do local ins, m = funcbc(func, pc) if not ins then break end if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end end return target end -- Dump bytecode instructions of a function. local function bcdump(func, out, all, lineinfo) if not out then out = stdout end local fi = funcinfo(func) if all and fi.children then for n=-1,-1000000000,-1 do local k = funck(func, n) if not k then break end if type(k) == "proto" then bcdump(k, out, true, lineinfo) end end end out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined)) for n=-1,-1000000000,-1 do local kc = funck(func, n) if not kc then break end local typ = type(kc) if typ == "string" then kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) out:write(format("KGC %d %s\n", -(n + 1), kc)) elseif typ == "proto" then local fi = funcinfo(kc) if fi.ffid then kc = vmdef.ffnames[fi.ffid] else kc = fi.loc end out:write(format("KGC %d %s\n", -(n + 1), kc)) elseif typ == "table" then out:write(format("KGC %d table\n", -(n + 1))) else -- error("unknown KGC type: " .. typ) end end for n=1,1000000000 do local kc = funck(func, n) if not kc then break end if type(kc) == "number" then out:write(format("KN %d %s\n", n, kc)) end end local target = bctargets(func) for pc=1,1000000000 do local s = bcline(func, pc, target[pc] and "=>", lineinfo) if not s then break end out:write(s) end out:write("\n") out:flush() end ------------------------------------------------------------------------------ -- Active flag and output file handle. local active, out -- List handler. local function h_list(func) return bcdump(func, out) end -- Detach list handler. local function bclistoff() if active then active = false jit.attach(h_list) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach list handler. local function bcliston(outfile) if active then bclistoff() end if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stderr end jit.attach(h_list, "bc") active = true end -- Public module functions. return { line = bcline, dump = bcdump, targets = bctargets, on = bcliston, off = bclistoff, start = bcliston -- For -j command line option. } ================================================ FILE: Luajit/jit/bcsave.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT module to save/list bytecode. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module saves or lists the bytecode for an input file. -- It's run by the -b command line option. -- ------------------------------------------------------------------------------ local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local bit = require("bit") -- Symbol name prefix for LuaJIT bytecode. local LJBC_PREFIX = "luaJIT_BC_" ------------------------------------------------------------------------------ local function usage() io.stderr:write[[ Save LuaJIT bytecode: luajit -b[options] input output -l Only list bytecode. -L Only list bytecode with lineinfo. -s Strip debug info (default). -g Keep debug info. -n name Set module name (default: auto-detect from input name). -t type Set output file type (default: auto-detect from output name). -a arch Override architecture for object files (default: native). -o os Override OS for object files (default: native). -e chunk Use chunk string as input. -- Stop handling options. - Use stdin as input and/or stdout as output. File types: c h obj o raw (default) ]] os.exit(1) end local function check(ok, ...) if ok then return ok, ... end io.stderr:write("luajit: ", ...) io.stderr:write("\n") os.exit(1) end local function readfile(input) if type(input) == "function" then return input end if input == "-" then input = nil end return check(loadfile(input)) end local function savefile(name, mode) if name == "-" then return io.stdout end return check(io.open(name, mode)) end ------------------------------------------------------------------------------ local map_type = { raw = "raw", c = "c", h = "h", o = "obj", obj = "obj", } local map_arch = { x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true, ppc = true, mips = true, mipsel = true, } local map_os = { linux = true, windows = true, osx = true, freebsd = true, netbsd = true, openbsd = true, dragonfly = true, solaris = true, } local function checkarg(str, map, err) str = string.lower(str) local s = check(map[str], "unknown ", err) return s == true and str or s end local function detecttype(str) local ext = string.match(string.lower(str), "%.(%a+)$") return map_type[ext] or "raw" end local function checkmodname(str) check(string.match(str, "^[%w_.%-]+$"), "bad module name") return string.gsub(str, "[%.%-]", "_") end local function detectmodname(str) if type(str) == "string" then local tail = string.match(str, "[^/\\]+$") if tail then str = tail end local head = string.match(str, "^(.*)%.[^.]*$") if head then str = head end str = string.match(str, "^[%w_.%-]+") else str = nil end check(str, "cannot derive module name, use -n name") return string.gsub(str, "[%.%-]", "_") end ------------------------------------------------------------------------------ local function bcsave_tail(fp, output, s) local ok, err = fp:write(s) if ok and output ~= "-" then ok, err = fp:close() end check(ok, "cannot write ", output, ": ", err) end local function bcsave_raw(output, s) local fp = savefile(output, "wb") bcsave_tail(fp, output, s) end local function bcsave_c(ctx, output, s) local fp = savefile(output, "w") if ctx.type == "c" then fp:write(string.format([[ #ifdef _cplusplus extern "C" #endif #ifdef _WIN32 __declspec(dllexport) #endif const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname)) else fp:write(string.format([[ #define %s%s_SIZE %d static const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname)) end local t, n, m = {}, 0, 0 for i=1,#s do local b = tostring(string.byte(s, i)) m = m + #b + 1 if m > 78 then fp:write(table.concat(t, ",", 1, n), ",\n") n, m = 0, #b + 1 end n = n + 1 t[n] = b end bcsave_tail(fp, output, table.concat(t, ",", 1, n).."\n};\n") end local function bcsave_elfobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; uint16_t type, machine; uint32_t version; uint32_t entry, phofs, shofs; uint32_t flags; uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; } ELF32header; typedef struct { uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; uint16_t type, machine; uint32_t version; uint64_t entry, phofs, shofs; uint32_t flags; uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; } ELF64header; typedef struct { uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize; } ELF32sectheader; typedef struct { uint32_t name, type; uint64_t flags, addr, ofs, size; uint32_t link, info; uint64_t align, entsize; } ELF64sectheader; typedef struct { uint32_t name, value, size; uint8_t info, other; uint16_t sectidx; } ELF32symbol; typedef struct { uint32_t name; uint8_t info, other; uint16_t sectidx; uint64_t value, size; } ELF64symbol; typedef struct { ELF32header hdr; ELF32sectheader sect[6]; ELF32symbol sym[2]; uint8_t space[4096]; } ELF32obj; typedef struct { ELF64header hdr; ELF64sectheader sect[6]; ELF64symbol sym[2]; uint8_t space[4096]; } ELF64obj; ]] local symname = LJBC_PREFIX..ctx.modname local is64, isbe = false, false if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then is64 = true elseif ctx.arch == "ppc" or ctx.arch == "mips" then isbe = true end -- Handle different host/target endianess. local function f32(x) return x end local f16, fofs = f32, f32 if ffi.abi("be") ~= isbe then f32 = bit.bswap function f16(x) return bit.rshift(bit.bswap(x), 16) end if is64 then local two32 = ffi.cast("int64_t", 2^32) function fofs(x) return bit.bswap(x)*two32 end else fofs = f32 end end -- Create ELF object and fill in header. local o = ffi.new(is64 and "ELF64obj" or "ELF32obj") local hdr = o.hdr if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi. local bf = assert(io.open("/bin/ls", "rb")) local bs = bf:read(9) bf:close() ffi.copy(o, bs, 9) check(hdr.emagic[0] == 127, "no support for writing native object files") else hdr.emagic = "\127ELF" hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0 end hdr.eclass = is64 and 2 or 1 hdr.eendian = isbe and 2 or 1 hdr.eversion = 1 hdr.type = f16(1) hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch]) if ctx.arch == "mips" or ctx.arch == "mipsel" then hdr.flags = f32(0x50001006) end hdr.version = f32(1) hdr.shofs = fofs(ffi.offsetof(o, "sect")) hdr.ehsize = f16(ffi.sizeof(hdr)) hdr.shentsize = f16(ffi.sizeof(o.sect[0])) hdr.shnum = f16(6) hdr.shstridx = f16(2) -- Fill in sections and symbols. local sofs, ofs = ffi.offsetof(o, "space"), 1 for i,name in ipairs{ ".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack", } do local sect = o.sect[i] sect.align = fofs(1) sect.name = f32(ofs) ffi.copy(o.space+ofs, name) ofs = ofs + #name+1 end o.sect[1].type = f32(2) -- .symtab o.sect[1].link = f32(3) o.sect[1].info = f32(1) o.sect[1].align = fofs(8) o.sect[1].ofs = fofs(ffi.offsetof(o, "sym")) o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0])) o.sect[1].size = fofs(ffi.sizeof(o.sym)) o.sym[1].name = f32(1) o.sym[1].sectidx = f16(4) o.sym[1].size = fofs(#s) o.sym[1].info = 17 o.sect[2].type = f32(3) -- .shstrtab o.sect[2].ofs = fofs(sofs) o.sect[2].size = fofs(ofs) o.sect[3].type = f32(3) -- .strtab o.sect[3].ofs = fofs(sofs + ofs) o.sect[3].size = fofs(#symname+2) ffi.copy(o.space+ofs+1, symname) ofs = ofs + #symname + 2 o.sect[4].type = f32(1) -- .rodata o.sect[4].flags = fofs(2) o.sect[4].ofs = fofs(sofs + ofs) o.sect[4].size = fofs(#s) o.sect[5].type = f32(1) -- .note.GNU-stack o.sect[5].ofs = fofs(sofs + ofs + #s) -- Write ELF object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) bcsave_tail(fp, output, s) end local function bcsave_peobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint16_t arch, nsects; uint32_t time, symtabofs, nsyms; uint16_t opthdrsz, flags; } PEheader; typedef struct { char name[8]; uint32_t vsize, vaddr, size, ofs, relocofs, lineofs; uint16_t nreloc, nline; uint32_t flags; } PEsection; typedef struct __attribute((packed)) { union { char name[8]; uint32_t nameref[2]; }; uint32_t value; int16_t sect; uint16_t type; uint8_t scl, naux; } PEsym; typedef struct __attribute((packed)) { uint32_t size; uint16_t nreloc, nline; uint32_t cksum; uint16_t assoc; uint8_t comdatsel, unused[3]; } PEsymaux; typedef struct { PEheader hdr; PEsection sect[2]; // Must be an even number of symbol structs. PEsym sym0; PEsymaux sym0aux; PEsym sym1; PEsymaux sym1aux; PEsym sym2; PEsym sym3; uint32_t strtabsize; uint8_t space[4096]; } PEobj; ]] local symname = LJBC_PREFIX..ctx.modname local is64 = false if ctx.arch == "x86" then symname = "_"..symname elseif ctx.arch == "x64" then is64 = true end local symexport = " /EXPORT:"..symname..",DATA " -- The file format is always little-endian. Swap if the host is big-endian. local function f32(x) return x end local f16 = f32 if ffi.abi("be") then f32 = bit.bswap function f16(x) return bit.rshift(bit.bswap(x), 16) end end -- Create PE object and fill in header. local o = ffi.new("PEobj") local hdr = o.hdr hdr.arch = f16(({ x86=0x14c, x64=0x8664, arm=0x1c0, ppc=0x1f2, mips=0x366, mipsel=0x366 })[ctx.arch]) hdr.nsects = f16(2) hdr.symtabofs = f32(ffi.offsetof(o, "sym0")) hdr.nsyms = f32(6) -- Fill in sections and symbols. o.sect[0].name = ".drectve" o.sect[0].size = f32(#symexport) o.sect[0].flags = f32(0x00100a00) o.sym0.sect = f16(1) o.sym0.scl = 3 o.sym0.name = ".drectve" o.sym0.naux = 1 o.sym0aux.size = f32(#symexport) o.sect[1].name = ".rdata" o.sect[1].size = f32(#s) o.sect[1].flags = f32(0x40300040) o.sym1.sect = f16(2) o.sym1.scl = 3 o.sym1.name = ".rdata" o.sym1.naux = 1 o.sym1aux.size = f32(#s) o.sym2.sect = f16(2) o.sym2.scl = 2 o.sym2.nameref[1] = f32(4) o.sym3.sect = f16(-1) o.sym3.scl = 2 o.sym3.value = f32(1) o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant. ffi.copy(o.space, symname) local ofs = #symname + 1 o.strtabsize = f32(ofs + 4) o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs) ffi.copy(o.space + ofs, symexport) ofs = ofs + #symexport o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs) -- Write PE object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) bcsave_tail(fp, output, s) end local function bcsave_machobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags; } mach_header; typedef struct { mach_header; uint32_t reserved; } mach_header_64; typedef struct { uint32_t cmd, cmdsize; char segname[16]; uint32_t vmaddr, vmsize, fileoff, filesize; uint32_t maxprot, initprot, nsects, flags; } mach_segment_command; typedef struct { uint32_t cmd, cmdsize; char segname[16]; uint64_t vmaddr, vmsize, fileoff, filesize; uint32_t maxprot, initprot, nsects, flags; } mach_segment_command_64; typedef struct { char sectname[16], segname[16]; uint32_t addr, size; uint32_t offset, align, reloff, nreloc, flags; uint32_t reserved1, reserved2; } mach_section; typedef struct { char sectname[16], segname[16]; uint64_t addr, size; uint32_t offset, align, reloff, nreloc, flags; uint32_t reserved1, reserved2, reserved3; } mach_section_64; typedef struct { uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize; } mach_symtab_command; typedef struct { int32_t strx; uint8_t type, sect; int16_t desc; uint32_t value; } mach_nlist; typedef struct { uint32_t strx; uint8_t type, sect; uint16_t desc; uint64_t value; } mach_nlist_64; typedef struct { uint32_t magic, nfat_arch; } mach_fat_header; typedef struct { uint32_t cputype, cpusubtype, offset, size, align; } mach_fat_arch; typedef struct { struct { mach_header hdr; mach_segment_command seg; mach_section sec; mach_symtab_command sym; } arch[1]; mach_nlist sym_entry; uint8_t space[4096]; } mach_obj; typedef struct { struct { mach_header_64 hdr; mach_segment_command_64 seg; mach_section_64 sec; mach_symtab_command sym; } arch[1]; mach_nlist_64 sym_entry; uint8_t space[4096]; } mach_obj_64; typedef struct { mach_fat_header fat; mach_fat_arch fat_arch[2]; struct { mach_header hdr; mach_segment_command seg; mach_section sec; mach_symtab_command sym; } arch[2]; mach_nlist sym_entry; uint8_t space[4096]; } mach_fat_obj; ]] local symname = '_'..LJBC_PREFIX..ctx.modname local isfat, is64, align, mobj = false, false, 4, "mach_obj" if ctx.arch == "x64" then is64, align, mobj = true, 8, "mach_obj_64" elseif ctx.arch == "arm" then isfat, mobj = true, "mach_fat_obj" elseif ctx.arch == "arm64" then is64, align, isfat, mobj = true, 8, true, "mach_fat_obj" else check(ctx.arch == "x86", "unsupported architecture for OSX") end local function aligned(v, a) return bit.band(v+a-1, -a) end local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE. -- Create Mach-O object and fill in header. local o = ffi.new(mobj) local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align) local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch] local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch] if isfat then o.fat.magic = be32(0xcafebabe) o.fat.nfat_arch = be32(#cpusubtype) end -- Fill in sections and symbols. for i=0,#cpusubtype-1 do local ofs = 0 if isfat then local a = o.fat_arch[i] a.cputype = be32(cputype[i+1]) a.cpusubtype = be32(cpusubtype[i+1]) -- Subsequent slices overlap each other to share data. ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0]) a.offset = be32(ofs) a.size = be32(mach_size-ofs+#s) end local a = o.arch[i] a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface a.hdr.cputype = cputype[i+1] a.hdr.cpusubtype = cpusubtype[i+1] a.hdr.filetype = 1 a.hdr.ncmds = 2 a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym) a.seg.cmd = is64 and 0x19 or 0x1 a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec) a.seg.vmsize = #s a.seg.fileoff = mach_size-ofs a.seg.filesize = #s a.seg.maxprot = 1 a.seg.initprot = 1 a.seg.nsects = 1 ffi.copy(a.sec.sectname, "__data") ffi.copy(a.sec.segname, "__DATA") a.sec.size = #s a.sec.offset = mach_size-ofs a.sym.cmd = 2 a.sym.cmdsize = ffi.sizeof(a.sym) a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs a.sym.nsyms = 1 a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs a.sym.strsize = aligned(#symname+2, align) end o.sym_entry.type = 0xf o.sym_entry.sect = 1 o.sym_entry.strx = 1 ffi.copy(o.space+1, symname) -- Write Macho-O object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, mach_size)) bcsave_tail(fp, output, s) end local function bcsave_obj(ctx, output, s) local ok, ffi = pcall(require, "ffi") check(ok, "FFI library required to write this file type") if ctx.os == "windows" then return bcsave_peobj(ctx, output, s, ffi) elseif ctx.os == "osx" then return bcsave_machobj(ctx, output, s, ffi) else return bcsave_elfobj(ctx, output, s, ffi) end end ------------------------------------------------------------------------------ local function bclist(input, output, lineinfo) local f = readfile(input) require("jit.bc").dump(f, savefile(output, "w"), true, lineinfo) end local function bcsave(ctx, input, output) local f = readfile(input) local s = string.dump(f, ctx.strip) local t = ctx.type if not t then t = detecttype(output) ctx.type = t end if t == "raw" then bcsave_raw(output, s) else if not ctx.modname then ctx.modname = detectmodname(input) end if t == "obj" then bcsave_obj(ctx, output, s) else bcsave_c(ctx, output, s) end end end local function docmd(...) local arg = {...} local n = 1 local list = false local lineinfo = false local ctx = { strip = true, arch = jit.arch, os = string.lower(jit.os), type = false, modname = false, } while n <= #arg do local a = arg[n] if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then table.remove(arg, n) if a == "--" then break end for m=2,#a do local opt = string.sub(a, m, m) if opt == "l" then list = true elseif opt == "L" then list = true lineinfo = true elseif opt == "s" then ctx.strip = true elseif opt == "g" then ctx.strip = false else if arg[n] == nil or m ~= #a then usage() end if opt == "e" then if n ~= 1 then usage() end arg[1] = check(loadstring(arg[1])) elseif opt == "n" then ctx.modname = checkmodname(table.remove(arg, n)) elseif opt == "t" then ctx.type = checkarg(table.remove(arg, n), map_type, "file type") elseif opt == "a" then ctx.arch = checkarg(table.remove(arg, n), map_arch, "architecture") elseif opt == "o" then ctx.os = checkarg(table.remove(arg, n), map_os, "OS name") else usage() end end end else n = n + 1 end end if list then if #arg == 0 or #arg > 2 then usage() end bclist(arg[1], arg[2] or "-", lineinfo) else if #arg ~= 2 then usage() end bcsave(ctx, arg[1], arg[2]) end end ------------------------------------------------------------------------------ -- Public module functions. return { start = docmd -- Process -b command line option. } ================================================ FILE: Luajit/jit/dis_arm.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles most user-mode ARMv7 instructions -- NYI: Advanced SIMD and VFP instructions. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Opcode maps ------------------------------------------------------------------------------ local map_loadc = { shift = 8, mask = 15, [10] = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "vmovFmDN", "vstmFNdr", _ = { shift = 21, mask = 1, [0] = "vstrFdl", { shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", } }, }, { shift = 23, mask = 3, [0] = "vmovFDNm", { shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", }, _ = { shift = 21, mask = 1, [0] = "vldrFdl", "vldmdbFNdr", }, }, }, [11] = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "vmovGmDN", "vstmGNdr", _ = { shift = 21, mask = 1, [0] = "vstrGdl", { shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", } }, }, { shift = 23, mask = 3, [0] = "vmovGDNm", { shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", }, _ = { shift = 21, mask = 1, [0] = "vldrGdl", "vldmdbGNdr", }, }, }, _ = { shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc. }, } local map_vfps = { shift = 6, mask = 0x2c001, [0] = "vmlaF.dnm", "vmlsF.dnm", [0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm", [0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm", [0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm", [0x20000] = "vdivF.dnm", [0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm", [0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm", [0x2c000] = "vmovF.dY", [0x2c001] = { shift = 7, mask = 0x1e01, [0] = "vmovF.dm", "vabsF.dm", [0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm", [0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm", [0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d", [0x0e01] = "vcvtG.dF.m", [0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm", [0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm", [0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm", }, } local map_vfpd = { shift = 6, mask = 0x2c001, [0] = "vmlaG.dnm", "vmlsG.dnm", [0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm", [0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm", [0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm", [0x20000] = "vdivG.dnm", [0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm", [0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm", [0x2c000] = "vmovG.dY", [0x2c001] = { shift = 7, mask = 0x1e01, [0] = "vmovG.dm", "vabsG.dm", [0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm", [0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm", [0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d", [0x0e01] = "vcvtF.dG.m", [0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm", [0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m", [0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m", }, } local map_datac = { shift = 24, mask = 1, [0] = { shift = 4, mask = 1, [0] = { shift = 8, mask = 15, [10] = map_vfps, [11] = map_vfpd, -- NYI cdp, mcr, mrc. }, { shift = 8, mask = 15, [10] = { shift = 20, mask = 15, [0] = "vmovFnD", "vmovFDn", [14] = "vmsrD", [15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", }, }, }, }, "svcT", } local map_loadcu = { shift = 0, mask = 0, -- NYI unconditional CP load/store. } local map_datacu = { shift = 0, mask = 0, -- NYI unconditional CP data. } local map_simddata = { shift = 0, mask = 0, -- NYI SIMD data. } local map_simdload = { shift = 0, mask = 0, -- NYI SIMD load/store, preload. } local map_preload = { shift = 0, mask = 0, -- NYI preload. } local map_media = { shift = 20, mask = 31, [0] = false, { --01 shift = 5, mask = 7, [0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM", "sadd8DNM", false, false, "ssub8DNM", }, { --02 shift = 5, mask = 7, [0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM", "qadd8DNM", false, false, "qsub8DNM", }, { --03 shift = 5, mask = 7, [0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM", "shadd8DNM", false, false, "shsub8DNM", }, false, { --05 shift = 5, mask = 7, [0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM", "uadd8DNM", false, false, "usub8DNM", }, { --06 shift = 5, mask = 7, [0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM", "uqadd8DNM", false, false, "uqsub8DNM", }, { --07 shift = 5, mask = 7, [0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM", "uhadd8DNM", false, false, "uhsub8DNM", }, { --08 shift = 5, mask = 7, [0] = "pkhbtDNMU", false, "pkhtbDNMU", { shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", }, "pkhbtDNMU", "selDNM", "pkhtbDNMU", }, false, { --0a shift = 5, mask = 7, [0] = "ssatDxMu", "ssat16DxM", "ssatDxMu", { shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", }, "ssatDxMu", false, "ssatDxMu", }, { --0b shift = 5, mask = 7, [0] = "ssatDxMu", "revDM", "ssatDxMu", { shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", }, "ssatDxMu", "rev16DM", "ssatDxMu", }, { --0c shift = 5, mask = 7, [3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", }, }, false, { --0e shift = 5, mask = 7, [0] = "usatDwMu", "usat16DwM", "usatDwMu", { shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", }, "usatDwMu", false, "usatDwMu", }, { --0f shift = 5, mask = 7, [0] = "usatDwMu", "rbitDM", "usatDwMu", { shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", }, "usatDwMu", "revshDM", "usatDwMu", }, { --10 shift = 12, mask = 15, [15] = { shift = 5, mask = 7, "smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS", }, _ = { shift = 5, mask = 7, [0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD", }, }, false, false, false, { --14 shift = 5, mask = 7, [0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS", }, { --15 shift = 5, mask = 7, [0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", }, { shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", }, false, false, false, false, "smmlsNMSD", "smmlsrNMSD", }, false, false, { --18 shift = 5, mask = 7, [0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", }, }, false, { --1a shift = 5, mask = 3, [2] = "sbfxDMvw", }, { --1b shift = 5, mask = 3, [2] = "sbfxDMvw", }, { --1c shift = 5, mask = 3, [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, }, { --1d shift = 5, mask = 3, [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, }, { --1e shift = 5, mask = 3, [2] = "ubfxDMvw", }, { --1f shift = 5, mask = 3, [2] = "ubfxDMvw", }, } local map_load = { shift = 21, mask = 9, { shift = 20, mask = 5, [0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL", }, _ = { shift = 20, mask = 5, [0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL", } } local map_load1 = { shift = 4, mask = 1, [0] = map_load, map_media, } local map_loadm = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "stmdaNR", "stmNR", { shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR", }, { shift = 23, mask = 3, [0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", }, "ldmdbNR", "ldmibNR", }, } local map_data = { shift = 21, mask = 15, [0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs", "addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs", "tstNP", "teqNP", "cmpNP", "cmnNP", "orrDNPs", "movDPs", "bicDNPs", "mvnDPs", } local map_mul = { shift = 21, mask = 7, [0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS", "umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs", } local map_sync = { shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd. [0] = "swpDMN", false, false, false, "swpbDMN", false, false, false, "strexDMN", "ldrexDN", "strexdDN", "ldrexdDN", "strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN", } local map_mulh = { shift = 21, mask = 3, [0] = { shift = 5, mask = 3, [0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", }, { shift = 5, mask = 3, [0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", }, { shift = 5, mask = 3, [0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", }, { shift = 5, mask = 3, [0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", }, } local map_misc = { shift = 4, mask = 7, -- NYI: decode PSR bits of msr. [0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", }, { shift = 21, mask = 3, "bxM", false, "clzDM", }, { shift = 21, mask = 3, "bxjM", }, { shift = 21, mask = 3, "blxM", }, false, { shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", }, false, { shift = 21, mask = 3, "bkptK", }, } local map_datar = { shift = 4, mask = 9, [9] = { shift = 5, mask = 3, [0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, }, { shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", }, { shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", }, { shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", }, }, _ = { shift = 20, mask = 25, [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, }, _ = { shift = 0, mask = 0xffffffff, [bor(0xe1a00000)] = "nop", _ = map_data, } }, } local map_datai = { shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12. [16] = "movwDW", [20] = "movtDW", [18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", }, [22] = "msrNW", _ = map_data, } local map_branch = { shift = 24, mask = 1, [0] = "bB", "blB" } local map_condins = { [0] = map_datar, map_datai, map_load, map_load1, map_loadm, map_branch, map_loadc, map_datac } -- NYI: setend. local map_uncondins = { [0] = false, map_simddata, map_simdload, map_preload, false, "blxB", map_loadcu, map_datacu, } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", } local map_cond = { [0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al", } local map_shift = { [0] = "lsl", "lsr", "asr", "ror", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then extra = "\t; 0x"..tohex(ctx.rel) end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-5s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-5s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end -- Format operand 2 of load/store opcodes. local function fmtload(ctx, op, pos) local base = map_gpr[band(rshift(op, 16), 15)] local x, ofs local ext = (band(op, 0x04000000) == 0) if not ext and band(op, 0x02000000) == 0 then ofs = band(op, 4095) if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end ofs = "#"..ofs elseif ext and band(op, 0x00400000) ~= 0 then ofs = band(op, 15) + band(rshift(op, 4), 0xf0) if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end ofs = "#"..ofs else ofs = map_gpr[band(op, 15)] if ext or band(op, 0xfe0) == 0 then elseif band(op, 0xfe0) == 0x60 then ofs = format("%s, rrx", ofs) else local sh = band(rshift(op, 7), 31) if sh == 0 then sh = 32 end ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh) end if band(op, 0x00800000) == 0 then ofs = "-"..ofs end end if ofs == "#0" then x = format("[%s]", base) elseif band(op, 0x01000000) == 0 then x = format("[%s], %s", base, ofs) else x = format("[%s, %s]", base, ofs) end if band(op, 0x01200000) == 0x01200000 then x = x.."!" end return x end -- Format operand 2 of vector load/store opcodes. local function fmtvload(ctx, op, pos) local base = map_gpr[band(rshift(op, 16), 15)] local ofs = band(op, 255)*4 if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end if ofs == 0 then return format("[%s]", base) else return format("[%s, #%d]", base, ofs) end end local function fmtvr(op, vr, sh0, sh1) if vr == "s" then return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1)) else return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16)) end end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) local operands = {} local suffix = "" local last, name, pat local vr ctx.op = op ctx.rel = nil local cond = rshift(op, 28) local opat if cond == 15 then opat = map_uncondins[band(rshift(op, 25), 7)] else if cond ~= 14 then suffix = map_cond[cond] end opat = map_condins[band(rshift(op, 25), 7)] end while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end name, pat = match(opat, "^([a-z0-9]*)(.*)") if sub(pat, 1, 1) == "." then local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") suffix = suffix..s2 pat = p2 end for p in gmatch(pat, ".") do local x = nil if p == "D" then x = map_gpr[band(rshift(op, 12), 15)] elseif p == "N" then x = map_gpr[band(rshift(op, 16), 15)] elseif p == "S" then x = map_gpr[band(rshift(op, 8), 15)] elseif p == "M" then x = map_gpr[band(op, 15)] elseif p == "d" then x = fmtvr(op, vr, 12, 22) elseif p == "n" then x = fmtvr(op, vr, 16, 7) elseif p == "m" then x = fmtvr(op, vr, 0, 5) elseif p == "P" then if band(op, 0x02000000) ~= 0 then x = ror(band(op, 255), 2*band(rshift(op, 8), 15)) else x = map_gpr[band(op, 15)] if band(op, 0xff0) ~= 0 then operands[#operands+1] = x local s = map_shift[band(rshift(op, 5), 3)] local r = nil if band(op, 0xf90) == 0 then if s == "ror" then s = "rrx" else r = "#32" end elseif band(op, 0x10) == 0 then r = "#"..band(rshift(op, 7), 31) else r = map_gpr[band(rshift(op, 8), 15)] end if name == "mov" then name = s; x = r elseif r then x = format("%s %s", s, r) else x = s end end end elseif p == "L" then x = fmtload(ctx, op, pos) elseif p == "l" then x = fmtvload(ctx, op, pos) elseif p == "B" then local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6) if cond == 15 then addr = addr + band(rshift(op, 23), 2) end ctx.rel = addr x = "0x"..tohex(addr) elseif p == "F" then vr = "s" elseif p == "G" then vr = "d" elseif p == "." then suffix = suffix..(vr == "s" and ".f32" or ".f64") elseif p == "R" then if band(op, 0x00200000) ~= 0 and #operands == 1 then operands[1] = operands[1].."!" end local t = {} for i=0,15 do if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end end x = "{"..concat(t, ", ").."}" elseif p == "r" then if band(op, 0x00200000) ~= 0 and #operands == 2 then operands[1] = operands[1].."!" end local s = tonumber(sub(last, 2)) local n = band(op, 255) if vr == "d" then n = rshift(n, 1) end operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1) elseif p == "W" then x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000) elseif p == "T" then x = "#0x"..tohex(band(op, 0x00ffffff), 6) elseif p == "U" then x = band(rshift(op, 7), 31) if x == 0 then x = nil end elseif p == "u" then x = band(rshift(op, 7), 31) if band(op, 0x40) == 0 then if x == 0 then x = nil else x = "lsl #"..x end else if x == 0 then x = "asr #32" else x = "asr #"..x end end elseif p == "v" then x = band(rshift(op, 7), 31) elseif p == "w" then x = band(rshift(op, 16), 31) elseif p == "x" then x = band(rshift(op, 16), 31) + 1 elseif p == "X" then x = band(rshift(op, 16), 31) - last + 1 elseif p == "Y" then x = band(rshift(op, 12), 0xf0) + band(op, 0x0f) elseif p == "K" then x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4) elseif p == "s" then if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end else assert(false) end if x then last = x if type(x) == "number" then x = "#"..x end operands[#operands+1] = x end end return putop(ctx, name..suffix, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ctx.pos = ofs ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 16 then return map_gpr[r] end return "d"..(r-16) end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Luajit/jit/dis_arm64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM64 disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h -- -- Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com. -- Sponsored by Cisco Systems, Inc. ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles most user-mode AArch64 instructions. -- NYI: Advanced SIMD and VFP instructions. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") local band, bor, bxor, tohex = bit.band, bit.bor, bit.bxor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift local ror = bit.ror ------------------------------------------------------------------------------ -- Opcode maps ------------------------------------------------------------------------------ local map_adr = { -- PC-relative addressing. shift = 31, mask = 1, [0] = "adrDBx", "adrpDBx" } local map_addsubi = { -- Add/subtract immediate. shift = 29, mask = 3, [0] = "add|movDNIg", "adds|cmnD0NIg", "subDNIg", "subs|cmpD0NIg", } local map_logi = { -- Logical immediate. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig" }, false -- unallocated }, { shift = 29, mask = 3, [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig" } } local map_movwi = { -- Move wide immediate. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg" }, false -- unallocated }, { shift = 29, mask = 3, [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg" }, } local map_bitf = { -- Bitfield. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12w", "bfm|bfi|bfxilDN13w", "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12w" } }, { shift = 22, mask = 1, { shift = 29, mask = 3, [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12x", "bfm|bfi|bfxilDN13x", "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12x" } } } local map_datai = { -- Data processing - immediate. shift = 23, mask = 7, [0] = map_adr, map_adr, map_addsubi, false, map_logi, map_movwi, map_bitf, { shift = 15, mask = 0x1c0c1, [0] = "extr|rorDNM4w", [0x10080] = "extr|rorDNM4x", [0x10081] = "extr|rorDNM4x" } } local map_logsr = { -- Logical, shifted register. shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 29, mask = 3, [0] = { shift = 21, mask = 7, [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg" }, { shift = 21, mask = 7, [0] ="orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg" }, { shift = 21, mask = 7, [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg" }, { shift = 21, mask = 7, [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg" } }, false -- unallocated }, { shift = 29, mask = 3, [0] = { shift = 21, mask = 7, [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg" }, { shift = 21, mask = 7, [0] = "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg" }, { shift = 21, mask = 7, [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg" }, { shift = 21, mask = 7, [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg" } } } local map_assh = { shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 29, mask = 3, [0] = { shift = 22, mask = 3, [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg" }, { shift = 22, mask = 3, [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMg" }, { shift = 22, mask = 3, [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg" }, { shift = 22, mask = 3, [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg" }, }, false -- unallocated }, { shift = 29, mask = 3, [0] = { shift = 22, mask = 3, [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg" }, { shift = 22, mask = 3, [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMg" }, { shift = 22, mask = 3, [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg" }, { shift = 22, mask = 3, [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg" } } } local map_addsubsh = { -- Add/subtract, shifted register. shift = 22, mask = 3, [0] = map_assh, map_assh, map_assh } local map_addsubex = { -- Add/subtract, extended register. shift = 22, mask = 3, [0] = { shift = 29, mask = 3, [0] = "addDNMXg", "adds|cmnD0NMXg", "subDNMXg", "subs|cmpD0NMzXg", } } local map_addsubc = { -- Add/subtract, with carry. shift = 10, mask = 63, [0] = { shift = 29, mask = 3, [0] = "adcDNMg", "adcsDNMg", "sbc|ngcDN0Mg", "sbcs|ngcsDN0Mg", } } local map_ccomp = { shift = 4, mask = 1, [0] = { shift = 10, mask = 3, [0] = { -- Conditional compare register. shift = 29, mask = 3, "ccmnNMVCg", false, "ccmpNMVCg", }, [2] = { -- Conditional compare immediate. shift = 29, mask = 3, "ccmnN5VCg", false, "ccmpN5VCg", } } } local map_csel = { -- Conditional select. shift = 11, mask = 1, [0] = { shift = 10, mask = 1, [0] = { shift = 29, mask = 3, [0] = "cselDNMzCg", false, "csinv|cinv|csetmDNMcg", false, }, { shift = 29, mask = 3, [0] = "csinc|cinc|csetDNMcg", false, "csneg|cnegDNMcg", false, } } } local map_data1s = { -- Data processing, 1 source. shift = 29, mask = 1, [0] = { shift = 31, mask = 1, [0] = { shift = 10, mask = 0x7ff, [0] = "rbitDNg", "rev16DNg", "revDNw", false, "clzDNg", "clsDNg" }, { shift = 10, mask = 0x7ff, [0] = "rbitDNg", "rev16DNg", "rev32DNx", "revDNx", "clzDNg", "clsDNg" } } } local map_data2s = { -- Data processing, 2 sources. shift = 29, mask = 1, [0] = { shift = 10, mask = 63, false, "udivDNMg", "sdivDNMg", false, false, false, false, "lslDNMg", "lsrDNMg", "asrDNMg", "rorDNMg" } } local map_data3s = { -- Data processing, 3 sources. shift = 29, mask = 7, [0] = { shift = 21, mask = 7, [0] = { shift = 15, mask = 1, [0] = "madd|mulDNMA0g", "msub|mnegDNMA0g" } }, false, false, false, { shift = 15, mask = 1, [0] = { shift = 21, mask = 7, [0] = "madd|mulDNMA0g", "smaddl|smullDxNMwA0x", "smulhDNMx", false, false, "umaddl|umullDxNMwA0x", "umulhDNMx" }, { shift = 21, mask = 7, [0] = "msub|mnegDNMA0g", "smsubl|smneglDxNMwA0x", false, false, false, "umsubl|umneglDxNMwA0x" } } } local map_datar = { -- Data processing, register. shift = 28, mask = 1, [0] = { shift = 24, mask = 1, [0] = map_logsr, { shift = 21, mask = 1, [0] = map_addsubsh, map_addsubex } }, { shift = 21, mask = 15, [0] = map_addsubc, false, map_ccomp, false, map_csel, false, { shift = 30, mask = 1, [0] = map_data2s, map_data1s }, false, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s } } local map_lrl = { -- Load register, literal. shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = "ldrDwB", "ldrDxB", "ldrswDxB" }, { shift = 30, mask = 3, [0] = "ldrDsB", "ldrDdB" } } local map_lsriind = { -- Load/store register, immediate pre/post-indexed. shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strbDwzL", "ldrbDwzL", "ldrsbDxzL", "ldrsbDwzL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strhDwzL", "ldrhDwzL", "ldrshDxzL", "ldrshDwzL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strDwzL", "ldrDwzL", "ldrswDxzL" }, { shift = 22, mask = 3, [0] = "strDszL", "ldrDszL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strDxzL", "ldrDxzL" }, { shift = 22, mask = 3, [0] = "strDdzL", "ldrDdzL" } } } local map_lsriro = { shift = 21, mask = 1, [0] = { -- Load/store register immediate. shift = 10, mask = 3, [0] = { -- Unscaled immediate. shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "sturbDwK", "ldurbDwK" }, { shift = 22, mask = 3, [0] = "sturhDwK", "ldurhDwK" }, { shift = 22, mask = 3, [0] = "sturDwK", "ldurDwK" }, { shift = 22, mask = 3, [0] = "sturDxK", "ldurDxK" } } }, map_lsriind, false, map_lsriind }, { -- Load/store register, register offset. shift = 10, mask = 3, [2] = { shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "strbDwO", "ldrbDwO", "ldrsbDxO", "ldrsbDwO" }, { shift = 22, mask = 3, [0] = "strhDwO", "ldrhDwO", "ldrshDxO", "ldrshDwO" }, { shift = 22, mask = 3, [0] = "strDwO", "ldrDwO", "ldrswDxO" }, { shift = 22, mask = 3, [0] = "strDxO", "ldrDxO" } }, { shift = 30, mask = 3, [2] = { shift = 22, mask = 3, [0] = "strDsO", "ldrDsO" }, [3] = { shift = 22, mask = 3, [0] = "strDdO", "ldrDdO" } } } } } local map_lsp = { -- Load/store register pair, offset. shift = 22, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = "stpDzAzwP", "stpDzAzsP", }, { shift = 26, mask = 1, "stpDzAzdP" }, { shift = 26, mask = 1, [0] = "stpDzAzxP" } }, { shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = "ldpDzAzwP", "ldpDzAzsP", }, { shift = 26, mask = 1, [0] = "ldpswDAxP", "ldpDzAzdP" }, { shift = 26, mask = 1, [0] = "ldpDzAzxP" } } } local map_ls = { -- Loads and stores. shift = 24, mask = 0x31, [0x10] = map_lrl, [0x30] = map_lsriro, [0x20] = { shift = 23, mask = 3, map_lsp, map_lsp, map_lsp }, [0x21] = { shift = 23, mask = 3, map_lsp, map_lsp, map_lsp }, [0x31] = { shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "strbDwzU", "ldrbDwzU" }, { shift = 22, mask = 3, [0] = "strhDwzU", "ldrhDwzU" }, { shift = 22, mask = 3, [0] = "strDwzU", "ldrDwzU" }, { shift = 22, mask = 3, [0] = "strDxzU", "ldrDxzU" } }, { shift = 30, mask = 3, [2] = { shift = 22, mask = 3, [0] = "strDszU", "ldrDszU" }, [3] = { shift = 22, mask = 3, [0] = "strDdzU", "ldrDdzU" } } }, } local map_datafp = { -- Data processing, SIMD and FP. shift = 28, mask = 7, { -- 001 shift = 24, mask = 1, [0] = { shift = 21, mask = 1, { shift = 10, mask = 3, [0] = { shift = 12, mask = 1, [0] = { shift = 13, mask = 1, [0] = { shift = 14, mask = 1, [0] = { shift = 15, mask = 1, [0] = { -- FP/int conversion. shift = 31, mask = 1, [0] = { shift = 16, mask = 0xff, [0x20] = "fcvtnsDwNs", [0x21] = "fcvtnuDwNs", [0x22] = "scvtfDsNw", [0x23] = "ucvtfDsNw", [0x24] = "fcvtasDwNs", [0x25] = "fcvtauDwNs", [0x26] = "fmovDwNs", [0x27] = "fmovDsNw", [0x28] = "fcvtpsDwNs", [0x29] = "fcvtpuDwNs", [0x30] = "fcvtmsDwNs", [0x31] = "fcvtmuDwNs", [0x38] = "fcvtzsDwNs", [0x39] = "fcvtzuDwNs", [0x60] = "fcvtnsDwNd", [0x61] = "fcvtnuDwNd", [0x62] = "scvtfDdNw", [0x63] = "ucvtfDdNw", [0x64] = "fcvtasDwNd", [0x65] = "fcvtauDwNd", [0x68] = "fcvtpsDwNd", [0x69] = "fcvtpuDwNd", [0x70] = "fcvtmsDwNd", [0x71] = "fcvtmuDwNd", [0x78] = "fcvtzsDwNd", [0x79] = "fcvtzuDwNd" }, { shift = 16, mask = 0xff, [0x20] = "fcvtnsDxNs", [0x21] = "fcvtnuDxNs", [0x22] = "scvtfDsNx", [0x23] = "ucvtfDsNx", [0x24] = "fcvtasDxNs", [0x25] = "fcvtauDxNs", [0x28] = "fcvtpsDxNs", [0x29] = "fcvtpuDxNs", [0x30] = "fcvtmsDxNs", [0x31] = "fcvtmuDxNs", [0x38] = "fcvtzsDxNs", [0x39] = "fcvtzuDxNs", [0x60] = "fcvtnsDxNd", [0x61] = "fcvtnuDxNd", [0x62] = "scvtfDdNx", [0x63] = "ucvtfDdNx", [0x64] = "fcvtasDxNd", [0x65] = "fcvtauDxNd", [0x66] = "fmovDxNd", [0x67] = "fmovDdNx", [0x68] = "fcvtpsDxNd", [0x69] = "fcvtpuDxNd", [0x70] = "fcvtmsDxNd", [0x71] = "fcvtmuDxNd", [0x78] = "fcvtzsDxNd", [0x79] = "fcvtzuDxNd" } } }, { -- FP data-processing, 1 source. shift = 31, mask = 1, [0] = { shift = 22, mask = 3, [0] = { shift = 15, mask = 63, [0] = "fmovDNf", "fabsDNf", "fnegDNf", "fsqrtDNf", false, "fcvtDdNs", false, false, "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf", "frintaDNf", false, "frintxDNf", "frintiDNf", }, { shift = 15, mask = 63, [0] = "fmovDNf", "fabsDNf", "fnegDNf", "fsqrtDNf", "fcvtDsNd", false, false, false, "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf", "frintaDNf", false, "frintxDNf", "frintiDNf", } } } }, { -- FP compare. shift = 31, mask = 1, [0] = { shift = 14, mask = 3, [0] = { shift = 23, mask = 1, [0] = { shift = 0, mask = 31, [0] = "fcmpNMf", [8] = "fcmpNZf", [16] = "fcmpeNMf", [24] = "fcmpeNZf", } } } } }, { -- FP immediate. shift = 31, mask = 1, [0] = { shift = 5, mask = 31, [0] = { shift = 23, mask = 1, [0] = "fmovDFf" } } } }, { -- FP conditional compare. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = { shift = 4, mask = 1, [0] = "fccmpNMVCf", "fccmpeNMVCf" } } }, { -- FP data-processing, 2 sources. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = { shift = 12, mask = 15, [0] = "fmulDNMf", "fdivDNMf", "faddDNMf", "fsubDNMf", "fmaxDNMf", "fminDNMf", "fmaxnmDNMf", "fminnmDNMf", "fnmulDNMf" } } }, { -- FP conditional select. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = "fcselDNMCf" } } } }, { -- FP data-processing, 3 sources. shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 21, mask = 5, [0] = "fmaddDNMAf", "fnmaddDNMAf" }, { shift = 21, mask = 5, [0] = "fmsubDNMAf", "fnmsubDNMAf" } } } } } local map_br = { -- Branches, exception generating and system instructions. shift = 29, mask = 7, [0] = "bB", { -- Compare & branch, immediate. shift = 24, mask = 3, [0] = "cbzDBg", "cbnzDBg", "tbzDTBw", "tbnzDTBw" }, { -- Conditional branch, immediate. shift = 24, mask = 3, [0] = { shift = 4, mask = 1, [0] = { shift = 0, mask = 15, [0] = "beqB", "bneB", "bhsB", "bloB", "bmiB", "bplB", "bvsB", "bvcB", "bhiB", "blsB", "bgeB", "bltB", "bgtB", "bleB", "balB" } } }, false, "blB", { -- Compare & branch, immediate. shift = 24, mask = 3, [0] = "cbzDBg", "cbnzDBg", "tbzDTBx", "tbnzDTBx" }, { shift = 24, mask = 3, [0] = { -- Exception generation. shift = 0, mask = 0xe0001f, [0x200000] = "brkW" }, { -- System instructions. shift = 0, mask = 0x3fffff, [0x03201f] = "nop" }, { -- Unconditional branch, register. shift = 0, mask = 0xfffc1f, [0x1f0000] = "brNx", [0x3f0000] = "blrNx", [0x5f0000] = "retNx" }, } } local map_init = { shift = 25, mask = 15, [0] = false, false, false, false, map_ls, map_datar, map_ls, map_datafp, map_datai, map_datai, map_br, map_br, map_ls, map_datar, map_ls, map_datafp } ------------------------------------------------------------------------------ local map_regs = { x = {}, w = {}, d = {}, s = {} } for i=0,30 do map_regs.x[i] = "x"..i map_regs.w[i] = "w"..i map_regs.d[i] = "d"..i map_regs.s[i] = "s"..i end map_regs.x[31] = "sp" map_regs.w[31] = "wsp" map_regs.d[31] = "d31" map_regs.s[31] = "s31" local map_cond = { [0] = "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al", } local map_shift = { [0] = "lsl", "lsr", "asr", } local map_extend = { [0] = "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-5s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-5s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end local function match_reg(p, pat, regnum) return map_regs[match(pat, p.."%w-([xwds])")][regnum] end local function fmt_hex32(x) if x < 0 then return tohex(x) else return format("%x", x) end end local imm13_rep = { 0x55555555, 0x11111111, 0x01010101, 0x00010001, 0x00000001 } local function decode_imm13(op) local imms = band(rshift(op, 10), 63) local immr = band(rshift(op, 16), 63) if band(op, 0x00400000) == 0 then local len = 5 if imms >= 56 then if imms >= 60 then len = 1 else len = 2 end elseif imms >= 48 then len = 3 elseif imms >= 32 then len = 4 end local l = lshift(1, len)-1 local s = band(imms, l) local r = band(immr, l) local imm = ror(rshift(-1, 31-s), r) if len ~= 5 then imm = band(imm, lshift(1, l)-1) + rshift(imm, 31-l) end imm = imm * imm13_rep[len] local ix = fmt_hex32(imm) if rshift(op, 31) ~= 0 then return ix..tohex(imm) else return ix end else local lo, hi = -1, 0 if imms < 32 then lo = rshift(-1, 31-imms) else hi = rshift(-1, 63-imms) end if immr ~= 0 then lo, hi = ror(lo, immr), ror(hi, immr) local x = immr == 32 and 0 or band(bxor(lo, hi), lshift(-1, 32-immr)) lo, hi = bxor(lo, x), bxor(hi, x) if immr >= 32 then lo, hi = hi, lo end end if hi ~= 0 then return fmt_hex32(hi)..tohex(lo) else return fmt_hex32(lo) end end end local function parse_immpc(op, name) if name == "b" or name == "bl" then return arshift(lshift(op, 6), 4) elseif name == "adr" or name == "adrp" then local immlo = band(rshift(op, 29), 3) local immhi = lshift(arshift(lshift(op, 8), 13), 2) return bor(immhi, immlo) elseif name == "tbz" or name == "tbnz" then return lshift(arshift(lshift(op, 13), 18), 2) else return lshift(arshift(lshift(op, 8), 13), 2) end end local function parse_fpimm8(op) local sign = band(op, 0x100000) == 0 and 1 or -1 local exp = bxor(rshift(arshift(lshift(op, 12), 5), 24), 0x80) - 131 local frac = 16+band(rshift(op, 13), 15) return sign * frac * 2^exp end local function prefer_bfx(sf, uns, imms, immr) if imms < immr or imms == 31 or imms == 63 then return false end if immr == 0 then if sf == 0 and (imms == 7 or imms == 15) then return false end if sf ~= 0 and uns == 0 and (imms == 7 or imms == 15 or imms == 31) then return false end end return true end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) local operands = {} local suffix = "" local last, name, pat local map_reg ctx.op = op ctx.rel = nil last = nil local opat opat = map_init[band(rshift(op, 25), 15)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end name, pat = match(opat, "^([a-z0-9]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") if altname then pat = pat2 end if sub(pat, 1, 1) == "." then local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") suffix = suffix..s2 pat = p2 end local rt = match(pat, "[gf]") if rt then if rt == "g" then map_reg = band(op, 0x80000000) ~= 0 and map_regs.x or map_regs.w else map_reg = band(op, 0x400000) ~= 0 and map_regs.d or map_regs.s end end local second0, immr for p in gmatch(pat, ".") do local x = nil if p == "D" then local regnum = band(op, 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "N" then local regnum = band(rshift(op, 5), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "M" then local regnum = band(rshift(op, 16), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "A" then local regnum = band(rshift(op, 10), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "B" then local addr = ctx.addr + pos + parse_immpc(op, name) ctx.rel = addr x = "0x"..tohex(addr) elseif p == "T" then x = bor(band(rshift(op, 26), 32), band(rshift(op, 19), 31)) elseif p == "V" then x = band(op, 15) elseif p == "C" then x = map_cond[band(rshift(op, 12), 15)] elseif p == "c" then local rn = band(rshift(op, 5), 31) local rm = band(rshift(op, 16), 31) local cond = band(rshift(op, 12), 15) local invc = bxor(cond, 1) x = map_cond[cond] if altname and cond ~= 14 and cond ~= 15 then local a1, a2 = match(altname, "([^|]*)|(.*)") if rn == rm then local n = #operands operands[n] = nil x = map_cond[invc] if rn ~= 31 then if a1 then name = a1 else name = altname end else operands[n-1] = nil name = a2 end end end elseif p == "W" then x = band(rshift(op, 5), 0xffff) elseif p == "Y" then x = band(rshift(op, 5), 0xffff) local hw = band(rshift(op, 21), 3) if altname and (hw == 0 or x ~= 0) then name = altname end elseif p == "L" then local rn = map_regs.x[band(rshift(op, 5), 31)] local imm9 = arshift(lshift(op, 11), 23) if band(op, 0x800) ~= 0 then x = "["..rn..", #"..imm9.."]!" else x = "["..rn.."], #"..imm9 end elseif p == "U" then local rn = map_regs.x[band(rshift(op, 5), 31)] local sz = band(rshift(op, 30), 3) local imm12 = lshift(arshift(lshift(op, 10), 20), sz) if imm12 ~= 0 then x = "["..rn..", #"..imm12.."]" else x = "["..rn.."]" end elseif p == "K" then local rn = map_regs.x[band(rshift(op, 5), 31)] local imm9 = arshift(lshift(op, 11), 23) if imm9 ~= 0 then x = "["..rn..", #"..imm9.."]" else x = "["..rn.."]" end elseif p == "O" then local rn, rm = map_regs.x[band(rshift(op, 5), 31)] local m = band(rshift(op, 13), 1) if m == 0 then rm = map_regs.w[band(rshift(op, 16), 31)] else rm = map_regs.x[band(rshift(op, 16), 31)] end x = "["..rn..", "..rm local opt = band(rshift(op, 13), 7) local s = band(rshift(op, 12), 1) local sz = band(rshift(op, 30), 3) -- extension to be applied if opt == 3 then if s == 0 then x = x.."]" else x = x..", lsl #"..sz.."]" end elseif opt == 2 or opt == 6 or opt == 7 then if s == 0 then x = x..", "..map_extend[opt].."]" else x = x..", "..map_extend[opt].." #"..sz.."]" end else x = x.."]" end elseif p == "P" then local opcv, sh = rshift(op, 26), 2 if opcv >= 0x2a then sh = 4 elseif opcv >= 0x1b then sh = 3 end local imm7 = lshift(arshift(lshift(op, 10), 25), sh) local rn = map_regs.x[band(rshift(op, 5), 31)] local ind = band(rshift(op, 23), 3) if ind == 1 then x = "["..rn.."], #"..imm7 elseif ind == 2 then if imm7 == 0 then x = "["..rn.."]" else x = "["..rn..", #"..imm7.."]" end elseif ind == 3 then x = "["..rn..", #"..imm7.."]!" end elseif p == "I" then local shf = band(rshift(op, 22), 3) local imm12 = band(rshift(op, 10), 0x0fff) local rn, rd = band(rshift(op, 5), 31), band(op, 31) if altname == "mov" and shf == 0 and imm12 == 0 and (rn == 31 or rd == 31) then name = altname x = nil elseif shf == 0 then x = imm12 elseif shf == 1 then x = imm12..", lsl #12" end elseif p == "i" then x = "#0x"..decode_imm13(op) elseif p == "1" then immr = band(rshift(op, 16), 63) x = immr elseif p == "2" then x = band(rshift(op, 10), 63) if altname then local a1, a2, a3, a4, a5, a6 = match(altname, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|(.*)") local sf = band(rshift(op, 26), 32) local uns = band(rshift(op, 30), 1) if prefer_bfx(sf, uns, x, immr) then name = a2 x = x - immr + 1 elseif immr == 0 and x == 7 then local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] name = a6 x = nil elseif immr == 0 and x == 15 then local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] name = a5 x = nil elseif x == 31 or x == 63 then if x == 31 and immr == 0 and name == "sbfm" then name = a4 local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] else name = a3 end x = nil elseif band(x, 31) ~= 31 and immr == x+1 and name == "ubfm" then name = a4 last = "#"..(sf+32 - immr) operands[#operands] = last x = nil elseif x < immr then name = a1 last = "#"..(sf+32 - immr) operands[#operands] = last x = x + 1 end end elseif p == "3" then x = band(rshift(op, 10), 63) if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if x < immr then name = a1 local sf = band(rshift(op, 26), 32) last = "#"..(sf+32 - immr) operands[#operands] = last x = x + 1 elseif x >= immr then name = a2 x = x - immr + 1 end end elseif p == "4" then x = band(rshift(op, 10), 63) local rn = band(rshift(op, 5), 31) local rm = band(rshift(op, 16), 31) if altname and rn == rm then local n = #operands operands[n] = nil last = operands[n-1] name = altname end elseif p == "5" then x = band(rshift(op, 16), 31) elseif p == "S" then x = band(rshift(op, 10), 63) if x == 0 then x = nil else x = map_shift[band(rshift(op, 22), 3)].." #"..x end elseif p == "X" then local opt = band(rshift(op, 13), 7) -- Width specifier . if opt ~= 3 and opt ~= 7 then last = map_regs.w[band(rshift(op, 16), 31)] operands[#operands] = last end x = band(rshift(op, 10), 7) -- Extension. if opt == 2 + band(rshift(op, 31), 1) and band(rshift(op, second0 and 5 or 0), 31) == 31 then if x == 0 then x = nil else x = "lsl #"..x end else if x == 0 then x = map_extend[band(rshift(op, 13), 7)] else x = map_extend[band(rshift(op, 13), 7)].." #"..x end end elseif p == "R" then x = band(rshift(op,21), 3) if x == 0 then x = nil else x = "lsl #"..x*16 end elseif p == "z" then local n = #operands if operands[n] == "sp" then operands[n] = "xzr" elseif operands[n] == "wsp" then operands[n] = "wzr" end elseif p == "Z" then x = 0 elseif p == "F" then x = parse_fpimm8(op) elseif p == "g" or p == "f" or p == "x" or p == "w" or p == "d" or p == "s" then -- These are handled in D/N/M/A. elseif p == "0" then if last == "sp" or last == "wsp" then local n = #operands operands[n] = nil last = operands[n-1] if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if not a1 then name = altname elseif second0 then name, altname = a2, a1 else name, altname = a1, a2 end end end second0 = true else assert(false) end if x then last = x if type(x) == "number" then x = "#"..x end operands[#operands+1] = x end end return putop(ctx, name..suffix, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ctx.pos = ofs ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_regs.x[r] end return map_regs.d[r-32] end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Luajit/jit/dis_arm64be.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM64BE disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- ARM64 instructions are always little-endian. So just forward to the -- common ARM64 disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ return require((string.match(..., ".*%.") or "").."dis_arm64") ================================================ FILE: Luajit/jit/dis_mips.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles all standard MIPS32R1/R2 instructions. -- Default mode is big-endian, but see: dis_mipsel.lua ------------------------------------------------------------------------------ local type = type local byte, format = string.byte, string.format local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Primary and extended opcode maps ------------------------------------------------------------------------------ local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", } local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", } local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", } local map_special = { shift = 0, mask = 63, [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" }, map_movci, map_srl, "sraDTA", "sllvDTS", false, map_srlv, "sravDTS", "jrS", "jalrD1S", "movzDST", "movnDST", "syscallY", "breakY", false, "sync", "mfhiD", "mthiS", "mfloD", "mtloS", "dsllvDST", false, "dsrlvDST", "dsravDST", "multST", "multuST", "divST", "divuST", "dmultST", "dmultuST", "ddivST", "ddivuST", "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", "andDST", "or|moveDST0", "xorDST", "nor|notDST0", false, false, "sltDST", "sltuDST", "daddDST", "dadduDST", "dsubDST", "dsubuDST", "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", "teqSTZ", false, "tneSTZ", false, "dsllDTA", false, "dsrlDTA", "dsraDTA", "dsll32DTA", false, "dsrl32DTA", "dsra32DTA", } local map_special2 = { shift = 0, mask = 63, [0] = "maddST", "madduST", "mulDST", false, "msubST", "msubuST", [32] = "clzDS", [33] = "cloDS", [63] = "sdbbpY", } local map_bshfl = { shift = 6, mask = 31, [2] = "wsbhDT", [16] = "sebDT", [24] = "sehDT", } local map_dbshfl = { shift = 6, mask = 31, [2] = "dsbhDT", [5] = "dshdDT", } local map_special3 = { shift = 0, mask = 63, [0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK", [4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL", [32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD", } local map_regimm = { shift = 16, mask = 31, [0] = "bltzSB", "bgezSB", "bltzlSB", "bgezlSB", false, false, false, false, "tgeiSI", "tgeiuSI", "tltiSI", "tltiuSI", "teqiSI", false, "tneiSI", false, "bltzalSB", "bgezalSB", "bltzallSB", "bgezallSB", false, false, false, false, false, false, false, false, false, false, false, "synciSO", } local map_cop0 = { shift = 25, mask = 1, [0] = { shift = 21, mask = 15, [0] = "mfc0TDW", [4] = "mtc0TDW", [10] = "rdpgprDT", [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", }, [14] = "wrpgprDT", }, { shift = 0, mask = 63, [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp", [24] = "eret", [31] = "deret", [32] = "wait", }, } local map_cop1s = { shift = 0, mask = 63, [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH", "sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG", "round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG", "round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG", false, { shift = 16, mask = 1, [0] = "movf.sFGC", "movt.sFGC" }, "movz.sFGT", "movn.sFGT", false, "recip.sFG", "rsqrt.sFG", false, false, false, false, false, false, false, false, false, false, "cvt.d.sFG", false, false, "cvt.w.sFG", "cvt.l.sFG", "cvt.ps.sFGH", false, false, false, false, false, false, false, false, false, "c.f.sVGH", "c.un.sVGH", "c.eq.sVGH", "c.ueq.sVGH", "c.olt.sVGH", "c.ult.sVGH", "c.ole.sVGH", "c.ule.sVGH", "c.sf.sVGH", "c.ngle.sVGH", "c.seq.sVGH", "c.ngl.sVGH", "c.lt.sVGH", "c.nge.sVGH", "c.le.sVGH", "c.ngt.sVGH", } local map_cop1d = { shift = 0, mask = 63, [0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH", "sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG", "round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG", "round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG", false, { shift = 16, mask = 1, [0] = "movf.dFGC", "movt.dFGC" }, "movz.dFGT", "movn.dFGT", false, "recip.dFG", "rsqrt.dFG", false, false, false, false, false, false, false, false, false, "cvt.s.dFG", false, false, false, "cvt.w.dFG", "cvt.l.dFG", false, false, false, false, false, false, false, false, false, false, "c.f.dVGH", "c.un.dVGH", "c.eq.dVGH", "c.ueq.dVGH", "c.olt.dVGH", "c.ult.dVGH", "c.ole.dVGH", "c.ule.dVGH", "c.df.dVGH", "c.ngle.dVGH", "c.deq.dVGH", "c.ngl.dVGH", "c.lt.dVGH", "c.nge.dVGH", "c.le.dVGH", "c.ngt.dVGH", } local map_cop1ps = { shift = 0, mask = 63, [0] = "add.psFGH", "sub.psFGH", "mul.psFGH", false, false, "abs.psFG", "mov.psFG", "neg.psFG", false, false, false, false, false, false, false, false, false, { shift = 16, mask = 1, [0] = "movf.psFGC", "movt.psFGC" }, "movz.psFGT", "movn.psFGT", false, false, false, false, false, false, false, false, false, false, false, false, "cvt.s.puFG", false, false, false, false, false, false, false, "cvt.s.plFG", false, false, false, "pll.psFGH", "plu.psFGH", "pul.psFGH", "puu.psFGH", "c.f.psVGH", "c.un.psVGH", "c.eq.psVGH", "c.ueq.psVGH", "c.olt.psVGH", "c.ult.psVGH", "c.ole.psVGH", "c.ule.psVGH", "c.psf.psVGH", "c.ngle.psVGH", "c.pseq.psVGH", "c.ngl.psVGH", "c.lt.psVGH", "c.nge.psVGH", "c.le.psVGH", "c.ngt.psVGH", } local map_cop1w = { shift = 0, mask = 63, [32] = "cvt.s.wFG", [33] = "cvt.d.wFG", } local map_cop1l = { shift = 0, mask = 63, [32] = "cvt.s.lFG", [33] = "cvt.d.lFG", } local map_cop1bc = { shift = 16, mask = 3, [0] = "bc1fCB", "bc1tCB", "bc1flCB", "bc1tlCB", } local map_cop1 = { shift = 21, mask = 31, [0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG", "mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG", map_cop1bc, false, false, false, false, false, false, false, map_cop1s, map_cop1d, false, false, map_cop1w, map_cop1l, map_cop1ps, } local map_cop1x = { shift = 0, mask = 63, [0] = "lwxc1FSX", "ldxc1FSX", false, false, false, "luxc1FSX", false, false, "swxc1FSX", "sdxc1FSX", false, false, false, "suxc1FSX", false, "prefxMSX", false, false, false, false, false, false, false, false, false, false, false, false, false, false, "alnv.psFGHS", false, "madd.sFRGH", "madd.dFRGH", false, false, false, false, "madd.psFRGH", false, "msub.sFRGH", "msub.dFRGH", false, false, false, false, "msub.psFRGH", false, "nmadd.sFRGH", "nmadd.dFRGH", false, false, false, false, "nmadd.psFRGH", false, "nmsub.sFRGH", "nmsub.dFRGH", false, false, false, false, "nmsub.psFRGH", false, } local map_pri = { [0] = map_special, map_regimm, "jJ", "jalJ", "beq|beqz|bST00B", "bne|bnezST0B", "blezSB", "bgtzSB", "addiTSI", "addiu|liTS0I", "sltiTSI", "sltiuTSI", "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU", map_cop0, map_cop1, false, map_cop1x, "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB", "daddiTSI", "daddiuTSI", false, false, map_special2, "jalxJ", false, map_special3, "lbTSO", "lhTSO", "lwlTSO", "lwTSO", "lbuTSO", "lhuTSO", "lwrTSO", false, "sbTSO", "shTSO", "swlTSO", "swTSO", false, false, "swrTSO", "cacheNSO", "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO", false, "ldc1HSO", "ldc2TSO", "ldTSO", "scTSO", "swc1HSO", "swc2TSO", false, false, "sdc1HSO", "sdc2TSO", "sdTSO", } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "sp", "r30", "ra", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-7s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-7s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end local function get_be(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) return bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) end local function get_le(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) end -- Disassemble a single instruction. local function disass_ins(ctx) local op = ctx:get() local operands = {} local last = nil ctx.op = op ctx.rel = nil local opat = map_pri[rshift(op, 26)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") if altname then pat = pat2 end for p in gmatch(pat, ".") do local x = nil if p == "S" then x = map_gpr[band(rshift(op, 21), 31)] elseif p == "T" then x = map_gpr[band(rshift(op, 16), 31)] elseif p == "D" then x = map_gpr[band(rshift(op, 11), 31)] elseif p == "F" then x = "f"..band(rshift(op, 6), 31) elseif p == "G" then x = "f"..band(rshift(op, 11), 31) elseif p == "H" then x = "f"..band(rshift(op, 16), 31) elseif p == "R" then x = "f"..band(rshift(op, 21), 31) elseif p == "A" then x = band(rshift(op, 6), 31) elseif p == "E" then x = band(rshift(op, 6), 31) + 32 elseif p == "M" then x = band(rshift(op, 11), 31) elseif p == "N" then x = band(rshift(op, 16), 31) elseif p == "C" then x = band(rshift(op, 18), 7) if x == 0 then x = nil end elseif p == "K" then x = band(rshift(op, 11), 31) + 1 elseif p == "P" then x = band(rshift(op, 11), 31) + 33 elseif p == "L" then x = band(rshift(op, 11), 31) - last + 1 elseif p == "Q" then x = band(rshift(op, 11), 31) - last + 33 elseif p == "I" then x = arshift(lshift(op, 16), 16) elseif p == "U" then x = band(op, 0xffff) elseif p == "O" then local disp = arshift(lshift(op, 16), 16) operands[#operands] = format("%d(%s)", disp, last) elseif p == "X" then local index = map_gpr[band(rshift(op, 16), 31)] operands[#operands] = format("%s(%s)", index, last) elseif p == "B" then x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4 ctx.rel = x x = format("0x%08x", x) elseif p == "J" then local a = ctx.addr + ctx.pos x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4 ctx.rel = x x = format("0x%08x", x) elseif p == "V" then x = band(rshift(op, 8), 7) if x == 0 then x = nil end elseif p == "W" then x = band(op, 7) if x == 0 then x = nil end elseif p == "Y" then x = band(rshift(op, 6), 0x000fffff) if x == 0 then x = nil end elseif p == "Z" then x = band(rshift(op, 6), 1023) if x == 0 then x = nil end elseif p == "0" then if last == "r0" or last == 0 then local n = #operands operands[n] = nil last = operands[n-1] if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if a1 then name, altname = a1, a2 else name = altname end end end elseif p == "1" then if last == "ra" then operands[#operands] = nil end else assert(false) end if x then operands[#operands+1] = x; last = x end end return putop(ctx, name, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code stop = stop - stop % 4 ctx.pos = ofs - ofs % 4 ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 ctx.get = get_be return ctx end local function create_el(code, addr, out) local ctx = create(code, addr, out) ctx.get = get_le return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end local function disass_el(code, addr, out) create_el(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_gpr[r] end return "f"..(r-32) end -- Public module functions. return { create = create, create_el = create_el, disass = disass, disass_el = disass_el, regname = regname } ================================================ FILE: Luajit/jit/dis_mips64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS64 disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the big-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create, disass = dis_mips.disass, regname = dis_mips.regname } ================================================ FILE: Luajit/jit/dis_mips64el.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS64EL disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the little-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create_el, disass = dis_mips.disass_el, regname = dis_mips.regname } ================================================ FILE: Luajit/jit/dis_mipsel.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPSEL disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the little-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create_el, disass = dis_mips.disass_el, regname = dis_mips.regname } ================================================ FILE: Luajit/jit/dis_ppc.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT PPC disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles all common, non-privileged 32/64 bit PowerPC instructions -- plus the e500 SPE instructions and some Cell/Xenon extensions. -- -- NYI: VMX, VMX128 ------------------------------------------------------------------------------ local type = type local byte, format = string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Primary and extended opcode maps ------------------------------------------------------------------------------ local map_crops = { shift = 1, mask = 1023, [0] = "mcrfXX", [33] = "crnor|crnotCCC=", [129] = "crandcCCC", [193] = "crxor|crclrCCC%", [225] = "crnandCCC", [257] = "crandCCC", [289] = "creqv|crsetCCC%", [417] = "crorcCCC", [449] = "cror|crmoveCCC=", [16] = "b_lrKB", [528] = "b_ctrKB", [150] = "isync", } local map_rlwinm = setmetatable({ shift = 0, mask = -1, }, { __index = function(t, x) local rot = band(rshift(x, 11), 31) local mb = band(rshift(x, 6), 31) local me = band(rshift(x, 1), 31) if mb == 0 and me == 31-rot then return "slwiRR~A." elseif me == 31 and mb == 32-rot then return "srwiRR~-A." else return "rlwinmRR~AAA." end end }) local map_rld = { shift = 2, mask = 7, [0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.", { shift = 1, mask = 1, [0] = "rldclRR~RM.", "rldcrRR~RM.", }, } local map_ext = setmetatable({ shift = 1, mask = 1023, [0] = "cmp_YLRR", [32] = "cmpl_YLRR", [4] = "twARR", [68] = "tdARR", [8] = "subfcRRR.", [40] = "subfRRR.", [104] = "negRR.", [136] = "subfeRRR.", [200] = "subfzeRR.", [232] = "subfmeRR.", [520] = "subfcoRRR.", [552] = "subfoRRR.", [616] = "negoRR.", [648] = "subfeoRRR.", [712] = "subfzeoRR.", [744] = "subfmeoRR.", [9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.", [457] = "divduRRR.", [489] = "divdRRR.", [745] = "mulldoRRR.", [969] = "divduoRRR.", [1001] = "divdoRRR.", [10] = "addcRRR.", [138] = "addeRRR.", [202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.", [522] = "addcoRRR.", [650] = "addeoRRR.", [714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.", [11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.", [459] = "divwuRRR.", [491] = "divwRRR.", [747] = "mullwoRRR.", [971] = "divwouRRR.", [1003] = "divwoRRR.", [15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR", [144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", }, [19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", }, [371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", }, [339] = { shift = 11, mask = 1023, [32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR", }, [467] = { shift = 11, mask = 1023, [32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR", }, [20] = "lwarxRR0R", [84] = "ldarxRR0R", [21] = "ldxRR0R", [53] = "lduxRRR", [149] = "stdxRR0R", [181] = "stduxRRR", [341] = "lwaxRR0R", [373] = "lwauxRRR", [23] = "lwzxRR0R", [55] = "lwzuxRRR", [87] = "lbzxRR0R", [119] = "lbzuxRRR", [151] = "stwxRR0R", [183] = "stwuxRRR", [215] = "stbxRR0R", [247] = "stbuxRRR", [279] = "lhzxRR0R", [311] = "lhzuxRRR", [343] = "lhaxRR0R", [375] = "lhauxRRR", [407] = "sthxRR0R", [439] = "sthuxRRR", [54] = "dcbst-R0R", [86] = "dcbf-R0R", [150] = "stwcxRR0R.", [214] = "stdcxRR0R.", [246] = "dcbtst-R0R", [278] = "dcbt-R0R", [310] = "eciwxRR0R", [438] = "ecowxRR0R", [470] = "dcbi-RR", [598] = { shift = 21, mask = 3, [0] = "sync", "lwsync", "ptesync", }, [758] = "dcba-RR", [854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R", [26] = "cntlzwRR~", [58] = "cntlzdRR~", [122] = "popcntbRR~", [154] = "prtywRR~", [186] = "prtydRR~", [28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.", [284] = "eqvRR~R.", [316] = "xorRR~R.", [412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.", [508] = "cmpbRR~R", [512] = "mcrxrX", [532] = "ldbrxRR0R", [660] = "stdbrxRR0R", [533] = "lswxRR0R", [597] = "lswiRR0A", [661] = "stswxRR0R", [725] = "stswiRR0A", [534] = "lwbrxRR0R", [662] = "stwbrxRR0R", [790] = "lhbrxRR0R", [918] = "sthbrxRR0R", [535] = "lfsxFR0R", [567] = "lfsuxFRR", [599] = "lfdxFR0R", [631] = "lfduxFRR", [663] = "stfsxFR0R", [695] = "stfsuxFRR", [727] = "stfdxFR0R", [759] = "stfduxFR0R", [855] = "lfiwaxFR0R", [983] = "stfiwxFR0R", [24] = "slwRR~R.", [27] = "sldRR~R.", [536] = "srwRR~R.", [792] = "srawRR~R.", [824] = "srawiRR~A.", [794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.", [922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.", [539] = "srdRR~R.", }, { __index = function(t, x) if band(x, 31) == 15 then return "iselRRRC" end end }) local map_ld = { shift = 0, mask = 3, [0] = "ldRRE", "lduRRE", "lwaRRE", } local map_std = { shift = 0, mask = 3, [0] = "stdRRE", "stduRRE", } local map_fps = { shift = 5, mask = 1, { shift = 1, mask = 15, [0] = false, false, "fdivsFFF.", false, "fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false, "fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false, "fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.", } } local map_fpd = { shift = 5, mask = 1, [0] = { shift = 1, mask = 1023, [0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX", [38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>", [8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.", [136] = "fnabsF-F.", [264] = "fabsF-F.", [12] = "frspF-F.", [14] = "fctiwF-F.", [15] = "fctiwzF-F.", [583] = "mffsF.", [711] = "mtfsfZF.", [392] = "frinF-F.", [424] = "frizF-F.", [456] = "fripF-F.", [488] = "frimF-F.", [814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.", }, { shift = 1, mask = 15, [0] = false, false, "fdivFFF.", false, "fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.", "freF-F.", "fmulFF-F.", "frsqrteF-F.", false, "fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.", } } local map_spe = { shift = 0, mask = 2047, [512] = "evaddwRRR", [514] = "evaddiwRAR~", [516] = "evsubwRRR~", [518] = "evsubiwRAR~", [520] = "evabsRR", [521] = "evnegRR", [522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR", [525] = "evcntlzwRR", [526] = "evcntlswRR", [527] = "brincRRR", [529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR", [535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=", [537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR", [544] = "evsrwuRRR", [545] = "evsrwsRRR", [546] = "evsrwiuRRA", [547] = "evsrwisRRA", [548] = "evslwRRR", [550] = "evslwiRRA", [552] = "evrlwRRR", [553] = "evsplatiRS", [554] = "evrlwiRRA", [555] = "evsplatfiRS", [556] = "evmergehiRRR", [557] = "evmergeloRRR", [558] = "evmergehiloRRR", [559] = "evmergelohiRRR", [560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR", [562] = "evcmpltuYRR", [563] = "evcmpltsYRR", [564] = "evcmpeqYRR", [632] = "evselRRR", [633] = "evselRRRW", [634] = "evselRRRW", [635] = "evselRRRW", [636] = "evselRRRW", [637] = "evselRRRW", [638] = "evselRRRW", [639] = "evselRRRW", [640] = "evfsaddRRR", [641] = "evfssubRRR", [644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR", [648] = "evfsmulRRR", [649] = "evfsdivRRR", [652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR", [656] = "evfscfuiR-R", [657] = "evfscfsiR-R", [658] = "evfscfufR-R", [659] = "evfscfsfR-R", [660] = "evfsctuiR-R", [661] = "evfsctsiR-R", [662] = "evfsctufR-R", [663] = "evfsctsfR-R", [664] = "evfsctuizR-R", [666] = "evfsctsizR-R", [668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR", [704] = "efsaddRRR", [705] = "efssubRRR", [708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR", [712] = "efsmulRRR", [713] = "efsdivRRR", [716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR", [719] = "efscfdR-R", [720] = "efscfuiR-R", [721] = "efscfsiR-R", [722] = "efscfufR-R", [723] = "efscfsfR-R", [724] = "efsctuiR-R", [725] = "efsctsiR-R", [726] = "efsctufR-R", [727] = "efsctsfR-R", [728] = "efsctuizR-R", [730] = "efsctsizR-R", [732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR", [736] = "efdaddRRR", [737] = "efdsubRRR", [738] = "efdcfuidR-R", [739] = "efdcfsidR-R", [740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR", [744] = "efdmulRRR", [745] = "efddivRRR", [746] = "efdctuidzR-R", [747] = "efdctsidzR-R", [748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR", [751] = "efdcfsR-R", [752] = "efdcfuiR-R", [753] = "efdcfsiR-R", [754] = "efdcfufR-R", [755] = "efdcfsfR-R", [756] = "efdctuiR-R", [757] = "efdctsiR-R", [758] = "efdctufR-R", [759] = "efdctsfR-R", [760] = "efdctuizR-R", [762] = "efdctsizR-R", [764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR", [768] = "evlddxRR0R", [769] = "evlddRR8", [770] = "evldwxRR0R", [771] = "evldwRR8", [772] = "evldhxRR0R", [773] = "evldhRR8", [776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2", [780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2", [782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2", [784] = "evlwhexRR0R", [785] = "evlwheRR4", [788] = "evlwhouxRR0R", [789] = "evlwhouRR4", [790] = "evlwhosxRR0R", [791] = "evlwhosRR4", [792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4", [796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4", [800] = "evstddxRR0R", [801] = "evstddRR8", [802] = "evstdwxRR0R", [803] = "evstdwRR8", [804] = "evstdhxRR0R", [805] = "evstdhRR8", [816] = "evstwhexRR0R", [817] = "evstwheRR4", [820] = "evstwhoxRR0R", [821] = "evstwhoRR4", [824] = "evstwwexRR0R", [825] = "evstwweRR4", [828] = "evstwwoxRR0R", [829] = "evstwwoRR4", [1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR", [1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR", [1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR", [1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR", [1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR", [1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR", [1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR", [1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR", [1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR", [1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR", [1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR", [1147] = "evmwsmfaRRR", [1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR", [1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR", [1220] = "evmraRR", [1222] = "evdivwsRRR", [1223] = "evdivwuRRR", [1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR", [1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR", [1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR", [1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR", [1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR", [1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR", [1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR", [1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR", [1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR", [1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR", [1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR", [1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR", [1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR", [1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR", [1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR", [1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR", [1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR", [1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR", [1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR", [1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR", [1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR", [1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR", [1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR", [1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR", [1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR", [1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR", [1491] = "evmwssfanRRR", [1496] = "evmwumianRRR", [1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR", } local map_pri = { [0] = false, false, "tdiARI", "twiARI", map_spe, false, false, "mulliRRI", "subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI", "addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I", "b_KBJ", "sc", "bKJ", map_crops, "rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.", "oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U", "andi.RR~U", "andis.RR~U", map_rld, map_ext, "lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD", "stwRRD", "stwuRRD", "stbRRD", "stbuRRD", "lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD", "sthRRD", "sthuRRD", "lmwRRD", "stmwRRD", "lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD", "stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD", false, false, map_ld, map_fps, false, false, map_std, map_fpd, } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", } local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", } -- Format a condition bit. local function condfmt(cond) if cond <= 3 then return map_cond[band(cond, 3)] else return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)]) end end ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-7s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-7s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) local operands = {} local last = nil local rs = 21 ctx.op = op ctx.rel = nil local opat = map_pri[rshift(b0, 2)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] end local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)") if altname then pat = pat2 end for p in gmatch(pat, ".") do local x = nil if p == "R" then x = map_gpr[band(rshift(op, rs), 31)] rs = rs - 5 elseif p == "F" then x = "f"..band(rshift(op, rs), 31) rs = rs - 5 elseif p == "A" then x = band(rshift(op, rs), 31) rs = rs - 5 elseif p == "S" then x = arshift(lshift(op, 27-rs), 27) rs = rs - 5 elseif p == "I" then x = arshift(lshift(op, 16), 16) elseif p == "U" then x = band(op, 0xffff) elseif p == "D" or p == "E" then local disp = arshift(lshift(op, 16), 16) if p == "E" then disp = band(disp, -4) end if last == "r0" then last = "0" end operands[#operands] = format("%d(%s)", disp, last) elseif p >= "2" and p <= "8" then local disp = band(rshift(op, rs), 31) * p if last == "r0" then last = "0" end operands[#operands] = format("%d(%s)", disp, last) elseif p == "H" then x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4) rs = rs - 5 elseif p == "M" then x = band(rshift(op, rs), 31) + band(op, 0x20) elseif p == "C" then x = condfmt(band(rshift(op, rs), 31)) rs = rs - 5 elseif p == "B" then local bo = rshift(op, 21) local cond = band(rshift(op, 16), 31) local cn = "" rs = rs - 10 if band(bo, 4) == 0 then cn = band(bo, 2) == 0 and "dnz" or "dz" if band(bo, 0x10) == 0 then cn = cn..(band(bo, 8) == 0 and "f" or "t") end if band(bo, 0x10) == 0 then x = condfmt(cond) end name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") elseif band(bo, 0x10) == 0 then cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)] if cond > 3 then x = "cr"..rshift(cond, 2) end name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") end name = gsub(name, "_", cn) elseif p == "J" then x = arshift(lshift(op, 27-rs), 29-rs)*4 if band(op, 2) == 0 then x = ctx.addr + pos + x end ctx.rel = x x = "0x"..tohex(x) elseif p == "K" then if band(op, 1) ~= 0 then name = name.."l" end if band(op, 2) ~= 0 then name = name.."a" end elseif p == "X" or p == "Y" then x = band(rshift(op, rs+2), 7) if x == 0 and p == "Y" then x = nil else x = "cr"..x end rs = rs - 5 elseif p == "W" then x = "cr"..band(op, 7) elseif p == "Z" then x = band(rshift(op, rs-4), 255) rs = rs - 10 elseif p == ">" then operands[#operands] = rshift(operands[#operands], 1) elseif p == "0" then if last == "r0" then operands[#operands] = nil if altname then name = altname end end elseif p == "L" then name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w") elseif p == "." then if band(op, 1) == 1 then name = name.."." end elseif p == "N" then if op == 0x60000000 then name = "nop"; break end elseif p == "~" then local n = #operands operands[n-1], operands[n] = operands[n], operands[n-1] elseif p == "=" then local n = #operands if last == operands[n-1] then operands[n] = nil name = altname end elseif p == "%" then local n = #operands if last == operands[n-1] and last == operands[n-2] then operands[n] = nil operands[n-1] = nil name = altname end elseif p == "-" then rs = rs - 5 else assert(false) end if x then operands[#operands+1] = x; last = x end end return putop(ctx, name, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code stop = stop - stop % 4 ctx.pos = ofs - ofs % 4 ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_gpr[r] end return "f"..(r-32) end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Luajit/jit/dis_x64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT x64 disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the 64 bit functions from the combined -- x86/x64 disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86") return { create = dis_x86.create64, disass = dis_x86.disass64, regname = dis_x86.regname64 } ================================================ FILE: Luajit/jit/dis_x86.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT x86/x64 disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- Sending small code snippets to an external disassembler and mixing the -- output with our own stuff was too fragile. So I had to bite the bullet -- and write yet another x86 disassembler. Oh well ... -- -- The output format is very similar to what ndisasm generates. But it has -- been developed independently by looking at the opcode tables from the -- Intel and AMD manuals. The supported instruction set is quite extensive -- and reflects what a current generation Intel or AMD CPU implements in -- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3, -- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor -- (VMX/SVM) instructions. -- -- Notes: -- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported. -- * No attempt at optimization has been made -- it's fast enough for my needs. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local lower, rep = string.lower, string.rep local bit = require("bit") local tohex = bit.tohex -- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on. local map_opc1_32 = { --0x [0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es", "orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*", --1x "adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss", "sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds", --2x "andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa", "subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das", --3x "xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa", "cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas", --4x "incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR", "decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR", --5x "pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR", "popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR", --6x "sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr", "fs:seg","gs:seg","o16:","a16", "pushUi","imulVrmi","pushBs","imulVrms", "insb","insVS","outsb","outsVS", --7x "joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj", "jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj", --8x "arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms", "testBmr","testVmr","xchgBrm","xchgVrm", "movBmr","movVmr","movBrm","movVrm", "movVmg","leaVrm","movWgm","popUm", --9x "nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR", "xchgVaR","xchgVaR","xchgVaR","xchgVaR", "sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait", "sz*pushfw,pushf","sz*popfw,popf","sahf","lahf", --Ax "movBao","movVao","movBoa","movVoa", "movsb","movsVS","cmpsb","cmpsVS", "testBai","testVai","stosb","stosVS", "lodsb","lodsVS","scasb","scasVS", --Bx "movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi", "movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI", --Cx "shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi", "enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS", --Dx "shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb", "fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7", --Ex "loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj", "inBau","inVau","outBua","outVua", "callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda", --Fx "lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm", "clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm", } assert(#map_opc1_32 == 255) -- Map for 1st opcode byte in 64 bit mode (overrides only). local map_opc1_64 = setmetatable({ [0x06]=false, [0x07]=false, [0x0e]=false, [0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false, [0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false, [0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:", [0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb", [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb", [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb", [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb", [0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false, [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false, }, { __index = map_opc1_32 }) -- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you. -- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2 local map_opc2 = { --0x [0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret", "invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu", --1x "movupsXrm|movssXrvm|movupdXrm|movsdXrvm", "movupsXmr|movssXmvr|movupdXmr|movsdXmvr", "movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", "movlpsXmr||movlpdXmr", "unpcklpsXrvm||unpcklpdXrvm", "unpckhpsXrvm||unpckhpdXrvm", "movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm", "movhpsXmr||movhpdXmr", "$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm", "hintnopVm","hintnopVm","hintnopVm","hintnopVm", --2x "movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil, "movapsXrm||movapdXrm", "movapsXmr||movapdXmr", "cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt", "movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr", "cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm", "cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm", "ucomissXrm||ucomisdXrm", "comissXrm||comisdXrm", --3x "wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec", "opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil, --4x "cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm", "cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm", "cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm", "cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm", --5x "movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm", "rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm", "andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm", "orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm", "addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm", "cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm", "cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm", "subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm", "divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm", --6x "punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm", "pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm", "punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm", "||punpcklqdqXrvm","||punpckhqdqXrvm", "movPrVSm","movqMrm|movdquXrm|movdqaXrm", --7x "pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu", "pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu", "pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|", "vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$", nil,nil, "||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm", "movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr", --8x "joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj", "jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj", --9x "setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm", "setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm", --Ax "push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil, "push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm", --Bx "cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr", "$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt", "|popcntVrm","ud2Dp","bt!Vmu","btcVmr", "bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt", --Cx "xaddBmr","xaddVmr", "cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|", "pinsrwPrvWmu","pextrwDrPmu", "shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp", "bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR", --Dx "||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm", "paddqPrvm","pmullwPrvm", "|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm", "psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm", "paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm", --Ex "pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm", "pmulhuwPrvm","pmulhwPrvm", "|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr", "psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm", "paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm", --Fx "|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm", "pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$", "psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm", "paddbPrvm","paddwPrvm","padddPrvm","ud", } assert(map_opc2[255] == "ud") -- Map for three-byte opcodes. Can't wait for their next invention. local map_opc3 = { ["38"] = { -- [66] 0f 38 xx --0x [0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm", "pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm", "psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm", "||permilpsXrvm","||permilpdXrvm",nil,nil, --1x "||pblendvbXrma",nil,nil,nil, "||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm", "||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil, "pabsbPrm","pabswPrm","pabsdPrm",nil, --2x "||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm", "||pmovsxwqXrm","||pmovsxdqXrm",nil,nil, "||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm", "||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr", --3x "||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm", "||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm", "||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm", "||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm", --4x "||pmulddXrvm","||phminposuwXrm",nil,nil, nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm", --5x [0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm", [0x5a] = "||broadcasti128XrlXm", --7x [0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm", --8x [0x8c] = "||pmaskmovXrvVSm", [0x8e] = "||pmaskmovVSmXvr", --9x [0x96] = "||fmaddsub132pHXrvm",[0x97] = "||fmsubadd132pHXrvm", [0x98] = "||fmadd132pHXrvm",[0x99] = "||fmadd132sHXrvm", [0x9a] = "||fmsub132pHXrvm",[0x9b] = "||fmsub132sHXrvm", [0x9c] = "||fnmadd132pHXrvm",[0x9d] = "||fnmadd132sHXrvm", [0x9e] = "||fnmsub132pHXrvm",[0x9f] = "||fnmsub132sHXrvm", --Ax [0xa6] = "||fmaddsub213pHXrvm",[0xa7] = "||fmsubadd213pHXrvm", [0xa8] = "||fmadd213pHXrvm",[0xa9] = "||fmadd213sHXrvm", [0xaa] = "||fmsub213pHXrvm",[0xab] = "||fmsub213sHXrvm", [0xac] = "||fnmadd213pHXrvm",[0xad] = "||fnmadd213sHXrvm", [0xae] = "||fnmsub213pHXrvm",[0xaf] = "||fnmsub213sHXrvm", --Bx [0xb6] = "||fmaddsub231pHXrvm",[0xb7] = "||fmsubadd231pHXrvm", [0xb8] = "||fmadd231pHXrvm",[0xb9] = "||fmadd231sHXrvm", [0xba] = "||fmsub231pHXrvm",[0xbb] = "||fmsub231sHXrvm", [0xbc] = "||fnmadd231pHXrvm",[0xbd] = "||fnmadd231sHXrvm", [0xbe] = "||fnmsub231pHXrvm",[0xbf] = "||fnmsub231sHXrvm", --Dx [0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm", [0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm", --Fx [0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt", [0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv", }, ["3a"] = { -- [66] 0f 3a xx --0x [0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil, "||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil, "||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu", "||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu", --1x nil,nil,nil,nil, "||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru", "||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil, nil,nil,nil,nil, --2x "||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil, --3x [0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru", --4x [0x40] = "||dppsXrvmu", [0x41] = "||dppdXrvmu", [0x42] = "||mpsadbwXrvmu", [0x44] = "||pclmulqdqXrvmu", [0x46] = "||perm2i128Xrvmu", [0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb", [0x4c] = "||pblendvbXrvmb", --6x [0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu", [0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu", [0xdf] = "||aeskeygenassistXrmu", --Fx [0xf0] = "||| rorxVrmu", }, } -- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands). local map_opcvm = { [0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff", [0xc8]="monitor",[0xc9]="mwait", [0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave", [0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga", [0xf8]="swapgs",[0xf9]="rdtscp", } -- Map for FP opcodes. And you thought stack machines are simple? local map_opcfp = { -- D8-DF 00-BF: opcodes with a memory operand. -- D8 [0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm", "fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm", -- DA "fiaddDm","fimulDm","ficomDm","ficompDm", "fisubDm","fisubrDm","fidivDm","fidivrDm", -- DB "fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp", -- DC "faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm", -- DD "fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm", -- DE "fiaddWm","fimulWm","ficomWm","ficompWm", "fisubWm","fisubrWm","fidivWm","fidivrWm", -- DF "fildWm","fisttpWm","fistWm","fistpWm", "fbld twordFmp","fildQm","fbstp twordFmp","fistpQm", -- xx C0-FF: opcodes with a pseudo-register operand. -- D8 "faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf", -- D9 "fldFf","fxchFf",{"fnop"},nil, {"fchs","fabs",nil,nil,"ftst","fxam"}, {"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"}, {"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"}, {"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"}, -- DA "fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil, -- DB "fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf", {nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil, -- DC "fadd toFf","fmul toFf",nil,nil, "fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf", -- DD "ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil, -- DE "faddpFf","fmulpFf",nil,{nil,"fcompp"}, "fsubrpFf","fsubpFf","fdivrpFf","fdivpFf", -- DF nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil, } assert(map_opcfp[126] == "fcomipFf") -- Map for opcode groups. The subkey is sp from the ModRM byte. local map_opcgroup = { arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" }, shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" }, testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" }, testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" }, incb = { "inc", "dec" }, incd = { "inc", "dec", "callUmp", "$call farDmp", "jmpUmp", "$jmp farDmp", "pushUm" }, sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" }, sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt", "smsw", nil, "lmsw", "vm*$invlpg" }, bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" }, cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil, nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" }, pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" }, pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" }, pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" }, pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" }, fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr", nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" }, prefetch = { "prefetch", "prefetchw" }, prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" }, } ------------------------------------------------------------------------------ -- Maps for register names. local map_regs = { B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" }, D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" }, Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }, M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext! X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" }, Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" }, } local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" } -- Maps for size names. local map_sz2n = { B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32, } local map_sz2prefix = { B = "byte", W = "word", D = "dword", Q = "qword", M = "qword", X = "xword", Y = "yword", F = "dword", G = "qword", -- No need for sizes/register names for these two. } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local code, pos, hex = ctx.code, ctx.pos, "" local hmax = ctx.hexdump if hmax > 0 then for i=ctx.start,pos-1 do hex = hex..format("%02X", byte(code, i, i)) end if #hex > hmax then hex = sub(hex, 1, hmax)..". " else hex = hex..rep(" ", hmax-#hex+2) end end if operands then text = text.." "..operands end if ctx.o16 then text = "o16 "..text; ctx.o16 = false end if ctx.a32 then text = "a32 "..text; ctx.a32 = false end if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end if ctx.rex then local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "").. (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "").. (ctx.vexl and "l" or "") if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "") elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rex = false; ctx.vexl = false; ctx.vexv = false end if ctx.seg then local text2, n = gsub(text, "%[", "["..ctx.seg..":") if n == 0 then text = ctx.seg.." "..text else text = text2 end ctx.seg = false end if ctx.lock then text = "lock "..text; ctx.lock = false end local imm = ctx.imm if imm then local sym = ctx.symtab[imm] if sym then text = text.."\t->"..sym end end ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text)) ctx.mrm = false ctx.vexv = false ctx.start = pos ctx.imm = nil end -- Clear all prefix flags. local function clearprefixes(ctx) ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rex = false; ctx.a32 = false; ctx.vexl = false end -- Fallback for incomplete opcodes at the end. local function incomplete(ctx) ctx.pos = ctx.stop+1 clearprefixes(ctx) return putop(ctx, "(incomplete)") end -- Fallback for unknown opcodes. local function unknown(ctx) clearprefixes(ctx) return putop(ctx, "(unknown)") end -- Return an immediate of the specified size. local function getimm(ctx, pos, n) if pos+n-1 > ctx.stop then return incomplete(ctx) end local code = ctx.code if n == 1 then local b1 = byte(code, pos, pos) return b1 elseif n == 2 then local b1, b2 = byte(code, pos, pos+1) return b1+b2*256 else local b1, b2, b3, b4 = byte(code, pos, pos+3) local imm = b1+b2*256+b3*65536+b4*16777216 ctx.imm = imm return imm end end -- Process pattern string and generate the operands. local function putpat(ctx, name, pat) local operands, regs, sz, mode, sp, rm, sc, rx, sdisp local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl -- Chars used: 1DFGHIMPQRSTUVWXYabcdfgijlmoprstuvwxyz for p in gmatch(pat, ".") do local x = nil if p == "V" or p == "U" then if ctx.rexw then sz = "Q"; ctx.rexw = false elseif ctx.o16 then sz = "W"; ctx.o16 = false elseif p == "U" and ctx.x64 then sz = "Q" else sz = "D" end regs = map_regs[sz] elseif p == "T" then if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end regs = map_regs[sz] elseif p == "B" then sz = "B" regs = ctx.rex and map_regs.B64 or map_regs.B elseif match(p, "[WDQMXYFG]") then sz = p if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end regs = map_regs[sz] elseif p == "P" then sz = ctx.o16 and "X" or "M"; ctx.o16 = false if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end regs = map_regs[sz] elseif p == "H" then name = name..(ctx.rexw and "d" or "s") ctx.rexw = false elseif p == "S" then name = name..lower(sz) elseif p == "s" then local imm = getimm(ctx, pos, 1); if not imm then return end x = imm <= 127 and format("+0x%02x", imm) or format("-0x%02x", 256-imm) pos = pos+1 elseif p == "u" then local imm = getimm(ctx, pos, 1); if not imm then return end x = format("0x%02x", imm) pos = pos+1 elseif p == "b" then local imm = getimm(ctx, pos, 1); if not imm then return end x = regs[imm/16+1] pos = pos+1 elseif p == "w" then local imm = getimm(ctx, pos, 2); if not imm then return end x = format("0x%x", imm) pos = pos+2 elseif p == "o" then -- [offset] if ctx.x64 then local imm1 = getimm(ctx, pos, 4); if not imm1 then return end local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end x = format("[0x%08x%08x]", imm2, imm1) pos = pos+8 else local imm = getimm(ctx, pos, 4); if not imm then return end x = format("[0x%08x]", imm) pos = pos+4 end elseif p == "i" or p == "I" then local n = map_sz2n[sz] if n == 8 and ctx.x64 and p == "I" then local imm1 = getimm(ctx, pos, 4); if not imm1 then return end local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end x = format("0x%08x%08x", imm2, imm1) else if n == 8 then n = 4 end local imm = getimm(ctx, pos, n); if not imm then return end if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then imm = (0xffffffff+1)-imm x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm) else x = format(imm > 65535 and "0x%08x" or "0x%x", imm) end end pos = pos+n elseif p == "j" then local n = map_sz2n[sz] if n == 8 then n = 4 end local imm = getimm(ctx, pos, n); if not imm then return end if sz == "B" and imm > 127 then imm = imm-256 elseif imm > 2147483647 then imm = imm-4294967296 end pos = pos+n imm = imm + pos + ctx.addr if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end ctx.imm = imm if sz == "W" then x = format("word 0x%04x", imm%65536) elseif ctx.x64 then local lo = imm % 0x1000000 x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo) else x = "0x"..tohex(imm) end elseif p == "R" then local r = byte(code, pos-1, pos-1)%8 if ctx.rexb then r = r + 8; ctx.rexb = false end x = regs[r+1] elseif p == "a" then x = regs[1] elseif p == "c" then x = "cl" elseif p == "d" then x = "dx" elseif p == "1" then x = "1" else if not mode then mode = ctx.mrm if not mode then if pos > stop then return incomplete(ctx) end mode = byte(code, pos, pos) pos = pos+1 end rm = mode%8; mode = (mode-rm)/8 sp = mode%8; mode = (mode-sp)/8 sdisp = "" if mode < 3 then if rm == 4 then if pos > stop then return incomplete(ctx) end sc = byte(code, pos, pos) pos = pos+1 rm = sc%8; sc = (sc-rm)/8 rx = sc%8; sc = (sc-rx)/8 if ctx.rexx then rx = rx + 8; ctx.rexx = false end if rx == 4 then rx = nil end end if mode > 0 or rm == 5 then local dsz = mode if dsz ~= 1 then dsz = 4 end local disp = getimm(ctx, pos, dsz); if not disp then return end if mode == 0 then rm = nil end if rm or rx or (not sc and ctx.x64 and not ctx.a32) then if dsz == 1 and disp > 127 then sdisp = format("-0x%x", 256-disp) elseif disp >= 0 and disp <= 0x7fffffff then sdisp = format("+0x%x", disp) else sdisp = format("-0x%x", (0xffffffff+1)-disp) end else sdisp = format(ctx.x64 and not ctx.a32 and not (disp >= 0 and disp <= 0x7fffffff) and "0xffffffff%08x" or "0x%08x", disp) end pos = pos+dsz end end if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end if ctx.rexr then sp = sp + 8; ctx.rexr = false end end if p == "m" then if mode == 3 then x = regs[rm+1] else local aregs = ctx.a32 and map_regs.D or ctx.aregs local srm, srx = "", "" if rm then srm = aregs[rm+1] elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end ctx.a32 = false if rx then if rm then srm = srm.."+" end srx = aregs[rx+1] if sc > 0 then srx = srx.."*"..(2^sc) end end x = format("[%s%s%s]", srm, srx, sdisp) end if mode < 3 and (not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck. x = map_sz2prefix[sz].." "..x end elseif p == "r" then x = regs[sp+1] elseif p == "g" then x = map_segregs[sp+1] elseif p == "p" then -- Suppress prefix. elseif p == "f" then x = "st"..rm elseif p == "x" then if sp == 0 and ctx.lock and not ctx.x64 then x = "CR8"; ctx.lock = false else x = "CR"..sp end elseif p == "v" then if ctx.vexv then x = regs[ctx.vexv+1]; ctx.vexv = false end elseif p == "y" then x = "DR"..sp elseif p == "z" then x = "TR"..sp elseif p == "l" then vexl = false elseif p == "t" then else error("bad pattern `"..pat.."'") end end if x then operands = operands and operands..", "..x or x end end ctx.pos = pos return putop(ctx, name, operands) end -- Forward declaration. local map_act -- Fetch and cache MRM byte. local function getmrm(ctx) local mrm = ctx.mrm if not mrm then local pos = ctx.pos if pos > ctx.stop then return nil end mrm = byte(ctx.code, pos, pos) ctx.pos = pos+1 ctx.mrm = mrm end return mrm end -- Dispatch to handler depending on pattern. local function dispatch(ctx, opat, patgrp) if not opat then return unknown(ctx) end if match(opat, "%|") then -- MMX/SSE variants depending on prefix. local p if ctx.rep then p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)" ctx.rep = false elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false else p = "^[^%|]*" end opat = match(opat, p) if not opat then return unknown(ctx) end -- ctx.rep = false; ctx.o16 = false --XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi] --XXX remove in branches? end if match(opat, "%$") then -- reg$mem variants. local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)") if opat == "" then return unknown(ctx) end end if opat == "" then return unknown(ctx) end local name, pat = match(opat, "^([a-z0-9 ]*)(.*)") if pat == "" and patgrp then pat = patgrp end return map_act[sub(pat, 1, 1)](ctx, name, pat) end -- Get a pattern from an opcode map and dispatch to handler. local function dispatchmap(ctx, opcmap) local pos = ctx.pos local opat = opcmap[byte(ctx.code, pos, pos)] pos = pos + 1 ctx.pos = pos return dispatch(ctx, opat) end -- Map for action codes. The key is the first char after the name. map_act = { -- Simple opcodes without operands. [""] = function(ctx, name, pat) return putop(ctx, name) end, -- Operand size chars fall right through. B = putpat, W = putpat, D = putpat, Q = putpat, V = putpat, U = putpat, T = putpat, M = putpat, X = putpat, P = putpat, F = putpat, G = putpat, Y = putpat, H = putpat, -- Collect prefixes. [":"] = function(ctx, name, pat) ctx[pat == ":" and name or sub(pat, 2)] = name if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes. end, -- Chain to special handler specified by name. ["*"] = function(ctx, name, pat) return map_act[name](ctx, name, sub(pat, 2)) end, -- Use named subtable for opcode group. ["!"] = function(ctx, name, pat) local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2)) end, -- o16,o32[,o64] variants. sz = function(ctx, name, pat) if ctx.o16 then ctx.o16 = false else pat = match(pat, ",(.*)") if ctx.rexw then local p = match(pat, ",(.*)") if p then pat = p; ctx.rexw = false end end end pat = match(pat, "^[^,]*") return dispatch(ctx, pat) end, -- Two-byte opcode dispatch. opc2 = function(ctx, name, pat) return dispatchmap(ctx, map_opc2) end, -- Three-byte opcode dispatch. opc3 = function(ctx, name, pat) return dispatchmap(ctx, map_opc3[pat]) end, -- VMX/SVM dispatch. vm = function(ctx, name, pat) return dispatch(ctx, map_opcvm[ctx.mrm]) end, -- Floating point opcode dispatch. fp = function(ctx, name, pat) local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end local rm = mrm%8 local idx = pat*8 + ((mrm-rm)/8)%8 if mrm >= 192 then idx = idx + 64 end local opat = map_opcfp[idx] if type(opat) == "table" then opat = opat[rm+1] end return dispatch(ctx, opat) end, -- REX prefix. rex = function(ctx, name, pat) if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. for p in gmatch(pat, ".") do ctx["rex"..p] = true end ctx.rex = "rex" end, -- VEX prefix. vex = function(ctx, name, pat) if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. ctx.rex = "vex" local pos = ctx.pos if ctx.mrm then ctx.mrm = nil pos = pos-1 end local b = byte(ctx.code, pos, pos) if not b then return incomplete(ctx) end pos = pos+1 if b < 128 then ctx.rexr = true end local m = 1 if pat == "3" then m = b%32; b = (b-m)/32 local nb = b%2; b = (b-nb)/2 if nb == 0 then ctx.rexb = true end local nx = b%2 if nx == 0 then ctx.rexx = true end b = byte(ctx.code, pos, pos) if not b then return incomplete(ctx) end pos = pos+1 if b >= 128 then ctx.rexw = true end end ctx.pos = pos local map if m == 1 then map = map_opc2 elseif m == 2 then map = map_opc3["38"] elseif m == 3 then map = map_opc3["3a"] else return unknown(ctx) end local p = b%4; b = (b-p)/4 if p == 1 then ctx.o16 = "o16" elseif p == 2 then ctx.rep = "rep" elseif p == 3 then ctx.rep = "repne" end local l = b%2; b = (b-l)/2 if l ~= 0 then ctx.vexl = true end ctx.vexv = (-1-b)%16 return dispatchmap(ctx, map) end, -- Special case for nop with REX prefix. nop = function(ctx, name, pat) return dispatch(ctx, ctx.rex and pat or "nop") end, -- Special case for 0F 77. emms = function(ctx, name, pat) if ctx.rex ~= "vex" then return putop(ctx, "emms") elseif ctx.vexl then ctx.vexl = false return putop(ctx, "zeroall") else return putop(ctx, "zeroupper") end end, } ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ofs = ofs + 1 ctx.start = ofs ctx.pos = ofs ctx.stop = stop ctx.imm = nil ctx.mrm = false clearprefixes(ctx) while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end if ctx.pos ~= ctx.start then incomplete(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = (addr or 0) - 1 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 16 ctx.x64 = false ctx.map1 = map_opc1_32 ctx.aregs = map_regs.D return ctx end local function create64(code, addr, out) local ctx = create(code, addr, out) ctx.x64 = true ctx.map1 = map_opc1_64 ctx.aregs = map_regs.Q return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end local function disass64(code, addr, out) create64(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 8 then return map_regs.D[r+1] end return map_regs.X[r-7] end local function regname64(r) if r < 16 then return map_regs.Q[r+1] end return map_regs.X[r-15] end -- Public module functions. return { create = create, create64 = create64, disass = disass, disass64 = disass64, regname = regname, regname64 = regname64 } ================================================ FILE: Luajit/jit/dump.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT compiler dump module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module can be used to debug the JIT compiler itself. It dumps the -- code representations and structures used in various compiler stages. -- -- Example usage: -- -- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)" -- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R -- luajit -jdump=is myapp.lua | less -R -- luajit -jdump=-b myapp.lua -- luajit -jdump=+aH,myapp.html myapp.lua -- luajit -jdump=ixT,myapp.dump myapp.lua -- -- The first argument specifies the dump mode. The second argument gives -- the output file name. Default output is to stdout, unless the environment -- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the -- module is started. -- -- Different features can be turned on or off with the dump mode. If the -- mode starts with a '+', the following features are added to the default -- set of features; a '-' removes them. Otherwise the features are replaced. -- -- The following dump features are available (* marks the default): -- -- * t Print a line for each started, ended or aborted trace (see also -jv). -- * b Dump the traced bytecode. -- * i Dump the IR (intermediate representation). -- r Augment the IR with register/stack slots. -- s Dump the snapshot map. -- * m Dump the generated machine code. -- x Print each taken trace exit. -- X Print each taken trace exit and the contents of all registers. -- a Print the IR of aborted traces, too. -- -- The output format can be set with the following characters: -- -- T Plain text output. -- A ANSI-colored text output -- H Colorized HTML + CSS output. -- -- The default output format is plain text. It's set to ANSI-colored text -- if the COLORTERM variable is set. Note: this is independent of any output -- redirection, which is actually considered a feature. -- -- You probably want to use less -R to enjoy viewing ANSI-colored text from -- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R" -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr local bit = require("bit") local band, shr, tohex = bit.band, bit.rshift, bit.tohex local sub, gsub, format = string.sub, string.gsub, string.format local byte, rep = string.byte, string.rep local type, tostring = type, tostring local stdout, stderr = io.stdout, io.stderr -- Load other modules on-demand. local bcline, disass -- Active flag, output file handle and dump mode. local active, out, dumpmode ------------------------------------------------------------------------------ local symtabmt = { __index = false } local symtab = {} local nexitsym = 0 -- Fill nested symbol table with per-trace exit stub addresses. local function fillsymtab_tr(tr, nexit) local t = {} symtabmt.__index = t if jit.arch:sub(1, 4) == "mips" then t[traceexitstub(tr, 0)] = "exit" return end for i=0,nexit-1 do local addr = traceexitstub(tr, i) if addr < 0 then addr = addr + 2^32 end t[addr] = tostring(i) end local addr = traceexitstub(tr, nexit) if addr then t[addr] = "stack_check" end end -- Fill symbol table with trace exit stub addresses. local function fillsymtab(tr, nexit) local t = symtab if nexitsym == 0 then local ircall = vmdef.ircall for i=0,#ircall do local addr = ircalladdr(i) if addr ~= 0 then if addr < 0 then addr = addr + 2^32 end t[addr] = ircall[i] end end end if nexitsym == 1000000 then -- Per-trace exit stubs. fillsymtab_tr(tr, nexit) elseif nexit > nexitsym then -- Shared exit stubs. for i=nexitsym,nexit-1 do local addr = traceexitstub(i) if addr == nil then -- Fall back to per-trace exit stubs. fillsymtab_tr(tr, nexit) setmetatable(symtab, symtabmt) nexit = 1000000 break end if addr < 0 then addr = addr + 2^32 end t[addr] = tostring(i) end nexitsym = nexit end return t end local function dumpwrite(s) out:write(s) end -- Disassemble machine code. local function dump_mcode(tr) local info = traceinfo(tr) if not info then return end local mcode, addr, loop = tracemc(tr) if not mcode then return end if not disass then disass = require("jit.dis_"..jit.arch) end if addr < 0 then addr = addr + 2^32 end out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") local ctx = disass.create(mcode, addr, dumpwrite) ctx.hexdump = 0 ctx.symtab = fillsymtab(tr, info.nexit) if loop ~= 0 then symtab[addr+loop] = "LOOP" ctx:disass(0, loop) out:write("->LOOP:\n") ctx:disass(loop, #mcode-loop) symtab[addr+loop] = nil else ctx:disass(0, #mcode) end end ------------------------------------------------------------------------------ local irtype_text = { [0] = "nil", "fal", "tru", "lud", "str", "p32", "thr", "pro", "fun", "p64", "cdt", "tab", "udt", "flt", "num", "i8 ", "u8 ", "i16", "u16", "int", "u32", "i64", "u64", "sfp", } local colortype_ansi = { [0] = "%s", "%s", "%s", "\027[36m%s\027[m", "\027[32m%s\027[m", "%s", "\027[1m%s\027[m", "%s", "\027[1m%s\027[m", "%s", "\027[33m%s\027[m", "\027[31m%s\027[m", "\027[36m%s\027[m", "\027[34m%s\027[m", "\027[34m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", } local function colorize_text(s) return s end local function colorize_ansi(s, t) return format(colortype_ansi[t], s) end local irtype_ansi = setmetatable({}, { __index = function(tab, t) local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end }) local html_escape = { ["<"] = "<", [">"] = ">", ["&"] = "&", } local function colorize_html(s, t) s = gsub(s, "[<>&]", html_escape) return format('%s', irtype_text[t], s) end local irtype_html = setmetatable({}, { __index = function(tab, t) local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end }) local header_html = [[ ]] local colorize, irtype -- Lookup tables to convert some literals into names. local litname = { ["SLOAD "] = setmetatable({}, { __index = function(t, mode) local s = "" if band(mode, 1) ~= 0 then s = s.."P" end if band(mode, 2) ~= 0 then s = s.."F" end if band(mode, 4) ~= 0 then s = s.."T" end if band(mode, 8) ~= 0 then s = s.."C" end if band(mode, 16) ~= 0 then s = s.."R" end if band(mode, 32) ~= 0 then s = s.."I" end t[mode] = s return s end}), ["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", }, ["CONV "] = setmetatable({}, { __index = function(t, mode) local s = irtype[band(mode, 31)] s = irtype[band(shr(mode, 5), 31)].."."..s if band(mode, 0x800) ~= 0 then s = s.." sext" end local c = shr(mode, 14) if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end t[mode] = s return s end}), ["FLOAD "] = vmdef.irfield, ["FREF "] = vmdef.irfield, ["FPMATH"] = vmdef.irfpm, ["BUFHDR"] = { [0] = "RESET", "APPEND" }, ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, } local function ctlsub(c) if c == "\n" then return "\\n" elseif c == "\r" then return "\\r" elseif c == "\t" then return "\\t" else return format("\\%03d", byte(c)) end end local function fmtfunc(func, pc) local fi = funcinfo(func, pc) if fi.loc then return fi.loc elseif fi.ffid then return vmdef.ffnames[fi.ffid] elseif fi.addr then return format("C:%x", fi.addr) else return "(?)" end end local function formatk(tr, idx, sn) local k, t, slot = tracek(tr, idx) local tn = type(k) local s if tn == "number" then if band(sn or 0, 0x30000) ~= 0 then s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz" elseif k == 2^52+2^51 then s = "bias" else s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k) end elseif tn == "string" then s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) elseif tn == "function" then s = fmtfunc(k) elseif tn == "table" then s = format("{%p}", k) elseif tn == "userdata" then if t == 12 then s = format("userdata:%p", k) else s = format("[%p]", k) if s == "[NULL]" then s = "NULL" end end elseif t == 21 then -- int64_t s = sub(tostring(k), 1, -3) if sub(s, 1, 1) ~= "-" then s = "+"..s end elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL) return "----" -- Special case for LJ_FR2 slot 1. else s = tostring(k) -- For primitives. end s = colorize(format("%-4s", s), t) if slot then s = format("%s @%d", s, slot) end return s end local function printsnap(tr, snap) local n = 2 for s=0,snap[1]-1 do local sn = snap[n] if shr(sn, 24) == s then n = n + 1 local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS if ref < 0 then out:write(formatk(tr, ref, sn)) elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM out:write(colorize(format("%04d/%04d", ref, ref+1), 14)) else local m, ot, op1, op2 = traceir(tr, ref) out:write(colorize(format("%04d", ref), band(ot, 31))) end out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME else out:write("---- ") end end out:write("]\n") end -- Dump snapshots (not interleaved with IR). local function dump_snap(tr) out:write("---- TRACE ", tr, " snapshots\n") for i=0,1000000000 do local snap = tracesnap(tr, i) if not snap then break end out:write(format("#%-3d %04d [ ", i, snap[0])) printsnap(tr, snap) end end -- Return a register name or stack slot for a rid/sp location. local function ridsp_name(ridsp, ins) if not disass then disass = require("jit.dis_"..jit.arch) end local rid, slot = band(ridsp, 0xff), shr(ridsp, 8) if rid == 253 or rid == 254 then return (slot == 0 or slot == 255) and " {sink" or format(" {%04d", ins-slot) end if ridsp > 255 then return format("[%x]", slot*4) end if rid < 128 then return disass.regname(rid) end return "" end -- Dump CALL* function ref and return optional ctype. local function dumpcallfunc(tr, ins) local ctype if ins > 0 then local m, ot, op1, op2 = traceir(tr, ins) if band(ot, 31) == 0 then -- nil type means CARG(func, ctype). ins = op1 ctype = formatk(tr, op2) end end if ins < 0 then out:write(format("[0x%x](", tonumber((tracek(tr, ins))))) else out:write(format("%04d (", ins)) end return ctype end -- Recursively gather CALL* args and dump them. local function dumpcallargs(tr, ins) if ins < 0 then out:write(formatk(tr, ins)) else local m, ot, op1, op2 = traceir(tr, ins) local oidx = 6*shr(ot, 8) local op = sub(vmdef.irnames, oidx+1, oidx+6) if op == "CARG " then dumpcallargs(tr, op1) if op2 < 0 then out:write(" ", formatk(tr, op2)) else out:write(" ", format("%04d", op2)) end else out:write(format("%04d", ins)) end end end -- Dump IR and interleaved snapshots. local function dump_ir(tr, dumpsnap, dumpreg) local info = traceinfo(tr) if not info then return end local nins = info.nins out:write("---- TRACE ", tr, " IR\n") local irnames = vmdef.irnames local snapref = 65536 local snap, snapno if dumpsnap then snap = tracesnap(tr, 0) snapref = snap[0] snapno = 0 end for ins=1,nins do if ins >= snapref then if dumpreg then out:write(format(".... SNAP #%-3d [ ", snapno)) else out:write(format(".... SNAP #%-3d [ ", snapno)) end printsnap(tr, snap) snapno = snapno + 1 snap = tracesnap(tr, snapno) snapref = snap and snap[0] or 65536 end local m, ot, op1, op2, ridsp = traceir(tr, ins) local oidx, t = 6*shr(ot, 8), band(ot, 31) local op = sub(irnames, oidx+1, oidx+6) if op == "LOOP " then if dumpreg then out:write(format("%04d ------------ LOOP ------------\n", ins)) else out:write(format("%04d ------ LOOP ------------\n", ins)) end elseif op ~= "NOP " and op ~= "CARG " and (dumpreg or op ~= "RENAME") then local rid = band(ridsp, 255) if dumpreg then out:write(format("%04d %-6s", ins, ridsp_name(ridsp, ins))) else out:write(format("%04d ", ins)) end out:write(format("%s%s %s %s ", (rid == 254 or rid == 253) and "}" or (band(ot, 128) == 0 and " " or ">"), band(ot, 64) == 0 and " " or "+", irtype[t], op)) local m1, m2 = band(m, 3), band(m, 3*4) if sub(op, 1, 4) == "CALL" then local ctype if m2 == 1*4 then -- op2 == IRMlit out:write(format("%-10s (", vmdef.ircall[op2])) else ctype = dumpcallfunc(tr, op2) end if op1 ~= -1 then dumpcallargs(tr, op1) end out:write(")") if ctype then out:write(" ctype ", ctype) end elseif op == "CNEW " and op2 == -1 then out:write(formatk(tr, op1)) elseif m1 ~= 3 then -- op1 != IRMnone if op1 < 0 then out:write(formatk(tr, op1)) else out:write(format(m1 == 0 and "%04d" or "#%-3d", op1)) end if m2 ~= 3*4 then -- op2 != IRMnone if m2 == 1*4 then -- op2 == IRMlit local litn = litname[op] if litn and litn[op2] then out:write(" ", litn[op2]) elseif op == "UREFO " or op == "UREFC " then out:write(format(" #%-3d", shr(op2, 8))) else out:write(format(" #%-3d", op2)) end elseif op2 < 0 then out:write(" ", formatk(tr, op2)) else out:write(format(" %04d", op2)) end end end out:write("\n") end end if snap then if dumpreg then out:write(format(".... SNAP #%-3d [ ", snapno)) else out:write(format(".... SNAP #%-3d [ ", snapno)) end printsnap(tr, snap) end end ------------------------------------------------------------------------------ local recprefix = "" local recdepth = 0 -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err end -- Dump trace states. local function dump_trace(what, tr, func, pc, otr, oex) if what == "stop" or (what == "abort" and dumpmode.a) then if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop") elseif dumpmode.s then dump_snap(tr) end if dumpmode.m then dump_mcode(tr) end end if what == "start" then if dumpmode.H then out:write('
\n') end
    out:write("---- TRACE ", tr, " ", what)
    if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
    out:write(" ", fmtfunc(func, pc), "\n")
  elseif what == "stop" or what == "abort" then
    out:write("---- TRACE ", tr, " ", what)
    if what == "abort" then
      out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
    else
      local info = traceinfo(tr)
      local link, ltype = info.link, info.linktype
      if link == tr or link == 0 then
	out:write(" -> ", ltype, "\n")
      elseif ltype == "root" then
	out:write(" -> ", link, "\n")
      else
	out:write(" -> ", link, " ", ltype, "\n")
      end
    end
    if dumpmode.H then out:write("
\n\n") else out:write("\n") end else if what == "flush" then symtab, nexitsym = {}, 0 end out:write("---- TRACE ", what, "\n\n") end out:flush() end -- Dump recorded bytecode. local function dump_record(tr, func, pc, depth, callee) if depth ~= recdepth then recdepth = depth recprefix = rep(" .", depth) end local line if pc >= 0 then line = bcline(func, pc, recprefix) if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end if pc > 0 then line = sub(line, 1, -2) .. " (" .. fmtfunc(func, pc) .. ")\n" end else line = "0000 "..recprefix.." FUNCC \n" callee = func end if pc <= 0 then out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n") else out:write(line) end if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond. end end ------------------------------------------------------------------------------ -- Dump taken trace exits. local function dump_texit(tr, ex, ngpr, nfpr, ...) out:write("---- TRACE ", tr, " exit ", ex, "\n") if dumpmode.X then local regs = {...} if jit.arch == "x64" then for i=1,ngpr do out:write(format(" %016x", regs[i])) if i % 4 == 0 then out:write("\n") end end else for i=1,ngpr do out:write(" ", tohex(regs[i])) if i % 8 == 0 then out:write("\n") end end end if jit.arch == "mips" or jit.arch == "mipsel" then for i=1,nfpr,2 do out:write(format(" %+17.14g", regs[ngpr+i])) if i % 8 == 7 then out:write("\n") end end else for i=1,nfpr do out:write(format(" %+17.14g", regs[ngpr+i])) if i % 4 == 0 then out:write("\n") end end end end end ------------------------------------------------------------------------------ -- Detach dump handlers. local function dumpoff() if active then active = false jit.attach(dump_texit) jit.attach(dump_record) jit.attach(dump_trace) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach dump handlers. local function dumpon(opt, outfile) if active then dumpoff() end local term = os.getenv("TERM") local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T" if opt then opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end) end local m = { t=true, b=true, i=true, m=true, } if opt and opt ~= "" then local o = sub(opt, 1, 1) if o ~= "+" and o ~= "-" then m = {} end for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end end dumpmode = m if m.t or m.b or m.i or m.s or m.m then jit.attach(dump_trace, "trace") end if m.b then jit.attach(dump_record, "record") if not bcline then bcline = require("jit.bc").line end end if m.x or m.X then jit.attach(dump_texit, "texit") end if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stdout end m[colormode] = true if colormode == "A" then colorize = colorize_ansi irtype = irtype_ansi elseif colormode == "H" then colorize = colorize_html irtype = irtype_html out:write(header_html) else colorize = colorize_text irtype = irtype_text end active = true end -- Public module functions. return { on = dumpon, off = dumpoff, start = dumpon -- For -j command line option. } ================================================ FILE: Luajit/jit/p.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT profiler. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module is a simple command line interface to the built-in -- low-overhead profiler of LuaJIT. -- -- The lower-level API of the profiler is accessible via the "jit.profile" -- module or the luaJIT_profile_* C API. -- -- Example usage: -- -- luajit -jp myapp.lua -- luajit -jp=s myapp.lua -- luajit -jp=-s myapp.lua -- luajit -jp=vl myapp.lua -- luajit -jp=G,profile.txt myapp.lua -- -- The following dump features are available: -- -- f Stack dump: function name, otherwise module:line. Default mode. -- F Stack dump: ditto, but always prepend module. -- l Stack dump: module:line. -- stack dump depth (callee < caller). Default: 1. -- - Inverse stack dump depth (caller > callee). -- s Split stack dump after first stack level. Implies abs(depth) >= 2. -- p Show full path for module names. -- v Show VM states. Can be combined with stack dumps, e.g. vf or fv. -- z Show zones. Can be combined with stack dumps, e.g. zf or fz. -- r Show raw sample counts. Default: show percentages. -- a Annotate excerpts from source code files. -- A Annotate complete source code files. -- G Produce raw output suitable for graphical tools (e.g. flame graphs). -- m Minimum sample percentage to be shown. Default: 3. -- i Sampling interval in milliseconds. Default: 10. -- ---------------------------------------------------------------------------- -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local profile = require("jit.profile") local vmdef = require("jit.vmdef") local math = math local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor local sort, format = table.sort, string.format local stdout = io.stdout local zone -- Load jit.zone module on demand. -- Output file handle. local out ------------------------------------------------------------------------------ local prof_ud local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth local prof_ann, prof_count1, prof_count2, prof_samples local map_vmmode = { N = "Compiled", I = "Interpreted", C = "C code", G = "Garbage Collector", J = "JIT Compiler", } -- Profiler callback. local function prof_cb(th, samples, vmmode) prof_samples = prof_samples + samples local key_stack, key_stack2, key_state -- Collect keys for sample. if prof_states then if prof_states == "v" then key_state = map_vmmode[vmmode] or vmmode else key_state = zone:get() or "(none)" end end if prof_fmt then key_stack = profile.dumpstack(th, prof_fmt, prof_depth) key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x) return vmdef.ffnames[tonumber(x)] end) if prof_split == 2 then local k1, k2 = key_stack:match("(.-) [<>] (.*)") if k2 then key_stack, key_stack2 = k1, k2 end elseif prof_split == 3 then key_stack2 = profile.dumpstack(th, "l", 1) end end -- Order keys. local k1, k2 if prof_split == 1 then if key_state then k1 = key_state if key_stack then k2 = key_stack end end elseif key_stack then k1 = key_stack if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end end -- Coalesce samples in one or two levels. if k1 then local t1 = prof_count1 t1[k1] = (t1[k1] or 0) + samples if k2 then local t2 = prof_count2 local t3 = t2[k1] if not t3 then t3 = {}; t2[k1] = t3 end t3[k2] = (t3[k2] or 0) + samples end end end ------------------------------------------------------------------------------ -- Show top N list. local function prof_top(count1, count2, samples, indent) local t, n = {}, 0 for k in pairs(count1) do n = n + 1 t[n] = k end sort(t, function(a, b) return count1[a] > count1[b] end) for i=1,n do local k = t[i] local v = count1[k] local pct = floor(v*100/samples + 0.5) if pct < prof_min then break end if not prof_raw then out:write(format("%s%2d%% %s\n", indent, pct, k)) elseif prof_raw == "r" then out:write(format("%s%5d %s\n", indent, v, k)) else out:write(format("%s %d\n", k, v)) end if count2 then local r = count2[k] if r then prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or (prof_depth < 0 and " -> " or " <- ")) end end end end -- Annotate source code local function prof_annotate(count1, samples) local files = {} local ms = 0 for k, v in pairs(count1) do local pct = floor(v*100/samples + 0.5) ms = math.max(ms, v) if pct >= prof_min then local file, line = k:match("^(.*):(%d+)$") if not file then file = k; line = 0 end local fl = files[file] if not fl then fl = {}; files[file] = fl; files[#files+1] = file end line = tonumber(line) fl[line] = prof_raw and v or pct end end sort(files) local fmtv, fmtn = " %3d%% | %s\n", " | %s\n" if prof_raw then local n = math.max(5, math.ceil(math.log10(ms))) fmtv = "%"..n.."d | %s\n" fmtn = (" "):rep(n).." | %s\n" end local ann = prof_ann for _, file in ipairs(files) do local f0 = file:byte() if f0 == 40 or f0 == 91 then out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file)) break end local fp, err = io.open(file) if not fp then out:write(format("====== ERROR: %s: %s\n", file, err)) break end out:write(format("\n====== %s ======\n", file)) local fl = files[file] local n, show = 1, false if ann ~= 0 then for i=1,ann do if fl[i] then show = true; out:write("@@ 1 @@\n"); break end end end for line in fp:lines() do if line:byte() == 27 then out:write("[Cannot annotate bytecode file]\n") break end local v = fl[n] if ann ~= 0 then local v2 = fl[n+ann] if show then if v2 then show = n+ann elseif v then show = n elseif show+ann < n then show = false end elseif v2 then show = n+ann out:write(format("@@ %d @@\n", n)) end if not show then goto next end end if v then out:write(format(fmtv, v, line)) else out:write(format(fmtn, line)) end ::next:: n = n + 1 end fp:close() end end ------------------------------------------------------------------------------ -- Finish profiling and dump result. local function prof_finish() if prof_ud then profile.stop() local samples = prof_samples if samples == 0 then if prof_raw ~= true then out:write("[No samples collected]\n") end return end if prof_ann then prof_annotate(prof_count1, samples) else prof_top(prof_count1, prof_count2, samples, "") end prof_count1 = nil prof_count2 = nil prof_ud = nil end end -- Start profiling. local function prof_start(mode) local interval = "" mode = mode:gsub("i%d*", function(s) interval = s; return "" end) prof_min = 3 mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end) prof_depth = 1 mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end) local m = {} for c in mode:gmatch(".") do m[c] = c end prof_states = m.z or m.v if prof_states == "z" then zone = require("jit.zone") end local scope = m.l or m.f or m.F or (prof_states and "" or "f") local flags = (m.p or "") prof_raw = m.r if m.s then prof_split = 2 if prof_depth == -1 or m["-"] then prof_depth = -2 elseif prof_depth == 1 then prof_depth = 2 end elseif mode:find("[fF].*l") then scope = "l" prof_split = 3 else prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0 end prof_ann = m.A and 0 or (m.a and 3) if prof_ann then scope = "l" prof_fmt = "pl" prof_split = 0 prof_depth = 1 elseif m.G and scope ~= "" then prof_fmt = flags..scope.."Z;" prof_depth = -100 prof_raw = true prof_min = 0 elseif scope == "" then prof_fmt = false else local sc = prof_split == 3 and m.f or m.F or scope prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ") end prof_count1 = {} prof_count2 = {} prof_samples = 0 profile.start(scope:lower()..interval, prof_cb) prof_ud = newproxy(true) getmetatable(prof_ud).__gc = prof_finish end ------------------------------------------------------------------------------ local function start(mode, outfile) if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stdout end prof_start(mode or "f") end -- Public module functions. return { start = start, -- For -j command line option. stop = prof_finish } ================================================ FILE: Luajit/jit/v.lua ================================================ ---------------------------------------------------------------------------- -- Verbose mode of the LuaJIT compiler. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module shows verbose information about the progress of the -- JIT compiler. It prints one line for each generated trace. This module -- is useful to see which code has been compiled or where the compiler -- punts and falls back to the interpreter. -- -- Example usage: -- -- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end" -- luajit -jv=myapp.out myapp.lua -- -- Default output is to stderr. To redirect the output to a file, pass a -- filename as an argument (use '-' for stdout) or set the environment -- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the -- module is started. -- -- The output from the first example should look like this: -- -- [TRACE 1 (command line):1 loop] -- [TRACE 2 (1/3) (command line):1 -> 1] -- -- The first number in each line is the internal trace number. Next are -- the file name ('(command line)') and the line number (':1') where the -- trace has started. Side traces also show the parent trace number and -- the exit number where they are attached to in parentheses ('(1/3)'). -- An arrow at the end shows where the trace links to ('-> 1'), unless -- it loops to itself. -- -- In this case the inner loop gets hot and is traced first, generating -- a root trace. Then the last exit from the 1st trace gets hot, too, -- and triggers generation of the 2nd trace. The side trace follows the -- path along the outer loop and *around* the inner loop, back to its -- start, and then links to the 1st trace. Yes, this may seem unusual, -- if you know how traditional compilers work. Trace compilers are full -- of surprises like this -- have fun! :-) -- -- Aborted traces are shown like this: -- -- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50] -- -- Don't worry -- trace aborts are quite common, even in programs which -- can be fully compiled. The compiler may retry several times until it -- finds a suitable trace. -- -- Of course this doesn't work with features that are not-yet-implemented -- (NYI error messages). The VM simply falls back to the interpreter. This -- may not matter at all if the particular trace is not very high up in -- the CPU usage profile. Oh, and the interpreter is quite fast, too. -- -- Also check out the -jdump module, which prints all the gory details. -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo local type, format = type, string.format local stdout, stderr = io.stdout, io.stderr -- Active flag and output file handle. local active, out ------------------------------------------------------------------------------ local startloc, startex local function fmtfunc(func, pc) local fi = funcinfo(func, pc) if fi.loc then return fi.loc elseif fi.ffid then return vmdef.ffnames[fi.ffid] elseif fi.addr then return format("C:%x", fi.addr) else return "(?)" end end -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err end -- Dump trace states. local function dump_trace(what, tr, func, pc, otr, oex) if what == "start" then startloc = fmtfunc(func, pc) startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or "" else if what == "abort" then local loc = fmtfunc(func, pc) if loc ~= startloc then out:write(format("[TRACE --- %s%s -- %s at %s]\n", startex, startloc, fmterr(otr, oex), loc)) else out:write(format("[TRACE --- %s%s -- %s]\n", startex, startloc, fmterr(otr, oex))) end elseif what == "stop" then local info = traceinfo(tr) local link, ltype = info.link, info.linktype if ltype == "interpreter" then out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n", tr, startex, startloc)) elseif ltype == "stitch" then out:write(format("[TRACE %3s %s%s %s %s]\n", tr, startex, startloc, ltype, fmtfunc(func, pc))) elseif link == tr or link == 0 then out:write(format("[TRACE %3s %s%s %s]\n", tr, startex, startloc, ltype)) elseif ltype == "root" then out:write(format("[TRACE %3s %s%s -> %d]\n", tr, startex, startloc, link)) else out:write(format("[TRACE %3s %s%s -> %d %s]\n", tr, startex, startloc, link, ltype)) end else out:write(format("[TRACE %s]\n", what)) end out:flush() end end ------------------------------------------------------------------------------ -- Detach dump handlers. local function dumpoff() if active then active = false jit.attach(dump_trace) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach dump handlers. local function dumpon(outfile) if active then dumpoff() end if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stderr end jit.attach(dump_trace, "trace") active = true end -- Public module functions. return { on = dumpon, off = dumpoff, start = dumpon -- For -j command line option. } ================================================ FILE: Luajit/jit/vmdef.lua ================================================ -- This is a generated file. DO NOT EDIT! return { bcnames = "ISLT ISGE ISLE ISGT ISEQV ISNEV ISEQS ISNES ISEQN ISNEN ISEQP ISNEP ISTC ISFC IST ISF ISTYPEISNUM MOV NOT UNM LEN ADDVN SUBVN MULVN DIVVN MODVN ADDNV SUBNV MULNV DIVNV MODNV ADDVV SUBVV MULVV DIVVV MODVV POW CAT KSTR KCDATAKSHORTKNUM KPRI KNIL UGET USETV USETS USETN USETP UCLO FNEW TNEW TDUP GGET GSET TGETV TGETS TGETB TGETR TSETV TSETS TSETB TSETM TSETR CALLM CALL CALLMTCALLT ITERC ITERN VARG ISNEXTRETM RET RET0 RET1 FORI JFORI FORL IFORL JFORL ITERL IITERLJITERLLOOP ILOOP JLOOP JMP FUNCF IFUNCFJFUNCFFUNCV IFUNCVJFUNCVFUNCC FUNCCW", irnames = "LT GE LE GT ULT UGE ULE UGT EQ NE ABC RETF NOP BASE PVAL GCSTEPHIOP LOOP USE PHI RENAMEPROF KPRI KINT KGC KPTR KKPTR KNULL KNUM KINT64KSLOT BNOT BSWAP BAND BOR BXOR BSHL BSHR BSAR BROL BROR ADD SUB MUL DIV MOD POW NEG ABS ATAN2 LDEXP MIN MAX FPMATHADDOV SUBOV MULOV AREF HREFK HREF NEWREFUREFO UREFC FREF STRREFLREF ALOAD HLOAD ULOAD FLOAD XLOAD SLOAD VLOAD ASTOREHSTOREUSTOREFSTOREXSTORESNEW XSNEW TNEW TDUP CNEW CNEWI BUFHDRBUFPUTBUFSTRTBAR OBAR XBAR CONV TOBIT TOSTR STRTO CALLN CALLA CALLL CALLS CALLXSCARG ", irfpm = { [0]="floor", "ceil", "trunc", "sqrt", "exp", "exp2", "log", "log2", "log10", "sin", "cos", "tan", "other", }, irfield = { [0]="str.len", "func.env", "func.pc", "func.ffid", "thread.env", "thread.exdata", "tab.meta", "tab.array", "tab.node", "tab.asize", "tab.hmask", "tab.nomm", "udata.meta", "udata.udtype", "udata.file", "cdata.ctypeid", "cdata.ptr", "cdata.int", "cdata.int64", "cdata.int64_4", }, ircall = { [0]="lj_str_cmp", "lj_str_find", "lj_str_new", "lj_strscan_num", "lj_strfmt_int", "lj_strfmt_num", "lj_strfmt_char", "lj_strfmt_putint", "lj_strfmt_putnum", "lj_strfmt_putquoted", "lj_strfmt_putfxint", "lj_strfmt_putfnum_int", "lj_strfmt_putfnum_uint", "lj_strfmt_putfnum", "lj_strfmt_putfstr", "lj_strfmt_putfchar", "lj_buf_putmem", "lj_buf_putstr", "lj_buf_putchar", "lj_buf_putstr_reverse", "lj_buf_putstr_lower", "lj_buf_putstr_upper", "lj_buf_putstr_rep", "lj_buf_puttab", "lj_buf_tostr", "lj_tab_new_ah", "lj_tab_new1", "lj_tab_dup", "lj_tab_clear", "lj_tab_newkey", "lj_tab_len", "lj_tab_clone", "lj_tab_isarray", "lj_tab_nkeys", "lj_tab_isempty", "lj_gc_step_jit", "lj_gc_barrieruv", "lj_mem_newgco", "lj_math_random_step", "lj_vm_modi", "sinh", "cosh", "tanh", "fputc", "fwrite", "fflush", "lj_vm_floor", "lj_vm_ceil", "lj_vm_trunc", "sqrt", "exp", "lj_vm_exp2", "log", "lj_vm_log2", "log10", "sin", "cos", "tan", "lj_vm_powi", "pow", "atan2", "ldexp", "lj_vm_tobit", "softfp_add", "softfp_sub", "softfp_mul", "softfp_div", "softfp_cmp", "softfp_i2d", "softfp_d2i", "lj_vm_sfmin", "lj_vm_sfmax", "lj_vm_tointg", "softfp_ui2d", "softfp_f2d", "softfp_d2ui", "softfp_d2f", "softfp_i2f", "softfp_ui2f", "softfp_f2i", "softfp_f2ui", "fp64_l2d", "fp64_ul2d", "fp64_l2f", "fp64_ul2f", "fp64_d2l", "fp64_d2ul", "fp64_f2l", "fp64_f2ul", "lj_carith_divi64", "lj_carith_divu64", "lj_carith_modi64", "lj_carith_modu64", "lj_carith_powi64", "lj_carith_powu64", "lj_cdata_newv", "lj_cdata_setfin", "strlen", "memcpy", "memset", "lj_vm_errno", "lj_carith_mul64", "lj_carith_shl64", "lj_carith_shr64", "lj_carith_sar64", "lj_carith_rol64", "lj_carith_ror64", }, traceerr = { [0]="error thrown or hook called during recording", "trace too short", "trace too long", "trace too deep", "too many snapshots", "blacklisted", "retry recording", "NYI: bytecode %d", "leaving loop in root trace", "inner loop in root trace", "loop unroll limit reached", "bad argument type", "JIT compilation disabled for function", "call unroll limit reached", "down-recursion, restarting", "NYI: unsupported variant of FastFunc %s", "NYI: return to lower frame", "store with nil or NaN key", "missing metamethod", "looping index lookup", "NYI: mixed sparse/dense table", "symbol not in cache", "NYI: unsupported C type conversion", "NYI: unsupported C function type", "guard would always fail", "too many PHIs", "persistent type instability", "failed to allocate mcode memory", "machine code too long", "hit mcode limit (retrying)", "too many spill slots", "inconsistent register allocation", "NYI: cannot assemble IR instruction %d", "NYI: PHI shuffling too complex", "NYI: register coalescing too complex", }, ffnames = { [0]="Lua", "C", "assert", "type", "next", "pairs", "ipairs_aux", "ipairs", "getmetatable", "setmetatable", "getfenv", "setfenv", "rawget", "rawset", "rawequal", "unpack", "select", "tonumber", "tostring", "error", "pcall", "xpcall", "loadfile", "load", "loadstring", "dofile", "gcinfo", "collectgarbage", "newproxy", "print", "coroutine.status", "coroutine.running", "coroutine.isyieldable", "coroutine.create", "coroutine.yield", "coroutine.resume", "coroutine.wrap_aux", "coroutine.wrap", "thread.exdata", "math.abs", "math.floor", "math.ceil", "math.sqrt", "math.log10", "math.exp", "math.sin", "math.cos", "math.tan", "math.asin", "math.acos", "math.atan", "math.sinh", "math.cosh", "math.tanh", "math.frexp", "math.modf", "math.log", "math.atan2", "math.pow", "math.fmod", "math.ldexp", "math.min", "math.max", "math.random", "math.randomseed", "bit.tobit", "bit.bnot", "bit.bswap", "bit.lshift", "bit.rshift", "bit.arshift", "bit.rol", "bit.ror", "bit.band", "bit.bor", "bit.bxor", "bit.tohex", "string.byte", "string.char", "string.sub", "string.rep", "string.reverse", "string.lower", "string.upper", "string.dump", "string.find", "string.match", "string.gmatch_aux", "string.gmatch", "string.gsub", "string.format", "table.maxn", "table.insert", "table.concat", "table.clone", "table.isarray", "table.nkeys", "table.isempty", "table.sort", "table.new", "table.clear", "io.method.close", "io.method.read", "io.method.write", "io.method.flush", "io.method.seek", "io.method.setvbuf", "io.method.lines", "io.method.__gc", "io.method.__tostring", "io.open", "io.popen", "io.tmpfile", "io.close", "io.read", "io.write", "io.flush", "io.input", "io.output", "io.lines", "io.type", "os.execute", "os.remove", "os.rename", "os.tmpname", "os.getenv", "os.exit", "os.clock", "os.date", "os.time", "os.difftime", "os.setlocale", "debug.getregistry", "debug.getmetatable", "debug.setmetatable", "debug.getfenv", "debug.setfenv", "debug.getinfo", "debug.getlocal", "debug.setlocal", "debug.getupvalue", "debug.setupvalue", "debug.upvalueid", "debug.upvaluejoin", "debug.sethook", "debug.gethook", "debug.debug", "debug.traceback", "jit.on", "jit.off", "jit.flush", "jit.status", "jit.attach", "jit.prngstate", "jit.util.funcinfo", "jit.util.funcbc", "jit.util.funck", "jit.util.funcuvname", "jit.util.traceinfo", "jit.util.traceir", "jit.util.tracek", "jit.util.tracesnap", "jit.util.tracemc", "jit.util.traceexitstub", "jit.util.ircalladdr", "jit.opt.start", "jit.profile.start", "jit.profile.stop", "jit.profile.dumpstack", "ffi.meta.__index", "ffi.meta.__newindex", "ffi.meta.__eq", "ffi.meta.__len", "ffi.meta.__lt", "ffi.meta.__le", "ffi.meta.__concat", "ffi.meta.__call", "ffi.meta.__add", "ffi.meta.__sub", "ffi.meta.__mul", "ffi.meta.__div", "ffi.meta.__mod", "ffi.meta.__pow", "ffi.meta.__unm", "ffi.meta.__tostring", "ffi.meta.__pairs", "ffi.meta.__ipairs", "ffi.clib.__index", "ffi.clib.__newindex", "ffi.clib.__gc", "ffi.callback.free", "ffi.callback.set", "ffi.cdef", "ffi.new", "ffi.cast", "ffi.typeof", "ffi.typeinfo", "ffi.istype", "ffi.sizeof", "ffi.alignof", "ffi.offsetof", "ffi.errno", "ffi.string", "ffi.copy", "ffi.fill", "ffi.abi", "ffi.metatype", "ffi.gc", "ffi.load", }, } ================================================ FILE: Luajit/jit/zone.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT profiler zones. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module implements a simple hierarchical zone model. -- -- Example usage: -- -- local zone = require("jit.zone") -- zone("AI") -- ... -- zone("A*") -- ... -- print(zone:get()) --> "A*" -- ... -- zone() -- ... -- print(zone:get()) --> "AI" -- ... -- zone() -- ---------------------------------------------------------------------------- local remove = table.remove return setmetatable({ flush = function(t) for i=#t,1,-1 do t[i] = nil end end, get = function(t) return t[#t] end }, { __call = function(t, zone) if zone then t[#t+1] = zone else return (assert(remove(t), "empty zone stack")) end end }) ================================================ FILE: Luajit64/Build.bat ================================================ @echo off cd /d %~dp0 if not exist jit (mkdir jit) if not exist Out (mkdir Out) xcopy /Y /D ..\..\..\Luajit64\jit jit setlocal enabledelayedexpansion for /r %%i in (*.lua) do ( set v=%%~dpi call :loop set v=!v:%~dp0=! if not exist %~dp0out\!v! (mkdir %~dp0Out\!v!) ) for /r %%i in (*.lua) do ( set v=%%i set v=!v:%~dp0=! call :loop ..\..\..\Luajit64\luajit64.exe -b -g !v! Out\!v!.bytes ) rd /s/q jit rd /s/q .\Out\jit\ setlocal disabledelayedexpansion :loop if "!v:~-1!"==" " set "v=!v:~0,-1!" & goto loop ================================================ FILE: Luajit64/jit/bc.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT bytecode listing module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module lists the bytecode of a Lua function. If it's loaded by -jbc -- it hooks into the parser and lists all functions of a chunk as they -- are parsed. -- -- Example usage: -- -- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)' -- luajit -jbc=- foo.lua -- luajit -jbc=foo.list foo.lua -- -- Default output is to stderr. To redirect the output to a file, pass a -- filename as an argument (use '-' for stdout) or set the environment -- variable LUAJIT_LISTFILE. The file is overwritten every time the module -- is started. -- -- This module can also be used programmatically: -- -- local bc = require("jit.bc") -- -- local function foo() print("hello") end -- -- bc.dump(foo) --> -- BYTECODE -- [...] -- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello" -- -- local out = { -- -- Do something with each line: -- write = function(t, ...) io.write(...) end, -- close = function(t) end, -- flush = function(t) end, -- } -- bc.dump(foo, out) -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local bit = require("bit") local sub, gsub, format = string.sub, string.gsub, string.format local byte, band, shr = string.byte, bit.band, bit.rshift local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck local funcuvname = jutil.funcuvname local bcnames = vmdef.bcnames local stdout, stderr = io.stdout, io.stderr ------------------------------------------------------------------------------ local function ctlsub(c) if c == "\n" then return "\\n" elseif c == "\r" then return "\\r" elseif c == "\t" then return "\\t" else return format("\\%03d", byte(c)) end end -- Return one bytecode line. local function bcline(func, pc, prefix, lineinfo) local ins, m, l = funcbc(func, pc, lineinfo and 1 or 0) if not ins then return end local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128) local a = band(shr(ins, 8), 0xff) local oidx = 6*band(ins, 0xff) local op = sub(bcnames, oidx+1, oidx+6) local s if lineinfo then s = format("%04d %7s %s %-6s %3s ", pc, "["..l.."]", prefix or " ", op, ma == 0 and "" or a) else s = format("%04d %s %-6s %3s ", pc, prefix or " ", op, ma == 0 and "" or a) end local d = shr(ins, 16) if mc == 13*128 then -- BCMjump return format("%s=> %04d\n", s, pc+d-0x7fff) end if mb ~= 0 then d = band(d, 0xff) elseif mc == 0 then return s.."\n" end local kc if mc == 10*128 then -- BCMstr kc = funck(func, -d-1) kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) elseif mc == 9*128 then -- BCMnum kc = funck(func, d) if op == "TSETM " then kc = kc - 2^52 end elseif mc == 12*128 then -- BCMfunc local fi = funcinfo(funck(func, -d-1)) if fi.ffid then kc = vmdef.ffnames[fi.ffid] else kc = fi.loc end elseif mc == 5*128 then -- BCMuv kc = funcuvname(func, d) end if ma == 5 then -- BCMuv local ka = funcuvname(func, a) if kc then kc = ka.." ; "..kc else kc = ka end end if mb ~= 0 then local b = shr(ins, 24) if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end return format("%s%3d %3d\n", s, b, d) end if kc then return format("%s%3d ; %s\n", s, d, kc) end if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits return format("%s%3d\n", s, d) end -- Collect branch targets of a function. local function bctargets(func) local target = {} for pc=1,1000000000 do local ins, m = funcbc(func, pc) if not ins then break end if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end end return target end -- Dump bytecode instructions of a function. local function bcdump(func, out, all, lineinfo) if not out then out = stdout end local fi = funcinfo(func) if all and fi.children then for n=-1,-1000000000,-1 do local k = funck(func, n) if not k then break end if type(k) == "proto" then bcdump(k, out, true, lineinfo) end end end out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined)) for n=-1,-1000000000,-1 do local kc = funck(func, n) if not kc then break end local typ = type(kc) if typ == "string" then kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) out:write(format("KGC %d %s\n", -(n + 1), kc)) elseif typ == "proto" then local fi = funcinfo(kc) if fi.ffid then kc = vmdef.ffnames[fi.ffid] else kc = fi.loc end out:write(format("KGC %d %s\n", -(n + 1), kc)) elseif typ == "table" then out:write(format("KGC %d table\n", -(n + 1))) else -- error("unknown KGC type: " .. typ) end end for n=1,1000000000 do local kc = funck(func, n) if not kc then break end if type(kc) == "number" then out:write(format("KN %d %s\n", n, kc)) end end local target = bctargets(func) for pc=1,1000000000 do local s = bcline(func, pc, target[pc] and "=>", lineinfo) if not s then break end out:write(s) end out:write("\n") out:flush() end ------------------------------------------------------------------------------ -- Active flag and output file handle. local active, out -- List handler. local function h_list(func) return bcdump(func, out) end -- Detach list handler. local function bclistoff() if active then active = false jit.attach(h_list) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach list handler. local function bcliston(outfile) if active then bclistoff() end if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stderr end jit.attach(h_list, "bc") active = true end -- Public module functions. return { line = bcline, dump = bcdump, targets = bctargets, on = bcliston, off = bclistoff, start = bcliston -- For -j command line option. } ================================================ FILE: Luajit64/jit/bcsave.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT module to save/list bytecode. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module saves or lists the bytecode for an input file. -- It's run by the -b command line option. -- ------------------------------------------------------------------------------ local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local bit = require("bit") -- Symbol name prefix for LuaJIT bytecode. local LJBC_PREFIX = "luaJIT_BC_" ------------------------------------------------------------------------------ local function usage() io.stderr:write[[ Save LuaJIT bytecode: luajit -b[options] input output -l Only list bytecode. -L Only list bytecode with lineinfo. -s Strip debug info (default). -g Keep debug info. -n name Set module name (default: auto-detect from input name). -t type Set output file type (default: auto-detect from output name). -a arch Override architecture for object files (default: native). -o os Override OS for object files (default: native). -e chunk Use chunk string as input. -- Stop handling options. - Use stdin as input and/or stdout as output. File types: c h obj o raw (default) ]] os.exit(1) end local function check(ok, ...) if ok then return ok, ... end io.stderr:write("luajit: ", ...) io.stderr:write("\n") os.exit(1) end local function readfile(input) if type(input) == "function" then return input end if input == "-" then input = nil end return check(loadfile(input)) end local function savefile(name, mode) if name == "-" then return io.stdout end return check(io.open(name, mode)) end ------------------------------------------------------------------------------ local map_type = { raw = "raw", c = "c", h = "h", o = "obj", obj = "obj", } local map_arch = { x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true, ppc = true, mips = true, mipsel = true, } local map_os = { linux = true, windows = true, osx = true, freebsd = true, netbsd = true, openbsd = true, dragonfly = true, solaris = true, } local function checkarg(str, map, err) str = string.lower(str) local s = check(map[str], "unknown ", err) return s == true and str or s end local function detecttype(str) local ext = string.match(string.lower(str), "%.(%a+)$") return map_type[ext] or "raw" end local function checkmodname(str) check(string.match(str, "^[%w_.%-]+$"), "bad module name") return string.gsub(str, "[%.%-]", "_") end local function detectmodname(str) if type(str) == "string" then local tail = string.match(str, "[^/\\]+$") if tail then str = tail end local head = string.match(str, "^(.*)%.[^.]*$") if head then str = head end str = string.match(str, "^[%w_.%-]+") else str = nil end check(str, "cannot derive module name, use -n name") return string.gsub(str, "[%.%-]", "_") end ------------------------------------------------------------------------------ local function bcsave_tail(fp, output, s) local ok, err = fp:write(s) if ok and output ~= "-" then ok, err = fp:close() end check(ok, "cannot write ", output, ": ", err) end local function bcsave_raw(output, s) local fp = savefile(output, "wb") bcsave_tail(fp, output, s) end local function bcsave_c(ctx, output, s) local fp = savefile(output, "w") if ctx.type == "c" then fp:write(string.format([[ #ifdef _cplusplus extern "C" #endif #ifdef _WIN32 __declspec(dllexport) #endif const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname)) else fp:write(string.format([[ #define %s%s_SIZE %d static const unsigned char %s%s[] = { ]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname)) end local t, n, m = {}, 0, 0 for i=1,#s do local b = tostring(string.byte(s, i)) m = m + #b + 1 if m > 78 then fp:write(table.concat(t, ",", 1, n), ",\n") n, m = 0, #b + 1 end n = n + 1 t[n] = b end bcsave_tail(fp, output, table.concat(t, ",", 1, n).."\n};\n") end local function bcsave_elfobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; uint16_t type, machine; uint32_t version; uint32_t entry, phofs, shofs; uint32_t flags; uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; } ELF32header; typedef struct { uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7]; uint16_t type, machine; uint32_t version; uint64_t entry, phofs, shofs; uint32_t flags; uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx; } ELF64header; typedef struct { uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize; } ELF32sectheader; typedef struct { uint32_t name, type; uint64_t flags, addr, ofs, size; uint32_t link, info; uint64_t align, entsize; } ELF64sectheader; typedef struct { uint32_t name, value, size; uint8_t info, other; uint16_t sectidx; } ELF32symbol; typedef struct { uint32_t name; uint8_t info, other; uint16_t sectidx; uint64_t value, size; } ELF64symbol; typedef struct { ELF32header hdr; ELF32sectheader sect[6]; ELF32symbol sym[2]; uint8_t space[4096]; } ELF32obj; typedef struct { ELF64header hdr; ELF64sectheader sect[6]; ELF64symbol sym[2]; uint8_t space[4096]; } ELF64obj; ]] local symname = LJBC_PREFIX..ctx.modname local is64, isbe = false, false if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then is64 = true elseif ctx.arch == "ppc" or ctx.arch == "mips" then isbe = true end -- Handle different host/target endianess. local function f32(x) return x end local f16, fofs = f32, f32 if ffi.abi("be") ~= isbe then f32 = bit.bswap function f16(x) return bit.rshift(bit.bswap(x), 16) end if is64 then local two32 = ffi.cast("int64_t", 2^32) function fofs(x) return bit.bswap(x)*two32 end else fofs = f32 end end -- Create ELF object and fill in header. local o = ffi.new(is64 and "ELF64obj" or "ELF32obj") local hdr = o.hdr if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi. local bf = assert(io.open("/bin/ls", "rb")) local bs = bf:read(9) bf:close() ffi.copy(o, bs, 9) check(hdr.emagic[0] == 127, "no support for writing native object files") else hdr.emagic = "\127ELF" hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0 end hdr.eclass = is64 and 2 or 1 hdr.eendian = isbe and 2 or 1 hdr.eversion = 1 hdr.type = f16(1) hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch]) if ctx.arch == "mips" or ctx.arch == "mipsel" then hdr.flags = f32(0x50001006) end hdr.version = f32(1) hdr.shofs = fofs(ffi.offsetof(o, "sect")) hdr.ehsize = f16(ffi.sizeof(hdr)) hdr.shentsize = f16(ffi.sizeof(o.sect[0])) hdr.shnum = f16(6) hdr.shstridx = f16(2) -- Fill in sections and symbols. local sofs, ofs = ffi.offsetof(o, "space"), 1 for i,name in ipairs{ ".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack", } do local sect = o.sect[i] sect.align = fofs(1) sect.name = f32(ofs) ffi.copy(o.space+ofs, name) ofs = ofs + #name+1 end o.sect[1].type = f32(2) -- .symtab o.sect[1].link = f32(3) o.sect[1].info = f32(1) o.sect[1].align = fofs(8) o.sect[1].ofs = fofs(ffi.offsetof(o, "sym")) o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0])) o.sect[1].size = fofs(ffi.sizeof(o.sym)) o.sym[1].name = f32(1) o.sym[1].sectidx = f16(4) o.sym[1].size = fofs(#s) o.sym[1].info = 17 o.sect[2].type = f32(3) -- .shstrtab o.sect[2].ofs = fofs(sofs) o.sect[2].size = fofs(ofs) o.sect[3].type = f32(3) -- .strtab o.sect[3].ofs = fofs(sofs + ofs) o.sect[3].size = fofs(#symname+2) ffi.copy(o.space+ofs+1, symname) ofs = ofs + #symname + 2 o.sect[4].type = f32(1) -- .rodata o.sect[4].flags = fofs(2) o.sect[4].ofs = fofs(sofs + ofs) o.sect[4].size = fofs(#s) o.sect[5].type = f32(1) -- .note.GNU-stack o.sect[5].ofs = fofs(sofs + ofs + #s) -- Write ELF object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) bcsave_tail(fp, output, s) end local function bcsave_peobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint16_t arch, nsects; uint32_t time, symtabofs, nsyms; uint16_t opthdrsz, flags; } PEheader; typedef struct { char name[8]; uint32_t vsize, vaddr, size, ofs, relocofs, lineofs; uint16_t nreloc, nline; uint32_t flags; } PEsection; typedef struct __attribute((packed)) { union { char name[8]; uint32_t nameref[2]; }; uint32_t value; int16_t sect; uint16_t type; uint8_t scl, naux; } PEsym; typedef struct __attribute((packed)) { uint32_t size; uint16_t nreloc, nline; uint32_t cksum; uint16_t assoc; uint8_t comdatsel, unused[3]; } PEsymaux; typedef struct { PEheader hdr; PEsection sect[2]; // Must be an even number of symbol structs. PEsym sym0; PEsymaux sym0aux; PEsym sym1; PEsymaux sym1aux; PEsym sym2; PEsym sym3; uint32_t strtabsize; uint8_t space[4096]; } PEobj; ]] local symname = LJBC_PREFIX..ctx.modname local is64 = false if ctx.arch == "x86" then symname = "_"..symname elseif ctx.arch == "x64" then is64 = true end local symexport = " /EXPORT:"..symname..",DATA " -- The file format is always little-endian. Swap if the host is big-endian. local function f32(x) return x end local f16 = f32 if ffi.abi("be") then f32 = bit.bswap function f16(x) return bit.rshift(bit.bswap(x), 16) end end -- Create PE object and fill in header. local o = ffi.new("PEobj") local hdr = o.hdr hdr.arch = f16(({ x86=0x14c, x64=0x8664, arm=0x1c0, ppc=0x1f2, mips=0x366, mipsel=0x366 })[ctx.arch]) hdr.nsects = f16(2) hdr.symtabofs = f32(ffi.offsetof(o, "sym0")) hdr.nsyms = f32(6) -- Fill in sections and symbols. o.sect[0].name = ".drectve" o.sect[0].size = f32(#symexport) o.sect[0].flags = f32(0x00100a00) o.sym0.sect = f16(1) o.sym0.scl = 3 o.sym0.name = ".drectve" o.sym0.naux = 1 o.sym0aux.size = f32(#symexport) o.sect[1].name = ".rdata" o.sect[1].size = f32(#s) o.sect[1].flags = f32(0x40300040) o.sym1.sect = f16(2) o.sym1.scl = 3 o.sym1.name = ".rdata" o.sym1.naux = 1 o.sym1aux.size = f32(#s) o.sym2.sect = f16(2) o.sym2.scl = 2 o.sym2.nameref[1] = f32(4) o.sym3.sect = f16(-1) o.sym3.scl = 2 o.sym3.value = f32(1) o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant. ffi.copy(o.space, symname) local ofs = #symname + 1 o.strtabsize = f32(ofs + 4) o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs) ffi.copy(o.space + ofs, symexport) ofs = ofs + #symexport o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs) -- Write PE object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs)) bcsave_tail(fp, output, s) end local function bcsave_machobj(ctx, output, s, ffi) ffi.cdef[[ typedef struct { uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags; } mach_header; typedef struct { mach_header; uint32_t reserved; } mach_header_64; typedef struct { uint32_t cmd, cmdsize; char segname[16]; uint32_t vmaddr, vmsize, fileoff, filesize; uint32_t maxprot, initprot, nsects, flags; } mach_segment_command; typedef struct { uint32_t cmd, cmdsize; char segname[16]; uint64_t vmaddr, vmsize, fileoff, filesize; uint32_t maxprot, initprot, nsects, flags; } mach_segment_command_64; typedef struct { char sectname[16], segname[16]; uint32_t addr, size; uint32_t offset, align, reloff, nreloc, flags; uint32_t reserved1, reserved2; } mach_section; typedef struct { char sectname[16], segname[16]; uint64_t addr, size; uint32_t offset, align, reloff, nreloc, flags; uint32_t reserved1, reserved2, reserved3; } mach_section_64; typedef struct { uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize; } mach_symtab_command; typedef struct { int32_t strx; uint8_t type, sect; int16_t desc; uint32_t value; } mach_nlist; typedef struct { uint32_t strx; uint8_t type, sect; uint16_t desc; uint64_t value; } mach_nlist_64; typedef struct { uint32_t magic, nfat_arch; } mach_fat_header; typedef struct { uint32_t cputype, cpusubtype, offset, size, align; } mach_fat_arch; typedef struct { struct { mach_header hdr; mach_segment_command seg; mach_section sec; mach_symtab_command sym; } arch[1]; mach_nlist sym_entry; uint8_t space[4096]; } mach_obj; typedef struct { struct { mach_header_64 hdr; mach_segment_command_64 seg; mach_section_64 sec; mach_symtab_command sym; } arch[1]; mach_nlist_64 sym_entry; uint8_t space[4096]; } mach_obj_64; typedef struct { mach_fat_header fat; mach_fat_arch fat_arch[2]; struct { mach_header hdr; mach_segment_command seg; mach_section sec; mach_symtab_command sym; } arch[2]; mach_nlist sym_entry; uint8_t space[4096]; } mach_fat_obj; ]] local symname = '_'..LJBC_PREFIX..ctx.modname local isfat, is64, align, mobj = false, false, 4, "mach_obj" if ctx.arch == "x64" then is64, align, mobj = true, 8, "mach_obj_64" elseif ctx.arch == "arm" then isfat, mobj = true, "mach_fat_obj" elseif ctx.arch == "arm64" then is64, align, isfat, mobj = true, 8, true, "mach_fat_obj" else check(ctx.arch == "x86", "unsupported architecture for OSX") end local function aligned(v, a) return bit.band(v+a-1, -a) end local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE. -- Create Mach-O object and fill in header. local o = ffi.new(mobj) local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align) local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch] local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch] if isfat then o.fat.magic = be32(0xcafebabe) o.fat.nfat_arch = be32(#cpusubtype) end -- Fill in sections and symbols. for i=0,#cpusubtype-1 do local ofs = 0 if isfat then local a = o.fat_arch[i] a.cputype = be32(cputype[i+1]) a.cpusubtype = be32(cpusubtype[i+1]) -- Subsequent slices overlap each other to share data. ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0]) a.offset = be32(ofs) a.size = be32(mach_size-ofs+#s) end local a = o.arch[i] a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface a.hdr.cputype = cputype[i+1] a.hdr.cpusubtype = cpusubtype[i+1] a.hdr.filetype = 1 a.hdr.ncmds = 2 a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym) a.seg.cmd = is64 and 0x19 or 0x1 a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec) a.seg.vmsize = #s a.seg.fileoff = mach_size-ofs a.seg.filesize = #s a.seg.maxprot = 1 a.seg.initprot = 1 a.seg.nsects = 1 ffi.copy(a.sec.sectname, "__data") ffi.copy(a.sec.segname, "__DATA") a.sec.size = #s a.sec.offset = mach_size-ofs a.sym.cmd = 2 a.sym.cmdsize = ffi.sizeof(a.sym) a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs a.sym.nsyms = 1 a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs a.sym.strsize = aligned(#symname+2, align) end o.sym_entry.type = 0xf o.sym_entry.sect = 1 o.sym_entry.strx = 1 ffi.copy(o.space+1, symname) -- Write Macho-O object file. local fp = savefile(output, "wb") fp:write(ffi.string(o, mach_size)) bcsave_tail(fp, output, s) end local function bcsave_obj(ctx, output, s) local ok, ffi = pcall(require, "ffi") check(ok, "FFI library required to write this file type") if ctx.os == "windows" then return bcsave_peobj(ctx, output, s, ffi) elseif ctx.os == "osx" then return bcsave_machobj(ctx, output, s, ffi) else return bcsave_elfobj(ctx, output, s, ffi) end end ------------------------------------------------------------------------------ local function bclist(input, output, lineinfo) local f = readfile(input) require("jit.bc").dump(f, savefile(output, "w"), true, lineinfo) end local function bcsave(ctx, input, output) local f = readfile(input) local s = string.dump(f, ctx.strip) local t = ctx.type if not t then t = detecttype(output) ctx.type = t end if t == "raw" then bcsave_raw(output, s) else if not ctx.modname then ctx.modname = detectmodname(input) end if t == "obj" then bcsave_obj(ctx, output, s) else bcsave_c(ctx, output, s) end end end local function docmd(...) local arg = {...} local n = 1 local list = false local lineinfo = false local ctx = { strip = true, arch = jit.arch, os = string.lower(jit.os), type = false, modname = false, } while n <= #arg do local a = arg[n] if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then table.remove(arg, n) if a == "--" then break end for m=2,#a do local opt = string.sub(a, m, m) if opt == "l" then list = true elseif opt == "L" then list = true lineinfo = true elseif opt == "s" then ctx.strip = true elseif opt == "g" then ctx.strip = false else if arg[n] == nil or m ~= #a then usage() end if opt == "e" then if n ~= 1 then usage() end arg[1] = check(loadstring(arg[1])) elseif opt == "n" then ctx.modname = checkmodname(table.remove(arg, n)) elseif opt == "t" then ctx.type = checkarg(table.remove(arg, n), map_type, "file type") elseif opt == "a" then ctx.arch = checkarg(table.remove(arg, n), map_arch, "architecture") elseif opt == "o" then ctx.os = checkarg(table.remove(arg, n), map_os, "OS name") else usage() end end end else n = n + 1 end end if list then if #arg == 0 or #arg > 2 then usage() end bclist(arg[1], arg[2] or "-", lineinfo) else if #arg ~= 2 then usage() end bcsave(ctx, arg[1], arg[2]) end end ------------------------------------------------------------------------------ -- Public module functions. return { start = docmd -- Process -b command line option. } ================================================ FILE: Luajit64/jit/dis_arm.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles most user-mode ARMv7 instructions -- NYI: Advanced SIMD and VFP instructions. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Opcode maps ------------------------------------------------------------------------------ local map_loadc = { shift = 8, mask = 15, [10] = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "vmovFmDN", "vstmFNdr", _ = { shift = 21, mask = 1, [0] = "vstrFdl", { shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", } }, }, { shift = 23, mask = 3, [0] = "vmovFDNm", { shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", }, _ = { shift = 21, mask = 1, [0] = "vldrFdl", "vldmdbFNdr", }, }, }, [11] = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "vmovGmDN", "vstmGNdr", _ = { shift = 21, mask = 1, [0] = "vstrGdl", { shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", } }, }, { shift = 23, mask = 3, [0] = "vmovGDNm", { shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", }, _ = { shift = 21, mask = 1, [0] = "vldrGdl", "vldmdbGNdr", }, }, }, _ = { shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc. }, } local map_vfps = { shift = 6, mask = 0x2c001, [0] = "vmlaF.dnm", "vmlsF.dnm", [0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm", [0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm", [0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm", [0x20000] = "vdivF.dnm", [0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm", [0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm", [0x2c000] = "vmovF.dY", [0x2c001] = { shift = 7, mask = 0x1e01, [0] = "vmovF.dm", "vabsF.dm", [0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm", [0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm", [0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d", [0x0e01] = "vcvtG.dF.m", [0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm", [0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm", [0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm", }, } local map_vfpd = { shift = 6, mask = 0x2c001, [0] = "vmlaG.dnm", "vmlsG.dnm", [0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm", [0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm", [0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm", [0x20000] = "vdivG.dnm", [0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm", [0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm", [0x2c000] = "vmovG.dY", [0x2c001] = { shift = 7, mask = 0x1e01, [0] = "vmovG.dm", "vabsG.dm", [0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm", [0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm", [0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d", [0x0e01] = "vcvtF.dG.m", [0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm", [0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m", [0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m", }, } local map_datac = { shift = 24, mask = 1, [0] = { shift = 4, mask = 1, [0] = { shift = 8, mask = 15, [10] = map_vfps, [11] = map_vfpd, -- NYI cdp, mcr, mrc. }, { shift = 8, mask = 15, [10] = { shift = 20, mask = 15, [0] = "vmovFnD", "vmovFDn", [14] = "vmsrD", [15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", }, }, }, }, "svcT", } local map_loadcu = { shift = 0, mask = 0, -- NYI unconditional CP load/store. } local map_datacu = { shift = 0, mask = 0, -- NYI unconditional CP data. } local map_simddata = { shift = 0, mask = 0, -- NYI SIMD data. } local map_simdload = { shift = 0, mask = 0, -- NYI SIMD load/store, preload. } local map_preload = { shift = 0, mask = 0, -- NYI preload. } local map_media = { shift = 20, mask = 31, [0] = false, { --01 shift = 5, mask = 7, [0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM", "sadd8DNM", false, false, "ssub8DNM", }, { --02 shift = 5, mask = 7, [0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM", "qadd8DNM", false, false, "qsub8DNM", }, { --03 shift = 5, mask = 7, [0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM", "shadd8DNM", false, false, "shsub8DNM", }, false, { --05 shift = 5, mask = 7, [0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM", "uadd8DNM", false, false, "usub8DNM", }, { --06 shift = 5, mask = 7, [0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM", "uqadd8DNM", false, false, "uqsub8DNM", }, { --07 shift = 5, mask = 7, [0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM", "uhadd8DNM", false, false, "uhsub8DNM", }, { --08 shift = 5, mask = 7, [0] = "pkhbtDNMU", false, "pkhtbDNMU", { shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", }, "pkhbtDNMU", "selDNM", "pkhtbDNMU", }, false, { --0a shift = 5, mask = 7, [0] = "ssatDxMu", "ssat16DxM", "ssatDxMu", { shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", }, "ssatDxMu", false, "ssatDxMu", }, { --0b shift = 5, mask = 7, [0] = "ssatDxMu", "revDM", "ssatDxMu", { shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", }, "ssatDxMu", "rev16DM", "ssatDxMu", }, { --0c shift = 5, mask = 7, [3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", }, }, false, { --0e shift = 5, mask = 7, [0] = "usatDwMu", "usat16DwM", "usatDwMu", { shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", }, "usatDwMu", false, "usatDwMu", }, { --0f shift = 5, mask = 7, [0] = "usatDwMu", "rbitDM", "usatDwMu", { shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", }, "usatDwMu", "revshDM", "usatDwMu", }, { --10 shift = 12, mask = 15, [15] = { shift = 5, mask = 7, "smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS", }, _ = { shift = 5, mask = 7, [0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD", }, }, false, false, false, { --14 shift = 5, mask = 7, [0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS", }, { --15 shift = 5, mask = 7, [0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", }, { shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", }, false, false, false, false, "smmlsNMSD", "smmlsrNMSD", }, false, false, { --18 shift = 5, mask = 7, [0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", }, }, false, { --1a shift = 5, mask = 3, [2] = "sbfxDMvw", }, { --1b shift = 5, mask = 3, [2] = "sbfxDMvw", }, { --1c shift = 5, mask = 3, [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, }, { --1d shift = 5, mask = 3, [0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", }, }, { --1e shift = 5, mask = 3, [2] = "ubfxDMvw", }, { --1f shift = 5, mask = 3, [2] = "ubfxDMvw", }, } local map_load = { shift = 21, mask = 9, { shift = 20, mask = 5, [0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL", }, _ = { shift = 20, mask = 5, [0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL", } } local map_load1 = { shift = 4, mask = 1, [0] = map_load, map_media, } local map_loadm = { shift = 20, mask = 1, [0] = { shift = 23, mask = 3, [0] = "stmdaNR", "stmNR", { shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR", }, { shift = 23, mask = 3, [0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", }, "ldmdbNR", "ldmibNR", }, } local map_data = { shift = 21, mask = 15, [0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs", "addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs", "tstNP", "teqNP", "cmpNP", "cmnNP", "orrDNPs", "movDPs", "bicDNPs", "mvnDPs", } local map_mul = { shift = 21, mask = 7, [0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS", "umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs", } local map_sync = { shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd. [0] = "swpDMN", false, false, false, "swpbDMN", false, false, false, "strexDMN", "ldrexDN", "strexdDN", "ldrexdDN", "strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN", } local map_mulh = { shift = 21, mask = 3, [0] = { shift = 5, mask = 3, [0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", }, { shift = 5, mask = 3, [0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", }, { shift = 5, mask = 3, [0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", }, { shift = 5, mask = 3, [0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", }, } local map_misc = { shift = 4, mask = 7, -- NYI: decode PSR bits of msr. [0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", }, { shift = 21, mask = 3, "bxM", false, "clzDM", }, { shift = 21, mask = 3, "bxjM", }, { shift = 21, mask = 3, "blxM", }, false, { shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", }, false, { shift = 21, mask = 3, "bkptK", }, } local map_datar = { shift = 4, mask = 9, [9] = { shift = 5, mask = 3, [0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, }, { shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", }, { shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", }, { shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", }, }, _ = { shift = 20, mask = 25, [16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, }, _ = { shift = 0, mask = 0xffffffff, [bor(0xe1a00000)] = "nop", _ = map_data, } }, } local map_datai = { shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12. [16] = "movwDW", [20] = "movtDW", [18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", }, [22] = "msrNW", _ = map_data, } local map_branch = { shift = 24, mask = 1, [0] = "bB", "blB" } local map_condins = { [0] = map_datar, map_datai, map_load, map_load1, map_loadm, map_branch, map_loadc, map_datac } -- NYI: setend. local map_uncondins = { [0] = false, map_simddata, map_simdload, map_preload, false, "blxB", map_loadcu, map_datacu, } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", } local map_cond = { [0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al", } local map_shift = { [0] = "lsl", "lsr", "asr", "ror", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then extra = "\t; 0x"..tohex(ctx.rel) end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-5s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-5s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end -- Format operand 2 of load/store opcodes. local function fmtload(ctx, op, pos) local base = map_gpr[band(rshift(op, 16), 15)] local x, ofs local ext = (band(op, 0x04000000) == 0) if not ext and band(op, 0x02000000) == 0 then ofs = band(op, 4095) if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end ofs = "#"..ofs elseif ext and band(op, 0x00400000) ~= 0 then ofs = band(op, 15) + band(rshift(op, 4), 0xf0) if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end ofs = "#"..ofs else ofs = map_gpr[band(op, 15)] if ext or band(op, 0xfe0) == 0 then elseif band(op, 0xfe0) == 0x60 then ofs = format("%s, rrx", ofs) else local sh = band(rshift(op, 7), 31) if sh == 0 then sh = 32 end ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh) end if band(op, 0x00800000) == 0 then ofs = "-"..ofs end end if ofs == "#0" then x = format("[%s]", base) elseif band(op, 0x01000000) == 0 then x = format("[%s], %s", base, ofs) else x = format("[%s, %s]", base, ofs) end if band(op, 0x01200000) == 0x01200000 then x = x.."!" end return x end -- Format operand 2 of vector load/store opcodes. local function fmtvload(ctx, op, pos) local base = map_gpr[band(rshift(op, 16), 15)] local ofs = band(op, 255)*4 if band(op, 0x00800000) == 0 then ofs = -ofs end if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end if ofs == 0 then return format("[%s]", base) else return format("[%s, #%d]", base, ofs) end end local function fmtvr(op, vr, sh0, sh1) if vr == "s" then return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1)) else return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16)) end end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) local operands = {} local suffix = "" local last, name, pat local vr ctx.op = op ctx.rel = nil local cond = rshift(op, 28) local opat if cond == 15 then opat = map_uncondins[band(rshift(op, 25), 7)] else if cond ~= 14 then suffix = map_cond[cond] end opat = map_condins[band(rshift(op, 25), 7)] end while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end name, pat = match(opat, "^([a-z0-9]*)(.*)") if sub(pat, 1, 1) == "." then local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") suffix = suffix..s2 pat = p2 end for p in gmatch(pat, ".") do local x = nil if p == "D" then x = map_gpr[band(rshift(op, 12), 15)] elseif p == "N" then x = map_gpr[band(rshift(op, 16), 15)] elseif p == "S" then x = map_gpr[band(rshift(op, 8), 15)] elseif p == "M" then x = map_gpr[band(op, 15)] elseif p == "d" then x = fmtvr(op, vr, 12, 22) elseif p == "n" then x = fmtvr(op, vr, 16, 7) elseif p == "m" then x = fmtvr(op, vr, 0, 5) elseif p == "P" then if band(op, 0x02000000) ~= 0 then x = ror(band(op, 255), 2*band(rshift(op, 8), 15)) else x = map_gpr[band(op, 15)] if band(op, 0xff0) ~= 0 then operands[#operands+1] = x local s = map_shift[band(rshift(op, 5), 3)] local r = nil if band(op, 0xf90) == 0 then if s == "ror" then s = "rrx" else r = "#32" end elseif band(op, 0x10) == 0 then r = "#"..band(rshift(op, 7), 31) else r = map_gpr[band(rshift(op, 8), 15)] end if name == "mov" then name = s; x = r elseif r then x = format("%s %s", s, r) else x = s end end end elseif p == "L" then x = fmtload(ctx, op, pos) elseif p == "l" then x = fmtvload(ctx, op, pos) elseif p == "B" then local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6) if cond == 15 then addr = addr + band(rshift(op, 23), 2) end ctx.rel = addr x = "0x"..tohex(addr) elseif p == "F" then vr = "s" elseif p == "G" then vr = "d" elseif p == "." then suffix = suffix..(vr == "s" and ".f32" or ".f64") elseif p == "R" then if band(op, 0x00200000) ~= 0 and #operands == 1 then operands[1] = operands[1].."!" end local t = {} for i=0,15 do if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end end x = "{"..concat(t, ", ").."}" elseif p == "r" then if band(op, 0x00200000) ~= 0 and #operands == 2 then operands[1] = operands[1].."!" end local s = tonumber(sub(last, 2)) local n = band(op, 255) if vr == "d" then n = rshift(n, 1) end operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1) elseif p == "W" then x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000) elseif p == "T" then x = "#0x"..tohex(band(op, 0x00ffffff), 6) elseif p == "U" then x = band(rshift(op, 7), 31) if x == 0 then x = nil end elseif p == "u" then x = band(rshift(op, 7), 31) if band(op, 0x40) == 0 then if x == 0 then x = nil else x = "lsl #"..x end else if x == 0 then x = "asr #32" else x = "asr #"..x end end elseif p == "v" then x = band(rshift(op, 7), 31) elseif p == "w" then x = band(rshift(op, 16), 31) elseif p == "x" then x = band(rshift(op, 16), 31) + 1 elseif p == "X" then x = band(rshift(op, 16), 31) - last + 1 elseif p == "Y" then x = band(rshift(op, 12), 0xf0) + band(op, 0x0f) elseif p == "K" then x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4) elseif p == "s" then if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end else assert(false) end if x then last = x if type(x) == "number" then x = "#"..x end operands[#operands+1] = x end end return putop(ctx, name..suffix, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ctx.pos = ofs ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 16 then return map_gpr[r] end return "d"..(r-16) end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Luajit64/jit/dis_arm64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM64 disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h -- -- Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com. -- Sponsored by Cisco Systems, Inc. ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles most user-mode AArch64 instructions. -- NYI: Advanced SIMD and VFP instructions. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") local band, bor, bxor, tohex = bit.band, bit.bor, bit.bxor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift local ror = bit.ror ------------------------------------------------------------------------------ -- Opcode maps ------------------------------------------------------------------------------ local map_adr = { -- PC-relative addressing. shift = 31, mask = 1, [0] = "adrDBx", "adrpDBx" } local map_addsubi = { -- Add/subtract immediate. shift = 29, mask = 3, [0] = "add|movDNIg", "adds|cmnD0NIg", "subDNIg", "subs|cmpD0NIg", } local map_logi = { -- Logical immediate. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig" }, false -- unallocated }, { shift = 29, mask = 3, [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig" } } local map_movwi = { -- Move wide immediate. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg" }, false -- unallocated }, { shift = 29, mask = 3, [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg" }, } local map_bitf = { -- Bitfield. shift = 31, mask = 1, [0] = { shift = 22, mask = 1, [0] = { shift = 29, mask = 3, [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12w", "bfm|bfi|bfxilDN13w", "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12w" } }, { shift = 22, mask = 1, { shift = 29, mask = 3, [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12x", "bfm|bfi|bfxilDN13x", "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12x" } } } local map_datai = { -- Data processing - immediate. shift = 23, mask = 7, [0] = map_adr, map_adr, map_addsubi, false, map_logi, map_movwi, map_bitf, { shift = 15, mask = 0x1c0c1, [0] = "extr|rorDNM4w", [0x10080] = "extr|rorDNM4x", [0x10081] = "extr|rorDNM4x" } } local map_logsr = { -- Logical, shifted register. shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 29, mask = 3, [0] = { shift = 21, mask = 7, [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg" }, { shift = 21, mask = 7, [0] ="orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg" }, { shift = 21, mask = 7, [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg" }, { shift = 21, mask = 7, [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg" } }, false -- unallocated }, { shift = 29, mask = 3, [0] = { shift = 21, mask = 7, [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg" }, { shift = 21, mask = 7, [0] = "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg" }, { shift = 21, mask = 7, [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg" }, { shift = 21, mask = 7, [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg" } } } local map_assh = { shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 29, mask = 3, [0] = { shift = 22, mask = 3, [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg" }, { shift = 22, mask = 3, [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMg" }, { shift = 22, mask = 3, [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg" }, { shift = 22, mask = 3, [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg" }, }, false -- unallocated }, { shift = 29, mask = 3, [0] = { shift = 22, mask = 3, [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg" }, { shift = 22, mask = 3, [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMg" }, { shift = 22, mask = 3, [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg" }, { shift = 22, mask = 3, [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg" } } } local map_addsubsh = { -- Add/subtract, shifted register. shift = 22, mask = 3, [0] = map_assh, map_assh, map_assh } local map_addsubex = { -- Add/subtract, extended register. shift = 22, mask = 3, [0] = { shift = 29, mask = 3, [0] = "addDNMXg", "adds|cmnD0NMXg", "subDNMXg", "subs|cmpD0NMzXg", } } local map_addsubc = { -- Add/subtract, with carry. shift = 10, mask = 63, [0] = { shift = 29, mask = 3, [0] = "adcDNMg", "adcsDNMg", "sbc|ngcDN0Mg", "sbcs|ngcsDN0Mg", } } local map_ccomp = { shift = 4, mask = 1, [0] = { shift = 10, mask = 3, [0] = { -- Conditional compare register. shift = 29, mask = 3, "ccmnNMVCg", false, "ccmpNMVCg", }, [2] = { -- Conditional compare immediate. shift = 29, mask = 3, "ccmnN5VCg", false, "ccmpN5VCg", } } } local map_csel = { -- Conditional select. shift = 11, mask = 1, [0] = { shift = 10, mask = 1, [0] = { shift = 29, mask = 3, [0] = "cselDNMzCg", false, "csinv|cinv|csetmDNMcg", false, }, { shift = 29, mask = 3, [0] = "csinc|cinc|csetDNMcg", false, "csneg|cnegDNMcg", false, } } } local map_data1s = { -- Data processing, 1 source. shift = 29, mask = 1, [0] = { shift = 31, mask = 1, [0] = { shift = 10, mask = 0x7ff, [0] = "rbitDNg", "rev16DNg", "revDNw", false, "clzDNg", "clsDNg" }, { shift = 10, mask = 0x7ff, [0] = "rbitDNg", "rev16DNg", "rev32DNx", "revDNx", "clzDNg", "clsDNg" } } } local map_data2s = { -- Data processing, 2 sources. shift = 29, mask = 1, [0] = { shift = 10, mask = 63, false, "udivDNMg", "sdivDNMg", false, false, false, false, "lslDNMg", "lsrDNMg", "asrDNMg", "rorDNMg" } } local map_data3s = { -- Data processing, 3 sources. shift = 29, mask = 7, [0] = { shift = 21, mask = 7, [0] = { shift = 15, mask = 1, [0] = "madd|mulDNMA0g", "msub|mnegDNMA0g" } }, false, false, false, { shift = 15, mask = 1, [0] = { shift = 21, mask = 7, [0] = "madd|mulDNMA0g", "smaddl|smullDxNMwA0x", "smulhDNMx", false, false, "umaddl|umullDxNMwA0x", "umulhDNMx" }, { shift = 21, mask = 7, [0] = "msub|mnegDNMA0g", "smsubl|smneglDxNMwA0x", false, false, false, "umsubl|umneglDxNMwA0x" } } } local map_datar = { -- Data processing, register. shift = 28, mask = 1, [0] = { shift = 24, mask = 1, [0] = map_logsr, { shift = 21, mask = 1, [0] = map_addsubsh, map_addsubex } }, { shift = 21, mask = 15, [0] = map_addsubc, false, map_ccomp, false, map_csel, false, { shift = 30, mask = 1, [0] = map_data2s, map_data1s }, false, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s } } local map_lrl = { -- Load register, literal. shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = "ldrDwB", "ldrDxB", "ldrswDxB" }, { shift = 30, mask = 3, [0] = "ldrDsB", "ldrDdB" } } local map_lsriind = { -- Load/store register, immediate pre/post-indexed. shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strbDwzL", "ldrbDwzL", "ldrsbDxzL", "ldrsbDwzL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strhDwzL", "ldrhDwzL", "ldrshDxzL", "ldrshDwzL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strDwzL", "ldrDwzL", "ldrswDxzL" }, { shift = 22, mask = 3, [0] = "strDszL", "ldrDszL" } }, { shift = 26, mask = 1, [0] = { shift = 22, mask = 3, [0] = "strDxzL", "ldrDxzL" }, { shift = 22, mask = 3, [0] = "strDdzL", "ldrDdzL" } } } local map_lsriro = { shift = 21, mask = 1, [0] = { -- Load/store register immediate. shift = 10, mask = 3, [0] = { -- Unscaled immediate. shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "sturbDwK", "ldurbDwK" }, { shift = 22, mask = 3, [0] = "sturhDwK", "ldurhDwK" }, { shift = 22, mask = 3, [0] = "sturDwK", "ldurDwK" }, { shift = 22, mask = 3, [0] = "sturDxK", "ldurDxK" } } }, map_lsriind, false, map_lsriind }, { -- Load/store register, register offset. shift = 10, mask = 3, [2] = { shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "strbDwO", "ldrbDwO", "ldrsbDxO", "ldrsbDwO" }, { shift = 22, mask = 3, [0] = "strhDwO", "ldrhDwO", "ldrshDxO", "ldrshDwO" }, { shift = 22, mask = 3, [0] = "strDwO", "ldrDwO", "ldrswDxO" }, { shift = 22, mask = 3, [0] = "strDxO", "ldrDxO" } }, { shift = 30, mask = 3, [2] = { shift = 22, mask = 3, [0] = "strDsO", "ldrDsO" }, [3] = { shift = 22, mask = 3, [0] = "strDdO", "ldrDdO" } } } } } local map_lsp = { -- Load/store register pair, offset. shift = 22, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = "stpDzAzwP", "stpDzAzsP", }, { shift = 26, mask = 1, "stpDzAzdP" }, { shift = 26, mask = 1, [0] = "stpDzAzxP" } }, { shift = 30, mask = 3, [0] = { shift = 26, mask = 1, [0] = "ldpDzAzwP", "ldpDzAzsP", }, { shift = 26, mask = 1, [0] = "ldpswDAxP", "ldpDzAzdP" }, { shift = 26, mask = 1, [0] = "ldpDzAzxP" } } } local map_ls = { -- Loads and stores. shift = 24, mask = 0x31, [0x10] = map_lrl, [0x30] = map_lsriro, [0x20] = { shift = 23, mask = 3, map_lsp, map_lsp, map_lsp }, [0x21] = { shift = 23, mask = 3, map_lsp, map_lsp, map_lsp }, [0x31] = { shift = 26, mask = 1, [0] = { shift = 30, mask = 3, [0] = { shift = 22, mask = 3, [0] = "strbDwzU", "ldrbDwzU" }, { shift = 22, mask = 3, [0] = "strhDwzU", "ldrhDwzU" }, { shift = 22, mask = 3, [0] = "strDwzU", "ldrDwzU" }, { shift = 22, mask = 3, [0] = "strDxzU", "ldrDxzU" } }, { shift = 30, mask = 3, [2] = { shift = 22, mask = 3, [0] = "strDszU", "ldrDszU" }, [3] = { shift = 22, mask = 3, [0] = "strDdzU", "ldrDdzU" } } }, } local map_datafp = { -- Data processing, SIMD and FP. shift = 28, mask = 7, { -- 001 shift = 24, mask = 1, [0] = { shift = 21, mask = 1, { shift = 10, mask = 3, [0] = { shift = 12, mask = 1, [0] = { shift = 13, mask = 1, [0] = { shift = 14, mask = 1, [0] = { shift = 15, mask = 1, [0] = { -- FP/int conversion. shift = 31, mask = 1, [0] = { shift = 16, mask = 0xff, [0x20] = "fcvtnsDwNs", [0x21] = "fcvtnuDwNs", [0x22] = "scvtfDsNw", [0x23] = "ucvtfDsNw", [0x24] = "fcvtasDwNs", [0x25] = "fcvtauDwNs", [0x26] = "fmovDwNs", [0x27] = "fmovDsNw", [0x28] = "fcvtpsDwNs", [0x29] = "fcvtpuDwNs", [0x30] = "fcvtmsDwNs", [0x31] = "fcvtmuDwNs", [0x38] = "fcvtzsDwNs", [0x39] = "fcvtzuDwNs", [0x60] = "fcvtnsDwNd", [0x61] = "fcvtnuDwNd", [0x62] = "scvtfDdNw", [0x63] = "ucvtfDdNw", [0x64] = "fcvtasDwNd", [0x65] = "fcvtauDwNd", [0x68] = "fcvtpsDwNd", [0x69] = "fcvtpuDwNd", [0x70] = "fcvtmsDwNd", [0x71] = "fcvtmuDwNd", [0x78] = "fcvtzsDwNd", [0x79] = "fcvtzuDwNd" }, { shift = 16, mask = 0xff, [0x20] = "fcvtnsDxNs", [0x21] = "fcvtnuDxNs", [0x22] = "scvtfDsNx", [0x23] = "ucvtfDsNx", [0x24] = "fcvtasDxNs", [0x25] = "fcvtauDxNs", [0x28] = "fcvtpsDxNs", [0x29] = "fcvtpuDxNs", [0x30] = "fcvtmsDxNs", [0x31] = "fcvtmuDxNs", [0x38] = "fcvtzsDxNs", [0x39] = "fcvtzuDxNs", [0x60] = "fcvtnsDxNd", [0x61] = "fcvtnuDxNd", [0x62] = "scvtfDdNx", [0x63] = "ucvtfDdNx", [0x64] = "fcvtasDxNd", [0x65] = "fcvtauDxNd", [0x66] = "fmovDxNd", [0x67] = "fmovDdNx", [0x68] = "fcvtpsDxNd", [0x69] = "fcvtpuDxNd", [0x70] = "fcvtmsDxNd", [0x71] = "fcvtmuDxNd", [0x78] = "fcvtzsDxNd", [0x79] = "fcvtzuDxNd" } } }, { -- FP data-processing, 1 source. shift = 31, mask = 1, [0] = { shift = 22, mask = 3, [0] = { shift = 15, mask = 63, [0] = "fmovDNf", "fabsDNf", "fnegDNf", "fsqrtDNf", false, "fcvtDdNs", false, false, "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf", "frintaDNf", false, "frintxDNf", "frintiDNf", }, { shift = 15, mask = 63, [0] = "fmovDNf", "fabsDNf", "fnegDNf", "fsqrtDNf", "fcvtDsNd", false, false, false, "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf", "frintaDNf", false, "frintxDNf", "frintiDNf", } } } }, { -- FP compare. shift = 31, mask = 1, [0] = { shift = 14, mask = 3, [0] = { shift = 23, mask = 1, [0] = { shift = 0, mask = 31, [0] = "fcmpNMf", [8] = "fcmpNZf", [16] = "fcmpeNMf", [24] = "fcmpeNZf", } } } } }, { -- FP immediate. shift = 31, mask = 1, [0] = { shift = 5, mask = 31, [0] = { shift = 23, mask = 1, [0] = "fmovDFf" } } } }, { -- FP conditional compare. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = { shift = 4, mask = 1, [0] = "fccmpNMVCf", "fccmpeNMVCf" } } }, { -- FP data-processing, 2 sources. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = { shift = 12, mask = 15, [0] = "fmulDNMf", "fdivDNMf", "faddDNMf", "fsubDNMf", "fmaxDNMf", "fminDNMf", "fmaxnmDNMf", "fminnmDNMf", "fnmulDNMf" } } }, { -- FP conditional select. shift = 31, mask = 1, [0] = { shift = 23, mask = 1, [0] = "fcselDNMCf" } } } }, { -- FP data-processing, 3 sources. shift = 31, mask = 1, [0] = { shift = 15, mask = 1, [0] = { shift = 21, mask = 5, [0] = "fmaddDNMAf", "fnmaddDNMAf" }, { shift = 21, mask = 5, [0] = "fmsubDNMAf", "fnmsubDNMAf" } } } } } local map_br = { -- Branches, exception generating and system instructions. shift = 29, mask = 7, [0] = "bB", { -- Compare & branch, immediate. shift = 24, mask = 3, [0] = "cbzDBg", "cbnzDBg", "tbzDTBw", "tbnzDTBw" }, { -- Conditional branch, immediate. shift = 24, mask = 3, [0] = { shift = 4, mask = 1, [0] = { shift = 0, mask = 15, [0] = "beqB", "bneB", "bhsB", "bloB", "bmiB", "bplB", "bvsB", "bvcB", "bhiB", "blsB", "bgeB", "bltB", "bgtB", "bleB", "balB" } } }, false, "blB", { -- Compare & branch, immediate. shift = 24, mask = 3, [0] = "cbzDBg", "cbnzDBg", "tbzDTBx", "tbnzDTBx" }, { shift = 24, mask = 3, [0] = { -- Exception generation. shift = 0, mask = 0xe0001f, [0x200000] = "brkW" }, { -- System instructions. shift = 0, mask = 0x3fffff, [0x03201f] = "nop" }, { -- Unconditional branch, register. shift = 0, mask = 0xfffc1f, [0x1f0000] = "brNx", [0x3f0000] = "blrNx", [0x5f0000] = "retNx" }, } } local map_init = { shift = 25, mask = 15, [0] = false, false, false, false, map_ls, map_datar, map_ls, map_datafp, map_datai, map_datai, map_br, map_br, map_ls, map_datar, map_ls, map_datafp } ------------------------------------------------------------------------------ local map_regs = { x = {}, w = {}, d = {}, s = {} } for i=0,30 do map_regs.x[i] = "x"..i map_regs.w[i] = "w"..i map_regs.d[i] = "d"..i map_regs.s[i] = "s"..i end map_regs.x[31] = "sp" map_regs.w[31] = "wsp" map_regs.d[31] = "d31" map_regs.s[31] = "s31" local map_cond = { [0] = "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al", } local map_shift = { [0] = "lsl", "lsr", "asr", } local map_extend = { [0] = "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-5s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-5s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end local function match_reg(p, pat, regnum) return map_regs[match(pat, p.."%w-([xwds])")][regnum] end local function fmt_hex32(x) if x < 0 then return tohex(x) else return format("%x", x) end end local imm13_rep = { 0x55555555, 0x11111111, 0x01010101, 0x00010001, 0x00000001 } local function decode_imm13(op) local imms = band(rshift(op, 10), 63) local immr = band(rshift(op, 16), 63) if band(op, 0x00400000) == 0 then local len = 5 if imms >= 56 then if imms >= 60 then len = 1 else len = 2 end elseif imms >= 48 then len = 3 elseif imms >= 32 then len = 4 end local l = lshift(1, len)-1 local s = band(imms, l) local r = band(immr, l) local imm = ror(rshift(-1, 31-s), r) if len ~= 5 then imm = band(imm, lshift(1, l)-1) + rshift(imm, 31-l) end imm = imm * imm13_rep[len] local ix = fmt_hex32(imm) if rshift(op, 31) ~= 0 then return ix..tohex(imm) else return ix end else local lo, hi = -1, 0 if imms < 32 then lo = rshift(-1, 31-imms) else hi = rshift(-1, 63-imms) end if immr ~= 0 then lo, hi = ror(lo, immr), ror(hi, immr) local x = immr == 32 and 0 or band(bxor(lo, hi), lshift(-1, 32-immr)) lo, hi = bxor(lo, x), bxor(hi, x) if immr >= 32 then lo, hi = hi, lo end end if hi ~= 0 then return fmt_hex32(hi)..tohex(lo) else return fmt_hex32(lo) end end end local function parse_immpc(op, name) if name == "b" or name == "bl" then return arshift(lshift(op, 6), 4) elseif name == "adr" or name == "adrp" then local immlo = band(rshift(op, 29), 3) local immhi = lshift(arshift(lshift(op, 8), 13), 2) return bor(immhi, immlo) elseif name == "tbz" or name == "tbnz" then return lshift(arshift(lshift(op, 13), 18), 2) else return lshift(arshift(lshift(op, 8), 13), 2) end end local function parse_fpimm8(op) local sign = band(op, 0x100000) == 0 and 1 or -1 local exp = bxor(rshift(arshift(lshift(op, 12), 5), 24), 0x80) - 131 local frac = 16+band(rshift(op, 13), 15) return sign * frac * 2^exp end local function prefer_bfx(sf, uns, imms, immr) if imms < immr or imms == 31 or imms == 63 then return false end if immr == 0 then if sf == 0 and (imms == 7 or imms == 15) then return false end if sf ~= 0 and uns == 0 and (imms == 7 or imms == 15 or imms == 31) then return false end end return true end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) local operands = {} local suffix = "" local last, name, pat local map_reg ctx.op = op ctx.rel = nil last = nil local opat opat = map_init[band(rshift(op, 25), 15)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end name, pat = match(opat, "^([a-z0-9]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") if altname then pat = pat2 end if sub(pat, 1, 1) == "." then local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)") suffix = suffix..s2 pat = p2 end local rt = match(pat, "[gf]") if rt then if rt == "g" then map_reg = band(op, 0x80000000) ~= 0 and map_regs.x or map_regs.w else map_reg = band(op, 0x400000) ~= 0 and map_regs.d or map_regs.s end end local second0, immr for p in gmatch(pat, ".") do local x = nil if p == "D" then local regnum = band(op, 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "N" then local regnum = band(rshift(op, 5), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "M" then local regnum = band(rshift(op, 16), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "A" then local regnum = band(rshift(op, 10), 31) x = rt and map_reg[regnum] or match_reg(p, pat, regnum) elseif p == "B" then local addr = ctx.addr + pos + parse_immpc(op, name) ctx.rel = addr x = "0x"..tohex(addr) elseif p == "T" then x = bor(band(rshift(op, 26), 32), band(rshift(op, 19), 31)) elseif p == "V" then x = band(op, 15) elseif p == "C" then x = map_cond[band(rshift(op, 12), 15)] elseif p == "c" then local rn = band(rshift(op, 5), 31) local rm = band(rshift(op, 16), 31) local cond = band(rshift(op, 12), 15) local invc = bxor(cond, 1) x = map_cond[cond] if altname and cond ~= 14 and cond ~= 15 then local a1, a2 = match(altname, "([^|]*)|(.*)") if rn == rm then local n = #operands operands[n] = nil x = map_cond[invc] if rn ~= 31 then if a1 then name = a1 else name = altname end else operands[n-1] = nil name = a2 end end end elseif p == "W" then x = band(rshift(op, 5), 0xffff) elseif p == "Y" then x = band(rshift(op, 5), 0xffff) local hw = band(rshift(op, 21), 3) if altname and (hw == 0 or x ~= 0) then name = altname end elseif p == "L" then local rn = map_regs.x[band(rshift(op, 5), 31)] local imm9 = arshift(lshift(op, 11), 23) if band(op, 0x800) ~= 0 then x = "["..rn..", #"..imm9.."]!" else x = "["..rn.."], #"..imm9 end elseif p == "U" then local rn = map_regs.x[band(rshift(op, 5), 31)] local sz = band(rshift(op, 30), 3) local imm12 = lshift(arshift(lshift(op, 10), 20), sz) if imm12 ~= 0 then x = "["..rn..", #"..imm12.."]" else x = "["..rn.."]" end elseif p == "K" then local rn = map_regs.x[band(rshift(op, 5), 31)] local imm9 = arshift(lshift(op, 11), 23) if imm9 ~= 0 then x = "["..rn..", #"..imm9.."]" else x = "["..rn.."]" end elseif p == "O" then local rn, rm = map_regs.x[band(rshift(op, 5), 31)] local m = band(rshift(op, 13), 1) if m == 0 then rm = map_regs.w[band(rshift(op, 16), 31)] else rm = map_regs.x[band(rshift(op, 16), 31)] end x = "["..rn..", "..rm local opt = band(rshift(op, 13), 7) local s = band(rshift(op, 12), 1) local sz = band(rshift(op, 30), 3) -- extension to be applied if opt == 3 then if s == 0 then x = x.."]" else x = x..", lsl #"..sz.."]" end elseif opt == 2 or opt == 6 or opt == 7 then if s == 0 then x = x..", "..map_extend[opt].."]" else x = x..", "..map_extend[opt].." #"..sz.."]" end else x = x.."]" end elseif p == "P" then local opcv, sh = rshift(op, 26), 2 if opcv >= 0x2a then sh = 4 elseif opcv >= 0x1b then sh = 3 end local imm7 = lshift(arshift(lshift(op, 10), 25), sh) local rn = map_regs.x[band(rshift(op, 5), 31)] local ind = band(rshift(op, 23), 3) if ind == 1 then x = "["..rn.."], #"..imm7 elseif ind == 2 then if imm7 == 0 then x = "["..rn.."]" else x = "["..rn..", #"..imm7.."]" end elseif ind == 3 then x = "["..rn..", #"..imm7.."]!" end elseif p == "I" then local shf = band(rshift(op, 22), 3) local imm12 = band(rshift(op, 10), 0x0fff) local rn, rd = band(rshift(op, 5), 31), band(op, 31) if altname == "mov" and shf == 0 and imm12 == 0 and (rn == 31 or rd == 31) then name = altname x = nil elseif shf == 0 then x = imm12 elseif shf == 1 then x = imm12..", lsl #12" end elseif p == "i" then x = "#0x"..decode_imm13(op) elseif p == "1" then immr = band(rshift(op, 16), 63) x = immr elseif p == "2" then x = band(rshift(op, 10), 63) if altname then local a1, a2, a3, a4, a5, a6 = match(altname, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|(.*)") local sf = band(rshift(op, 26), 32) local uns = band(rshift(op, 30), 1) if prefer_bfx(sf, uns, x, immr) then name = a2 x = x - immr + 1 elseif immr == 0 and x == 7 then local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] name = a6 x = nil elseif immr == 0 and x == 15 then local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] name = a5 x = nil elseif x == 31 or x == 63 then if x == 31 and immr == 0 and name == "sbfm" then name = a4 local n = #operands operands[n] = nil if sf ~= 0 then operands[n-1] = gsub(operands[n-1], "x", "w") end last = operands[n-1] else name = a3 end x = nil elseif band(x, 31) ~= 31 and immr == x+1 and name == "ubfm" then name = a4 last = "#"..(sf+32 - immr) operands[#operands] = last x = nil elseif x < immr then name = a1 last = "#"..(sf+32 - immr) operands[#operands] = last x = x + 1 end end elseif p == "3" then x = band(rshift(op, 10), 63) if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if x < immr then name = a1 local sf = band(rshift(op, 26), 32) last = "#"..(sf+32 - immr) operands[#operands] = last x = x + 1 elseif x >= immr then name = a2 x = x - immr + 1 end end elseif p == "4" then x = band(rshift(op, 10), 63) local rn = band(rshift(op, 5), 31) local rm = band(rshift(op, 16), 31) if altname and rn == rm then local n = #operands operands[n] = nil last = operands[n-1] name = altname end elseif p == "5" then x = band(rshift(op, 16), 31) elseif p == "S" then x = band(rshift(op, 10), 63) if x == 0 then x = nil else x = map_shift[band(rshift(op, 22), 3)].." #"..x end elseif p == "X" then local opt = band(rshift(op, 13), 7) -- Width specifier . if opt ~= 3 and opt ~= 7 then last = map_regs.w[band(rshift(op, 16), 31)] operands[#operands] = last end x = band(rshift(op, 10), 7) -- Extension. if opt == 2 + band(rshift(op, 31), 1) and band(rshift(op, second0 and 5 or 0), 31) == 31 then if x == 0 then x = nil else x = "lsl #"..x end else if x == 0 then x = map_extend[band(rshift(op, 13), 7)] else x = map_extend[band(rshift(op, 13), 7)].." #"..x end end elseif p == "R" then x = band(rshift(op,21), 3) if x == 0 then x = nil else x = "lsl #"..x*16 end elseif p == "z" then local n = #operands if operands[n] == "sp" then operands[n] = "xzr" elseif operands[n] == "wsp" then operands[n] = "wzr" end elseif p == "Z" then x = 0 elseif p == "F" then x = parse_fpimm8(op) elseif p == "g" or p == "f" or p == "x" or p == "w" or p == "d" or p == "s" then -- These are handled in D/N/M/A. elseif p == "0" then if last == "sp" or last == "wsp" then local n = #operands operands[n] = nil last = operands[n-1] if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if not a1 then name = altname elseif second0 then name, altname = a2, a1 else name, altname = a1, a2 end end end second0 = true else assert(false) end if x then last = x if type(x) == "number" then x = "#"..x end operands[#operands+1] = x end end return putop(ctx, name..suffix, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ctx.pos = ofs ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_regs.x[r] end return map_regs.d[r-32] end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Luajit64/jit/dis_arm64be.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT ARM64BE disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- ARM64 instructions are always little-endian. So just forward to the -- common ARM64 disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ return require((string.match(..., ".*%.") or "").."dis_arm64") ================================================ FILE: Luajit64/jit/dis_mips.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles all standard MIPS32R1/R2 instructions. -- Default mode is big-endian, but see: dis_mipsel.lua ------------------------------------------------------------------------------ local type = type local byte, format = string.byte, string.format local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Primary and extended opcode maps ------------------------------------------------------------------------------ local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", } local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", } local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", } local map_special = { shift = 0, mask = 63, [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" }, map_movci, map_srl, "sraDTA", "sllvDTS", false, map_srlv, "sravDTS", "jrS", "jalrD1S", "movzDST", "movnDST", "syscallY", "breakY", false, "sync", "mfhiD", "mthiS", "mfloD", "mtloS", "dsllvDST", false, "dsrlvDST", "dsravDST", "multST", "multuST", "divST", "divuST", "dmultST", "dmultuST", "ddivST", "ddivuST", "addDST", "addu|moveDST0", "subDST", "subu|neguDS0T", "andDST", "or|moveDST0", "xorDST", "nor|notDST0", false, false, "sltDST", "sltuDST", "daddDST", "dadduDST", "dsubDST", "dsubuDST", "tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ", "teqSTZ", false, "tneSTZ", false, "dsllDTA", false, "dsrlDTA", "dsraDTA", "dsll32DTA", false, "dsrl32DTA", "dsra32DTA", } local map_special2 = { shift = 0, mask = 63, [0] = "maddST", "madduST", "mulDST", false, "msubST", "msubuST", [32] = "clzDS", [33] = "cloDS", [63] = "sdbbpY", } local map_bshfl = { shift = 6, mask = 31, [2] = "wsbhDT", [16] = "sebDT", [24] = "sehDT", } local map_dbshfl = { shift = 6, mask = 31, [2] = "dsbhDT", [5] = "dshdDT", } local map_special3 = { shift = 0, mask = 63, [0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK", [4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL", [32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD", } local map_regimm = { shift = 16, mask = 31, [0] = "bltzSB", "bgezSB", "bltzlSB", "bgezlSB", false, false, false, false, "tgeiSI", "tgeiuSI", "tltiSI", "tltiuSI", "teqiSI", false, "tneiSI", false, "bltzalSB", "bgezalSB", "bltzallSB", "bgezallSB", false, false, false, false, false, false, false, false, false, false, false, "synciSO", } local map_cop0 = { shift = 25, mask = 1, [0] = { shift = 21, mask = 15, [0] = "mfc0TDW", [4] = "mtc0TDW", [10] = "rdpgprDT", [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", }, [14] = "wrpgprDT", }, { shift = 0, mask = 63, [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp", [24] = "eret", [31] = "deret", [32] = "wait", }, } local map_cop1s = { shift = 0, mask = 63, [0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH", "sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG", "round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG", "round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG", false, { shift = 16, mask = 1, [0] = "movf.sFGC", "movt.sFGC" }, "movz.sFGT", "movn.sFGT", false, "recip.sFG", "rsqrt.sFG", false, false, false, false, false, false, false, false, false, false, "cvt.d.sFG", false, false, "cvt.w.sFG", "cvt.l.sFG", "cvt.ps.sFGH", false, false, false, false, false, false, false, false, false, "c.f.sVGH", "c.un.sVGH", "c.eq.sVGH", "c.ueq.sVGH", "c.olt.sVGH", "c.ult.sVGH", "c.ole.sVGH", "c.ule.sVGH", "c.sf.sVGH", "c.ngle.sVGH", "c.seq.sVGH", "c.ngl.sVGH", "c.lt.sVGH", "c.nge.sVGH", "c.le.sVGH", "c.ngt.sVGH", } local map_cop1d = { shift = 0, mask = 63, [0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH", "sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG", "round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG", "round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG", false, { shift = 16, mask = 1, [0] = "movf.dFGC", "movt.dFGC" }, "movz.dFGT", "movn.dFGT", false, "recip.dFG", "rsqrt.dFG", false, false, false, false, false, false, false, false, false, "cvt.s.dFG", false, false, false, "cvt.w.dFG", "cvt.l.dFG", false, false, false, false, false, false, false, false, false, false, "c.f.dVGH", "c.un.dVGH", "c.eq.dVGH", "c.ueq.dVGH", "c.olt.dVGH", "c.ult.dVGH", "c.ole.dVGH", "c.ule.dVGH", "c.df.dVGH", "c.ngle.dVGH", "c.deq.dVGH", "c.ngl.dVGH", "c.lt.dVGH", "c.nge.dVGH", "c.le.dVGH", "c.ngt.dVGH", } local map_cop1ps = { shift = 0, mask = 63, [0] = "add.psFGH", "sub.psFGH", "mul.psFGH", false, false, "abs.psFG", "mov.psFG", "neg.psFG", false, false, false, false, false, false, false, false, false, { shift = 16, mask = 1, [0] = "movf.psFGC", "movt.psFGC" }, "movz.psFGT", "movn.psFGT", false, false, false, false, false, false, false, false, false, false, false, false, "cvt.s.puFG", false, false, false, false, false, false, false, "cvt.s.plFG", false, false, false, "pll.psFGH", "plu.psFGH", "pul.psFGH", "puu.psFGH", "c.f.psVGH", "c.un.psVGH", "c.eq.psVGH", "c.ueq.psVGH", "c.olt.psVGH", "c.ult.psVGH", "c.ole.psVGH", "c.ule.psVGH", "c.psf.psVGH", "c.ngle.psVGH", "c.pseq.psVGH", "c.ngl.psVGH", "c.lt.psVGH", "c.nge.psVGH", "c.le.psVGH", "c.ngt.psVGH", } local map_cop1w = { shift = 0, mask = 63, [32] = "cvt.s.wFG", [33] = "cvt.d.wFG", } local map_cop1l = { shift = 0, mask = 63, [32] = "cvt.s.lFG", [33] = "cvt.d.lFG", } local map_cop1bc = { shift = 16, mask = 3, [0] = "bc1fCB", "bc1tCB", "bc1flCB", "bc1tlCB", } local map_cop1 = { shift = 21, mask = 31, [0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG", "mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG", map_cop1bc, false, false, false, false, false, false, false, map_cop1s, map_cop1d, false, false, map_cop1w, map_cop1l, map_cop1ps, } local map_cop1x = { shift = 0, mask = 63, [0] = "lwxc1FSX", "ldxc1FSX", false, false, false, "luxc1FSX", false, false, "swxc1FSX", "sdxc1FSX", false, false, false, "suxc1FSX", false, "prefxMSX", false, false, false, false, false, false, false, false, false, false, false, false, false, false, "alnv.psFGHS", false, "madd.sFRGH", "madd.dFRGH", false, false, false, false, "madd.psFRGH", false, "msub.sFRGH", "msub.dFRGH", false, false, false, false, "msub.psFRGH", false, "nmadd.sFRGH", "nmadd.dFRGH", false, false, false, false, "nmadd.psFRGH", false, "nmsub.sFRGH", "nmsub.dFRGH", false, false, false, false, "nmsub.psFRGH", false, } local map_pri = { [0] = map_special, map_regimm, "jJ", "jalJ", "beq|beqz|bST00B", "bne|bnezST0B", "blezSB", "bgtzSB", "addiTSI", "addiu|liTS0I", "sltiTSI", "sltiuTSI", "andiTSU", "ori|liTS0U", "xoriTSU", "luiTU", map_cop0, map_cop1, false, map_cop1x, "beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB", "daddiTSI", "daddiuTSI", false, false, map_special2, "jalxJ", false, map_special3, "lbTSO", "lhTSO", "lwlTSO", "lwTSO", "lbuTSO", "lhuTSO", "lwrTSO", false, "sbTSO", "shTSO", "swlTSO", "swTSO", false, false, "swrTSO", "cacheNSO", "llTSO", "lwc1HSO", "lwc2TSO", "prefNSO", false, "ldc1HSO", "ldc2TSO", "ldTSO", "scTSO", "swc1HSO", "swc2TSO", false, false, "sdc1HSO", "sdc2TSO", "sdTSO", } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "sp", "r30", "ra", } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-7s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-7s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end local function get_be(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) return bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) end local function get_le(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0) end -- Disassemble a single instruction. local function disass_ins(ctx) local op = ctx:get() local operands = {} local last = nil ctx.op = op ctx.rel = nil local opat = map_pri[rshift(op, 26)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._ end local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)") if altname then pat = pat2 end for p in gmatch(pat, ".") do local x = nil if p == "S" then x = map_gpr[band(rshift(op, 21), 31)] elseif p == "T" then x = map_gpr[band(rshift(op, 16), 31)] elseif p == "D" then x = map_gpr[band(rshift(op, 11), 31)] elseif p == "F" then x = "f"..band(rshift(op, 6), 31) elseif p == "G" then x = "f"..band(rshift(op, 11), 31) elseif p == "H" then x = "f"..band(rshift(op, 16), 31) elseif p == "R" then x = "f"..band(rshift(op, 21), 31) elseif p == "A" then x = band(rshift(op, 6), 31) elseif p == "E" then x = band(rshift(op, 6), 31) + 32 elseif p == "M" then x = band(rshift(op, 11), 31) elseif p == "N" then x = band(rshift(op, 16), 31) elseif p == "C" then x = band(rshift(op, 18), 7) if x == 0 then x = nil end elseif p == "K" then x = band(rshift(op, 11), 31) + 1 elseif p == "P" then x = band(rshift(op, 11), 31) + 33 elseif p == "L" then x = band(rshift(op, 11), 31) - last + 1 elseif p == "Q" then x = band(rshift(op, 11), 31) - last + 33 elseif p == "I" then x = arshift(lshift(op, 16), 16) elseif p == "U" then x = band(op, 0xffff) elseif p == "O" then local disp = arshift(lshift(op, 16), 16) operands[#operands] = format("%d(%s)", disp, last) elseif p == "X" then local index = map_gpr[band(rshift(op, 16), 31)] operands[#operands] = format("%s(%s)", index, last) elseif p == "B" then x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4 ctx.rel = x x = format("0x%08x", x) elseif p == "J" then local a = ctx.addr + ctx.pos x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4 ctx.rel = x x = format("0x%08x", x) elseif p == "V" then x = band(rshift(op, 8), 7) if x == 0 then x = nil end elseif p == "W" then x = band(op, 7) if x == 0 then x = nil end elseif p == "Y" then x = band(rshift(op, 6), 0x000fffff) if x == 0 then x = nil end elseif p == "Z" then x = band(rshift(op, 6), 1023) if x == 0 then x = nil end elseif p == "0" then if last == "r0" or last == 0 then local n = #operands operands[n] = nil last = operands[n-1] if altname then local a1, a2 = match(altname, "([^|]*)|(.*)") if a1 then name, altname = a1, a2 else name = altname end end end elseif p == "1" then if last == "ra" then operands[#operands] = nil end else assert(false) end if x then operands[#operands+1] = x; last = x end end return putop(ctx, name, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code stop = stop - stop % 4 ctx.pos = ofs - ofs % 4 ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 ctx.get = get_be return ctx end local function create_el(code, addr, out) local ctx = create(code, addr, out) ctx.get = get_le return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end local function disass_el(code, addr, out) create_el(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_gpr[r] end return "f"..(r-32) end -- Public module functions. return { create = create, create_el = create_el, disass = disass, disass_el = disass_el, regname = regname } ================================================ FILE: Luajit64/jit/dis_mips64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS64 disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the big-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create, disass = dis_mips.disass, regname = dis_mips.regname } ================================================ FILE: Luajit64/jit/dis_mips64el.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPS64EL disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the little-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create_el, disass = dis_mips.disass_el, regname = dis_mips.regname } ================================================ FILE: Luajit64/jit/dis_mipsel.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT MIPSEL disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the little-endian functions from the -- MIPS disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") return { create = dis_mips.create_el, disass = dis_mips.disass_el, regname = dis_mips.regname } ================================================ FILE: Luajit64/jit/dis_ppc.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT PPC disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT/X license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- It disassembles all common, non-privileged 32/64 bit PowerPC instructions -- plus the e500 SPE instructions and some Cell/Xenon extensions. -- -- NYI: VMX, VMX128 ------------------------------------------------------------------------------ local type = type local byte, format = string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift ------------------------------------------------------------------------------ -- Primary and extended opcode maps ------------------------------------------------------------------------------ local map_crops = { shift = 1, mask = 1023, [0] = "mcrfXX", [33] = "crnor|crnotCCC=", [129] = "crandcCCC", [193] = "crxor|crclrCCC%", [225] = "crnandCCC", [257] = "crandCCC", [289] = "creqv|crsetCCC%", [417] = "crorcCCC", [449] = "cror|crmoveCCC=", [16] = "b_lrKB", [528] = "b_ctrKB", [150] = "isync", } local map_rlwinm = setmetatable({ shift = 0, mask = -1, }, { __index = function(t, x) local rot = band(rshift(x, 11), 31) local mb = band(rshift(x, 6), 31) local me = band(rshift(x, 1), 31) if mb == 0 and me == 31-rot then return "slwiRR~A." elseif me == 31 and mb == 32-rot then return "srwiRR~-A." else return "rlwinmRR~AAA." end end }) local map_rld = { shift = 2, mask = 7, [0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.", { shift = 1, mask = 1, [0] = "rldclRR~RM.", "rldcrRR~RM.", }, } local map_ext = setmetatable({ shift = 1, mask = 1023, [0] = "cmp_YLRR", [32] = "cmpl_YLRR", [4] = "twARR", [68] = "tdARR", [8] = "subfcRRR.", [40] = "subfRRR.", [104] = "negRR.", [136] = "subfeRRR.", [200] = "subfzeRR.", [232] = "subfmeRR.", [520] = "subfcoRRR.", [552] = "subfoRRR.", [616] = "negoRR.", [648] = "subfeoRRR.", [712] = "subfzeoRR.", [744] = "subfmeoRR.", [9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.", [457] = "divduRRR.", [489] = "divdRRR.", [745] = "mulldoRRR.", [969] = "divduoRRR.", [1001] = "divdoRRR.", [10] = "addcRRR.", [138] = "addeRRR.", [202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.", [522] = "addcoRRR.", [650] = "addeoRRR.", [714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.", [11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.", [459] = "divwuRRR.", [491] = "divwRRR.", [747] = "mullwoRRR.", [971] = "divwouRRR.", [1003] = "divwoRRR.", [15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR", [144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", }, [19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", }, [371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", }, [339] = { shift = 11, mask = 1023, [32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR", }, [467] = { shift = 11, mask = 1023, [32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR", }, [20] = "lwarxRR0R", [84] = "ldarxRR0R", [21] = "ldxRR0R", [53] = "lduxRRR", [149] = "stdxRR0R", [181] = "stduxRRR", [341] = "lwaxRR0R", [373] = "lwauxRRR", [23] = "lwzxRR0R", [55] = "lwzuxRRR", [87] = "lbzxRR0R", [119] = "lbzuxRRR", [151] = "stwxRR0R", [183] = "stwuxRRR", [215] = "stbxRR0R", [247] = "stbuxRRR", [279] = "lhzxRR0R", [311] = "lhzuxRRR", [343] = "lhaxRR0R", [375] = "lhauxRRR", [407] = "sthxRR0R", [439] = "sthuxRRR", [54] = "dcbst-R0R", [86] = "dcbf-R0R", [150] = "stwcxRR0R.", [214] = "stdcxRR0R.", [246] = "dcbtst-R0R", [278] = "dcbt-R0R", [310] = "eciwxRR0R", [438] = "ecowxRR0R", [470] = "dcbi-RR", [598] = { shift = 21, mask = 3, [0] = "sync", "lwsync", "ptesync", }, [758] = "dcba-RR", [854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R", [26] = "cntlzwRR~", [58] = "cntlzdRR~", [122] = "popcntbRR~", [154] = "prtywRR~", [186] = "prtydRR~", [28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.", [284] = "eqvRR~R.", [316] = "xorRR~R.", [412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.", [508] = "cmpbRR~R", [512] = "mcrxrX", [532] = "ldbrxRR0R", [660] = "stdbrxRR0R", [533] = "lswxRR0R", [597] = "lswiRR0A", [661] = "stswxRR0R", [725] = "stswiRR0A", [534] = "lwbrxRR0R", [662] = "stwbrxRR0R", [790] = "lhbrxRR0R", [918] = "sthbrxRR0R", [535] = "lfsxFR0R", [567] = "lfsuxFRR", [599] = "lfdxFR0R", [631] = "lfduxFRR", [663] = "stfsxFR0R", [695] = "stfsuxFRR", [727] = "stfdxFR0R", [759] = "stfduxFR0R", [855] = "lfiwaxFR0R", [983] = "stfiwxFR0R", [24] = "slwRR~R.", [27] = "sldRR~R.", [536] = "srwRR~R.", [792] = "srawRR~R.", [824] = "srawiRR~A.", [794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.", [922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.", [539] = "srdRR~R.", }, { __index = function(t, x) if band(x, 31) == 15 then return "iselRRRC" end end }) local map_ld = { shift = 0, mask = 3, [0] = "ldRRE", "lduRRE", "lwaRRE", } local map_std = { shift = 0, mask = 3, [0] = "stdRRE", "stduRRE", } local map_fps = { shift = 5, mask = 1, { shift = 1, mask = 15, [0] = false, false, "fdivsFFF.", false, "fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false, "fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false, "fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.", } } local map_fpd = { shift = 5, mask = 1, [0] = { shift = 1, mask = 1023, [0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX", [38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>", [8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.", [136] = "fnabsF-F.", [264] = "fabsF-F.", [12] = "frspF-F.", [14] = "fctiwF-F.", [15] = "fctiwzF-F.", [583] = "mffsF.", [711] = "mtfsfZF.", [392] = "frinF-F.", [424] = "frizF-F.", [456] = "fripF-F.", [488] = "frimF-F.", [814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.", }, { shift = 1, mask = 15, [0] = false, false, "fdivFFF.", false, "fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.", "freF-F.", "fmulFF-F.", "frsqrteF-F.", false, "fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.", } } local map_spe = { shift = 0, mask = 2047, [512] = "evaddwRRR", [514] = "evaddiwRAR~", [516] = "evsubwRRR~", [518] = "evsubiwRAR~", [520] = "evabsRR", [521] = "evnegRR", [522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR", [525] = "evcntlzwRR", [526] = "evcntlswRR", [527] = "brincRRR", [529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR", [535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=", [537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR", [544] = "evsrwuRRR", [545] = "evsrwsRRR", [546] = "evsrwiuRRA", [547] = "evsrwisRRA", [548] = "evslwRRR", [550] = "evslwiRRA", [552] = "evrlwRRR", [553] = "evsplatiRS", [554] = "evrlwiRRA", [555] = "evsplatfiRS", [556] = "evmergehiRRR", [557] = "evmergeloRRR", [558] = "evmergehiloRRR", [559] = "evmergelohiRRR", [560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR", [562] = "evcmpltuYRR", [563] = "evcmpltsYRR", [564] = "evcmpeqYRR", [632] = "evselRRR", [633] = "evselRRRW", [634] = "evselRRRW", [635] = "evselRRRW", [636] = "evselRRRW", [637] = "evselRRRW", [638] = "evselRRRW", [639] = "evselRRRW", [640] = "evfsaddRRR", [641] = "evfssubRRR", [644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR", [648] = "evfsmulRRR", [649] = "evfsdivRRR", [652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR", [656] = "evfscfuiR-R", [657] = "evfscfsiR-R", [658] = "evfscfufR-R", [659] = "evfscfsfR-R", [660] = "evfsctuiR-R", [661] = "evfsctsiR-R", [662] = "evfsctufR-R", [663] = "evfsctsfR-R", [664] = "evfsctuizR-R", [666] = "evfsctsizR-R", [668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR", [704] = "efsaddRRR", [705] = "efssubRRR", [708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR", [712] = "efsmulRRR", [713] = "efsdivRRR", [716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR", [719] = "efscfdR-R", [720] = "efscfuiR-R", [721] = "efscfsiR-R", [722] = "efscfufR-R", [723] = "efscfsfR-R", [724] = "efsctuiR-R", [725] = "efsctsiR-R", [726] = "efsctufR-R", [727] = "efsctsfR-R", [728] = "efsctuizR-R", [730] = "efsctsizR-R", [732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR", [736] = "efdaddRRR", [737] = "efdsubRRR", [738] = "efdcfuidR-R", [739] = "efdcfsidR-R", [740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR", [744] = "efdmulRRR", [745] = "efddivRRR", [746] = "efdctuidzR-R", [747] = "efdctsidzR-R", [748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR", [751] = "efdcfsR-R", [752] = "efdcfuiR-R", [753] = "efdcfsiR-R", [754] = "efdcfufR-R", [755] = "efdcfsfR-R", [756] = "efdctuiR-R", [757] = "efdctsiR-R", [758] = "efdctufR-R", [759] = "efdctsfR-R", [760] = "efdctuizR-R", [762] = "efdctsizR-R", [764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR", [768] = "evlddxRR0R", [769] = "evlddRR8", [770] = "evldwxRR0R", [771] = "evldwRR8", [772] = "evldhxRR0R", [773] = "evldhRR8", [776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2", [780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2", [782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2", [784] = "evlwhexRR0R", [785] = "evlwheRR4", [788] = "evlwhouxRR0R", [789] = "evlwhouRR4", [790] = "evlwhosxRR0R", [791] = "evlwhosRR4", [792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4", [796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4", [800] = "evstddxRR0R", [801] = "evstddRR8", [802] = "evstdwxRR0R", [803] = "evstdwRR8", [804] = "evstdhxRR0R", [805] = "evstdhRR8", [816] = "evstwhexRR0R", [817] = "evstwheRR4", [820] = "evstwhoxRR0R", [821] = "evstwhoRR4", [824] = "evstwwexRR0R", [825] = "evstwweRR4", [828] = "evstwwoxRR0R", [829] = "evstwwoRR4", [1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR", [1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR", [1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR", [1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR", [1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR", [1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR", [1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR", [1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR", [1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR", [1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR", [1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR", [1147] = "evmwsmfaRRR", [1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR", [1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR", [1220] = "evmraRR", [1222] = "evdivwsRRR", [1223] = "evdivwuRRR", [1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR", [1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR", [1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR", [1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR", [1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR", [1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR", [1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR", [1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR", [1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR", [1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR", [1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR", [1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR", [1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR", [1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR", [1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR", [1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR", [1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR", [1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR", [1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR", [1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR", [1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR", [1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR", [1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR", [1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR", [1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR", [1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR", [1491] = "evmwssfanRRR", [1496] = "evmwumianRRR", [1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR", } local map_pri = { [0] = false, false, "tdiARI", "twiARI", map_spe, false, false, "mulliRRI", "subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI", "addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I", "b_KBJ", "sc", "bKJ", map_crops, "rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.", "oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U", "andi.RR~U", "andis.RR~U", map_rld, map_ext, "lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD", "stwRRD", "stwuRRD", "stbRRD", "stbuRRD", "lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD", "sthRRD", "sthuRRD", "lmwRRD", "stmwRRD", "lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD", "stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD", false, false, map_ld, map_fps, false, false, map_std, map_fpd, } ------------------------------------------------------------------------------ local map_gpr = { [0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", } local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", } -- Format a condition bit. local function condfmt(cond) if cond <= 3 then return map_cond[band(cond, 3)] else return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)]) end end ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local pos = ctx.pos local extra = "" if ctx.rel then local sym = ctx.symtab[ctx.rel] if sym then extra = "\t->"..sym end end if ctx.hexdump > 0 then ctx.out(format("%08x %s %-7s %s%s\n", ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra)) else ctx.out(format("%08x %-7s %s%s\n", ctx.addr+pos, text, concat(operands, ", "), extra)) end ctx.pos = pos + 4 end -- Fallback for unknown opcodes. local function unknown(ctx) return putop(ctx, ".long", { "0x"..tohex(ctx.op) }) end -- Disassemble a single instruction. local function disass_ins(ctx) local pos = ctx.pos local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4) local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3) local operands = {} local last = nil local rs = 21 ctx.op = op ctx.rel = nil local opat = map_pri[rshift(b0, 2)] while type(opat) ~= "string" do if not opat then return unknown(ctx) end opat = opat[band(rshift(op, opat.shift), opat.mask)] end local name, pat = match(opat, "^([a-z0-9_.]*)(.*)") local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)") if altname then pat = pat2 end for p in gmatch(pat, ".") do local x = nil if p == "R" then x = map_gpr[band(rshift(op, rs), 31)] rs = rs - 5 elseif p == "F" then x = "f"..band(rshift(op, rs), 31) rs = rs - 5 elseif p == "A" then x = band(rshift(op, rs), 31) rs = rs - 5 elseif p == "S" then x = arshift(lshift(op, 27-rs), 27) rs = rs - 5 elseif p == "I" then x = arshift(lshift(op, 16), 16) elseif p == "U" then x = band(op, 0xffff) elseif p == "D" or p == "E" then local disp = arshift(lshift(op, 16), 16) if p == "E" then disp = band(disp, -4) end if last == "r0" then last = "0" end operands[#operands] = format("%d(%s)", disp, last) elseif p >= "2" and p <= "8" then local disp = band(rshift(op, rs), 31) * p if last == "r0" then last = "0" end operands[#operands] = format("%d(%s)", disp, last) elseif p == "H" then x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4) rs = rs - 5 elseif p == "M" then x = band(rshift(op, rs), 31) + band(op, 0x20) elseif p == "C" then x = condfmt(band(rshift(op, rs), 31)) rs = rs - 5 elseif p == "B" then local bo = rshift(op, 21) local cond = band(rshift(op, 16), 31) local cn = "" rs = rs - 10 if band(bo, 4) == 0 then cn = band(bo, 2) == 0 and "dnz" or "dz" if band(bo, 0x10) == 0 then cn = cn..(band(bo, 8) == 0 and "f" or "t") end if band(bo, 0x10) == 0 then x = condfmt(cond) end name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") elseif band(bo, 0x10) == 0 then cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)] if cond > 3 then x = "cr"..rshift(cond, 2) end name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+") end name = gsub(name, "_", cn) elseif p == "J" then x = arshift(lshift(op, 27-rs), 29-rs)*4 if band(op, 2) == 0 then x = ctx.addr + pos + x end ctx.rel = x x = "0x"..tohex(x) elseif p == "K" then if band(op, 1) ~= 0 then name = name.."l" end if band(op, 2) ~= 0 then name = name.."a" end elseif p == "X" or p == "Y" then x = band(rshift(op, rs+2), 7) if x == 0 and p == "Y" then x = nil else x = "cr"..x end rs = rs - 5 elseif p == "W" then x = "cr"..band(op, 7) elseif p == "Z" then x = band(rshift(op, rs-4), 255) rs = rs - 10 elseif p == ">" then operands[#operands] = rshift(operands[#operands], 1) elseif p == "0" then if last == "r0" then operands[#operands] = nil if altname then name = altname end end elseif p == "L" then name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w") elseif p == "." then if band(op, 1) == 1 then name = name.."." end elseif p == "N" then if op == 0x60000000 then name = "nop"; break end elseif p == "~" then local n = #operands operands[n-1], operands[n] = operands[n], operands[n-1] elseif p == "=" then local n = #operands if last == operands[n-1] then operands[n] = nil name = altname end elseif p == "%" then local n = #operands if last == operands[n-1] and last == operands[n-2] then operands[n] = nil operands[n-1] = nil name = altname end elseif p == "-" then rs = rs - 5 else assert(false) end if x then operands[#operands+1] = x; last = x end end return putop(ctx, name, operands) end ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code stop = stop - stop % 4 ctx.pos = ofs - ofs % 4 ctx.rel = nil while ctx.pos < stop do disass_ins(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = addr or 0 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 8 return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 32 then return map_gpr[r] end return "f"..(r-32) end -- Public module functions. return { create = create, disass = disass, regname = regname } ================================================ FILE: Luajit64/jit/dis_x64.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT x64 disassembler wrapper module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This module just exports the 64 bit functions from the combined -- x86/x64 disassembler module. All the interesting stuff is there. ------------------------------------------------------------------------------ local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86") return { create = dis_x86.create64, disass = dis_x86.disass64, regname = dis_x86.regname64 } ================================================ FILE: Luajit64/jit/dis_x86.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT x86/x64 disassembler module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- This is a helper module used by the LuaJIT machine code dumper module. -- -- Sending small code snippets to an external disassembler and mixing the -- output with our own stuff was too fragile. So I had to bite the bullet -- and write yet another x86 disassembler. Oh well ... -- -- The output format is very similar to what ndisasm generates. But it has -- been developed independently by looking at the opcode tables from the -- Intel and AMD manuals. The supported instruction set is quite extensive -- and reflects what a current generation Intel or AMD CPU implements in -- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3, -- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor -- (VMX/SVM) instructions. -- -- Notes: -- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported. -- * No attempt at optimization has been made -- it's fast enough for my needs. ------------------------------------------------------------------------------ local type = type local sub, byte, format = string.sub, string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local lower, rep = string.lower, string.rep local bit = require("bit") local tohex = bit.tohex -- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on. local map_opc1_32 = { --0x [0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es", "orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*", --1x "adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss", "sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds", --2x "andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa", "subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das", --3x "xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa", "cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas", --4x "incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR", "decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR", --5x "pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR", "popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR", --6x "sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr", "fs:seg","gs:seg","o16:","a16", "pushUi","imulVrmi","pushBs","imulVrms", "insb","insVS","outsb","outsVS", --7x "joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj", "jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj", --8x "arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms", "testBmr","testVmr","xchgBrm","xchgVrm", "movBmr","movVmr","movBrm","movVrm", "movVmg","leaVrm","movWgm","popUm", --9x "nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR", "xchgVaR","xchgVaR","xchgVaR","xchgVaR", "sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait", "sz*pushfw,pushf","sz*popfw,popf","sahf","lahf", --Ax "movBao","movVao","movBoa","movVoa", "movsb","movsVS","cmpsb","cmpsVS", "testBai","testVai","stosb","stosVS", "lodsb","lodsVS","scasb","scasVS", --Bx "movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi", "movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI", --Cx "shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi", "enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS", --Dx "shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb", "fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7", --Ex "loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj", "inBau","inVau","outBua","outVua", "callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda", --Fx "lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm", "clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm", } assert(#map_opc1_32 == 255) -- Map for 1st opcode byte in 64 bit mode (overrides only). local map_opc1_64 = setmetatable({ [0x06]=false, [0x07]=false, [0x0e]=false, [0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false, [0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false, [0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:", [0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb", [0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb", [0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb", [0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb", [0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false, [0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false, }, { __index = map_opc1_32 }) -- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you. -- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2 local map_opc2 = { --0x [0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret", "invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu", --1x "movupsXrm|movssXrvm|movupdXrm|movsdXrvm", "movupsXmr|movssXmvr|movupdXmr|movsdXmvr", "movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", "movlpsXmr||movlpdXmr", "unpcklpsXrvm||unpcklpdXrvm", "unpckhpsXrvm||unpckhpdXrvm", "movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm", "movhpsXmr||movhpdXmr", "$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm", "hintnopVm","hintnopVm","hintnopVm","hintnopVm", --2x "movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil, "movapsXrm||movapdXrm", "movapsXmr||movapdXmr", "cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt", "movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr", "cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm", "cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm", "ucomissXrm||ucomisdXrm", "comissXrm||comisdXrm", --3x "wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec", "opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil, --4x "cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm", "cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm", "cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm", "cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm", --5x "movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm", "rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm", "andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm", "orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm", "addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm", "cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm", "cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm", "subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm", "divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm", --6x "punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm", "pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm", "punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm", "||punpcklqdqXrvm","||punpckhqdqXrvm", "movPrVSm","movqMrm|movdquXrm|movdqaXrm", --7x "pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu", "pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu", "pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|", "vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$", nil,nil, "||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm", "movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr", --8x "joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj", "jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj", --9x "setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm", "setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm", --Ax "push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil, "push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm", --Bx "cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr", "$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt", "|popcntVrm","ud2Dp","bt!Vmu","btcVmr", "bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt", --Cx "xaddBmr","xaddVmr", "cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|", "pinsrwPrvWmu","pextrwDrPmu", "shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp", "bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR", --Dx "||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm", "paddqPrvm","pmullwPrvm", "|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm", "psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm", "paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm", --Ex "pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm", "pmulhuwPrvm","pmulhwPrvm", "|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr", "psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm", "paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm", --Fx "|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm", "pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$", "psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm", "paddbPrvm","paddwPrvm","padddPrvm","ud", } assert(map_opc2[255] == "ud") -- Map for three-byte opcodes. Can't wait for their next invention. local map_opc3 = { ["38"] = { -- [66] 0f 38 xx --0x [0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm", "pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm", "psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm", "||permilpsXrvm","||permilpdXrvm",nil,nil, --1x "||pblendvbXrma",nil,nil,nil, "||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm", "||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil, "pabsbPrm","pabswPrm","pabsdPrm",nil, --2x "||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm", "||pmovsxwqXrm","||pmovsxdqXrm",nil,nil, "||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm", "||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr", --3x "||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm", "||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm", "||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm", "||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm", --4x "||pmulddXrvm","||phminposuwXrm",nil,nil, nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm", --5x [0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm", [0x5a] = "||broadcasti128XrlXm", --7x [0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm", --8x [0x8c] = "||pmaskmovXrvVSm", [0x8e] = "||pmaskmovVSmXvr", --9x [0x96] = "||fmaddsub132pHXrvm",[0x97] = "||fmsubadd132pHXrvm", [0x98] = "||fmadd132pHXrvm",[0x99] = "||fmadd132sHXrvm", [0x9a] = "||fmsub132pHXrvm",[0x9b] = "||fmsub132sHXrvm", [0x9c] = "||fnmadd132pHXrvm",[0x9d] = "||fnmadd132sHXrvm", [0x9e] = "||fnmsub132pHXrvm",[0x9f] = "||fnmsub132sHXrvm", --Ax [0xa6] = "||fmaddsub213pHXrvm",[0xa7] = "||fmsubadd213pHXrvm", [0xa8] = "||fmadd213pHXrvm",[0xa9] = "||fmadd213sHXrvm", [0xaa] = "||fmsub213pHXrvm",[0xab] = "||fmsub213sHXrvm", [0xac] = "||fnmadd213pHXrvm",[0xad] = "||fnmadd213sHXrvm", [0xae] = "||fnmsub213pHXrvm",[0xaf] = "||fnmsub213sHXrvm", --Bx [0xb6] = "||fmaddsub231pHXrvm",[0xb7] = "||fmsubadd231pHXrvm", [0xb8] = "||fmadd231pHXrvm",[0xb9] = "||fmadd231sHXrvm", [0xba] = "||fmsub231pHXrvm",[0xbb] = "||fmsub231sHXrvm", [0xbc] = "||fnmadd231pHXrvm",[0xbd] = "||fnmadd231sHXrvm", [0xbe] = "||fnmsub231pHXrvm",[0xbf] = "||fnmsub231sHXrvm", --Dx [0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm", [0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm", --Fx [0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt", [0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv", }, ["3a"] = { -- [66] 0f 3a xx --0x [0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil, "||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil, "||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu", "||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu", --1x nil,nil,nil,nil, "||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru", "||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil, nil,nil,nil,nil, --2x "||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil, --3x [0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru", --4x [0x40] = "||dppsXrvmu", [0x41] = "||dppdXrvmu", [0x42] = "||mpsadbwXrvmu", [0x44] = "||pclmulqdqXrvmu", [0x46] = "||perm2i128Xrvmu", [0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb", [0x4c] = "||pblendvbXrvmb", --6x [0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu", [0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu", [0xdf] = "||aeskeygenassistXrmu", --Fx [0xf0] = "||| rorxVrmu", }, } -- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands). local map_opcvm = { [0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff", [0xc8]="monitor",[0xc9]="mwait", [0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave", [0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga", [0xf8]="swapgs",[0xf9]="rdtscp", } -- Map for FP opcodes. And you thought stack machines are simple? local map_opcfp = { -- D8-DF 00-BF: opcodes with a memory operand. -- D8 [0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm", "fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm", -- DA "fiaddDm","fimulDm","ficomDm","ficompDm", "fisubDm","fisubrDm","fidivDm","fidivrDm", -- DB "fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp", -- DC "faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm", -- DD "fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm", -- DE "fiaddWm","fimulWm","ficomWm","ficompWm", "fisubWm","fisubrWm","fidivWm","fidivrWm", -- DF "fildWm","fisttpWm","fistWm","fistpWm", "fbld twordFmp","fildQm","fbstp twordFmp","fistpQm", -- xx C0-FF: opcodes with a pseudo-register operand. -- D8 "faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf", -- D9 "fldFf","fxchFf",{"fnop"},nil, {"fchs","fabs",nil,nil,"ftst","fxam"}, {"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"}, {"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"}, {"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"}, -- DA "fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil, -- DB "fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf", {nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil, -- DC "fadd toFf","fmul toFf",nil,nil, "fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf", -- DD "ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil, -- DE "faddpFf","fmulpFf",nil,{nil,"fcompp"}, "fsubrpFf","fsubpFf","fdivrpFf","fdivpFf", -- DF nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil, } assert(map_opcfp[126] == "fcomipFf") -- Map for opcode groups. The subkey is sp from the ModRM byte. local map_opcgroup = { arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" }, shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" }, testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" }, testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" }, incb = { "inc", "dec" }, incd = { "inc", "dec", "callUmp", "$call farDmp", "jmpUmp", "$jmp farDmp", "pushUm" }, sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" }, sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt", "smsw", nil, "lmsw", "vm*$invlpg" }, bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" }, cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil, nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" }, pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" }, pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" }, pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" }, pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" }, fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr", nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" }, prefetch = { "prefetch", "prefetchw" }, prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" }, } ------------------------------------------------------------------------------ -- Maps for register names. local map_regs = { B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }, W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" }, D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" }, Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }, M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext! X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" }, Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" }, } local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" } -- Maps for size names. local map_sz2n = { B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32, } local map_sz2prefix = { B = "byte", W = "word", D = "dword", Q = "qword", M = "qword", X = "xword", Y = "yword", F = "dword", G = "qword", -- No need for sizes/register names for these two. } ------------------------------------------------------------------------------ -- Output a nicely formatted line with an opcode and operands. local function putop(ctx, text, operands) local code, pos, hex = ctx.code, ctx.pos, "" local hmax = ctx.hexdump if hmax > 0 then for i=ctx.start,pos-1 do hex = hex..format("%02X", byte(code, i, i)) end if #hex > hmax then hex = sub(hex, 1, hmax)..". " else hex = hex..rep(" ", hmax-#hex+2) end end if operands then text = text.." "..operands end if ctx.o16 then text = "o16 "..text; ctx.o16 = false end if ctx.a32 then text = "a32 "..text; ctx.a32 = false end if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end if ctx.rex then local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "").. (ctx.rexx and "x" or "")..(ctx.rexb and "b" or "").. (ctx.vexl and "l" or "") if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "") elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rex = false; ctx.vexl = false; ctx.vexv = false end if ctx.seg then local text2, n = gsub(text, "%[", "["..ctx.seg..":") if n == 0 then text = ctx.seg.." "..text else text = text2 end ctx.seg = false end if ctx.lock then text = "lock "..text; ctx.lock = false end local imm = ctx.imm if imm then local sym = ctx.symtab[imm] if sym then text = text.."\t->"..sym end end ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text)) ctx.mrm = false ctx.vexv = false ctx.start = pos ctx.imm = nil end -- Clear all prefix flags. local function clearprefixes(ctx) ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false ctx.rex = false; ctx.a32 = false; ctx.vexl = false end -- Fallback for incomplete opcodes at the end. local function incomplete(ctx) ctx.pos = ctx.stop+1 clearprefixes(ctx) return putop(ctx, "(incomplete)") end -- Fallback for unknown opcodes. local function unknown(ctx) clearprefixes(ctx) return putop(ctx, "(unknown)") end -- Return an immediate of the specified size. local function getimm(ctx, pos, n) if pos+n-1 > ctx.stop then return incomplete(ctx) end local code = ctx.code if n == 1 then local b1 = byte(code, pos, pos) return b1 elseif n == 2 then local b1, b2 = byte(code, pos, pos+1) return b1+b2*256 else local b1, b2, b3, b4 = byte(code, pos, pos+3) local imm = b1+b2*256+b3*65536+b4*16777216 ctx.imm = imm return imm end end -- Process pattern string and generate the operands. local function putpat(ctx, name, pat) local operands, regs, sz, mode, sp, rm, sc, rx, sdisp local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl -- Chars used: 1DFGHIMPQRSTUVWXYabcdfgijlmoprstuvwxyz for p in gmatch(pat, ".") do local x = nil if p == "V" or p == "U" then if ctx.rexw then sz = "Q"; ctx.rexw = false elseif ctx.o16 then sz = "W"; ctx.o16 = false elseif p == "U" and ctx.x64 then sz = "Q" else sz = "D" end regs = map_regs[sz] elseif p == "T" then if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end regs = map_regs[sz] elseif p == "B" then sz = "B" regs = ctx.rex and map_regs.B64 or map_regs.B elseif match(p, "[WDQMXYFG]") then sz = p if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end regs = map_regs[sz] elseif p == "P" then sz = ctx.o16 and "X" or "M"; ctx.o16 = false if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end regs = map_regs[sz] elseif p == "H" then name = name..(ctx.rexw and "d" or "s") ctx.rexw = false elseif p == "S" then name = name..lower(sz) elseif p == "s" then local imm = getimm(ctx, pos, 1); if not imm then return end x = imm <= 127 and format("+0x%02x", imm) or format("-0x%02x", 256-imm) pos = pos+1 elseif p == "u" then local imm = getimm(ctx, pos, 1); if not imm then return end x = format("0x%02x", imm) pos = pos+1 elseif p == "b" then local imm = getimm(ctx, pos, 1); if not imm then return end x = regs[imm/16+1] pos = pos+1 elseif p == "w" then local imm = getimm(ctx, pos, 2); if not imm then return end x = format("0x%x", imm) pos = pos+2 elseif p == "o" then -- [offset] if ctx.x64 then local imm1 = getimm(ctx, pos, 4); if not imm1 then return end local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end x = format("[0x%08x%08x]", imm2, imm1) pos = pos+8 else local imm = getimm(ctx, pos, 4); if not imm then return end x = format("[0x%08x]", imm) pos = pos+4 end elseif p == "i" or p == "I" then local n = map_sz2n[sz] if n == 8 and ctx.x64 and p == "I" then local imm1 = getimm(ctx, pos, 4); if not imm1 then return end local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end x = format("0x%08x%08x", imm2, imm1) else if n == 8 then n = 4 end local imm = getimm(ctx, pos, n); if not imm then return end if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then imm = (0xffffffff+1)-imm x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm) else x = format(imm > 65535 and "0x%08x" or "0x%x", imm) end end pos = pos+n elseif p == "j" then local n = map_sz2n[sz] if n == 8 then n = 4 end local imm = getimm(ctx, pos, n); if not imm then return end if sz == "B" and imm > 127 then imm = imm-256 elseif imm > 2147483647 then imm = imm-4294967296 end pos = pos+n imm = imm + pos + ctx.addr if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end ctx.imm = imm if sz == "W" then x = format("word 0x%04x", imm%65536) elseif ctx.x64 then local lo = imm % 0x1000000 x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo) else x = "0x"..tohex(imm) end elseif p == "R" then local r = byte(code, pos-1, pos-1)%8 if ctx.rexb then r = r + 8; ctx.rexb = false end x = regs[r+1] elseif p == "a" then x = regs[1] elseif p == "c" then x = "cl" elseif p == "d" then x = "dx" elseif p == "1" then x = "1" else if not mode then mode = ctx.mrm if not mode then if pos > stop then return incomplete(ctx) end mode = byte(code, pos, pos) pos = pos+1 end rm = mode%8; mode = (mode-rm)/8 sp = mode%8; mode = (mode-sp)/8 sdisp = "" if mode < 3 then if rm == 4 then if pos > stop then return incomplete(ctx) end sc = byte(code, pos, pos) pos = pos+1 rm = sc%8; sc = (sc-rm)/8 rx = sc%8; sc = (sc-rx)/8 if ctx.rexx then rx = rx + 8; ctx.rexx = false end if rx == 4 then rx = nil end end if mode > 0 or rm == 5 then local dsz = mode if dsz ~= 1 then dsz = 4 end local disp = getimm(ctx, pos, dsz); if not disp then return end if mode == 0 then rm = nil end if rm or rx or (not sc and ctx.x64 and not ctx.a32) then if dsz == 1 and disp > 127 then sdisp = format("-0x%x", 256-disp) elseif disp >= 0 and disp <= 0x7fffffff then sdisp = format("+0x%x", disp) else sdisp = format("-0x%x", (0xffffffff+1)-disp) end else sdisp = format(ctx.x64 and not ctx.a32 and not (disp >= 0 and disp <= 0x7fffffff) and "0xffffffff%08x" or "0x%08x", disp) end pos = pos+dsz end end if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end if ctx.rexr then sp = sp + 8; ctx.rexr = false end end if p == "m" then if mode == 3 then x = regs[rm+1] else local aregs = ctx.a32 and map_regs.D or ctx.aregs local srm, srx = "", "" if rm then srm = aregs[rm+1] elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end ctx.a32 = false if rx then if rm then srm = srm.."+" end srx = aregs[rx+1] if sc > 0 then srx = srx.."*"..(2^sc) end end x = format("[%s%s%s]", srm, srx, sdisp) end if mode < 3 and (not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck. x = map_sz2prefix[sz].." "..x end elseif p == "r" then x = regs[sp+1] elseif p == "g" then x = map_segregs[sp+1] elseif p == "p" then -- Suppress prefix. elseif p == "f" then x = "st"..rm elseif p == "x" then if sp == 0 and ctx.lock and not ctx.x64 then x = "CR8"; ctx.lock = false else x = "CR"..sp end elseif p == "v" then if ctx.vexv then x = regs[ctx.vexv+1]; ctx.vexv = false end elseif p == "y" then x = "DR"..sp elseif p == "z" then x = "TR"..sp elseif p == "l" then vexl = false elseif p == "t" then else error("bad pattern `"..pat.."'") end end if x then operands = operands and operands..", "..x or x end end ctx.pos = pos return putop(ctx, name, operands) end -- Forward declaration. local map_act -- Fetch and cache MRM byte. local function getmrm(ctx) local mrm = ctx.mrm if not mrm then local pos = ctx.pos if pos > ctx.stop then return nil end mrm = byte(ctx.code, pos, pos) ctx.pos = pos+1 ctx.mrm = mrm end return mrm end -- Dispatch to handler depending on pattern. local function dispatch(ctx, opat, patgrp) if not opat then return unknown(ctx) end if match(opat, "%|") then -- MMX/SSE variants depending on prefix. local p if ctx.rep then p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)" ctx.rep = false elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false else p = "^[^%|]*" end opat = match(opat, p) if not opat then return unknown(ctx) end -- ctx.rep = false; ctx.o16 = false --XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi] --XXX remove in branches? end if match(opat, "%$") then -- reg$mem variants. local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)") if opat == "" then return unknown(ctx) end end if opat == "" then return unknown(ctx) end local name, pat = match(opat, "^([a-z0-9 ]*)(.*)") if pat == "" and patgrp then pat = patgrp end return map_act[sub(pat, 1, 1)](ctx, name, pat) end -- Get a pattern from an opcode map and dispatch to handler. local function dispatchmap(ctx, opcmap) local pos = ctx.pos local opat = opcmap[byte(ctx.code, pos, pos)] pos = pos + 1 ctx.pos = pos return dispatch(ctx, opat) end -- Map for action codes. The key is the first char after the name. map_act = { -- Simple opcodes without operands. [""] = function(ctx, name, pat) return putop(ctx, name) end, -- Operand size chars fall right through. B = putpat, W = putpat, D = putpat, Q = putpat, V = putpat, U = putpat, T = putpat, M = putpat, X = putpat, P = putpat, F = putpat, G = putpat, Y = putpat, H = putpat, -- Collect prefixes. [":"] = function(ctx, name, pat) ctx[pat == ":" and name or sub(pat, 2)] = name if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes. end, -- Chain to special handler specified by name. ["*"] = function(ctx, name, pat) return map_act[name](ctx, name, sub(pat, 2)) end, -- Use named subtable for opcode group. ["!"] = function(ctx, name, pat) local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2)) end, -- o16,o32[,o64] variants. sz = function(ctx, name, pat) if ctx.o16 then ctx.o16 = false else pat = match(pat, ",(.*)") if ctx.rexw then local p = match(pat, ",(.*)") if p then pat = p; ctx.rexw = false end end end pat = match(pat, "^[^,]*") return dispatch(ctx, pat) end, -- Two-byte opcode dispatch. opc2 = function(ctx, name, pat) return dispatchmap(ctx, map_opc2) end, -- Three-byte opcode dispatch. opc3 = function(ctx, name, pat) return dispatchmap(ctx, map_opc3[pat]) end, -- VMX/SVM dispatch. vm = function(ctx, name, pat) return dispatch(ctx, map_opcvm[ctx.mrm]) end, -- Floating point opcode dispatch. fp = function(ctx, name, pat) local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end local rm = mrm%8 local idx = pat*8 + ((mrm-rm)/8)%8 if mrm >= 192 then idx = idx + 64 end local opat = map_opcfp[idx] if type(opat) == "table" then opat = opat[rm+1] end return dispatch(ctx, opat) end, -- REX prefix. rex = function(ctx, name, pat) if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. for p in gmatch(pat, ".") do ctx["rex"..p] = true end ctx.rex = "rex" end, -- VEX prefix. vex = function(ctx, name, pat) if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed. ctx.rex = "vex" local pos = ctx.pos if ctx.mrm then ctx.mrm = nil pos = pos-1 end local b = byte(ctx.code, pos, pos) if not b then return incomplete(ctx) end pos = pos+1 if b < 128 then ctx.rexr = true end local m = 1 if pat == "3" then m = b%32; b = (b-m)/32 local nb = b%2; b = (b-nb)/2 if nb == 0 then ctx.rexb = true end local nx = b%2 if nx == 0 then ctx.rexx = true end b = byte(ctx.code, pos, pos) if not b then return incomplete(ctx) end pos = pos+1 if b >= 128 then ctx.rexw = true end end ctx.pos = pos local map if m == 1 then map = map_opc2 elseif m == 2 then map = map_opc3["38"] elseif m == 3 then map = map_opc3["3a"] else return unknown(ctx) end local p = b%4; b = (b-p)/4 if p == 1 then ctx.o16 = "o16" elseif p == 2 then ctx.rep = "rep" elseif p == 3 then ctx.rep = "repne" end local l = b%2; b = (b-l)/2 if l ~= 0 then ctx.vexl = true end ctx.vexv = (-1-b)%16 return dispatchmap(ctx, map) end, -- Special case for nop with REX prefix. nop = function(ctx, name, pat) return dispatch(ctx, ctx.rex and pat or "nop") end, -- Special case for 0F 77. emms = function(ctx, name, pat) if ctx.rex ~= "vex" then return putop(ctx, "emms") elseif ctx.vexl then ctx.vexl = false return putop(ctx, "zeroall") else return putop(ctx, "zeroupper") end end, } ------------------------------------------------------------------------------ -- Disassemble a block of code. local function disass_block(ctx, ofs, len) if not ofs then ofs = 0 end local stop = len and ofs+len or #ctx.code ofs = ofs + 1 ctx.start = ofs ctx.pos = ofs ctx.stop = stop ctx.imm = nil ctx.mrm = false clearprefixes(ctx) while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end if ctx.pos ~= ctx.start then incomplete(ctx) end end -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). local function create(code, addr, out) local ctx = {} ctx.code = code ctx.addr = (addr or 0) - 1 ctx.out = out or io.write ctx.symtab = {} ctx.disass = disass_block ctx.hexdump = 16 ctx.x64 = false ctx.map1 = map_opc1_32 ctx.aregs = map_regs.D return ctx end local function create64(code, addr, out) local ctx = create(code, addr, out) ctx.x64 = true ctx.map1 = map_opc1_64 ctx.aregs = map_regs.Q return ctx end -- Simple API: disassemble code (a string) at address and output via out. local function disass(code, addr, out) create(code, addr, out):disass() end local function disass64(code, addr, out) create64(code, addr, out):disass() end -- Return register name for RID. local function regname(r) if r < 8 then return map_regs.D[r+1] end return map_regs.X[r-7] end local function regname64(r) if r < 16 then return map_regs.Q[r+1] end return map_regs.X[r-15] end -- Public module functions. return { create = create, create64 = create64, disass = disass, disass64 = disass64, regname = regname, regname64 = regname64 } ================================================ FILE: Luajit64/jit/dump.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT compiler dump module. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module can be used to debug the JIT compiler itself. It dumps the -- code representations and structures used in various compiler stages. -- -- Example usage: -- -- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)" -- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R -- luajit -jdump=is myapp.lua | less -R -- luajit -jdump=-b myapp.lua -- luajit -jdump=+aH,myapp.html myapp.lua -- luajit -jdump=ixT,myapp.dump myapp.lua -- -- The first argument specifies the dump mode. The second argument gives -- the output file name. Default output is to stdout, unless the environment -- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the -- module is started. -- -- Different features can be turned on or off with the dump mode. If the -- mode starts with a '+', the following features are added to the default -- set of features; a '-' removes them. Otherwise the features are replaced. -- -- The following dump features are available (* marks the default): -- -- * t Print a line for each started, ended or aborted trace (see also -jv). -- * b Dump the traced bytecode. -- * i Dump the IR (intermediate representation). -- r Augment the IR with register/stack slots. -- s Dump the snapshot map. -- * m Dump the generated machine code. -- x Print each taken trace exit. -- X Print each taken trace exit and the contents of all registers. -- a Print the IR of aborted traces, too. -- -- The output format can be set with the following characters: -- -- T Plain text output. -- A ANSI-colored text output -- H Colorized HTML + CSS output. -- -- The default output format is plain text. It's set to ANSI-colored text -- if the COLORTERM variable is set. Note: this is independent of any output -- redirection, which is actually considered a feature. -- -- You probably want to use less -R to enjoy viewing ANSI-colored text from -- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R" -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr local bit = require("bit") local band, shr, tohex = bit.band, bit.rshift, bit.tohex local sub, gsub, format = string.sub, string.gsub, string.format local byte, rep = string.byte, string.rep local type, tostring = type, tostring local stdout, stderr = io.stdout, io.stderr -- Load other modules on-demand. local bcline, disass -- Active flag, output file handle and dump mode. local active, out, dumpmode ------------------------------------------------------------------------------ local symtabmt = { __index = false } local symtab = {} local nexitsym = 0 -- Fill nested symbol table with per-trace exit stub addresses. local function fillsymtab_tr(tr, nexit) local t = {} symtabmt.__index = t if jit.arch:sub(1, 4) == "mips" then t[traceexitstub(tr, 0)] = "exit" return end for i=0,nexit-1 do local addr = traceexitstub(tr, i) if addr < 0 then addr = addr + 2^32 end t[addr] = tostring(i) end local addr = traceexitstub(tr, nexit) if addr then t[addr] = "stack_check" end end -- Fill symbol table with trace exit stub addresses. local function fillsymtab(tr, nexit) local t = symtab if nexitsym == 0 then local ircall = vmdef.ircall for i=0,#ircall do local addr = ircalladdr(i) if addr ~= 0 then if addr < 0 then addr = addr + 2^32 end t[addr] = ircall[i] end end end if nexitsym == 1000000 then -- Per-trace exit stubs. fillsymtab_tr(tr, nexit) elseif nexit > nexitsym then -- Shared exit stubs. for i=nexitsym,nexit-1 do local addr = traceexitstub(i) if addr == nil then -- Fall back to per-trace exit stubs. fillsymtab_tr(tr, nexit) setmetatable(symtab, symtabmt) nexit = 1000000 break end if addr < 0 then addr = addr + 2^32 end t[addr] = tostring(i) end nexitsym = nexit end return t end local function dumpwrite(s) out:write(s) end -- Disassemble machine code. local function dump_mcode(tr) local info = traceinfo(tr) if not info then return end local mcode, addr, loop = tracemc(tr) if not mcode then return end if not disass then disass = require("jit.dis_"..jit.arch) end if addr < 0 then addr = addr + 2^32 end out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") local ctx = disass.create(mcode, addr, dumpwrite) ctx.hexdump = 0 ctx.symtab = fillsymtab(tr, info.nexit) if loop ~= 0 then symtab[addr+loop] = "LOOP" ctx:disass(0, loop) out:write("->LOOP:\n") ctx:disass(loop, #mcode-loop) symtab[addr+loop] = nil else ctx:disass(0, #mcode) end end ------------------------------------------------------------------------------ local irtype_text = { [0] = "nil", "fal", "tru", "lud", "str", "p32", "thr", "pro", "fun", "p64", "cdt", "tab", "udt", "flt", "num", "i8 ", "u8 ", "i16", "u16", "int", "u32", "i64", "u64", "sfp", } local colortype_ansi = { [0] = "%s", "%s", "%s", "\027[36m%s\027[m", "\027[32m%s\027[m", "%s", "\027[1m%s\027[m", "%s", "\027[1m%s\027[m", "%s", "\027[33m%s\027[m", "\027[31m%s\027[m", "\027[36m%s\027[m", "\027[34m%s\027[m", "\027[34m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", "\027[35m%s\027[m", } local function colorize_text(s) return s end local function colorize_ansi(s, t) return format(colortype_ansi[t], s) end local irtype_ansi = setmetatable({}, { __index = function(tab, t) local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end }) local html_escape = { ["<"] = "<", [">"] = ">", ["&"] = "&", } local function colorize_html(s, t) s = gsub(s, "[<>&]", html_escape) return format('%s', irtype_text[t], s) end local irtype_html = setmetatable({}, { __index = function(tab, t) local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end }) local header_html = [[ ]] local colorize, irtype -- Lookup tables to convert some literals into names. local litname = { ["SLOAD "] = setmetatable({}, { __index = function(t, mode) local s = "" if band(mode, 1) ~= 0 then s = s.."P" end if band(mode, 2) ~= 0 then s = s.."F" end if band(mode, 4) ~= 0 then s = s.."T" end if band(mode, 8) ~= 0 then s = s.."C" end if band(mode, 16) ~= 0 then s = s.."R" end if band(mode, 32) ~= 0 then s = s.."I" end t[mode] = s return s end}), ["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", }, ["CONV "] = setmetatable({}, { __index = function(t, mode) local s = irtype[band(mode, 31)] s = irtype[band(shr(mode, 5), 31)].."."..s if band(mode, 0x800) ~= 0 then s = s.." sext" end local c = shr(mode, 14) if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end t[mode] = s return s end}), ["FLOAD "] = vmdef.irfield, ["FREF "] = vmdef.irfield, ["FPMATH"] = vmdef.irfpm, ["BUFHDR"] = { [0] = "RESET", "APPEND" }, ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, } local function ctlsub(c) if c == "\n" then return "\\n" elseif c == "\r" then return "\\r" elseif c == "\t" then return "\\t" else return format("\\%03d", byte(c)) end end local function fmtfunc(func, pc) local fi = funcinfo(func, pc) if fi.loc then return fi.loc elseif fi.ffid then return vmdef.ffnames[fi.ffid] elseif fi.addr then return format("C:%x", fi.addr) else return "(?)" end end local function formatk(tr, idx, sn) local k, t, slot = tracek(tr, idx) local tn = type(k) local s if tn == "number" then if band(sn or 0, 0x30000) ~= 0 then s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz" elseif k == 2^52+2^51 then s = "bias" else s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k) end elseif tn == "string" then s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) elseif tn == "function" then s = fmtfunc(k) elseif tn == "table" then s = format("{%p}", k) elseif tn == "userdata" then if t == 12 then s = format("userdata:%p", k) else s = format("[%p]", k) if s == "[NULL]" then s = "NULL" end end elseif t == 21 then -- int64_t s = sub(tostring(k), 1, -3) if sub(s, 1, 1) ~= "-" then s = "+"..s end elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL) return "----" -- Special case for LJ_FR2 slot 1. else s = tostring(k) -- For primitives. end s = colorize(format("%-4s", s), t) if slot then s = format("%s @%d", s, slot) end return s end local function printsnap(tr, snap) local n = 2 for s=0,snap[1]-1 do local sn = snap[n] if shr(sn, 24) == s then n = n + 1 local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS if ref < 0 then out:write(formatk(tr, ref, sn)) elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM out:write(colorize(format("%04d/%04d", ref, ref+1), 14)) else local m, ot, op1, op2 = traceir(tr, ref) out:write(colorize(format("%04d", ref), band(ot, 31))) end out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME else out:write("---- ") end end out:write("]\n") end -- Dump snapshots (not interleaved with IR). local function dump_snap(tr) out:write("---- TRACE ", tr, " snapshots\n") for i=0,1000000000 do local snap = tracesnap(tr, i) if not snap then break end out:write(format("#%-3d %04d [ ", i, snap[0])) printsnap(tr, snap) end end -- Return a register name or stack slot for a rid/sp location. local function ridsp_name(ridsp, ins) if not disass then disass = require("jit.dis_"..jit.arch) end local rid, slot = band(ridsp, 0xff), shr(ridsp, 8) if rid == 253 or rid == 254 then return (slot == 0 or slot == 255) and " {sink" or format(" {%04d", ins-slot) end if ridsp > 255 then return format("[%x]", slot*4) end if rid < 128 then return disass.regname(rid) end return "" end -- Dump CALL* function ref and return optional ctype. local function dumpcallfunc(tr, ins) local ctype if ins > 0 then local m, ot, op1, op2 = traceir(tr, ins) if band(ot, 31) == 0 then -- nil type means CARG(func, ctype). ins = op1 ctype = formatk(tr, op2) end end if ins < 0 then out:write(format("[0x%x](", tonumber((tracek(tr, ins))))) else out:write(format("%04d (", ins)) end return ctype end -- Recursively gather CALL* args and dump them. local function dumpcallargs(tr, ins) if ins < 0 then out:write(formatk(tr, ins)) else local m, ot, op1, op2 = traceir(tr, ins) local oidx = 6*shr(ot, 8) local op = sub(vmdef.irnames, oidx+1, oidx+6) if op == "CARG " then dumpcallargs(tr, op1) if op2 < 0 then out:write(" ", formatk(tr, op2)) else out:write(" ", format("%04d", op2)) end else out:write(format("%04d", ins)) end end end -- Dump IR and interleaved snapshots. local function dump_ir(tr, dumpsnap, dumpreg) local info = traceinfo(tr) if not info then return end local nins = info.nins out:write("---- TRACE ", tr, " IR\n") local irnames = vmdef.irnames local snapref = 65536 local snap, snapno if dumpsnap then snap = tracesnap(tr, 0) snapref = snap[0] snapno = 0 end for ins=1,nins do if ins >= snapref then if dumpreg then out:write(format(".... SNAP #%-3d [ ", snapno)) else out:write(format(".... SNAP #%-3d [ ", snapno)) end printsnap(tr, snap) snapno = snapno + 1 snap = tracesnap(tr, snapno) snapref = snap and snap[0] or 65536 end local m, ot, op1, op2, ridsp = traceir(tr, ins) local oidx, t = 6*shr(ot, 8), band(ot, 31) local op = sub(irnames, oidx+1, oidx+6) if op == "LOOP " then if dumpreg then out:write(format("%04d ------------ LOOP ------------\n", ins)) else out:write(format("%04d ------ LOOP ------------\n", ins)) end elseif op ~= "NOP " and op ~= "CARG " and (dumpreg or op ~= "RENAME") then local rid = band(ridsp, 255) if dumpreg then out:write(format("%04d %-6s", ins, ridsp_name(ridsp, ins))) else out:write(format("%04d ", ins)) end out:write(format("%s%s %s %s ", (rid == 254 or rid == 253) and "}" or (band(ot, 128) == 0 and " " or ">"), band(ot, 64) == 0 and " " or "+", irtype[t], op)) local m1, m2 = band(m, 3), band(m, 3*4) if sub(op, 1, 4) == "CALL" then local ctype if m2 == 1*4 then -- op2 == IRMlit out:write(format("%-10s (", vmdef.ircall[op2])) else ctype = dumpcallfunc(tr, op2) end if op1 ~= -1 then dumpcallargs(tr, op1) end out:write(")") if ctype then out:write(" ctype ", ctype) end elseif op == "CNEW " and op2 == -1 then out:write(formatk(tr, op1)) elseif m1 ~= 3 then -- op1 != IRMnone if op1 < 0 then out:write(formatk(tr, op1)) else out:write(format(m1 == 0 and "%04d" or "#%-3d", op1)) end if m2 ~= 3*4 then -- op2 != IRMnone if m2 == 1*4 then -- op2 == IRMlit local litn = litname[op] if litn and litn[op2] then out:write(" ", litn[op2]) elseif op == "UREFO " or op == "UREFC " then out:write(format(" #%-3d", shr(op2, 8))) else out:write(format(" #%-3d", op2)) end elseif op2 < 0 then out:write(" ", formatk(tr, op2)) else out:write(format(" %04d", op2)) end end end out:write("\n") end end if snap then if dumpreg then out:write(format(".... SNAP #%-3d [ ", snapno)) else out:write(format(".... SNAP #%-3d [ ", snapno)) end printsnap(tr, snap) end end ------------------------------------------------------------------------------ local recprefix = "" local recdepth = 0 -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err end -- Dump trace states. local function dump_trace(what, tr, func, pc, otr, oex) if what == "stop" or (what == "abort" and dumpmode.a) then if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop") elseif dumpmode.s then dump_snap(tr) end if dumpmode.m then dump_mcode(tr) end end if what == "start" then if dumpmode.H then out:write('
\n') end
    out:write("---- TRACE ", tr, " ", what)
    if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
    out:write(" ", fmtfunc(func, pc), "\n")
  elseif what == "stop" or what == "abort" then
    out:write("---- TRACE ", tr, " ", what)
    if what == "abort" then
      out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
    else
      local info = traceinfo(tr)
      local link, ltype = info.link, info.linktype
      if link == tr or link == 0 then
	out:write(" -> ", ltype, "\n")
      elseif ltype == "root" then
	out:write(" -> ", link, "\n")
      else
	out:write(" -> ", link, " ", ltype, "\n")
      end
    end
    if dumpmode.H then out:write("
\n\n") else out:write("\n") end else if what == "flush" then symtab, nexitsym = {}, 0 end out:write("---- TRACE ", what, "\n\n") end out:flush() end -- Dump recorded bytecode. local function dump_record(tr, func, pc, depth, callee) if depth ~= recdepth then recdepth = depth recprefix = rep(" .", depth) end local line if pc >= 0 then line = bcline(func, pc, recprefix) if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end if pc > 0 then line = sub(line, 1, -2) .. " (" .. fmtfunc(func, pc) .. ")\n" end else line = "0000 "..recprefix.." FUNCC \n" callee = func end if pc <= 0 then out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n") else out:write(line) end if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond. end end ------------------------------------------------------------------------------ -- Dump taken trace exits. local function dump_texit(tr, ex, ngpr, nfpr, ...) out:write("---- TRACE ", tr, " exit ", ex, "\n") if dumpmode.X then local regs = {...} if jit.arch == "x64" then for i=1,ngpr do out:write(format(" %016x", regs[i])) if i % 4 == 0 then out:write("\n") end end else for i=1,ngpr do out:write(" ", tohex(regs[i])) if i % 8 == 0 then out:write("\n") end end end if jit.arch == "mips" or jit.arch == "mipsel" then for i=1,nfpr,2 do out:write(format(" %+17.14g", regs[ngpr+i])) if i % 8 == 7 then out:write("\n") end end else for i=1,nfpr do out:write(format(" %+17.14g", regs[ngpr+i])) if i % 4 == 0 then out:write("\n") end end end end end ------------------------------------------------------------------------------ -- Detach dump handlers. local function dumpoff() if active then active = false jit.attach(dump_texit) jit.attach(dump_record) jit.attach(dump_trace) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach dump handlers. local function dumpon(opt, outfile) if active then dumpoff() end local term = os.getenv("TERM") local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T" if opt then opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end) end local m = { t=true, b=true, i=true, m=true, } if opt and opt ~= "" then local o = sub(opt, 1, 1) if o ~= "+" and o ~= "-" then m = {} end for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end end dumpmode = m if m.t or m.b or m.i or m.s or m.m then jit.attach(dump_trace, "trace") end if m.b then jit.attach(dump_record, "record") if not bcline then bcline = require("jit.bc").line end end if m.x or m.X then jit.attach(dump_texit, "texit") end if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stdout end m[colormode] = true if colormode == "A" then colorize = colorize_ansi irtype = irtype_ansi elseif colormode == "H" then colorize = colorize_html irtype = irtype_html out:write(header_html) else colorize = colorize_text irtype = irtype_text end active = true end -- Public module functions. return { on = dumpon, off = dumpoff, start = dumpon -- For -j command line option. } ================================================ FILE: Luajit64/jit/p.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT profiler. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module is a simple command line interface to the built-in -- low-overhead profiler of LuaJIT. -- -- The lower-level API of the profiler is accessible via the "jit.profile" -- module or the luaJIT_profile_* C API. -- -- Example usage: -- -- luajit -jp myapp.lua -- luajit -jp=s myapp.lua -- luajit -jp=-s myapp.lua -- luajit -jp=vl myapp.lua -- luajit -jp=G,profile.txt myapp.lua -- -- The following dump features are available: -- -- f Stack dump: function name, otherwise module:line. Default mode. -- F Stack dump: ditto, but always prepend module. -- l Stack dump: module:line. -- stack dump depth (callee < caller). Default: 1. -- - Inverse stack dump depth (caller > callee). -- s Split stack dump after first stack level. Implies abs(depth) >= 2. -- p Show full path for module names. -- v Show VM states. Can be combined with stack dumps, e.g. vf or fv. -- z Show zones. Can be combined with stack dumps, e.g. zf or fz. -- r Show raw sample counts. Default: show percentages. -- a Annotate excerpts from source code files. -- A Annotate complete source code files. -- G Produce raw output suitable for graphical tools (e.g. flame graphs). -- m Minimum sample percentage to be shown. Default: 3. -- i Sampling interval in milliseconds. Default: 10. -- ---------------------------------------------------------------------------- -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local profile = require("jit.profile") local vmdef = require("jit.vmdef") local math = math local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor local sort, format = table.sort, string.format local stdout = io.stdout local zone -- Load jit.zone module on demand. -- Output file handle. local out ------------------------------------------------------------------------------ local prof_ud local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth local prof_ann, prof_count1, prof_count2, prof_samples local map_vmmode = { N = "Compiled", I = "Interpreted", C = "C code", G = "Garbage Collector", J = "JIT Compiler", } -- Profiler callback. local function prof_cb(th, samples, vmmode) prof_samples = prof_samples + samples local key_stack, key_stack2, key_state -- Collect keys for sample. if prof_states then if prof_states == "v" then key_state = map_vmmode[vmmode] or vmmode else key_state = zone:get() or "(none)" end end if prof_fmt then key_stack = profile.dumpstack(th, prof_fmt, prof_depth) key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x) return vmdef.ffnames[tonumber(x)] end) if prof_split == 2 then local k1, k2 = key_stack:match("(.-) [<>] (.*)") if k2 then key_stack, key_stack2 = k1, k2 end elseif prof_split == 3 then key_stack2 = profile.dumpstack(th, "l", 1) end end -- Order keys. local k1, k2 if prof_split == 1 then if key_state then k1 = key_state if key_stack then k2 = key_stack end end elseif key_stack then k1 = key_stack if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end end -- Coalesce samples in one or two levels. if k1 then local t1 = prof_count1 t1[k1] = (t1[k1] or 0) + samples if k2 then local t2 = prof_count2 local t3 = t2[k1] if not t3 then t3 = {}; t2[k1] = t3 end t3[k2] = (t3[k2] or 0) + samples end end end ------------------------------------------------------------------------------ -- Show top N list. local function prof_top(count1, count2, samples, indent) local t, n = {}, 0 for k in pairs(count1) do n = n + 1 t[n] = k end sort(t, function(a, b) return count1[a] > count1[b] end) for i=1,n do local k = t[i] local v = count1[k] local pct = floor(v*100/samples + 0.5) if pct < prof_min then break end if not prof_raw then out:write(format("%s%2d%% %s\n", indent, pct, k)) elseif prof_raw == "r" then out:write(format("%s%5d %s\n", indent, v, k)) else out:write(format("%s %d\n", k, v)) end if count2 then local r = count2[k] if r then prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or (prof_depth < 0 and " -> " or " <- ")) end end end end -- Annotate source code local function prof_annotate(count1, samples) local files = {} local ms = 0 for k, v in pairs(count1) do local pct = floor(v*100/samples + 0.5) ms = math.max(ms, v) if pct >= prof_min then local file, line = k:match("^(.*):(%d+)$") if not file then file = k; line = 0 end local fl = files[file] if not fl then fl = {}; files[file] = fl; files[#files+1] = file end line = tonumber(line) fl[line] = prof_raw and v or pct end end sort(files) local fmtv, fmtn = " %3d%% | %s\n", " | %s\n" if prof_raw then local n = math.max(5, math.ceil(math.log10(ms))) fmtv = "%"..n.."d | %s\n" fmtn = (" "):rep(n).." | %s\n" end local ann = prof_ann for _, file in ipairs(files) do local f0 = file:byte() if f0 == 40 or f0 == 91 then out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file)) break end local fp, err = io.open(file) if not fp then out:write(format("====== ERROR: %s: %s\n", file, err)) break end out:write(format("\n====== %s ======\n", file)) local fl = files[file] local n, show = 1, false if ann ~= 0 then for i=1,ann do if fl[i] then show = true; out:write("@@ 1 @@\n"); break end end end for line in fp:lines() do if line:byte() == 27 then out:write("[Cannot annotate bytecode file]\n") break end local v = fl[n] if ann ~= 0 then local v2 = fl[n+ann] if show then if v2 then show = n+ann elseif v then show = n elseif show+ann < n then show = false end elseif v2 then show = n+ann out:write(format("@@ %d @@\n", n)) end if not show then goto next end end if v then out:write(format(fmtv, v, line)) else out:write(format(fmtn, line)) end ::next:: n = n + 1 end fp:close() end end ------------------------------------------------------------------------------ -- Finish profiling and dump result. local function prof_finish() if prof_ud then profile.stop() local samples = prof_samples if samples == 0 then if prof_raw ~= true then out:write("[No samples collected]\n") end return end if prof_ann then prof_annotate(prof_count1, samples) else prof_top(prof_count1, prof_count2, samples, "") end prof_count1 = nil prof_count2 = nil prof_ud = nil end end -- Start profiling. local function prof_start(mode) local interval = "" mode = mode:gsub("i%d*", function(s) interval = s; return "" end) prof_min = 3 mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end) prof_depth = 1 mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end) local m = {} for c in mode:gmatch(".") do m[c] = c end prof_states = m.z or m.v if prof_states == "z" then zone = require("jit.zone") end local scope = m.l or m.f or m.F or (prof_states and "" or "f") local flags = (m.p or "") prof_raw = m.r if m.s then prof_split = 2 if prof_depth == -1 or m["-"] then prof_depth = -2 elseif prof_depth == 1 then prof_depth = 2 end elseif mode:find("[fF].*l") then scope = "l" prof_split = 3 else prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0 end prof_ann = m.A and 0 or (m.a and 3) if prof_ann then scope = "l" prof_fmt = "pl" prof_split = 0 prof_depth = 1 elseif m.G and scope ~= "" then prof_fmt = flags..scope.."Z;" prof_depth = -100 prof_raw = true prof_min = 0 elseif scope == "" then prof_fmt = false else local sc = prof_split == 3 and m.f or m.F or scope prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ") end prof_count1 = {} prof_count2 = {} prof_samples = 0 profile.start(scope:lower()..interval, prof_cb) prof_ud = newproxy(true) getmetatable(prof_ud).__gc = prof_finish end ------------------------------------------------------------------------------ local function start(mode, outfile) if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stdout end prof_start(mode or "f") end -- Public module functions. return { start = start, -- For -j command line option. stop = prof_finish } ================================================ FILE: Luajit64/jit/v.lua ================================================ ---------------------------------------------------------------------------- -- Verbose mode of the LuaJIT compiler. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module shows verbose information about the progress of the -- JIT compiler. It prints one line for each generated trace. This module -- is useful to see which code has been compiled or where the compiler -- punts and falls back to the interpreter. -- -- Example usage: -- -- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end" -- luajit -jv=myapp.out myapp.lua -- -- Default output is to stderr. To redirect the output to a file, pass a -- filename as an argument (use '-' for stdout) or set the environment -- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the -- module is started. -- -- The output from the first example should look like this: -- -- [TRACE 1 (command line):1 loop] -- [TRACE 2 (1/3) (command line):1 -> 1] -- -- The first number in each line is the internal trace number. Next are -- the file name ('(command line)') and the line number (':1') where the -- trace has started. Side traces also show the parent trace number and -- the exit number where they are attached to in parentheses ('(1/3)'). -- An arrow at the end shows where the trace links to ('-> 1'), unless -- it loops to itself. -- -- In this case the inner loop gets hot and is traced first, generating -- a root trace. Then the last exit from the 1st trace gets hot, too, -- and triggers generation of the 2nd trace. The side trace follows the -- path along the outer loop and *around* the inner loop, back to its -- start, and then links to the 1st trace. Yes, this may seem unusual, -- if you know how traditional compilers work. Trace compilers are full -- of surprises like this -- have fun! :-) -- -- Aborted traces are shown like this: -- -- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50] -- -- Don't worry -- trace aborts are quite common, even in programs which -- can be fully compiled. The compiler may retry several times until it -- finds a suitable trace. -- -- Of course this doesn't work with features that are not-yet-implemented -- (NYI error messages). The VM simply falls back to the interpreter. This -- may not matter at all if the particular trace is not very high up in -- the CPU usage profile. Oh, and the interpreter is quite fast, too. -- -- Also check out the -jdump module, which prints all the gory details. -- ------------------------------------------------------------------------------ -- Cache some library functions and objects. local jit = require("jit") assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo local type, format = type, string.format local stdout, stderr = io.stdout, io.stderr -- Active flag and output file handle. local active, out ------------------------------------------------------------------------------ local startloc, startex local function fmtfunc(func, pc) local fi = funcinfo(func, pc) if fi.loc then return fi.loc elseif fi.ffid then return vmdef.ffnames[fi.ffid] elseif fi.addr then return format("C:%x", fi.addr) else return "(?)" end end -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err end -- Dump trace states. local function dump_trace(what, tr, func, pc, otr, oex) if what == "start" then startloc = fmtfunc(func, pc) startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or "" else if what == "abort" then local loc = fmtfunc(func, pc) if loc ~= startloc then out:write(format("[TRACE --- %s%s -- %s at %s]\n", startex, startloc, fmterr(otr, oex), loc)) else out:write(format("[TRACE --- %s%s -- %s]\n", startex, startloc, fmterr(otr, oex))) end elseif what == "stop" then local info = traceinfo(tr) local link, ltype = info.link, info.linktype if ltype == "interpreter" then out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n", tr, startex, startloc)) elseif ltype == "stitch" then out:write(format("[TRACE %3s %s%s %s %s]\n", tr, startex, startloc, ltype, fmtfunc(func, pc))) elseif link == tr or link == 0 then out:write(format("[TRACE %3s %s%s %s]\n", tr, startex, startloc, ltype)) elseif ltype == "root" then out:write(format("[TRACE %3s %s%s -> %d]\n", tr, startex, startloc, link)) else out:write(format("[TRACE %3s %s%s -> %d %s]\n", tr, startex, startloc, link, ltype)) end else out:write(format("[TRACE %s]\n", what)) end out:flush() end end ------------------------------------------------------------------------------ -- Detach dump handlers. local function dumpoff() if active then active = false jit.attach(dump_trace) if out and out ~= stdout and out ~= stderr then out:close() end out = nil end end -- Open the output file and attach dump handlers. local function dumpon(outfile) if active then dumpoff() end if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end if outfile then out = outfile == "-" and stdout or assert(io.open(outfile, "w")) else out = stderr end jit.attach(dump_trace, "trace") active = true end -- Public module functions. return { on = dumpon, off = dumpoff, start = dumpon -- For -j command line option. } ================================================ FILE: Luajit64/jit/vmdef.lua ================================================ -- This is a generated file. DO NOT EDIT! return { bcnames = "ISLT ISGE ISLE ISGT ISEQV ISNEV ISEQS ISNES ISEQN ISNEN ISEQP ISNEP ISTC ISFC IST ISF ISTYPEISNUM MOV NOT UNM LEN ADDVN SUBVN MULVN DIVVN MODVN ADDNV SUBNV MULNV DIVNV MODNV ADDVV SUBVV MULVV DIVVV MODVV POW CAT KSTR KCDATAKSHORTKNUM KPRI KNIL UGET USETV USETS USETN USETP UCLO FNEW TNEW TDUP GGET GSET TGETV TGETS TGETB TGETR TSETV TSETS TSETB TSETM TSETR CALLM CALL CALLMTCALLT ITERC ITERN VARG ISNEXTRETM RET RET0 RET1 FORI JFORI FORL IFORL JFORL ITERL IITERLJITERLLOOP ILOOP JLOOP JMP FUNCF IFUNCFJFUNCFFUNCV IFUNCVJFUNCVFUNCC FUNCCW", irnames = "LT GE LE GT ULT UGE ULE UGT EQ NE ABC RETF NOP BASE PVAL GCSTEPHIOP LOOP USE PHI RENAMEPROF KPRI KINT KGC KPTR KKPTR KNULL KNUM KINT64KSLOT BNOT BSWAP BAND BOR BXOR BSHL BSHR BSAR BROL BROR ADD SUB MUL DIV MOD POW NEG ABS ATAN2 LDEXP MIN MAX FPMATHADDOV SUBOV MULOV AREF HREFK HREF NEWREFUREFO UREFC FREF STRREFLREF ALOAD HLOAD ULOAD FLOAD XLOAD SLOAD VLOAD ASTOREHSTOREUSTOREFSTOREXSTORESNEW XSNEW TNEW TDUP CNEW CNEWI BUFHDRBUFPUTBUFSTRTBAR OBAR XBAR CONV TOBIT TOSTR STRTO CALLN CALLA CALLL CALLS CALLXSCARG ", irfpm = { [0]="floor", "ceil", "trunc", "sqrt", "exp", "exp2", "log", "log2", "log10", "sin", "cos", "tan", "other", }, irfield = { [0]="str.len", "func.env", "func.pc", "func.ffid", "thread.env", "thread.exdata", "tab.meta", "tab.array", "tab.node", "tab.asize", "tab.hmask", "tab.nomm", "udata.meta", "udata.udtype", "udata.file", "cdata.ctypeid", "cdata.ptr", "cdata.int", "cdata.int64", "cdata.int64_4", }, ircall = { [0]="lj_str_cmp", "lj_str_find", "lj_str_new", "lj_strscan_num", "lj_strfmt_int", "lj_strfmt_num", "lj_strfmt_char", "lj_strfmt_putint", "lj_strfmt_putnum", "lj_strfmt_putquoted", "lj_strfmt_putfxint", "lj_strfmt_putfnum_int", "lj_strfmt_putfnum_uint", "lj_strfmt_putfnum", "lj_strfmt_putfstr", "lj_strfmt_putfchar", "lj_buf_putmem", "lj_buf_putstr", "lj_buf_putchar", "lj_buf_putstr_reverse", "lj_buf_putstr_lower", "lj_buf_putstr_upper", "lj_buf_putstr_rep", "lj_buf_puttab", "lj_buf_tostr", "lj_tab_new_ah", "lj_tab_new1", "lj_tab_dup", "lj_tab_clear", "lj_tab_newkey", "lj_tab_len", "lj_tab_clone", "lj_tab_isarray", "lj_tab_nkeys", "lj_tab_isempty", "lj_gc_step_jit", "lj_gc_barrieruv", "lj_mem_newgco", "lj_math_random_step", "lj_vm_modi", "sinh", "cosh", "tanh", "fputc", "fwrite", "fflush", "lj_vm_floor", "lj_vm_ceil", "lj_vm_trunc", "sqrt", "exp", "lj_vm_exp2", "log", "lj_vm_log2", "log10", "sin", "cos", "tan", "lj_vm_powi", "pow", "atan2", "ldexp", "lj_vm_tobit", "softfp_add", "softfp_sub", "softfp_mul", "softfp_div", "softfp_cmp", "softfp_i2d", "softfp_d2i", "lj_vm_sfmin", "lj_vm_sfmax", "lj_vm_tointg", "softfp_ui2d", "softfp_f2d", "softfp_d2ui", "softfp_d2f", "softfp_i2f", "softfp_ui2f", "softfp_f2i", "softfp_f2ui", "fp64_l2d", "fp64_ul2d", "fp64_l2f", "fp64_ul2f", "fp64_d2l", "fp64_d2ul", "fp64_f2l", "fp64_f2ul", "lj_carith_divi64", "lj_carith_divu64", "lj_carith_modi64", "lj_carith_modu64", "lj_carith_powi64", "lj_carith_powu64", "lj_cdata_newv", "lj_cdata_setfin", "strlen", "memcpy", "memset", "lj_vm_errno", "lj_carith_mul64", "lj_carith_shl64", "lj_carith_shr64", "lj_carith_sar64", "lj_carith_rol64", "lj_carith_ror64", }, traceerr = { [0]="error thrown or hook called during recording", "trace too short", "trace too long", "trace too deep", "too many snapshots", "blacklisted", "retry recording", "NYI: bytecode %d", "leaving loop in root trace", "inner loop in root trace", "loop unroll limit reached", "bad argument type", "JIT compilation disabled for function", "call unroll limit reached", "down-recursion, restarting", "NYI: unsupported variant of FastFunc %s", "NYI: return to lower frame", "store with nil or NaN key", "missing metamethod", "looping index lookup", "NYI: mixed sparse/dense table", "symbol not in cache", "NYI: unsupported C type conversion", "NYI: unsupported C function type", "guard would always fail", "too many PHIs", "persistent type instability", "failed to allocate mcode memory", "machine code too long", "hit mcode limit (retrying)", "too many spill slots", "inconsistent register allocation", "NYI: cannot assemble IR instruction %d", "NYI: PHI shuffling too complex", "NYI: register coalescing too complex", }, ffnames = { [0]="Lua", "C", "assert", "type", "next", "pairs", "ipairs_aux", "ipairs", "getmetatable", "setmetatable", "getfenv", "setfenv", "rawget", "rawset", "rawequal", "unpack", "select", "tonumber", "tostring", "error", "pcall", "xpcall", "loadfile", "load", "loadstring", "dofile", "gcinfo", "collectgarbage", "newproxy", "print", "coroutine.status", "coroutine.running", "coroutine.isyieldable", "coroutine.create", "coroutine.yield", "coroutine.resume", "coroutine.wrap_aux", "coroutine.wrap", "thread.exdata", "math.abs", "math.floor", "math.ceil", "math.sqrt", "math.log10", "math.exp", "math.sin", "math.cos", "math.tan", "math.asin", "math.acos", "math.atan", "math.sinh", "math.cosh", "math.tanh", "math.frexp", "math.modf", "math.log", "math.atan2", "math.pow", "math.fmod", "math.ldexp", "math.min", "math.max", "math.random", "math.randomseed", "bit.tobit", "bit.bnot", "bit.bswap", "bit.lshift", "bit.rshift", "bit.arshift", "bit.rol", "bit.ror", "bit.band", "bit.bor", "bit.bxor", "bit.tohex", "string.byte", "string.char", "string.sub", "string.rep", "string.reverse", "string.lower", "string.upper", "string.dump", "string.find", "string.match", "string.gmatch_aux", "string.gmatch", "string.gsub", "string.format", "table.maxn", "table.insert", "table.concat", "table.clone", "table.isarray", "table.nkeys", "table.isempty", "table.sort", "table.new", "table.clear", "io.method.close", "io.method.read", "io.method.write", "io.method.flush", "io.method.seek", "io.method.setvbuf", "io.method.lines", "io.method.__gc", "io.method.__tostring", "io.open", "io.popen", "io.tmpfile", "io.close", "io.read", "io.write", "io.flush", "io.input", "io.output", "io.lines", "io.type", "os.execute", "os.remove", "os.rename", "os.tmpname", "os.getenv", "os.exit", "os.clock", "os.date", "os.time", "os.difftime", "os.setlocale", "debug.getregistry", "debug.getmetatable", "debug.setmetatable", "debug.getfenv", "debug.setfenv", "debug.getinfo", "debug.getlocal", "debug.setlocal", "debug.getupvalue", "debug.setupvalue", "debug.upvalueid", "debug.upvaluejoin", "debug.sethook", "debug.gethook", "debug.debug", "debug.traceback", "jit.on", "jit.off", "jit.flush", "jit.status", "jit.attach", "jit.prngstate", "jit.util.funcinfo", "jit.util.funcbc", "jit.util.funck", "jit.util.funcuvname", "jit.util.traceinfo", "jit.util.traceir", "jit.util.tracek", "jit.util.tracesnap", "jit.util.tracemc", "jit.util.traceexitstub", "jit.util.ircalladdr", "jit.opt.start", "jit.profile.start", "jit.profile.stop", "jit.profile.dumpstack", "ffi.meta.__index", "ffi.meta.__newindex", "ffi.meta.__eq", "ffi.meta.__len", "ffi.meta.__lt", "ffi.meta.__le", "ffi.meta.__concat", "ffi.meta.__call", "ffi.meta.__add", "ffi.meta.__sub", "ffi.meta.__mul", "ffi.meta.__div", "ffi.meta.__mod", "ffi.meta.__pow", "ffi.meta.__unm", "ffi.meta.__tostring", "ffi.meta.__pairs", "ffi.meta.__ipairs", "ffi.clib.__index", "ffi.clib.__newindex", "ffi.clib.__gc", "ffi.callback.free", "ffi.callback.set", "ffi.cdef", "ffi.new", "ffi.cast", "ffi.typeof", "ffi.typeinfo", "ffi.istype", "ffi.sizeof", "ffi.alignof", "ffi.offsetof", "ffi.errno", "ffi.string", "ffi.copy", "ffi.fill", "ffi.abi", "ffi.metatype", "ffi.gc", "ffi.load", }, } ================================================ FILE: Luajit64/jit/zone.lua ================================================ ---------------------------------------------------------------------------- -- LuaJIT profiler zones. -- -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- -- This module implements a simple hierarchical zone model. -- -- Example usage: -- -- local zone = require("jit.zone") -- zone("AI") -- ... -- zone("A*") -- ... -- print(zone:get()) --> "A*" -- ... -- zone() -- ... -- print(zone:get()) --> "AI" -- ... -- zone() -- ---------------------------------------------------------------------------- local remove = table.remove return setmetatable({ flush = function(t) for i=#t,1,-1 do t[i] = nil end end, get = function(t) return t[#t] end }, { __call = function(t, zone) if zone then t[#t+1] = zone else return (assert(remove(t), "empty zone stack")) end end }) ================================================ FILE: README-tolua.md ================================================ ## tolua# tolua# is a Unity lua static binder solution. the first solution that analyzes code by reflection and generates wrapper classes.
It is a Unity plugin that greatly simplifies the integration of C# code with Lua. which can automatically generate the binding code to access Unity from Lua and map c# constants, variables, functions, properties, classes, and enums to Lua.
tolua# grows up from cstolua. it's goal is to be a powerful development environment for Unity.
Support unity4.6.x and Unity5.x all(copy /Unity5.x/Assets to /Assets)
If you want to test examples(example 1 is excluded)in mobile, first click menu Lua/Copy lua files to Resources. then build it
如果你想在手机上测试例子(例子1除外),首先点击菜单Lua/Copy lua files to Resources, 之后再build.
欢迎大家点星支持,谢谢^_^
有bug 可以到QQ群286510803反馈。 可以加讨论群:
ulua&tolua技术交流群① 341746602(已满)
ulua&tolua技术讨论群② 469941220(已满)
tolua#技术讨论群④ 543826216(已满)
tolua#技术群 286510803
# Library **tolua_runtime**
https://github.com/topameng/tolua_runtime
**Debugger**
https://github.com/topameng/Debugger
**CString**
https://github.com/topameng/CString
**protoc-gen-lua**
https://github.com/topameng/protoc-gen-lua
# FrameWork and Demo **LuaFrameWork**
https://github.com/jarjin/LuaFramework_NGUI
https://github.com/jarjin/LuaFramework_UGUI
**XlsxToLua**
https://github.com/zhangqi-ulua/XlsxToLua
**UnityHello**
https://github.com/woshihuo12/UnityHello
**UWA-ToLua**
http://uwa-download.oss-cn-beijing.aliyuncs.com/plugins%2FiOS%2FUWA-iOS-ToLua.zip
# Debugger **EmmyLua**
https://github.com/tangzx/IntelliJ-EmmyLua
**unity_tolua-_zerobrane_api**
https://github.com/LabOfHoward/unity_tolua-_zerobrane_api
# Packages  **Basics**        **Math**      **Data Structures**
 luabitop       Quaternion       list
  struct         Vector3        event
  int64          Vector4        slot
  Time          Vector2
**Networking**        Ray
 luasocket         Color
 **Parsing**        Bounds
 lpeg             Mathf
 **Protol**           Touch
 pblua          RaycastHit
# 特性 * 自动生成绑定代码文件,非反射调用
* 大量内建基础类型支持,如枚举,委托,事件,Type, 数组,迭代器等
* 支持多种协同形式
* 支持所有unity内部类导出,支持委托类型导出
* 支持导出自定义,跳过某个空的基类,修改导出名称等
* 支持扩展函数自定义导出, 比如DoTween
* 支持值类型Nullable导出,包括Nullable<Vector3>等
* 支持Lua中function转委托,可以区分需要不同委托的参数的重载函数
* 支持c# LuaFunction对象转委托,简化调用方式。 支持无GC的多参数调用形式
* 支持重载函数自动折叠, 如:Convert.ToUInt32只导出double参数的函数
* 支持重载函数自动排序, 如:参数个数相同, object参数执行级最低, 不会出现错误匹配情况
* 支持导出函数重命名, 可以分离导出某个重载函数(可以导出被折叠掉的函数)
* 支持使用编辑器类改写导出规则
* 支持this数组访问,索引为int可以通过[]访问,其他可使用.get_Item或者.this:get()访问数组成员
* 支持委托(事件)+-lua function。支持通过函数接口的Add和Remove委托操作
* 支持静态反射操作, 形式同c#
* 支持peer表,可在lua端扩展导出的userdata
* 支持自定义struct压入和读取,做到无GC,并且结构成员无类型限制, 参考例子24
* 支持preloading, 可以通过requie后绑定wrap文件
* 支持int64, uint64
* 大量的lua数学类型,如Quaternion, Vector3, Mathf等 * 包含第三方lua扩展,包括luasocket, struct, lpeg, utf8, pb等库
* 当lua出现异常,能够同时捕获c#端和lua端堆栈,便于调试
* print信息,在编辑器点击日志, 能自动打开对应lua文件
* 支持unity所有版本
* **支持Lua hook C#相代码实现,一定程度上支持利用Lua代码修改C#端代码的bug**([暖更新使用说明](https://zhuanlan.zhihu.com/p/35124260)) 
# 快速入门 在CustomSetting.cs中添加需要导出的类或者委托,类加入到customTypeList列表,委托加入到customDelegateList列表
通过设置saveDir变量更改导出目录,默认生成在Assets/Source/Generate/下,点击菜单Lua->Generate All,生成绑定文件
在LuaConst.cs中配置开发lua文件目录luaDir以及tolua lua文件目录toluaDir
```csharp //例子1 LuaState lua = new LuaState(); lua.Start(); lua.DoString("print('hello world')"); lua.Dispose(); //例子2 LuaState luaState = null; void Awake() { luaState = LuaClient.GetMainState(); try { luaState.Call("UIShop.Awake", false); } catch (Exception e) { //Awake中必须这样特殊处理异常 luaState.ThrowLuaException(e); } } void Start() { luaState.Call("UIShop.Start", false); } ``` ```lua local go = GameObject('go') go:AddComponent(typeof(UnityEngine.ParticleSystem)) go.transform.position = Vector3.zero go.transform:Rotate(Vector3(0,90,0), UnityEngine.Space.World) go.transform:Rotate(Vector3(0, 1, 0), 0) --DoTween 需要在CustomSetting导出前定义USING_DOTWEENING宏,或者取消相关注释 go.transform:DORotate(Vector3(0,0,360), 2, DG.Tweening.RotateMode.FastBeyond360) Shop = {} function Shop:Awake() self.OnUpdate = UpdateBeat:CreateListener(Shop.Update, self) UpdateBeat:AddListener(self.OnUpdate) end function Shop:OnDestroy() UpdateBeat:RemoveListener(self.OnUpdate) end function Shop:OnClick() print("OnClick") end function Shop:OnToggle() print("OnToggle") end function Shop:Update() end --委托 local listener = UIEventListener.Get(go) listener.onClick = function() print("OnClick") end listener.onClick = nil listener.onClick = UIEventListener.VoidDelegate(Shop.OnClick, Shop) listener.onClick = listener.onClick + UIEventListener.VoidDelegate(Shop.OnClick, Shop) listener.onClick = listener.onClick - UIEventListener.VoidDelegate(Shop.OnClick, Shop) local toggle = go:GetComponent(typeof(UIToggle)) EventDelegate.Add(toggle.onChange, EventDelegate.Callback(Shop.OnToggle, Shop)) EventDelegate.Remove(toggle.onChange, EventDelegate.Callback(Shop.OnToggle, Shop)) --事件 local Client = {} function Client:Log(str) end Application.logMessageReceived = Application.logMessageReceived + Application.LogCallback(Clent.Log, Client) Application.logMessageReceived = Application.logMessageReceived - Application.LogCallback(Clent.Log, Client) --out参数 local _layer = 2 ^ LayerMask.NameToLayer('Default') local flag, hit = UnityEngine.Physics.Raycast(ray, nil, 5000, _layer) if flag then print('pick from lua, point: '..tostring(hit.point)) end ``` [这里](Assets/ToLua/Examples/README.md)是更多的示例。 # 关于反射 tolua# 不支持动态反射。动态反射对于重载函数有参数匹配问题,函数排序问题,ref,out 参数问题等等。
tolua#提供的替换方法是:
1. preloading, 把你未来可能需要的类型添加到导出列表customTypeList,同时也添加到dynamicList列表中,这样导出后该类型并不会随binder注册到lua中,你可以通过 require "namespace.classname" 动态注册到lua中,对于非枚举类型tolua#系统也可以在第一次push该类型时动态载入,当然也可在过场动画、资源下载、登录、场景加载或者某个的函数中require这个类型。
2. 静态反射,参考例子22。通过静态反射支持精确的函数参数匹配和类型检查。不会存在重载函数参数混乱匹配错误问题, 注意iOS必须配置好link.xml
# Performance | 平台 | 属性读写 | 重载函数 | Vector3构造 |GameObject构造|Vector3归一化|Slerp| | :-- | :-----------:|:---------:| :---------: |:-----------: |:----------: |:--: | | PC | 0.0465:0.15 | 0.076:0.12|0.02:0.001 |0.1:0.14 |0.014:0.001 |0.10:0.11| | Android | 0.16:1.1 | 0.28:0.76 |0.17:0.00035 |0.43:0.5 |0.21:0.02 |0.3:0.06| | iOS | 0.04:0.145 | 0.055:0.11 |0.017:0.05 |0.074:0.08 |0.035:0.11 |0.078:0.5| 测试结果为C#:Lua. 环境不同会略有差异。可用数字倍率做参考
PC: Intel(R) Core(TM) i5-4590 CPU@3.3GHz + 8GB + 64 位win7 + Unity5.4.5p4
Android: 中兴nubia z9 max(NX512J) + Adnroid5.0.2
iOS(il2cpp): IPhone6 Plus
按照1.0.7.355版本更新了测试数据, u5相对u4, 安卓上c#有了不小的提升
# Examples 参考包内1-24例子 # About Lua win, android ios using luajit2.1-beta3. macos using luac5.1.5(for u5.x). 注意iOS未编译模拟器库,请用真机测试 ================================================ FILE: README.md ================================================ # CSharpLuaForUnity CSharpLuaForUnity尝试使用[CSharp.lua](https://github.com/yanghuan/CSharp.lua)将Unity工程中的C#脚本编译至Lua,以使其可用C#进行高效的开发,但是也能用Lua完成热更新,也已经开始在部分新项目中被采用。 ## 依赖说明 * 使用[tolua](https://github.com/topameng/tolua)版本作为Lua支持环境 * 使用[LuaFramework_UGUI_V2](https://github.com/jarjin/LuaFramework_UGUI_V2)编译的动态链接tolua库(集成了pbc) * 使用[CSharp.lua](https://github.com/yanghuan/CSharp.lua)来将C#代码转换至Lua ## 如何使用 * 在Unity编辑器环境下,会新增菜单项'CSharpLua',子菜单'Compile'可将工程目录[Compiled](https://github.com/yanghuan/CSharpLuaForUnity/tree/master/Assets/CSharpLua/Compiled)下的C#代码编译成Lua代码放置到Assets/Lua/Compiled目录,子菜单'Switch to XXX'可在运行C#代码还是编译后的Lua代码中切换。**设想的是实际开发中一直使用C#代码开发和调试,需要真机发布时,才编译到Lua代码**。 * [Examples](https://github.com/yanghuan/CSharpLuaForUnity/tree/master/Assets/CSharpLua/Examples)目录下有一个简易的列子,可直接运行。可以看出能够支持在预设中挂载自定义的C#脚本,在运行Lua代码时,预设会被动态适配处理,具体实现可见代码。因而在打包时也需要对存在挂载了自定义C#脚本的的预设做相同的处理。 ## 项目结构 使用了[assembly definition files](https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html)额外定义了一些程序集工程,依赖顺序如下。 Assembly-CSharp.dll --------> Compiled.dll --------> Bridge.dll --------> Base.dll * Compiled 此工程中的代码可编译至Lua,需要热更新的代码放到这个工程中 * Bridge 可被Compiled引用的代码,需要Wrap到Lua的环境中 * Base 可被Bridge引用的代码,但是不需要被Compiled所引用到 ## 交流讨论 - [Issues](https://github.com/yanghuan/CSharpLuaForUnity/issues) - 邮箱:sy.yanghuan@gmail.com - QQ群: 715350749 ## 致谢 * https://github.com/topameng/tolua * https://github.com/jarjin/LuaFramework_UGUI_V2 ## 相关工程 * DCET 在ET框架的基础上集成了CSharp.lua和**xlua** https://github.com/DukeChiang/DCET * 也是在ET框架的基础上集成了CSharp.lua和**xlua** https://github.com/zzjfengqing/ETCsharpToXLua * 集成了tolua、LuaFramework_UGUI_V2和CSharp.lua https://gitee.com/googleapp/LuaFramework_UGUI_V2 * ILRuntime C#实现的IL运行环境 https://github.com/Ourpalm/ILRuntime ================================================ FILE: Tools/CSharpLua/CSharp.lua/CSharp.lua.Launcher.deps.json ================================================ { "runtimeTarget": { "name": ".NETCoreApp,Version=v5.0", "signature": "" }, "compilationOptions": {}, "targets": { ".NETCoreApp,Version=v5.0": { "CSharp.lua.Launcher/1.0.0": { "dependencies": { "CSharp.lua": "1.1.0" }, "runtime": { "CSharp.lua.Launcher.dll": {} } }, "Microsoft.CodeAnalysis.Analyzers/3.0.0": {}, "Microsoft.CodeAnalysis.Common/3.7.0": { "dependencies": { "Microsoft.CodeAnalysis.Analyzers": "3.0.0", "System.Collections.Immutable": "1.5.0", "System.Memory": "4.5.4", "System.Reflection.Metadata": "1.6.0", "System.Runtime.CompilerServices.Unsafe": "4.7.0", "System.Text.Encoding.CodePages": "4.5.1", "System.Threading.Tasks.Extensions": "4.5.3" }, "runtime": { "lib/netcoreapp3.1/Microsoft.CodeAnalysis.dll": { "assemblyVersion": "3.7.0.0", "fileVersion": "3.700.20.37502" } }, "resources": { "lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.resources.dll": { "locale": "cs" }, "lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.resources.dll": { "locale": "de" }, "lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.resources.dll": { "locale": "es" }, "lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.resources.dll": { "locale": "fr" }, "lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.resources.dll": { "locale": "it" }, "lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.resources.dll": { "locale": "ja" }, "lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.resources.dll": { "locale": "ko" }, "lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.resources.dll": { "locale": "pl" }, "lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.resources.dll": { "locale": "pt-BR" }, "lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.resources.dll": { "locale": "ru" }, "lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.resources.dll": { "locale": "tr" }, "lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.resources.dll": { "locale": "zh-Hans" }, "lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.resources.dll": { "locale": "zh-Hant" } } }, "Microsoft.CodeAnalysis.CSharp/3.7.0": { "dependencies": { "Microsoft.CodeAnalysis.Common": "3.7.0" }, "runtime": { "lib/netcoreapp3.1/Microsoft.CodeAnalysis.CSharp.dll": { "assemblyVersion": "3.7.0.0", "fileVersion": "3.700.20.37502" } }, "resources": { "lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "cs" }, "lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "de" }, "lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "es" }, "lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "fr" }, "lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "it" }, "lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "ja" }, "lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "ko" }, "lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "pl" }, "lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "pt-BR" }, "lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "ru" }, "lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "tr" }, "lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "zh-Hans" }, "lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll": { "locale": "zh-Hant" } } }, "Microsoft.NETCore.Platforms/2.1.2": {}, "System.Collections.Immutable/1.5.0": {}, "System.Memory/4.5.4": {}, "System.Reflection.Metadata/1.6.0": {}, "System.Runtime.CompilerServices.Unsafe/4.7.0": {}, "System.Text.Encoding.CodePages/4.5.1": { "dependencies": { "Microsoft.NETCore.Platforms": "2.1.2", "System.Runtime.CompilerServices.Unsafe": "4.7.0" } }, "System.Threading.Tasks.Extensions/4.5.3": {}, "CSharp.lua/1.1.0": { "dependencies": { "Microsoft.CodeAnalysis.CSharp": "3.7.0" }, "runtime": { "CSharp.lua.dll": {} } } } }, "libraries": { "CSharp.lua.Launcher/1.0.0": { "type": "project", "serviceable": false, "sha512": "" }, "Microsoft.CodeAnalysis.Analyzers/3.0.0": { "type": "package", "serviceable": true, "sha512": "sha512-ojG5pGAhTPmjxRGTNvuszO3H8XPZqksDwr9xLd4Ae/JBjZZdl6GuoLk7uLMf+o7yl5wO0TAqoWcEKkEWqrZE5g==", "path": "microsoft.codeanalysis.analyzers/3.0.0", "hashPath": "microsoft.codeanalysis.analyzers.3.0.0.nupkg.sha512" }, "Microsoft.CodeAnalysis.Common/3.7.0": { "type": "package", "serviceable": true, "sha512": "sha512-SFEdnbw8204hTlde3JePYSIpNX58h/MMXa7LctUsUDigWMR8Ar9gE8LnsLqAIFM0O33JEuQbJ0G4Sat+cPGldw==", "path": "microsoft.codeanalysis.common/3.7.0", "hashPath": "microsoft.codeanalysis.common.3.7.0.nupkg.sha512" }, "Microsoft.CodeAnalysis.CSharp/3.7.0": { "type": "package", "serviceable": true, "sha512": "sha512-sKi5PIVy9nVDerkbplY6OQhJBNzEO4XJsMGrnmb6KFEa6K1ulGCHIv6NtDjdUQ/dGrouU3OExc3yzww0COD76w==", "path": "microsoft.codeanalysis.csharp/3.7.0", "hashPath": "microsoft.codeanalysis.csharp.3.7.0.nupkg.sha512" }, "Microsoft.NETCore.Platforms/2.1.2": { "type": "package", "serviceable": true, "sha512": "sha512-mOJy3M0UN+LUG21dLGMxaWZEP6xYpQEpLuvuEQBaownaX4YuhH6NmNUlN9si+vNkAS6dwJ//N1O4DmLf2CikVg==", "path": "microsoft.netcore.platforms/2.1.2", "hashPath": "microsoft.netcore.platforms.2.1.2.nupkg.sha512" }, "System.Collections.Immutable/1.5.0": { "type": "package", "serviceable": true, "sha512": "sha512-EXKiDFsChZW0RjrZ4FYHu9aW6+P4MCgEDCklsVseRfhoO0F+dXeMSsMRAlVXIo06kGJ/zv+2w1a2uc2+kxxSaQ==", "path": "system.collections.immutable/1.5.0", "hashPath": "system.collections.immutable.1.5.0.nupkg.sha512" }, "System.Memory/4.5.4": { "type": "package", "serviceable": true, "sha512": "sha512-1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", "path": "system.memory/4.5.4", "hashPath": "system.memory.4.5.4.nupkg.sha512" }, "System.Reflection.Metadata/1.6.0": { "type": "package", "serviceable": true, "sha512": "sha512-COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==", "path": "system.reflection.metadata/1.6.0", "hashPath": "system.reflection.metadata.1.6.0.nupkg.sha512" }, "System.Runtime.CompilerServices.Unsafe/4.7.0": { "type": "package", "serviceable": true, "sha512": "sha512-IpU1lcHz8/09yDr9N+Juc7SCgNUz+RohkCQI+KsWKR67XxpFr8Z6c8t1iENCXZuRuNCc4HBwme/MDHNVCwyAKg==", "path": "system.runtime.compilerservices.unsafe/4.7.0", "hashPath": "system.runtime.compilerservices.unsafe.4.7.0.nupkg.sha512" }, "System.Text.Encoding.CodePages/4.5.1": { "type": "package", "serviceable": true, "sha512": "sha512-4J2JQXbftjPMppIHJ7IC+VXQ9XfEagN92vZZNoG12i+zReYlim5dMoXFC1Zzg7tsnKDM7JPo5bYfFK4Jheq44w==", "path": "system.text.encoding.codepages/4.5.1", "hashPath": "system.text.encoding.codepages.4.5.1.nupkg.sha512" }, "System.Threading.Tasks.Extensions/4.5.3": { "type": "package", "serviceable": true, "sha512": "sha512-+MvhNtcvIbqmhANyKu91jQnvIRVSTiaOiFNfKWwXGHG48YAb4I/TyH8spsySiPYla7gKal5ZnF3teJqZAximyQ==", "path": "system.threading.tasks.extensions/4.5.3", "hashPath": "system.threading.tasks.extensions.4.5.3.nupkg.sha512" }, "CSharp.lua/1.1.0": { "type": "project", "serviceable": false, "sha512": "" } } } ================================================ FILE: Tools/CSharpLua/CSharp.lua/CSharp.lua.Launcher.runtimeconfig.json ================================================ { "runtimeOptions": { "tfm": "net5.0", "framework": { "name": "Microsoft.NETCore.App", "version": "5.0.0" } } } ================================================ FILE: Tools/CSharpLua/CSharp.lua/System.xml ================================================  ================================================ FILE: Tools/CSharpLua/UnityEngine.xml ================================================ ================================================ FILE: Tools/CSharpLua/codes/All.lua ================================================ --[[ Copyright 2017 YANG Huan (sy.yanghuan@gmail.com). Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --]] return function(dir, conf) dir = (dir and #dir > 0) and (dir .. ".CoreSystem.") or "CoreSystem." local require = require local load = function(module) return require(dir .. module) end load("Core")(conf) load("Interfaces") load("Exception") load("Number") load("Char") load("String") load("Boolean") load("Delegate") load("Enum") load("TimeSpan") load("DateTime") load("Collections.EqualityComparer") load("Array") load("Type") load("Collections.List") load("Collections.Dictionary") load("Collections.Queue") load("Collections.Stack") load("Collections.HashSet") load("Collections.LinkedList") load("Collections.Linq") load("Convert") load("Math") load("Random") load("Text.StringBuilder") load("Console") load("IO.File") load("Reflection.Assembly") load("Threading.Timer") load("Threading.Thread") load("Threading.Task") load("Utilities") end ================================================ FILE: Tools/CSharpLua/disable_track.bat ================================================ git update-index --assume-unchanged ../../Assets/Source/Generate/LuaBinder.cs git update-index --assume-unchanged ../../Assets/Source/Generate/DelegateFactory.cs git update-index --assume-unchanged ../../ProjectSettings/GraphicsSettings.asset git update-index --assume-unchanged ../../ProjectSettings/ProjectSettings.asset ================================================ FILE: Tools/CSharpLua/enable_track.bat ================================================ git update-index --no-assume-unchanged ../../Assets/Source/Generate/LuaBinder.cs git update-index --no-assume-unchanged ../../Assets/Source/Generate/DelegateFactory.cs git update-index --no-assume-unchanged ../../ProjectSettings/GraphicsSettings.asset git update-index --no-assume-unchanged ../../ProjectSettings/ProjectSettings.asset ================================================ FILE: Tools/CSharpLua/update_csharp.lua.cmd ================================================ set csharplua=D:\Project\Person\CSharp.lua set launcher=%csharplua%\CSharp.lua.Launcher\bin\Debug\net5.0 set coresystem=%csharplua%\CSharp.lua\CoreSystem.Lua set localcoresystem=..\..\Assets\Lua\CoreSystemLua xcopy %launcher% CSharp.lua /y del /s /q CSharp.lua\*.dev.json del /s /q %localcoresystem%\*.lua xcopy %coresystem% %localcoresystem% /s /y del /s /q %localcoresystem%\All.lua rd /s /q %localcoresystem%\CoreSystem\Numerics rd /s /q %localcoresystem%\CoreSystem\Globalization xcopy codes\All.lua %localcoresystem% /s /y ================================================ FILE: Tools/ProtobufGen/protobuf-net/Licence.txt ================================================ The core Protocol Buffers technology is provided courtesy of Google. At the time of writing, this is released under the BSD license. Full details can be found here: http://code.google.com/p/protobuf/ This .NET implementation is Copyright 2008 Marc Gravell Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: Tools/ProtobufGen/protobuf-net/common.xslt ================================================  Node not handled: / ; ================================================ FILE: Tools/ProtobufGen/protobuf-net/csharp.xslt ================================================  //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ using ; using ; CSharp template for protobuf-net. Options: General: "help" - this page Additional serializer support: "xml" - enable explicit xml support (XmlSerializer) "datacontract" - enable data-contract support (DataContractSerializer; requires .NET 3.0) "binary" - enable binary support (BinaryFormatter; not supported on Silverlight) Other: "protoRpc" - enable proto-rpc client "observable" - change notification (observer pattern) support "preObservable" - pre-change notification (observer pattern) support (requires .NET 3.5) "partialMethods" - provide partial methods for changes (requires C# 3.0) "detectMissing" - provide *Specified properties to indicate whether fields are present "lightFramework" - omit additional attributes not included in CF/Silverlight "asynchronous" - emit asynchronous methods for use with WCF "clientProxy" - emit asynchronous client proxy class "import" - additional namespaces to import (semicolon delimited) "fixCase" - change type/member names (types/properties become PascalCase; fields become camelCase) Invalid options: xml and data-contract serialization are mutually exclusive. // Option: xml serialization ([XmlType]/[XmlElement]) enabled // Option: data-contract serialization ([DataContract]/[DataMember]) enabled // Option: binary serialization (ISerializable) enabled // Option: observable (OnPropertyChanged) enabled // Option: pre-observable (OnPropertyChanging) enabled // Option: partial methods (On*Changing/On*Changed) enabled // Option: missing-value detection (*Specified/ShouldSerialize*/Reset*) enabled // Option: light framework (CF/Silverlight) enabled // Option: proto-rpc enabled // Generated from: using System; using System.Collections.Generic; using ProtoBuf; namespace { } // Note: requires additional types generated from: [ProtoContract] [global::System.Runtime.Serialization.DataContract(Name=@"")] [global::System.Xml.Serialization.XmlType(TypeName=@"")] public partial class : IProtocol, global::System.Runtime.Serialization.ISerializable, global::System.ComponentModel.INotifyPropertyChanged, global::System.ComponentModel.INotifyPropertyChanging { protected (global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : this() { global::ProtoBuf.Serializer.Merge(info, this); } void global::System.Runtime.Serialization.ISerializable.GetObjectData(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) { global::ProtoBuf.Serializer.Serialize(info, this); } public event global::System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if(PropertyChanged != null) PropertyChanged(this, new global::System.ComponentModel.PropertyChangedEventArgs(propertyName)); } public event global::System.ComponentModel.PropertyChangingEventHandler PropertyChanging; protected virtual void OnPropertyChanging(string propertyName) { if(PropertyChanging != null) PropertyChanging(this, new global::System.ComponentModel.PropertyChangingEventArgs(propertyName)); } } [ProtoContract] [global::System.Runtime.Serialization.DataContract(Name=@"")] [global::System.Xml.Serialization.XmlType(TypeName=@"")] public enum { } 0 [ProtoEnum(Value=)] [global::System.Runtime.Serialization.EnumMember(Value=@"")] [global::System.Xml.Serialization.XmlEnum(@"")] = , @ |abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while| FixedSize Group TwosComplement ZigZag Default struct struct struct struct struct struct struct struct struct class class struct struct struct struct struct struct none Field type not implemented: (.) double double float long ulong int ulong uint bool string byte[] uint int long int long Field type not implemented: (.) @"" . /* */ null () . . "" null null . default() global::System.Obsolete, ? [ProtoMember(, IsRequired = false, DataFormat = DataFormat.)] [global::System.ComponentModel.DefaultValue()] [global::System.Xml.Serialization.XmlElement(@"", Order = )] [global::System.Runtime.Serialization.DataMember(Name=@"", Order = , IsRequired = false)] [ProtoMember(, IsRequired = true, DataFormat = DataFormat.)] [global::System.Xml.Serialization.XmlElement(@"", Order = )] [global::System.Runtime.Serialization.DataMember(Name=@"", Order = , IsRequired = true)] public { get; set; } partial void OnChanging( value); partial void OnChanged(); [global::System.Xml.Serialization.XmlIgnore] [global::System.ComponentModel.Browsable(false)] public bool Specified { get { return this. != null; } set { if (value == (this.== null)) this. = value ? this. : ()null; } } private bool ShouldSerialize() { return Specified; } private void Reset() { Specified = false; } [ProtoMember(, DataFormat = DataFormat., Options = global::ProtoBuf.MemberSerializationOptions.Packed)] [global::System.Runtime.Serialization.DataMember(Name=@"", Order = , IsRequired = false)] [global::System.Xml.Serialization.XmlElement(@"", Order = )] public List<> { get; set; } = new List<>(); [global::System.ServiceModel.ServiceContract(Name = @"")] public interface I { } public class Client : global::ProtoBuf.ServiceModel.RpcClient { public Client() : base(typeof(I)) { } } [global::System.ServiceModel.OperationContract(Name = @"")] [global::ProtoBuf.ServiceModel.ProtoBehavior] ( request); [global::System.ServiceModel.OperationContract(AsyncPattern = true, Name = @"")] global::System.IAsyncResult Begin( request, global::System.AsyncCallback callback, object state); End(global::System.IAsyncResult ar); ( request) { return () Send(@"", request); } public partial class CompletedEventArgs : global::System.ComponentModel.AsyncCompletedEventArgs { private object[] results; public CompletedEventArgs(object[] results, global::System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } public Result { get { base.RaiseExceptionIfNecessary(); return ()(this.results[0]); } } } [global::System.Diagnostics.DebuggerStepThroughAttribute()] public partial class Client : global::System.ServiceModel.ClientBase<I>, I { public Client() {} public Client(string endpointConfigurationName) : base(endpointConfigurationName) {} public Client(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) {} public Client(string endpointConfigurationName, global::System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) {} public Client(global::System.ServiceModel.Channels.Binding binding, global::System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) {} } private BeginOperationDelegate onBeginDelegate; private EndOperationDelegate onEndDelegate; private global::System.Threading.SendOrPostCallback onCompletedDelegate; public event global::System.EventHandler<CompletedEventArgs> Completed; public ( request) { return base.Channel.(request); } [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public global::System.IAsyncResult Begin( request, global::System.AsyncCallback callback, object asyncState) { return base.Channel.Begin(request, callback, asyncState); } [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public End(global::System.IAsyncResult result) { return base.Channel.End(result); } private global::System.IAsyncResult OnBegin(object[] inValues, global::System.AsyncCallback callback, object asyncState) { request = (()(inValues[0])); return this.Begin(request, callback, asyncState); } private object[] OnEnd(global::System.IAsyncResult result) { retVal = this.End(result); return new object[] { retVal}; } private void OnCompleted(object state) { if ((this.Completed != null)) { InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state)); this.Completed(this, new CompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState)); } } public void Async( request) { this.Async(request, null); } public void Async( request, object userState) { if ((this.onBeginDelegate == null)) { this.onBeginDelegate = new BeginOperationDelegate(this.OnBegin); } if ((this.onEndDelegate == null)) { this.onEndDelegate = new EndOperationDelegate(this.OnEnd); } if ((this.onCompletedDelegate == null)) { this.onCompletedDelegate = new global::System.Threading.SendOrPostCallback(this.OnCompleted); } base.InvokeAsync(this.onBeginDelegate, new object[] { request}, this.onEndDelegate, this.onCompletedDelegate, userState); } ================================================ FILE: Tools/ProtobufGen/protobuf-net/descriptor.proto ================================================ // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // // The messages in this file describe the definitions found in .proto files. // A valid .proto file can be translated directly to a FileDescriptorProto // without any other information (e.g. without reading its imports). package google.protobuf; option java_package = "com.google.protobuf"; option java_outer_classname = "DescriptorProtos"; // descriptor.proto must be optimized for speed because reflection-based // algorithms don't work during bootstrapping. option optimize_for = SPEED; // The protocol compiler can output a FileDescriptorSet containing the .proto // files it parses. message FileDescriptorSet { repeated FileDescriptorProto file = 1; } // Describes a complete .proto file. message FileDescriptorProto { optional string name = 1; // file name, relative to root of source tree optional string package = 2; // e.g. "foo", "foo.bar", etc. // Names of files imported by this file. repeated string dependency = 3; // All top-level definitions in this file. repeated DescriptorProto message_type = 4; repeated EnumDescriptorProto enum_type = 5; repeated ServiceDescriptorProto service = 6; repeated FieldDescriptorProto extension = 7; optional FileOptions options = 8; // This field contains optional information about the original source code. // You may safely remove this entire field whithout harming runtime // functionality of the descriptors -- the information is needed only by // development tools. optional SourceCodeInfo source_code_info = 9; } // Describes a message type. message DescriptorProto { optional string name = 1; repeated FieldDescriptorProto field = 2; repeated FieldDescriptorProto extension = 6; repeated DescriptorProto nested_type = 3; repeated EnumDescriptorProto enum_type = 4; message ExtensionRange { optional int32 start = 1; optional int32 end = 2; } repeated ExtensionRange extension_range = 5; optional MessageOptions options = 7; } // Describes a field within a message. message FieldDescriptorProto { enum Type { // 0 is reserved for errors. // Order is weird for historical reasons. TYPE_DOUBLE = 1; TYPE_FLOAT = 2; TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers // take 10 bytes. Use TYPE_SINT64 if negative // values are likely. TYPE_UINT64 = 4; TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers // take 10 bytes. Use TYPE_SINT32 if negative // values are likely. TYPE_FIXED64 = 6; TYPE_FIXED32 = 7; TYPE_BOOL = 8; TYPE_STRING = 9; TYPE_GROUP = 10; // Tag-delimited aggregate. TYPE_MESSAGE = 11; // Length-delimited aggregate. // New in version 2. TYPE_BYTES = 12; TYPE_UINT32 = 13; TYPE_ENUM = 14; TYPE_SFIXED32 = 15; TYPE_SFIXED64 = 16; TYPE_SINT32 = 17; // Uses ZigZag encoding. TYPE_SINT64 = 18; // Uses ZigZag encoding. }; enum Label { // 0 is reserved for errors LABEL_OPTIONAL = 1; LABEL_REQUIRED = 2; LABEL_REPEATED = 3; // TODO(sanjay): Should we add LABEL_MAP? }; optional string name = 1; optional int32 number = 3; optional Label label = 4; // If type_name is set, this need not be set. If both this and type_name // are set, this must be either TYPE_ENUM or TYPE_MESSAGE. optional Type type = 5; // For message and enum types, this is the name of the type. If the name // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping // rules are used to find the type (i.e. first the nested types within this // message are searched, then within the parent, on up to the root // namespace). optional string type_name = 6; // For extensions, this is the name of the type being extended. It is // resolved in the same manner as type_name. optional string extendee = 2; // For numeric types, contains the original text representation of the value. // For booleans, "true" or "false". // For strings, contains the default text contents (not escaped in any way). // For bytes, contains the C escaped value. All bytes >= 128 are escaped. // TODO(kenton): Base-64 encode? optional string default_value = 7; optional FieldOptions options = 8; } // Describes an enum type. message EnumDescriptorProto { optional string name = 1; repeated EnumValueDescriptorProto value = 2; optional EnumOptions options = 3; } // Describes a value within an enum. message EnumValueDescriptorProto { optional string name = 1; optional int32 number = 2; optional EnumValueOptions options = 3; } // Describes a service. message ServiceDescriptorProto { optional string name = 1; repeated MethodDescriptorProto method = 2; optional ServiceOptions options = 3; } // Describes a method of a service. message MethodDescriptorProto { optional string name = 1; // Input and output type names. These are resolved in the same way as // FieldDescriptorProto.type_name, but must refer to a message type. optional string input_type = 2; optional string output_type = 3; optional MethodOptions options = 4; } // =================================================================== // Options // Each of the definitions above may have "options" attached. These are // just annotations which may cause code to be generated slightly differently // or may contain hints for code that manipulates protocol messages. // // Clients may define custom options as extensions of the *Options messages. // These extensions may not yet be known at parsing time, so the parser cannot // store the values in them. Instead it stores them in a field in the *Options // message called uninterpreted_option. This field must have the same name // across all *Options messages. We then use this field to populate the // extensions when we build a descriptor, at which point all protos have been // parsed and so all extensions are known. // // Extension numbers for custom options may be chosen as follows: // * For options which will only be used within a single application or // organization, or for experimental options, use field numbers 50000 // through 99999. It is up to you to ensure that you do not use the // same number for multiple options. // * For options which will be published and used publicly by multiple // independent entities, e-mail kenton@google.com to reserve extension // numbers. Simply tell me how many you need and I'll send you back a // set of numbers to use -- there's no need to explain how you intend to // use them. If this turns out to be popular, a web service will be set up // to automatically assign option numbers. message FileOptions { // Sets the Java package where classes generated from this .proto will be // placed. By default, the proto package is used, but this is often // inappropriate because proto packages do not normally start with backwards // domain names. optional string java_package = 1; // If set, all the classes from the .proto file are wrapped in a single // outer class with the given name. This applies to both Proto1 // (equivalent to the old "--one_java_file" option) and Proto2 (where // a .proto always translates to a single class, but you may want to // explicitly choose the class name). optional string java_outer_classname = 8; // If set true, then the Java code generator will generate a separate .java // file for each top-level message, enum, and service defined in the .proto // file. Thus, these types will *not* be nested inside the outer class // named by java_outer_classname. However, the outer class will still be // generated to contain the file's getDescriptor() method as well as any // top-level extensions defined in the file. optional bool java_multiple_files = 10 [default=false]; // If set true, then the Java code generator will generate equals() and // hashCode() methods for all messages defined in the .proto file. This is // purely a speed optimization, as the AbstractMessage base class includes // reflection-based implementations of these methods. optional bool java_generate_equals_and_hash = 20 [default=false]; // Generated classes can be optimized for speed or code size. enum OptimizeMode { SPEED = 1; // Generate complete code for parsing, serialization, // etc. CODE_SIZE = 2; // Use ReflectionOps to implement these methods. LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. } optional OptimizeMode optimize_for = 9 [default=SPEED]; // Should generic services be generated in each language? "Generic" services // are not specific to any particular RPC system. They are generated by the // main code generators in each language (without additional plugins). // Generic services were the only kind of service generation supported by // early versions of proto2. // // Generic services are now considered deprecated in favor of using plugins // that generate code specific to your particular RPC system. Therefore, // these default to false. Old code which depends on generic services should // explicitly set them to true. optional bool cc_generic_services = 16 [default=false]; optional bool java_generic_services = 17 [default=false]; optional bool py_generic_services = 18 [default=false]; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message MessageOptions { // Set true to use the old proto1 MessageSet wire format for extensions. // This is provided for backwards-compatibility with the MessageSet wire // format. You should not use this for any other reason: It's less // efficient, has fewer features, and is more complicated. // // The message must be defined exactly as follows: // message Foo { // option message_set_wire_format = true; // extensions 4 to max; // } // Note that the message cannot have any defined fields; MessageSets only // have extensions. // // All extensions of your type must be singular messages; e.g. they cannot // be int32s, enums, or repeated messages. // // Because this is an option, the above two restrictions are not enforced by // the protocol compiler. optional bool message_set_wire_format = 1 [default=false]; // Disables the generation of the standard "descriptor()" accessor, which can // conflict with a field of the same name. This is meant to make migration // from proto1 easier; new code should avoid fields named "descriptor". optional bool no_standard_descriptor_accessor = 2 [default=false]; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message FieldOptions { // The ctype option instructs the C++ code generator to use a different // representation of the field than it normally would. See the specific // options below. This option is not yet implemented in the open source // release -- sorry, we'll try to include it in a future version! optional CType ctype = 1 [default = STRING]; enum CType { // Default mode. STRING = 0; CORD = 1; STRING_PIECE = 2; } // The packed option can be enabled for repeated primitive fields to enable // a more efficient representation on the wire. Rather than repeatedly // writing the tag and type for each element, the entire array is encoded as // a single length-delimited blob. optional bool packed = 2; // Is this field deprecated? // Depending on the target platform, this can emit Deprecated annotations // for accessors, or it will be completely ignored; in the very least, this // is a formalization for deprecating fields. optional bool deprecated = 3 [default=false]; // EXPERIMENTAL. DO NOT USE. // For "map" fields, the name of the field in the enclosed type that // is the key for this map. For example, suppose we have: // message Item { // required string name = 1; // required string value = 2; // } // message Config { // repeated Item items = 1 [experimental_map_key="name"]; // } // In this situation, the map key for Item will be set to "name". // TODO: Fully-implement this, then remove the "experimental_" prefix. optional string experimental_map_key = 9; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message EnumOptions { // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message EnumValueOptions { // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message ServiceOptions { // Note: Field numbers 1 through 32 are reserved for Google's internal RPC // framework. We apologize for hoarding these numbers to ourselves, but // we were already using them long before we decided to release Protocol // Buffers. // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message MethodOptions { // Note: Field numbers 1 through 32 are reserved for Google's internal RPC // framework. We apologize for hoarding these numbers to ourselves, but // we were already using them long before we decided to release Protocol // Buffers. // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } // A message representing a option the parser does not recognize. This only // appears in options protos created by the compiler::Parser class. // DescriptorPool resolves these when building Descriptor objects. Therefore, // options protos in descriptor objects (e.g. returned by Descriptor::options(), // or produced by Descriptor::CopyTo()) will never have UninterpretedOptions // in them. message UninterpretedOption { // The name of the uninterpreted option. Each string represents a segment in // a dot-separated name. is_extension is true iff a segment represents an // extension (denoted with parentheses in options specs in .proto files). // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents // "foo.(bar.baz).qux". message NamePart { required string name_part = 1; required bool is_extension = 2; } repeated NamePart name = 2; // The value of the uninterpreted option, in whatever type the tokenizer // identified it as during parsing. Exactly one of these should be set. optional string identifier_value = 3; optional uint64 positive_int_value = 4; optional int64 negative_int_value = 5; optional double double_value = 6; optional bytes string_value = 7; optional string aggregate_value = 8; } // =================================================================== // Optional source code info // Encapsulates information about the original source file from which a // FileDescriptorProto was generated. message SourceCodeInfo { // A Location identifies a piece of source code in a .proto file which // corresponds to a particular definition. This information is intended // to be useful to IDEs, code indexers, documentation generators, and similar // tools. // // For example, say we have a file like: // message Foo { // optional string foo = 1; // } // Let's look at just the field definition: // optional string foo = 1; // ^ ^^ ^^ ^ ^^^ // a bc de f ghi // We have the following locations: // span path represents // [a,i) [ 4, 0, 2, 0 ] The whole field definition. // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). // // Notes: // - A location may refer to a repeated field itself (i.e. not to any // particular index within it). This is used whenever a set of elements are // logically enclosed in a single code segment. For example, an entire // extend block (possibly containing multiple extension definitions) will // have an outer location whose path refers to the "extensions" repeated // field without an index. // - Multiple locations may have the same path. This happens when a single // logical declaration is spread out across multiple places. The most // obvious example is the "extend" block again -- there may be multiple // extend blocks in the same scope, each of which will have the same path. // - A location's span is not always a subset of its parent's span. For // example, the "extendee" of an extension declaration appears at the // beginning of the "extend" block and is shared by all extensions within // the block. // - Just because a location's span is a subset of some other location's span // does not mean that it is a descendent. For example, a "group" defines // both a type and a field in a single declaration. Thus, the locations // corresponding to the type and field and their components will overlap. // - Code which tries to interpret locations should probably be designed to // ignore those that it doesn't understand, as more types of locations could // be recorded in the future. repeated Location location = 1; message Location { // Identifies which part of the FileDescriptorProto was defined at this // location. // // Each element is a field number or an index. They form a path from // the root FileDescriptorProto to the place where the definition. For // example, this path: // [ 4, 3, 2, 7, 1 ] // refers to: // file.message_type(3) // 4, 3 // .field(7) // 2, 7 // .name() // 1 // This is because FileDescriptorProto.message_type has field number 4: // repeated DescriptorProto message_type = 4; // and DescriptorProto.field has field number 2: // repeated FieldDescriptorProto field = 2; // and FieldDescriptorProto.name has field number 1: // optional string name = 1; // // Thus, the above path gives the location of a field name. If we removed // the last element: // [ 4, 3, 2, 7 ] // this path refers to the whole field declaration (from the beginning // of the label to the terminating semicolon). repeated int32 path = 1 [packed=true]; // Always has exactly three or four elements: start line, start column, // end line (optional, otherwise assumed same as start line), end column. // These are packed into a single field for efficiency. Note that line // and column numbers are zero-based -- typically you will want to add // 1 to each before displaying to a user. repeated int32 span = 2 [packed=true]; // TODO(kenton): Record comments appearing before and after the // declaration. } } ================================================ FILE: Tools/ProtobufGen/protobuf-net/protobuf-net.xml ================================================ protobuf-net Provides support for common .NET types that do not have a direct representation in protobuf, using the definitions from bcl.proto Creates a new instance of the specified type, bypassing the constructor. The type to create The new instance If the platform does not support constructor-skipping Writes a TimeSpan to a protobuf stream Parses a TimeSpan from a protobuf stream Parses a DateTime from a protobuf stream Writes a DateTime to a protobuf stream, excluding the Kind Writes a DateTime to a protobuf stream, including the Kind Parses a decimal from a protobuf stream Writes a decimal to a protobuf stream Writes a Guid to a protobuf stream Parses a Guid from a protobuf stream Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. Optional behaviours that introduce .NET-specific functionality No special behaviour Enables full object-tracking/full-graph support. Embeds the type information into the stream, allowing usage with types not known in advance. If false, the constructor for the type is bypassed during deserialization, meaning any field initializers or other initialization code is skipped. Should the object index be reserved, rather than creating an object promptly Provides a simple buffer-based implementation of an extension object. Provides addition capability for supporting unexpected fields during protocol-buffer serialization/deserialization. This allows for loss-less round-trip/merge, even when the data is not fully understood. Requests a stream into which any unexpected fields can be persisted. A new stream suitable for storing data. Indicates that all unexpected fields have now been stored. The implementing class is responsible for closing the stream. If "commit" is not true the data may be discarded. The stream originally obtained by BeginAppend. True if the append operation completed successfully. Requests a stream of the unexpected fields previously stored. A prepared stream of the unexpected fields. Indicates that all unexpected fields have now been read. The implementing class is responsible for closing the stream. The stream originally obtained by BeginQuery. Requests the length of the raw binary stream; this is used when serializing sub-entities to indicate the expected size. The length of the binary stream representing unexpected data. Specifies a method on the root-contract in an hierarchy to be invoked before serialization. Specifies a method on the root-contract in an hierarchy to be invoked after serialization. Specifies a method on the root-contract in an hierarchy to be invoked before deserialization. Specifies a method on the root-contract in an hierarchy to be invoked after deserialization. Pushes a null reference onto the stack. Note that this should only be used to return a null (or set a variable to null); for null-tests use BranchIfTrue / BranchIfFalse. Creates a new "using" block (equivalent) around a variable; the variable must exist, and note that (unlike in C#) it is the variables *final* value that gets disposed. If you need *original* disposal, copy your variable first. It is the callers responsibility to ensure that the variable's scope fully-encapsulates the "using"; if not, the variable may be re-used (and thus re-assigned) unexpectedly. Indicates that a static member should be considered the same as though were an implicit / explicit conversion operator; in particular, this is useful for conversions that operator syntax does not allow, such as to/from interface types. Sub-format to use when serializing/deserializing data Uses the default encoding for the data-type. When applied to signed integer-based data (including Decimal), this indicates that zigzag variant encoding will be used. This means that values with small magnitude (regardless of sign) take a small amount of space to encode. When applied to signed integer-based data (including Decimal), this indicates that two's-complement variant encoding will be used. This means that any -ve number will take 10 bytes (even for 32-bit), so should only be used for compatibility. When applied to signed integer-based data (including Decimal), this indicates that a fixed amount of space will be used. When applied to a sub-message, indicates that the value should be treated as group-delimited. Simple base class for supporting unexpected fields allowing for loss-less round-tips/merge, even if the data is not understod. The additional fields are (by default) stored in-memory in a buffer. As an example of an alternative implementation, you might choose to use the file system (temporary files) as the back-end, tracking only the paths [such an object would ideally be IDisposable and use a finalizer to ensure that the files are removed]. Indicates that the implementing type has support for protocol-buffer extensions. Can be implemented by deriving from Extensible. Retrieves the extension object for the current instance, optionally creating it if it does not already exist. Should a new extension object be created if it does not already exist? The extension object if it exists (or was created), or null if the extension object does not exist or is not available. The createIfMissing argument is false during serialization, and true during deserialization upon encountering unexpected fields. Retrieves the extension object for the current instance, optionally creating it if it does not already exist. Should a new extension object be created if it does not already exist? The extension object if it exists (or was created), or null if the extension object does not exist or is not available. The createIfMissing argument is false during serialization, and true during deserialization upon encountering unexpected fields. Provides a simple, default implementation for extension support, optionally creating it if it does not already exist. Designed to be called by classes implementing . Should a new extension object be created if it does not already exist? The extension field to check (and possibly update). The extension object if it exists (or was created), or null if the extension object does not exist or is not available. The createIfMissing argument is false during serialization, and true during deserialization upon encountering unexpected fields. Appends the value as an additional (unexpected) data-field for the instance. Note that for non-repeated sub-objects, this equates to a merge operation; for repeated sub-objects this adds a new instance to the set; for simple values the new value supercedes the old value. Note that appending a value does not remove the old value from the stream; avoid repeatedly appending values for the same field. The type of the value to append. The extensible object to append the value to. The field identifier; the tag should not be defined as a known data-field for the instance. The value to append. Appends the value as an additional (unexpected) data-field for the instance. Note that for non-repeated sub-objects, this equates to a merge operation; for repeated sub-objects this adds a new instance to the set; for simple values the new value supercedes the old value. Note that appending a value does not remove the old value from the stream; avoid repeatedly appending values for the same field. The data-type of the field. The data-format to use when encoding the value. The extensible object to append the value to. The field identifier; the tag should not be defined as a known data-field for the instance. The value to append. Queries an extensible object for an additional (unexpected) data-field for the instance. The value returned is the composed value after merging any duplicated content; if the value is "repeated" (a list), then use GetValues instead. The data-type of the field. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. The effective value of the field, or the default value if not found. Queries an extensible object for an additional (unexpected) data-field for the instance. The value returned is the composed value after merging any duplicated content; if the value is "repeated" (a list), then use GetValues instead. The data-type of the field. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. The data-format to use when decoding the value. The effective value of the field, or the default value if not found. Queries an extensible object for an additional (unexpected) data-field for the instance. The value returned (in "value") is the composed value after merging any duplicated content; if the value is "repeated" (a list), then use GetValues instead. The data-type of the field. The effective value of the field, or the default value if not found. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. True if data for the field was present, false otherwise. Queries an extensible object for an additional (unexpected) data-field for the instance. The value returned (in "value") is the composed value after merging any duplicated content; if the value is "repeated" (a list), then use GetValues instead. The data-type of the field. The effective value of the field, or the default value if not found. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. The data-format to use when decoding the value. True if data for the field was present, false otherwise. Queries an extensible object for an additional (unexpected) data-field for the instance. The value returned (in "value") is the composed value after merging any duplicated content; if the value is "repeated" (a list), then use GetValues instead. The data-type of the field. The effective value of the field, or the default value if not found. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. The data-format to use when decoding the value. Allow tags that are present as part of the definition; for example, to query unknown enum values. True if data for the field was present, false otherwise. Queries an extensible object for an additional (unexpected) data-field for the instance. Each occurrence of the field is yielded separately, making this usage suitable for "repeated" (list) fields. The extended data is processed lazily as the enumerator is iterated. The data-type of the field. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. An enumerator that yields each occurrence of the field. Queries an extensible object for an additional (unexpected) data-field for the instance. Each occurrence of the field is yielded separately, making this usage suitable for "repeated" (list) fields. The extended data is processed lazily as the enumerator is iterated. The data-type of the field. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. The data-format to use when decoding the value. An enumerator that yields each occurrence of the field. Queries an extensible object for an additional (unexpected) data-field for the instance. The value returned (in "value") is the composed value after merging any duplicated content; if the value is "repeated" (a list), then use GetValues instead. The data-type of the field. The model to use for configuration. The effective value of the field, or the default value if not found. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. The data-format to use when decoding the value. Allow tags that are present as part of the definition; for example, to query unknown enum values. True if data for the field was present, false otherwise. Queries an extensible object for an additional (unexpected) data-field for the instance. Each occurrence of the field is yielded separately, making this usage suitable for "repeated" (list) fields. The extended data is processed lazily as the enumerator is iterated. The model to use for configuration. The data-type of the field. The extensible object to obtain the value from. The field identifier; the tag should not be defined as a known data-field for the instance. The data-format to use when decoding the value. An enumerator that yields each occurrence of the field. Appends the value as an additional (unexpected) data-field for the instance. Note that for non-repeated sub-objects, this equates to a merge operation; for repeated sub-objects this adds a new instance to the set; for simple values the new value supercedes the old value. Note that appending a value does not remove the old value from the stream; avoid repeatedly appending values for the same field. The model to use for configuration. The data-format to use when encoding the value. The extensible object to append the value to. The field identifier; the tag should not be defined as a known data-field for the instance. The value to append. This class acts as an internal wrapper allowing us to do a dynamic methodinfo invoke; an't put into Serializer as don't want on public API; can't put into Serializer<T> since we need to invoke accross classes, which isn't allowed in Silverlight) All this does is call GetExtendedValuesTyped with the correct type for "instance"; this ensures that we don't get issues with subclasses declaring conflicting types - the caller must respect the fields defined for the type they pass in. All this does is call GetExtendedValuesTyped with the correct type for "instance"; this ensures that we don't get issues with subclasses declaring conflicting types - the caller must respect the fields defined for the type they pass in. Not all frameworks are created equal (fx1.1 vs fx2.0, micro-framework, compact-framework, silverlight, etc). This class simply wraps up a few things that would otherwise make the real code unnecessarily messy, providing fallback implementations if necessary. Intended to be a direct map to regular TypeCode, but: - with missing types - existing on WinRT Specifies the method used to infer field tags for members of the type under consideration. Tags are deduced using the invariant alphabetic sequence of the members' names; this makes implicit field tags very brittle, and susceptible to changes such as field names (normally an isolated change). No members are serialized implicitly; all members require a suitable attribute such as [ProtoMember]. This is the recmomended mode for most scenarios. Public properties and fields are eligible for implicit serialization; this treats the public API as a contract. Ordering beings from ImplicitFirstTag. Public and non-public fields are eligible for implicit serialization; this acts as a state/implementation serializer. Ordering beings from ImplicitFirstTag. Represents the set of serialization callbacks to be used when serializing/deserializing a type. Called before serializing an instance Called before deserializing an instance Called after serializing an instance Called after deserializing an instance True if any callback is set, else False Represents a type at runtime for use with protobuf, allowing the field mappings (etc) to be defined Get the name of the type being represented Adds a known sub-type to the inheritance model Adds a known sub-type to the inheritance model Assigns the callbacks to use during serialiation/deserialization. The method (or null) called before serialization begins. The method (or null) called when serialization is complete. The method (or null) called before deserialization begins (or when a new instance is created during deserialization). The method (or null) called when deserialization is complete. The set of callbacks. Assigns the callbacks to use during serialiation/deserialization. The name of the method (or null) called before serialization begins. The name of the method (or null) called when serialization is complete. The name of the method (or null) called before deserialization begins (or when a new instance is created during deserialization). The name of the method (or null) called when deserialization is complete. The set of callbacks. Designate a factory-method to use to create instances of this type Designate a factory-method to use to create instances of this type Throws an exception if the type has been made immutable Adds a member (by name) to the MetaType Adds a member (by name) to the MetaType, returning the ValueMember rather than the fluent API. This is otherwise identical to Add. Adds a member (by name) to the MetaType Performs serialization of this type via a surrogate; all other serialization options are ignored and handled by the surrogate's configuration. Adds a set of members (by name) to the MetaType Adds a member (by name) to the MetaType Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists, returning the ValueMember rather than the fluent API. This is otherwise identical to Add. Returns the ValueMember instances associated with this type Returns the SubType instances associated with this type Compiles the serializer for this type; this is *not* a full standalone compile, but can significantly boost performance while allowing additional types to be added. An in-place compile can access non-public types / members Gets the base-type for this type When used to compile a model, should public serialization/deserialzation methods be included for this type? Should this type be treated as a reference by default? Indicates whether the current type has defined callbacks Indicates whether the current type has defined subtypes Returns the set of callbacks defined for this type Gets or sets the name of this contract. The runtime type that the meta-type represents Gets or sets whether the type should use a parameterless constructor (the default), or whether the type should skip the constructor completely. This option is not supported on compact-framework. The concrete type to create when a new instance of this type is needed; this may be useful when dealing with dynamic proxies, or with interface-based APIs Returns the ValueMember that matchs a given field number, or null if not found Returns the ValueMember that matchs a given member (property/field), or null if not found Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. Gets or sets a value indicating that this type should NOT be treated as a list, even if it has familiar list-like characteristics (enumerable, add, etc) Provides protobuf serialization support for a number of types that can be defined at runtime Provides protobuf serialization support for a number of types Should the Kind be included on date/time values? Resolve a System.Type to the compiler-specific type Resolve a System.Type to the compiler-specific type This is the more "complete" version of Serialize, which handles single instances of mapped types. The value is written as a complete field, including field-header and (for sub-objects) a length-prefix In addition to that, this provides support for: - basic values; individual int / string / Guid / etc - IEnumerable sequences of any type handled by TrySerializeAuxiliaryType Writes a protocol-buffer representation of the given instance to the supplied stream. The existing instance to be serialized (cannot be null). The destination stream to write to. Writes a protocol-buffer representation of the given instance to the supplied stream. The existing instance to be serialized (cannot be null). The destination stream to write to. Additional information about this serialization operation. Writes a protocol-buffer representation of the given instance to the supplied writer. The existing instance to be serialized (cannot be null). The destination writer to write to. Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed data - useful with network IO. The type being merged. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). How to encode the length prefix. The tag used as a prefix to each record (only used with base-128 style prefixes). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed data - useful with network IO. The type being merged. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). How to encode the length prefix. The tag used as a prefix to each record (only used with base-128 style prefixes). Used to resolve types on a per-field basis. The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed data - useful with network IO. The type being merged. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). How to encode the length prefix. The tag used as a prefix to each record (only used with base-128 style prefixes). Used to resolve types on a per-field basis. Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Reads a sequence of consecutive length-prefixed items from a stream, using either base-128 or fixed-length prefixes. Base-128 prefixes with a tag are directly comparable to serializing multiple items in succession (use the tag to emulate the implicit behavior when serializing a list/array). When a tag is specified, any records with different tags are silently omitted. The tag is ignored. The tag is ignores for fixed-length prefixes. The binary stream containing the serialized records. The prefix style used in the data. The tag of records to return (if non-positive, then no tag is expected and all records are returned). On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). The type of object to deserialize (can be null if "resolver" is specified). The sequence of deserialized objects. Reads a sequence of consecutive length-prefixed items from a stream, using either base-128 or fixed-length prefixes. Base-128 prefixes with a tag are directly comparable to serializing multiple items in succession (use the tag to emulate the implicit behavior when serializing a list/array). When a tag is specified, any records with different tags are silently omitted. The tag is ignored. The tag is ignores for fixed-length prefixes. The binary stream containing the serialized records. The prefix style used in the data. The tag of records to return (if non-positive, then no tag is expected and all records are returned). On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). The type of object to deserialize (can be null if "resolver" is specified). The sequence of deserialized objects. Additional information about this serialization operation. Reads a sequence of consecutive length-prefixed items from a stream, using either base-128 or fixed-length prefixes. Base-128 prefixes with a tag are directly comparable to serializing multiple items in succession (use the tag to emulate the implicit behavior when serializing a list/array). When a tag is specified, any records with different tags are silently omitted. The tag is ignored. The tag is ignores for fixed-length prefixes. The type of object to deserialize. The binary stream containing the serialized records. The prefix style used in the data. The tag of records to return (if non-positive, then no tag is expected and all records are returned). The sequence of deserialized objects. Reads a sequence of consecutive length-prefixed items from a stream, using either base-128 or fixed-length prefixes. Base-128 prefixes with a tag are directly comparable to serializing multiple items in succession (use the tag to emulate the implicit behavior when serializing a list/array). When a tag is specified, any records with different tags are silently omitted. The tag is ignored. The tag is ignores for fixed-length prefixes. The type of object to deserialize. The binary stream containing the serialized records. The prefix style used in the data. The tag of records to return (if non-positive, then no tag is expected and all records are returned). The sequence of deserialized objects. Additional information about this serialization operation. Writes a protocol-buffer representation of the given instance to the supplied stream, with a length-prefix. This is useful for socket programming, as DeserializeWithLengthPrefix can be used to read the single object back from an ongoing stream. The type being serialized. The existing instance to be serialized (cannot be null). How to encode the length prefix. The destination stream to write to. The tag used as a prefix to each record (only used with base-128 style prefixes). Writes a protocol-buffer representation of the given instance to the supplied stream, with a length-prefix. This is useful for socket programming, as DeserializeWithLengthPrefix can be used to read the single object back from an ongoing stream. The type being serialized. The existing instance to be serialized (cannot be null). How to encode the length prefix. The destination stream to write to. The tag used as a prefix to each record (only used with base-128 style prefixes). Additional information about this serialization operation. Applies a protocol-buffer stream to an existing instance (which may be null). The type (including inheritance) to consider. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Applies a protocol-buffer stream to an existing instance (which may be null). The type (including inheritance) to consider. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Additional information about this serialization operation. Applies a protocol-buffer stream to an existing instance (which may be null). The type (including inheritance) to consider. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). The number of bytes to consume. The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Applies a protocol-buffer stream to an existing instance (which may be null). The type (including inheritance) to consider. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). The number of bytes to consume (or -1 to read to the end of the stream). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Additional information about this serialization operation. Applies a protocol-buffer reader to an existing instance (which may be null). The type (including inheritance) to consider. The existing instance to be modified (can be null). The reader to apply to the instance (cannot be null). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. This is the more "complete" version of Deserialize, which handles single instances of mapped types. The value is read as a complete field, including field-header and (for sub-objects) a length-prefix..kmc In addition to that, this provides support for: - basic values; individual int / string / Guid / etc - IList sets of any type handled by TryDeserializeAuxiliaryType Creates a new runtime model, to which the caller can add support for a range of types. A model can be used "as is", or can be compiled for optimal performance. Applies common proxy scenarios, resolving the actual type to consider Indicates whether the supplied type is explicitly modelled by the model Provides the key that represents a given type in the current model. The type is also normalized for proxies at the same time. Provides the key that represents a given type in the current model. Writes a protocol-buffer representation of the given instance to the supplied stream. Represents the type (including inheritance) to consider. The existing instance to be serialized (cannot be null). The destination stream to write to. Applies a protocol-buffer stream to an existing instance (which may be null). Represents the type (including inheritance) to consider. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Create a deep clone of the supplied instance; any sub-items are also cloned. Indicates that while an inheritance tree exists, the exact type encountered was not specified in that hierarchy and cannot be processed. Indicates that the given type was not expected, and cannot be processed. Indicates that the given type cannot be constructed; it may still be possible to deserialize into existing instances. Returns true if the type supplied is either a recognised contract type, or a *list* of a recognised contract type. Note that primitives always return false, even though the engine will, if forced, try to serialize such True if this type is recognised as a serializable entity, else false Returns true if the type supplied is a basic type with inbuilt handling, a recognised contract type, or a *list* of a basic / contract type. Returns true if the type supplied is a basic type with inbuilt handling, or a *list* of a basic type with inbuilt handling Suggest a .proto definition for the given type The type to generate a .proto definition for, or null to generate a .proto that represents the entire model The .proto definition as a string Creates a new IFormatter that uses protocol-buffer [de]serialization. A new IFormatter to be used during [de]serialization. The type of object to be [de]deserialized by the formatter. Used to provide custom services for writing and parsing type names when using dynamic types. Both parsing and formatting are provided on a single API as it is essential that both are mapped identically at all times. Indicates the type of callback to be used Invoked before an object is serialized Invoked after an object is serialized Invoked before an object is deserialized (or when a new instance is created) Invoked after an object is deserialized Should the Kind be included on date/time values? Returns a sequence of the Type instances that can be processed by this model. Suggest a .proto definition for the given type The type to generate a .proto definition for, or null to generate a .proto that represents the entire model The .proto definition as a string Adds support for an additional type in this model, optionally appplying inbuilt patterns. If the type is already known to the model, the existing type is returned **without** applying any additional behaviour. Inbuilt patterns include: [ProtoContract]/[ProtoMember(n)] [DataContract]/[DataMember(Order=n)] [XmlType]/[XmlElement(Order=n)] [On{Des|S}erializ{ing|ed}] ShouldSerialize*/*Specified The type to be supported Whether to apply the inbuilt configuration patterns (via attributes etc), or just add the type with no additional configuration (the type must then be manually configured). The MetaType representing this type, allowing further configuration. Verifies that the model is still open to changes; if not, an exception is thrown Prevents further changes to this model Provides the key that represents a given type in the current model. Writes a protocol-buffer representation of the given instance to the supplied stream. Represents the type (including inheritance) to consider. The existing instance to be serialized (cannot be null). The destination stream to write to. Applies a protocol-buffer stream to an existing instance (which may be null). Represents the type (including inheritance) to consider. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Compiles the serializers individually; this is *not* a full standalone compile, but can significantly boost performance while allowing additional types to be added. An in-place compile can access non-public types / members Fully compiles the current model into a static-compiled model instance A full compilation is restricted to accessing public types / members An instance of the newly created compiled type-model Fully compiles the current model into a static-compiled serialization dll (the serialization dll still requires protobuf-net for support services). A full compilation is restricted to accessing public types / members The name of the TypeModel class to create The path for the new dll An instance of the newly created compiled type-model Fully compiles the current model into a static-compiled serialization dll (the serialization dll still requires protobuf-net for support services). A full compilation is restricted to accessing public types / members An instance of the newly created compiled type-model Designate a factory-method to use to create instances of any type; note that this only affect types seen by the serializer *after* setting the factory. Global default that enables/disables automatic tag generation based on the existing name / order of the defined members. See for usage and important warning / explanation. You must set the global default before attempting to serialize/deserialize any impacted type. Global default that determines whether types are considered serializable if they have [DataContract] / [XmlType]. With this enabled, ONLY types marked as [ProtoContract] are added automatically. Global switch that enables or disables the implicit handling of "zero defaults"; meanning: if no other default is specified, it assumes bools always default to false, integers to zero, etc. If this is disabled, no such assumptions are made and only *explicit* default values are processed. This is enabled by default to preserve similar logic to v1. Global switch that determines whether types with a .ToString() and a Parse(string) should be serialized as strings. Global switch that determines whether DateTime serialization should include the Kind of the date/time. The default model, used to support ProtoBuf.Serializer Obtains the MetaType associated with a given Type for the current model, allowing additional configuration. Should serializers be compiled on demand? It may be useful to disable this for debugging purposes. Should support for unexpected types be added automatically? If false, an exception is thrown when unexpected types are encountered. The amount of time to wait if there are concurrent metadata access operations If a lock-contention is detected, this event signals the *owner* of the lock responsible for the blockage, indicating what caused the problem; this is only raised if the lock-owning code successfully completes. Represents configuration options for compiling a model to a standalone assembly. Import framework options from an existing type The TargetFrameworkAttribute FrameworkName value to burn into the generated assembly The TargetFrameworkAttribute FrameworkDisplayName value to burn into the generated assembly The name of the TypeModel class to create The path for the new dll The runtime version for the generated assembly The runtime version for the generated assembly The acecssibility of the generated serializer Type accessibility Available to all callers Available to all callers in the same assembly, or assemblies specified via [InternalsVisibleTo(...)] Contains the stack-trace of the owning code when a lock-contention scenario is detected The stack-trace of the code that owned the lock when a lock-contention scenario occurred Event-type that is raised when a lock-contention scenario is detected Represents an inherited type in a type hierarchy. Creates a new SubType instance. The field-number that is used to encapsulate the data (as a nested message) for the derived dype. The sub-type to be considered. Specific encoding style to use; in particular, Grouped can be used to avoid buffering, but is not the default. The field-number that is used to encapsulate the data (as a nested message) for the derived dype. The sub-type to be considered. Event arguments needed to perform type-formatting functions; this could be resolving a Type to a string suitable for serialization, or could be requesting a Type from a string. If no changes are made, a default implementation will be used (from the assembly-qualified names). The type involved in this map; if this is initially null, a Type is expected to be provided for the string in FormattedName. The formatted-name involved in this map; if this is initially null, a formatted-name is expected from the type in Type. Delegate type used to perform type-formatting functions; the sender originates as the type-model. Represents a member (property/field) that is mapped to a protobuf field Creates a new ValueMember instance Creates a new ValueMember instance Specifies methods for working with optional data members. Provides a method (null for none) to query whether this member should be serialized; it must be of the form "bool {Method}()". The member is only serialized if the method returns true. Provides a method (null for none) to indicate that a member was deserialized; it must be of the form "void {Method}(bool)", and will be called with "true" when data is found. The number that identifies this member in a protobuf stream Gets the member (field/property) which this member relates to. Within a list / array / etc, the type of object for each item in the list (especially useful with ArrayList) The underlying type of the member For abstract types (IList etc), the type of concrete object to create (if required) The type the defines the member The default value of the item (members with this value will not be serialized) Specifies the rules used to process the field; this is used to determine the most appropriate wite-type, but also to describe subtypes within that wire-type (such as SignedVariant) Indicates whether this field should follow strict encoding rules; this means (for example) that if a "fixed32" is encountered when "variant" is defined, then it will fail (throw an exception) when parsing. Note that when serializing the defined type is always used. Indicates whether this field should use packed encoding (which can save lots of space for repeated primitive values). This option only applies to list/array data of primitive types (int, double, etc). Indicates whether this field should *repace* existing values (the default is false, meaning *append*). This option only applies to list/array data. Indicates whether this field is mandatory. Enables full object-tracking/full-graph support. Embeds the type information into the stream, allowing usage with types not known in advance. Gets the logical name for this member in the schema (this is not critical for binary serialization, but may be used when inferring a schema). Should lists have extended support for null values? Note this makes the serialization less efficient. Specifies the type of prefix that should be applied to messages. No length prefix is applied to the data; the data is terminated only be the end of the stream. A base-128 length prefix is applied to the data (efficient for short messages). A fixed-length (little-endian) length prefix is applied to the data (useful for compatibility). A fixed-length (big-endian) length prefix is applied to the data (useful for compatibility). Indicates that a type is defined for protocol-buffer serialization. Gets or sets the defined name of the type. Gets or sets the fist offset to use with implicit field tags; only uesd if ImplicitFields is set. If specified, alternative contract markers (such as markers for XmlSerailizer or DataContractSerializer) are ignored. If specified, do NOT treat this type as a list, even if it looks like one. Gets or sets the mechanism used to automatically infer field tags for members. This option should be used in advanced scenarios only. Please review the important notes against the ImplicitFields enumeration. Enables/disables automatic tag generation based on the existing name / order of the defined members. This option is not used for members marked with ProtoMemberAttribute, as intended to provide compatibility with WCF serialization. WARNING: when adding new fields you must take care to increase the Order for new elements, otherwise data corruption may occur. If not explicitly specified, the default is assumed from Serializer.GlobalOptions.InferTagFromName. Has a InferTagFromName value been explicitly set? if not, the default from the type-model is assumed. Specifies an offset to apply to [DataMember(Order=...)] markers; this is useful when working with mex-generated classes that have a different origin (usually 1 vs 0) than the original data-contract. This value is added to the Order of each member. If true, the constructor for the type is bypassed during deserialization, meaning any field initializers or other initialization code is skipped. Should this type be treated as a reference by default? Please also see the implications of this, as recorded on ProtoMemberAttribute.AsReference Applies only to enums (not to DTO classes themselves); gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. Has a EnumPassthru value been explicitly set? Used to define protocol-buffer specific behavior for enumerated values. Indicates whether this instance has a customised value mapping true if a specific value is set Gets or sets the specific value to use for this enum during serialization. Gets or sets the defined name of the enum, as used in .proto (this name is not used during serialization). Indicates an error during serialization/deserialization of a proto stream. Creates a new ProtoException instance. Creates a new ProtoException instance. Creates a new ProtoException instance. Creates a new ProtoException instance. Indicates that a member should be excluded from serialization; this is only normally used when using implict fields. Indicates that a member should be excluded from serialization; this is only normally used when using implict fields. This allows ProtoIgnoreAttribute usage even for partial classes where the individual members are not under direct control. Creates a new ProtoPartialIgnoreAttribute instance. Specifies the member to be ignored. The name of the member to be ignored. Indicates the known-types to support for an individual message. This serializes each level in the hierarchy as a nested message to retain wire-compatibility with other protocol-buffer implementations. Creates a new instance of the ProtoIncludeAttribute. The unique index (within the type) that will identify this data. The additional type to serialize/deserialize. Creates a new instance of the ProtoIncludeAttribute. The unique index (within the type) that will identify this data. The additional type to serialize/deserialize. Gets the unique index (within the type) that will identify this data. Gets the additional type to serialize/deserialize. Gets the additional type to serialize/deserialize. Specifies whether the inherited sype's sub-message should be written with a length-prefix (default), or with group markers. Declares a member to be used in protocol-buffer serialization, using the given Tag. A DataFormat may be used to optimise the serialization format (for instance, using zigzag encoding for negative numbers, or fixed-length encoding for large values. Compare with another ProtoMemberAttribute for sorting purposes Compare with another ProtoMemberAttribute for sorting purposes Creates a new ProtoMemberAttribute instance. Specifies the unique tag used to identify this member within the type. Gets or sets the original name defined in the .proto; not used during serialization. Gets or sets the data-format to be used when encoding this value. Gets the unique tag used to identify this member within the type. Gets or sets a value indicating whether this member is mandatory. Gets a value indicating whether this member is packed. This option only applies to list/array data of primitive types (int, double, etc). Indicates whether this field should *repace* existing values (the default is false, meaning *append*). This option only applies to list/array data. Enables full object-tracking/full-graph support. Embeds the type information into the stream, allowing usage with types not known in advance. Gets or sets a value indicating whether this member is packed (lists/arrays). Additional (optional) settings that control serialization of members Default; no additional options Indicates that repeated elements should use packed (length-prefixed) encoding Indicates that the given item is required Enables full object-tracking/full-graph support Embeds the type information into the stream, allowing usage with types not known in advance Indicates whether this field should *repace* existing values (the default is false, meaning *append*). This option only applies to list/array data. Determines whether the types AsReferenceDefault value is used, or whether this member's AsReference should be used Declares a member to be used in protocol-buffer serialization, using the given Tag and MemberName. This allows ProtoMemberAttribute usage even for partial classes where the individual members are not under direct control. A DataFormat may be used to optimise the serialization format (for instance, using zigzag encoding for negative numbers, or fixed-length encoding for large values. Creates a new ProtoMemberAttribute instance. Specifies the unique tag used to identify this member within the type. Specifies the member to be serialized. The name of the member to be serialized. A stateful reader, used to read a protobuf stream. Typical usage would be (sequentially) to call ReadFieldHeader and (after matching the field) an appropriate Read* method. Creates a new reader against a stream The source stream The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects Additional context about this serialization operation Creates a new reader against a stream The source stream The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects Additional context about this serialization operation The number of bytes to read, or -1 to read until the end of the stream Releases resources used by the reader, but importantly does not Dispose the underlying stream; in many typical use-cases the stream is used for different processes, so it is assumed that the consumer will Dispose their stream separately. Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 Reads a signed 16-bit integer from the stream: Variant, Fixed32, Fixed64, SignedVariant Reads an unsigned 16-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 Reads an unsigned 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 Reads a signed 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant Reads a signed 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant Reads a signed 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant Reads a string from the stream (using UTF8); supported wire-types: String Throws an exception indication that the given value cannot be mapped to an enum. Reads a double-precision number from the stream; supported wire-types: Fixed32, Fixed64 Reads (merges) a sub-message from the stream, internally calling StartSubItem and EndSubItem, and (in between) parsing the message in accordance with the model associated with the reader Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader should return zero) Begins consuming a nested message in the stream; supported wire-types: StartGroup, String The token returned must be help and used when callining EndSubItem Reads a field header from the stream, setting the wire-type and retuning the field number. If no more fields are available, then 0 is returned. This methods respects sub-messages. Looks ahead to see whether the next field in the stream is what we expect (typically; what we've just finished reading - for example ot read successive list items) Compares the streams current wire-type to the hinted wire-type, updating the reader if necessary; for example, a Variant may be updated to SignedVariant. If the hinted wire-type is unrelated then no change is made. Verifies that the stream's current wire-type is as expected, or a specialized sub-type (for example, SignedVariant) - in which case the current wire-type is updated. Otherwise an exception is thrown. Discards the data for the current field. Reads an unsigned 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 Reads a single-precision number from the stream; supported wire-types: Fixed32, Fixed64 Reads a boolean value from the stream; supported wire-types: Variant, Fixed32, Fixed64 Reads a byte-sequence from the stream, appending them to an existing byte-sequence (which can be null); supported wire-types: String Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length reader to be created. Reads a little-endian encoded integer. An exception is thrown if the data is not all available. Reads a big-endian encoded integer. An exception is thrown if the data is not all available. Reads a varint encoded integer. An exception is thrown if the data is not all available. Reads a string (of a given lenth, in bytes) directly from the source into a pre-existing buffer. An exception is thrown if the data is not all available. Reads a given number of bytes directly from the source. An exception is thrown if the data is not all available. Reads a string (of a given lenth, in bytes) directly from the source. An exception is thrown if the data is not all available. Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length reader to be created. The number of bytes consumed; 0 if no data available Copies the current field into the instance as extension data Indicates whether the reader still has data remaining in the current sub-item, additionally setting the wire-type for the next field if there is more data. This is used when decoding packed data. Utility method, not intended for public use; this helps maintain the root object is complex scenarios Reads a Type from the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String Merge two objects using the details from the current reader; this is used to change the type of objects when an inheritance relationship is discovered later than usual during deserilazation. Gets the number of the field being processed. Indicates the underlying proto serialization format on the wire. Gets / sets a flag indicating whether strings should be checked for repetition; if true, any repeated UTF-8 byte sequence will result in the same String instance, rather than a second instance of the same string. Enabled by default. Note that this uses a custom interner - the system-wide string interner is not used. Addition information about this deserialization operation. Returns the position of the current reader (note that this is not necessarily the same as the position in the underlying stream, if multiple readers are used on the same stream) Get the TypeModel associated with this reader Represents an output stream for writing protobuf data. Why is the API backwards (static methods with writer arguments)? See: http://marcgravell.blogspot.com/2010/03/last-will-be-first-and-first-will-be.html Write an encapsulated sub-object, using the supplied unique key (reprasenting a type). The object to write. The key that uniquely identifies the type within the model. The destination. Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the caller is asserting that this relationship is non-recursive; no recursion check will be performed. The object to write. The key that uniquely identifies the type within the model. The destination. Writes a field-header, indicating the format of the next data we plan to write. Writes a byte-array to the stream; supported wire-types: String Writes a byte-array to the stream; supported wire-types: String Indicates the start of a nested record. The instance to write. The destination. A token representing the state of the stream; this token is given to EndSubItem. Indicates the end of a nested record. The token obtained from StartubItem. The destination. Creates a new writer against a stream The destination stream The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects Additional context about this serialization operation Flushes data to the underlying stream, and releases any resources. The underlying stream is *not* disposed by this operation. Writes any buffered data (if possible) to the underlying stream. The writer to flush It is not always possible to fully flush, since some sequences may require values to be back-filled into the byte-stream. Writes an unsigned 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 Writes a string to the stream; supported wire-types: String Writes an unsigned 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 Writes a signed 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 Writes a signed 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64 Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64 Throws an exception indicating that the given enum cannot be mapped to a serialized value. Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64 Copies any extension data stored for the instance to the underlying stream Used for packed encoding; indicates that the next field should be skipped rather than a field header written. Note that the field number must match, else an exception is thrown when the attempt is made to write the (incorrect) field. The wire-type is taken from the subsequent call to WriteFieldHeader. Only primitive types can be packed. Specifies a known root object to use during reference-tracked serialization Writes a Type to the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String Addition information about this serialization operation. Get the TypeModel associated with this writer Additional information about a serialization operation Convert a SerializationContext to a StreamingContext Convert a StreamingContext to a SerializationContext Gets or sets a user-defined object containing additional information about this serialization/deserialization operation. A default SerializationContext, with minimal information. Gets or sets the source or destination of the transmitted data. Provides protocol-buffer serialization capability for concrete, attributed types. This is a *default* model, but custom serializer models are also supported. Protocol-buffer serialization is a compact binary format, designed to take advantage of sparse data and knowledge of specific data types; it is also extensible, allowing a type to be deserialized / merged even if some data is not recognised. The field number that is used as a default when serializing/deserializing a list of objects. The data is treated as repeated message with field number 1. Suggest a .proto definition for the given type The type to generate a .proto definition for The .proto definition as a string Create a deep clone of the supplied instance; any sub-items are also cloned. Applies a protocol-buffer stream to an existing instance. The type being merged. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Creates a new instance from a protocol-buffer stream The type to be created. The binary stream to apply to the new instance (cannot be null). A new, initialized instance. Writes a protocol-buffer representation of the given instance to the supplied stream. The existing instance to be serialized (cannot be null). The destination stream to write to. Serializes a given instance and deserializes it as a different type; this can be used to translate between wire-compatible objects (where two .NET types represent the same data), or to promote/demote a type through an inheritance hierarchy. No assumption of compatibility is made between the types. The type of the object being copied. The type of the new object to be created. The existing instance to use as a template. A new instane of type TNewType, with the data from TOldType. Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. The type being serialized. The existing instance to be serialized (cannot be null). The destination SerializationInfo to write to. Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. The type being serialized. The existing instance to be serialized (cannot be null). The destination SerializationInfo to write to. Additional information about this serialization operation. Writes a protocol-buffer representation of the given instance to the supplied XmlWriter. The type being serialized. The existing instance to be serialized (cannot be null). The destination XmlWriter to write to. Applies a protocol-buffer from an XmlReader to an existing instance. The type being merged. The existing instance to be modified (cannot be null). The XmlReader containing the data to apply to the instance (cannot be null). Applies a protocol-buffer from a SerializationInfo to an existing instance. The type being merged. The existing instance to be modified (cannot be null). The SerializationInfo containing the data to apply to the instance (cannot be null). Applies a protocol-buffer from a SerializationInfo to an existing instance. The type being merged. The existing instance to be modified (cannot be null). The SerializationInfo containing the data to apply to the instance (cannot be null). Additional information about this serialization operation. Precompiles the serializer for a given type. Creates a new IFormatter that uses protocol-buffer [de]serialization. The type of object to be [de]deserialized by the formatter. A new IFormatter to be used during [de]serialization. Reads a sequence of consecutive length-prefixed items from a stream, using either base-128 or fixed-length prefixes. Base-128 prefixes with a tag are directly comparable to serializing multiple items in succession (use the tag to emulate the implicit behavior when serializing a list/array). When a tag is specified, any records with different tags are silently omitted. The tag is ignored. The tag is ignores for fixed-length prefixes. The type of object to deserialize. The binary stream containing the serialized records. The prefix style used in the data. The tag of records to return (if non-positive, then no tag is expected and all records are returned). The sequence of deserialized objects. Creates a new instance from a protocol-buffer stream that has a length-prefix on data (to assist with network IO). The type to be created. The binary stream to apply to the new instance (cannot be null). How to encode the length prefix. A new, initialized instance. Creates a new instance from a protocol-buffer stream that has a length-prefix on data (to assist with network IO). The type to be created. The binary stream to apply to the new instance (cannot be null). How to encode the length prefix. The expected tag of the item (only used with base-128 prefix style). A new, initialized instance. Applies a protocol-buffer stream to an existing instance, using length-prefixed data - useful with network IO. The type being merged. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). How to encode the length prefix. The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Writes a protocol-buffer representation of the given instance to the supplied stream, with a length-prefix. This is useful for socket programming, as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back from an ongoing stream. The type being serialized. The existing instance to be serialized (cannot be null). How to encode the length prefix. The destination stream to write to. Writes a protocol-buffer representation of the given instance to the supplied stream, with a length-prefix. This is useful for socket programming, as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back from an ongoing stream. The type being serialized. The existing instance to be serialized (cannot be null). How to encode the length prefix. The destination stream to write to. The tag used as a prefix to each record (only used with base-128 style prefixes). Indicates the number of bytes expected for the next message. The stream containing the data to investigate for a length. The algorithm used to encode the length. The length of the message, if it could be identified. True if a length could be obtained, false otherwise. Indicates the number of bytes expected for the next message. The buffer containing the data to investigate for a length. The offset of the first byte to read from the buffer. The number of bytes to read from the buffer. The algorithm used to encode the length. The length of the message, if it could be identified. True if a length could be obtained, false otherwise. Releases any internal buffers that have been reserved for efficiency; this does not affect any serialization operations; simply: it can be used (optionally) to release the buffers for garbage collection (at the expense of having to re-allocate a new buffer for the next operation, rather than re-use prior buffers). Provides non-generic access to the default serializer. Create a deep clone of the supplied instance; any sub-items are also cloned. Writes a protocol-buffer representation of the given instance to the supplied stream. The existing instance to be serialized (cannot be null). The destination stream to write to. Creates a new instance from a protocol-buffer stream The type to be created. The binary stream to apply to the new instance (cannot be null). A new, initialized instance. Applies a protocol-buffer stream to an existing instance. The existing instance to be modified (cannot be null). The binary stream to apply to the instance (cannot be null). The updated instance Writes a protocol-buffer representation of the given instance to the supplied stream, with a length-prefix. This is useful for socket programming, as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back from an ongoing stream. The existing instance to be serialized (cannot be null). How to encode the length prefix. The destination stream to write to. The tag used as a prefix to each record (only used with base-128 style prefixes). Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed data - useful with network IO. The existing instance to be modified (can be null). The binary stream to apply to the instance (cannot be null). How to encode the length prefix. Used to resolve types on a per-field basis. The updated instance; this may be different to the instance argument if either the original instance was null, or the stream defines a known sub-type of the original instance. Indicates whether the supplied type is explicitly modelled by the model Global switches that change the behavior of protobuf-net Maps a field-number to a type Perform the steps necessary to serialize this data. The value to be serialized. The writer entity that is accumulating the output data. Perform the steps necessary to deserialize this data. The current value, if appropriate. The reader providing the input data. The updated / replacement value. Emit the IL necessary to perform the given actions to serialize this data. Details and utilities for the method being generated. The source of the data to work against; If the value is only needed once, then LoadValue is sufficient. If the value is needed multiple times, then note that a "null" means "the top of the stack", in which case you should create your own copy - GetLocalWithValue. Emit the IL necessary to perform the given actions to deserialize this data. Details and utilities for the method being generated. For nested values, the instance holding the values; note that this is not always provided - a null means not supplied. Since this is always a variable or argument, it is not necessary to consume this value. The type that this serializer is intended to work for. Indicates whether a Read operation replaces the existing value, or extends the value. If false, the "value" parameter to Read is discarded, and should be passed in as null. Now all Read operations return a value (although most do); if false no value should be expected. Uses protocol buffer serialization on the specified operation; note that this must be enabled on both the client and server. Configuration element to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. Creates a new ProtoBehaviorExtension instance. Creates a behavior extension based on the current configuration settings. The behavior extension. Gets the type of behavior. Behavior to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. Add the following to the server and client app.config in the system.serviceModel section: Configure your endpoints to have a behaviorConfiguration as follows: Describes a WCF operation behaviour that can perform protobuf serialization Create a new ProtoOperationBehavior instance Creates a protobuf serializer if possible (falling back to the default WCF serializer) The type-model that should be used with this behaviour An xml object serializer that can embed protobuf data in a base-64 hunk (looking like a byte[]) Attempt to create a new serializer for the given model and type A new serializer instance if the type is recognised by the model; null otherwise Creates a new serializer for the given model and type Ends an object in the output Begins an object in the output Writes the body of an object in the output Indicates whether this is the start of an object we are prepared to handle Reads the body of an object Used to hold particulars relating to nested objects. This is opaque to the caller - simply give back the token you are given at the end of an object. Indicates the encoding used to represent an individual value in a protobuf stream Represents an error condition Base-128 variant-length encoding Fixed-length 8-byte encoding Length-variant-prefixed encoding Indicates the start of a group Indicates the end of a group Fixed-length 4-byte encoding 10 This is not a formal wire-type in the "protocol buffers" spec, but denotes a variant integer that should be interpreted using zig-zag semantics (so -ve numbers aren't a significant overhead) ================================================ FILE: Tools/ProtobufGen/protobuf-net/protoc-license.txt ================================================ Protocol Buffers - Google's data interchange format Copyright 2008 Google Inc. http://code.google.com/p/protobuf/ This package contains a precompiled Win32 binary version of the protocol buffer compiler (protoc). This binary is intended for Windows users who want to use Protocol Buffers in Java or Python but do not want to compile protoc themselves. To install, simply place this binary somewhere in your PATH. This binary was built using MinGW, but the output is the same regardless of the C++ compiler used. You will still need to download the source code package in order to obtain the Java or Python runtime libraries. Get it from: http://code.google.com/p/protobuf/downloads/ ================================================ FILE: Tools/ProtobufGen/protobuf-net/protogen.exe.config ================================================ ================================================ FILE: Tools/ProtobufGen/protobuf-net/vb.xslt ================================================  VisualBasic template for protobuf-net. Options: General: "help" - this page Additional serializer support: "xml" - enable explicit xml support (XmlSerializer) "datacontract" - enable data-contract support (DataContractSerializer; requires .NET 3.0) "binary" - enable binary support (BinaryFormatter; not supported on Silverlight) Other: "protoRpc" - enable proto-rpc client "observable" - change notification (observer pattern) support "preObservable" - pre-change notification (observer pattern) support (requires .NET 3.5) "partialMethods" - provide partial methods for changes (requires C# 3.0) "detectMissing" - provide *Specified properties to indicate whether fields are present "lightFramework" - omit additional attributes not included in CF/Silverlight "asynchronous" - emit asynchronous methods for use with WCF "clientProxy" - emit asynchronous client proxy class Invalid options: xml and data-contract serialization are mutually exclusive. ' Generated from ' Option: xml serialization ([XmlType]/[XmlElement]) enabled ' Option: data-contract serialization ([DataContract]/[DataMember]) enabled ' Option: binary serialization (ISerializable) enabled ' Option: observable (OnPropertyChanged) enabled ' Option: pre-observable (OnPropertyChanging) enabled ' Option: partial methods (On*Changing/On*Changed) enabled ' Option: missing-value detection (*Specified/ShouldSerialize*/Reset*) enabled ' Option: light framework (CF/Silverlight) enabled ' Option: proto-rpc enabled ' Generated from: Namespace End Namespace ' Note: requires additional types generated from: <Global.System.Serializable, Global.ProtoBuf.ProtoContract(Name:="")> _ <Global.System.Runtime.Serialization.DataContract(Name:="")> _ <Global.System.Serializable, Global.ProtoBuf.ProtoContract(Name:="")> _ <Global.System.Xml.Serialization.XmlType(TypeName:="")> _ <Global.System.Serializable, Global.ProtoBuf.ProtoContract(Name:="")> _ Public Partial Class implements Global.ProtoBuf.IExtensible, Global.System.Runtime.Serialization.ISerializable, Global.System.ComponentModel.INotifyPropertyChanged, Global.System.ComponentModel.INotifyPropertyChanging Public Sub New End Sub Protected Sub New(ByVal info As Global.System.Runtime.Serialization.SerializationInfo, ByVal context As Global.System.Runtime.Serialization.StreamingContext) MyBase.New() Global.ProtoBuf.Serializer.Merge(info, Me) End Sub Sub GetObjectData(ByVal info As Global.System.Runtime.Serialization.SerializationInfo, ByVal context As Global.System.Runtime.Serialization.StreamingContext) implements Global.System.Runtime.Serialization.ISerializable.GetObjectData Global.ProtoBuf.Serializer.Serialize(info, Me) End Sub Public Event PropertyChanged As Global.System.ComponentModel.PropertyChangedEventHandler Implements Global.System.ComponentModel.INotifyPropertyChanged.PropertyChanged Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String) RaiseEvent PropertyChanged(Me, New Global.System.ComponentModel.PropertyChangedEventArgs(propertyName)) End Sub Public Event PropertyChanging As Global.System.ComponentModel.PropertyChangingEventHandler Implements Global.System.ComponentModel.INotifyPropertyChanging.PropertyChanging Protected Overridable Sub OnPropertyChanging(ByVal propertyName As String) RaiseEvent PropertyChanging(Me, New Global.System.ComponentModel.PropertyChangingEventArgs(propertyName)) End Sub Private extensionObject As Global.ProtoBuf.IExtension Function GetExtensionObject(createIfMissing As Boolean) As Global.ProtoBuf.IExtension Implements Global.ProtoBuf.IExtensible.GetExtensionObject Return Global.ProtoBuf.Extensible.GetExtensionObject(extensionObject, createIfMissing) End Function End Class Public Enum End Enum = 0 FixedSize Group TwosComplement ZigZag Default struct struct struct struct struct struct struct struct struct class class struct struct struct struct struct struct none Field type not implemented: (.) double Double Single Long ULong Integer ULong UInteger Boolean String Byte() UInteger Integer Long Integer Long Field type not implemented: (.) "" . ' CType(, ) . . 0.0 0.0F 0L 0L 0 0L 0 False "" Nothing 0 0 0L 0 0L Nothing . Nothing Nullable(Of ) Private = Private = <Global.ProtoBuf.ProtoMember(, IsRequired:=False, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.ComponentModel.DefaultValue(CType(, ))> _ <Global.System.ComponentModel.DefaultValue(CType(, ))> _ <Global.System.Xml.Serialization.XmlElement("", Order:=)> _ <Global.ProtoBuf.ProtoMember(, IsRequired:=False, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.ComponentModel.DefaultValue(CType(, ))> _ <Global.System.ComponentModel.DefaultValue(CType(, ))> _ <Global.System.Runtime.Serialization.DataMember(Name:="", Order:=, IsRequired:=False)> _ <Global.ProtoBuf.ProtoMember(, IsRequired:=False, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.ComponentModel.DefaultValue(CType(, ))> _ <Global.System.ComponentModel.DefaultValue(CType(, ))> _ <Global.ProtoBuf.ProtoMember(, IsRequired:=False, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.Runtime.Serialization.DataMember(Name:="", Order:=, IsRequired:=False)> _ <Global.ProtoBuf.ProtoMember(, IsRequired:=False, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.Xml.Serialization.XmlElement("", Order:=)> _ <Global.ProtoBuf.ProtoMember(, IsRequired:=False, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ Private <Global.ProtoBuf.ProtoMember(, IsRequired:=True, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.Runtime.Serialization.DataMember(Name:="", Order:=, IsRequired:=True)> _ <Global.ProtoBuf.ProtoMember(, IsRequired:=True, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.Xml.Serialization.XmlElement("", Order:=)> _ <Global.ProtoBuf.ProtoMember(, IsRequired:=True, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ Public Property Public Property Get Return If Not Is Nothing Then Return Else Return End If Return End Get Set() Set() OnChanging(value) OnPropertyChanging("") = value OnPropertyChanged("") OnChanged() End Set End Property partial void OnChanging( value); partial void OnChanged(); <Global.System.Xml.Serialization.XmlIgnore> _ <Global.System.ComponentModel.Browsable(false)> _ Public Property Specified As Boolean Get Return .HasValue End Get Set (ByVal value As Boolean) If Not .HasValue Then If value = True then = Else If value = False then = Nothing End If End Set End Property Public Property Specified As Boolean Get Return IsNot Nothing End Get Set (ByVal value As Boolean) If Is Nothing Then If value = True then = Else If value = False then = Nothing End If End Set End Property Private Function ShouldSerialize() As Boolean Return Specified End Function Private Sub Reset() Specified = false End Sub Private ReadOnly as Global.System.Collections.Generic.List(Of ) = New Global.System.Collections.Generic.List(Of )() Private ReadOnly as Global.System.Collections.Generic.List(Of ) = New Global.System.Collections.Generic.List(Of )() <Global.ProtoBuf.ProtoMember(, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.Runtime.Serialization.DataMember(Name:="", Order:=, IsRequired:=False)> _ <Global.ProtoBuf.ProtoMember(, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ <Global.System.Xml.Serialization.XmlElement("", Order:=)> _ <Global.ProtoBuf.ProtoMember(, Name:="", DataFormat:=Global.ProtoBuf.DataFormat.)> _ Public ReadOnly Property As Global.System.Collections.Generic.List(Of ) Public ReadOnly Property As Global.System.Collections.Generic.List(Of ) Get Return End Get Set (value As Global.System.Collections.Generic.List(Of )) Set (value As Global.System.Collections.Generic.List(Of )) = value End Set End Property <Global.System.ServiceModel.ServiceContract(Name:="")> _ Public Interface I End Interface Public Class Client : Global.ProtoBuf.ServiceModel.RpcClient public Client() : base(typeof(I)) { } End Class <Global.System.ServiceModel.OperationContract(Name:="")> _ <Global.ProtoBuf.ServiceModel.ProtoBehavior()> _ ( request); <Global.System.ServiceModel.OperationContract(AsyncPattern:=True, Name:="")> _ Global.System.IAsyncResult Begin( request, Global.System.AsyncCallback callback, object state); End(Global.System.IAsyncResult ar); ( request) { return () Send("", request); } Public Class CompletedEventArgs : Global.System.ComponentModel.AsyncCompletedEventArgs private object[] results; public CompletedEventArgs(object[] results, Global.System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } public Result { get { base.RaiseExceptionIfNecessary(); return ()(this.results[0]); } } End Class <Global.System.Diagnostics.DebuggerStepThroughAttribute()> _ public partial class Client : Global.System.ServiceModel.ClientBase<I>, I { public Client() {} public Client(string endpointConfigurationName) : base(endpointConfigurationName) {} public Client(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) {} public Client(string endpointConfigurationName, Global.System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) {} public Client(Global.System.ServiceModel.Channels.Binding binding, Global.System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) {} } private BeginOperationDelegate onBeginDelegate; private EndOperationDelegate onEndDelegate; private Global.System.Threading.SendOrPostCallback onCompletedDelegate; public event Global.System.EventHandler<CompletedEventArgs> Completed; public ( request) { return base.Channel.(request); } <Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ public Global.System.IAsyncResult Begin( request, Global.System.AsyncCallback callback, object asyncState) { return base.Channel.Begin(request, callback, asyncState); } <Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ public End(Global.System.IAsyncResult result) { return base.Channel.End(result); } private Global.System.IAsyncResult OnBegin(object[] inValues, Global.System.AsyncCallback callback, object asyncState) { request = (()(inValues[0])); return this.Begin(request, callback, asyncState); } private object[] OnEnd(Global.System.IAsyncResult result) { retVal = this.End(result); return new object[] { retVal}; } private void OnCompleted(object state) { if ((this.Completed != null)) { InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state)); this.Completed(this, new CompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState)); } } public void Async( request) { this.Async(request, null); } public void Async( request, object userState) { if ((this.onBeginDelegate == null)) { this.onBeginDelegate = new BeginOperationDelegate(this.OnBegin); } if ((this.onEndDelegate == null)) { this.onEndDelegate = new EndOperationDelegate(this.OnEnd); } if ((this.onCompletedDelegate == null)) { this.onCompletedDelegate = new Global.System.Threading.SendOrPostCallback(this.OnCompleted); } base.InvokeAsync(this.onBeginDelegate, new object[] { request}, this.onEndDelegate, this.onCompletedDelegate, userState); } [] |AddHandler|AddressOf|Alias|And|AndAlso|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDec|CDbl|Char|CInt|Class|CLng|CObj|Const|Continue|CSByte|CShort|CSng|CStr|CType|CUInt|CULng|CUShort|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|False|Finally|For|Friend|Function|Get|GetType|GetXMLNamespace|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|Narrowing|New|Next|Not|Nothing|NotInheritable|NotOverridable|Object|Of|On|Operator|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|REM|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|True|Try|TryCast|TypeOf|Variant|Wend|UInteger|ULong|UShort|Using|When|While|Widening|With|WithEvents|WriteOnly|Xor| ================================================ FILE: Tools/ProtobufGen/protobuf-net/xml.xslt ================================================  Xml template for protobuf-net. This template writes the proto descriptor as xml. No options available. ================================================ FILE: Tools/ProtobufGen/protogen.bat ================================================ set Protocol=..\..\Assets\CSharpLua\Compiled\Protocol\ set AutoGen=%Protocol%AutoGen\ set LuaProtocol=..\..\Assets\Lua\3rd\pbc\Protocol\ set cur=%cd% cd %Protocol% for %%i in (*.proto) do ( %cur%\protobuf-net\protogen -i:%%i -o:AutoGen\%%~ni.cs ) for %%i in (*.proto) do ( %cur%\protobuf-net\protoc %%i -o %cur%\%LuaProtocol%%%~ni.pb ) cd %cur% echo protogen success ================================================ FILE: Unity5.x/Assets/Plugins/Android/libs/armeabi-v7a/libtolua.so.meta ================================================ fileFormatVersion: 2 guid: 4fb9a29f65e536b4293f7f9affd19158 PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 platformData: Android: enabled: 1 settings: CPU: ARMv7 Any: enabled: 0 settings: {} Editor: enabled: 0 settings: CPU: AnyCPU DefaultValueInitialized: true OS: AnyOS Linux: enabled: 0 settings: CPU: x86 Linux64: enabled: 0 settings: CPU: x86_64 OSXIntel: enabled: 0 settings: CPU: AnyCPU OSXIntel64: enabled: 0 settings: CPU: AnyCPU Win: enabled: 0 settings: CPU: AnyCPU Win64: enabled: 0 settings: CPU: AnyCPU iOS: enabled: 0 settings: CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Unity5.x/Assets/Plugins/Android/libs/x86/libtolua.so.meta ================================================ fileFormatVersion: 2 guid: b3f1ad25b4054b34d9105289ee492b57 timeCreated: 1471082297 licenseType: Pro PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 platformData: Android: enabled: 1 settings: CPU: x86 Any: enabled: 0 settings: {} Editor: enabled: 0 settings: CPU: AnyCPU DefaultValueInitialized: true OS: AnyOS Linux: enabled: 0 settings: CPU: x86 Linux64: enabled: 0 settings: CPU: x86_64 OSXIntel: enabled: 0 settings: CPU: AnyCPU OSXIntel64: enabled: 0 settings: CPU: AnyCPU Win: enabled: 0 settings: CPU: AnyCPU Win64: enabled: 0 settings: CPU: AnyCPU iOS: enabled: 0 settings: CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Unity5.x/Assets/Plugins/iOS/libtolua.a.meta ================================================ fileFormatVersion: 2 guid: 54c35a8b7bc7347e0a91ff24faf55409 timeCreated: 1456833383 licenseType: Pro PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 platformData: Android: enabled: 0 settings: CPU: AnyCPU Any: enabled: 0 settings: {} Editor: enabled: 0 settings: CPU: AnyCPU DefaultValueInitialized: true OS: AnyOS Linux: enabled: 0 settings: CPU: x86 Linux64: enabled: 0 settings: CPU: x86_64 OSXIntel: enabled: 0 settings: CPU: AnyCPU OSXIntel64: enabled: 0 settings: CPU: AnyCPU Win: enabled: 0 settings: CPU: AnyCPU Win64: enabled: 0 settings: CPU: AnyCPU iOS: enabled: 1 settings: CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Unity5.x/Assets/Plugins/tolua.bundle.meta ================================================ fileFormatVersion: 2 guid: fd30d03bd8185a44ba7bc7fbfcca2201 folderAsset: yes PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 platformData: Android: enabled: 0 settings: CPU: AnyCPU Any: enabled: 0 settings: {} Editor: enabled: 1 settings: CPU: AnyCPU DefaultValueInitialized: true OS: OSX Linux: enabled: 1 settings: CPU: x86 Linux64: enabled: 1 settings: CPU: x86_64 LinuxUniversal: enabled: 1 settings: CPU: AnyCPU OSXIntel: enabled: 1 settings: CPU: AnyCPU OSXIntel64: enabled: 1 settings: CPU: AnyCPU OSXUniversal: enabled: 1 settings: CPU: AnyCPU Win: enabled: 1 settings: CPU: AnyCPU Win64: enabled: 1 settings: CPU: AnyCPU iOS: enabled: 0 settings: CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Unity5.x/Assets/Plugins/x86/tolua.dll.meta ================================================ fileFormatVersion: 2 guid: 8f4af3c74c7469d498c7c7c7a40ead91 PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 platformData: Android: enabled: 0 settings: CPU: AnyCPU Any: enabled: 0 settings: {} Editor: enabled: 1 settings: CPU: x86 DefaultValueInitialized: true OS: Windows Linux: enabled: 1 settings: CPU: x86 Linux64: enabled: 0 settings: CPU: None LinuxUniversal: enabled: 0 settings: CPU: x86 OSXIntel: enabled: 1 settings: CPU: AnyCPU OSXIntel64: enabled: 0 settings: CPU: None OSXUniversal: enabled: 0 settings: CPU: x86 Win: enabled: 1 settings: CPU: AnyCPU Win64: enabled: 0 settings: CPU: None iOS: enabled: 0 settings: CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: ================================================ FILE: Unity5.x/Assets/Plugins/x86_64/tolua.dll.meta ================================================ fileFormatVersion: 2 guid: 82bce848ef6ade348a8220c2ada7da08 PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 platformData: Android: enabled: 0 settings: CPU: AnyCPU Any: enabled: 0 settings: {} Editor: enabled: 1 settings: CPU: x86_64 DefaultValueInitialized: true OS: Windows Linux: enabled: 0 settings: CPU: None Linux64: enabled: 1 settings: CPU: x86_64 LinuxUniversal: enabled: 0 settings: CPU: x86_64 OSXIntel: enabled: 0 settings: CPU: None OSXIntel64: enabled: 1 settings: CPU: AnyCPU OSXUniversal: enabled: 0 settings: CPU: x86_64 Win: enabled: 0 settings: CPU: None Win64: enabled: 1 settings: CPU: AnyCPU iOS: enabled: 0 settings: CompileFlags: FrameworkDependencies: userData: assetBundleName: assetBundleVariant: