IEnumerator LoadHotFixAssembly() { //***创建flashplayer*** //***建议全局只使用一个as3运行时。因此将此脚本设置为一直存在,并将flashplayer保存在此对象中。 var flashplayer = new ASRuntime.Player(); //此处从StreamingAssetsPath中加载字节码,实际热更可从网络下载后执行。 //The byte code is loaded from the Streamingassetspath, and the actual project can be downloaded from the network and executed. #if UNITY_ANDROID WWW www = new WWW(Application.streamingAssetsPath + "/hotfix.cswc"); #else WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/hotfix.cswc"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } //加载as3编译器生成的字节码。 //Loads the byte code generated by the compiler. ASBinCode.CSWC swc = ASBinCode.CSWC.loadFromBytes(www.bytes); www.Dispose(); ASRuntime.nativefuncs.BuildInFunctionLoader.loadBuildInFunctions(swc); var extfunctions = new ASRuntime.extFunctions(); //加载导出的Unity API //Loading exported APIs var regenumerator = extfunctions.registrationFunction(swc); //**注册本地代码有可能非常之多。所以提供了一个进度条** //API code can be very much. So a progress bar is provided int functioncount = 0; while (regenumerator.MoveNext()) { functioncount++; if (functioncount % 50 == 0) { if (progress != null) { progress.value = extfunctions.progress; progressValue.text = "loading:" + extfunctions.progress * 100 + "%"; } yield return(null); } } if (progress != null) { progress.value = extfunctions.progress; progressValue.text = "loading:" + extfunctions.progress * 100 + "%"; } yield return(null); //注册额外的代码,这些代码为MonoBehaviour提供支持 //Register additional code that provides support for MonoBehaviour GObj_Special.registSpecialFunctions(swc); if (progress != null) { progress.gameObject.SetActive(false); progressValue.gameObject.SetActive(false); } this.player = flashplayer; flashplayer.loadCode(swc); if (string.IsNullOrEmpty(DocumentClass)) { Debug.LogError("请指定AS3入口文档类"); yield break; } main = flashplayer.createInstance(DocumentClass); updatemethod = flashplayer.getMethod(main, "update"); }
IEnumerator LoadHotFixAssembly() { //首先实例化ILRuntime的AppDomain,AppDomain是一个应用程序域,每个AppDomain都是一个独立的沙盒 appdomain = new ILRuntime.Runtime.Enviorment.AppDomain(); //正常项目中应该是自行从其他地方下载dll,或者打包在AssetBundle中读取,平时开发以及为了演示方便直接从StreammingAssets中读取, //正式发布的时候需要大家自行从其他地方读取dll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //这个DLL文件是直接编译HotFix_Project.sln生成的,已经在项目中设置好输出目录为StreamingAssets,在VS里直接编译即可生成到对应目录,无需手动拷贝 #if UNITY_ANDROID WWW www = new WWW(Application.streamingAssetsPath + "/HotFixProto.dll"); #else WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/HotFixProto.dll"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } byte[] dll = www.bytes; www.Dispose(); //PDB文件是调试数据库,如需要在日志中显示报错的行号,则必须提供PDB文件,不过由于会额外耗用内存,正式发布时请将PDB去掉,下面LoadAssembly的时候pdb传null即可 #if UNITY_ANDROID www = new WWW(Application.streamingAssetsPath + "/HotFixProto.pdb"); #else www = new WWW("file:///" + Application.streamingAssetsPath + "/HotFixProto.pdb"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } byte[] pdb = www.bytes; using (System.IO.MemoryStream fs = new MemoryStream(dll)) { using (System.IO.MemoryStream p = new MemoryStream(pdb)) { appdomain.LoadAssembly(fs, p, new Mono.Cecil.Pdb.PdbReaderProvider()); } } //***创建flashplayer*** //***我修改了Appdomain的代码,让Appdomain保存一个as3运行时的引用。这样可以避免静态变量。 var flashplayer = new ASRuntime.Player(new Assets.AS3Proto.UnityOutput()); //加载as3编译器生成的protobuf代码。 #if UNITY_ANDROID //www = new WWW(Application.streamingAssetsPath + "/as3test.cswc");// "/proto.cswc"); www = new WWW(Application.streamingAssetsPath + "/proto.cswc"); #else //www = new WWW("file:///" + Application.streamingAssetsPath + "/as3test.cswc");// "/proto.cswc"); www = new WWW("file:///" + Application.streamingAssetsPath + "/proto.cswc"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } ASBinCode.CSWC swc = ASBinCode.CSWC.loadFromBytes(www.bytes); flashplayer.loadCode(swc); appdomain.Tag = flashplayer; www.Dispose(); //flashplayer.run(null); InitializeILRuntime(); OnHotFixLoaded(); }
static void Main(string[] args) { //{ // ASRuntime.Player player = new ASRuntime.Player(); // byte[] bytecode = System.IO.File.ReadAllBytes("../Debug/as3unitylib.cswc"); // ASBinCode.CSWC swc2 = ASBinCode.CSWC.loadFromBytes(bytecode); // ASRuntime.nativefuncs.BuildInFunctionLoader.loadBuildInFunctions(swc2); // (new extFunctions()).registrationFunction(swc2); // player.loadCode(swc2); // player.run(null); // return; //} //ASCompiler.compiler.Builder bu = new ASCompiler.compiler.Builder(); //byte[] b = bu.BuildLibBin(); //System.IO.File.WriteAllBytes("astoolglobal.swc", b); ASTool.Grammar grammar = ASCompiler.Grammar.getGrammar(); //string teststring = "package{}var a:String = \"first\";var b:String = \"First\"; var c=a==b;"; string teststring = "package{}";//System.IO.File.ReadAllText("../../testScript/AS3Testproj/src/Main.as"); string[] files = null; Dictionary <string, string> srcFileProjFile = new Dictionary <string, string>(); if (args.Length > 0) { string path = args[0]; //path = @"F:\ASTool\ASCTest\bin\Release\tests\2_managed_array\"; //path = @"F:\ASTool\ASCTest\testScript\AS3Testproj\src\"; //path = @"E:\Manju-pc\as3protobuf\AS3ProtoBuf\src"; path = @"E:\Manju-pc\as3protobuf\AS3ProtoBuf\protobuflib"; //path = @"../..\testScript\AS3Testproj\amd"; //path = @"../..\testScript\AS3Testproj\src"; if (path.EndsWith(".as")) { path = System.IO.Path.GetDirectoryName(path); } if (string.IsNullOrEmpty(path)) { path = ".\\"; } //path = ""; //files =new string[] { "E:/Manju-pc/as3protobuf/AS3ProtoBuf/src/com/netease/protobuf/Message.as" }; path = path.Replace('\\', '/'); string[] ps = path.Split('/'); if (ps.Length == 2 && string.IsNullOrEmpty(ps[1]) && ps[0].IndexOf(System.IO.Path.VolumeSeparatorChar) > 0) { Console.WriteLine("无法在根目录下搜索.请将as源代码放到一个文件夹内"); return; } else if (System.IO.Directory.Exists(path)) { //Console.WriteLine(path); //teststring = System.IO.File.ReadAllText(args[0]); files = System.IO.Directory.GetFiles(path, "*.as", System.IO.SearchOption.AllDirectories); foreach (var item in files) { string projfile = item.Replace("\\", "/").Replace(path.Replace("\\", "/"), ""); if (projfile.StartsWith("/")) { projfile = projfile.Substring(1); } srcFileProjFile.Add(item, projfile); } } } else { Console.Write("输入as文件所在路径"); return; } if (files == null) { Console.Write("输入as文件所在路径"); return; } //*********加入API***** //{ // string apidir = @"../../..\LinkCodeGenCLI\bin\Debug\as3api"; // if (System.IO.Directory.Exists(apidir)) // { // var linkapi = System.IO.Directory.GetFiles(apidir, "*.as", System.IO.SearchOption.AllDirectories); // foreach (var item in linkapi) // { // string projfile = item.Replace("\\", "/").Replace(apidir.Replace("\\", "/"), ""); // if (projfile.StartsWith("/")) // projfile = projfile.Substring(1); // srcFileProjFile.Add(item, projfile); // } // string[] n = new string[files.Length + linkapi.Length]; // linkapi.CopyTo(n, 0); // files.CopyTo(n, linkapi.Length); // files = n; // } //} //{ // string apidir = @"..\..\..\as3_commapi\sharpapi"; // if (System.IO.Directory.Exists(apidir)) // { // var linkapi = System.IO.Directory.GetFiles(apidir, "*.as", System.IO.SearchOption.AllDirectories); // foreach (var item in linkapi) // { // string projfile = item.Replace("\\", "/").Replace(apidir.Replace("\\", "/"), ""); // if (projfile.StartsWith("/")) // projfile = projfile.Substring(1); // srcFileProjFile.Add(item, projfile); // } // string[] n = new string[files.Length + linkapi.Length]; // linkapi.CopyTo(n, 0); // files.CopyTo(n, linkapi.Length); // files = n; // } //} //********************* //*********加入ProtoBuf API***** //string apidir = @"E:\Manju-pc\as3protobuf\AS3ProtoBuf\protobuflib"; //if (System.IO.Directory.Exists(apidir)) //{ // var linkapi = System.IO.Directory.GetFiles(apidir, "*.as", System.IO.SearchOption.AllDirectories); // foreach (var item in linkapi) // { // string projfile = item.Replace("\\", "/").Replace(apidir.Replace("\\", "/"), ""); // if (projfile.StartsWith("/")) // projfile = projfile.Substring(1); // srcFileProjFile.Add(item, projfile); // } // string[] n = new string[files.Length + linkapi.Length]; // linkapi.CopyTo(n, 0); // files.CopyTo(n, linkapi.Length); // files = n; //} //********************* var proj = new ASTool.AS3.AS3Proj(); var srcout = new ASTool.ConSrcOut(); for (int i = 0; i < files.Length; i++) { grammar.hasError = false; teststring = System.IO.File.ReadAllText(files[i]); if (string.IsNullOrEmpty(teststring)) { continue; } var tree = grammar.ParseTree(teststring, ASTool.AS3LexKeywords.LEXKEYWORDS, ASTool.AS3LexKeywords.LEXSKIPBLANKWORDS, srcFileProjFile[files[i]]); //System.IO.File.WriteAllText("d:\\" + System.IO.Path.GetFileName(files[i]), tree.GetTreeString()); if (grammar.hasError) { Console.WriteLine(files[i]); Console.WriteLine("解析语法树失败!"); Console.ReadLine(); return; } var analyser = new ASTool.AS3FileGrammarAnalyser(proj, srcFileProjFile[files[i]]); if (!analyser.Analyse(tree)) //生成项目的语法树 { Console.WriteLine(analyser.err.ToString()); Console.WriteLine("语义分析失败!"); Console.ReadLine(); return; } #if DEBUG //Console.Clear(); #endif } #if DEBUG Console.WriteLine(); Console.WriteLine("====语法树翻译===="); //runtimeCompiler rtLoader = new runtimeCompiler(); foreach (var p in proj.SrcFiles) { p.Write(0, srcout); } #endif //Console.Read(); //return; ASCompiler.compiler.Builder builder = new ASCompiler.compiler.Builder(); //builder.LoadLibrary( System.IO.File.ReadAllBytes("as3protobuf.swc") ); //builder.LoadLibrary(System.IO.File.ReadAllBytes("F:/ASTool/LinkCodeGenCLI/bin/Debug/as3unitylib.cswc")); //builder.LoadLibrary(System.IO.File.ReadAllBytes("astoolglobal.swc")); //builder.Build(proj, new ASBinCode.INativeFunctionRegister[] { new extFunctions() } ); builder.options.CheckNativeFunctionSignature = false; builder.Build(proj, null); if (builder.buildErrors.Count == 0) { ASBinCode.CSWC swc = builder.getBuildOutSWC(); byte[] bin = swc.toBytes(); swc = ASBinCode.CSWC.loadFromBytes(bin); ASRuntime.nativefuncs.BuildInFunctionLoader.loadBuildInFunctions(swc); (new extFunctions()).registrationAllFunction(swc); //System.IO.File.WriteAllBytes("astoolglobal.swc", swc.toBytes()); System.IO.File.WriteAllBytes("as3protobuf.swc", swc.toBytes()); //System.IO.File.WriteAllBytes("as3test.cswc", swc.toBytes()); //System.IO.File.WriteAllBytes("as3unitylib.cswc", swc.toBytes()); if (swc != null) { #if DEBUG for (int i = 0; i < swc.blocks.Count; i++) { var block = swc.blocks[i]; if (block != null && block.name.EndsWith("::Main")) // "CRC32::update")) { Console.WriteLine(); Console.WriteLine("====操作指令 block " + block.name + " " + block.id + "===="); Console.WriteLine(); Console.WriteLine("total registers:" + block.totalStackSlots); Console.WriteLine(block.GetInstruction()); } } #endif if (swc.blocks.Count > 0) { ASRuntime.Player player = new ASRuntime.Player(); player.loadCode(swc); //byte[] bytecode = System.IO.File.ReadAllBytes("as3test.cswc"); //ASBinCode.CSWC swc2 = ASBinCode.CSWC.loadFromBytes(bytecode); //ASRuntime.nativefuncs.BuildInFunctionLoader.loadBuildInFunctions(swc2); //player.loadCode(swc2); //var d = player.createInstance("SProtoSpace.group_area_info"); //uint len = (uint)player.getMemberValue(d, "groupids.length"); //player.setMemberValue(d, "groupids.length", 3); //player.setMemberValue(d, "areaGroupName", null); //for (int i = 0; i < 3; i++) //{ // player.setMemberValue(d, "groupids", i + 5, i); //} ////var d = player.createInstance("SProtoSpace.role_base_info"); //ASRuntime.flash.utils.ByteArray array; //var byteArray = player.createByteArrayObject(out array); ////player.setMemberValue(d, "groupName", "账号你二大爷"); //var r = player.invokeMethod(d, "writeTo", byteArray); //var d2 = player.createInstance("SProtoSpace.group_area_info"); //player.setMemberValue(byteArray, "position", 0); //var k = player.invokeMethod(d2, "mergeFrom", byteArray); //var m = player.getMemberValue(d2, "groupids.length"); //var ts = player.invokeMethod(byteArray, "toString"); //var messageUnion = player.getMemberValue("SProtoSpace.base_msg_id", "name_check_ack_id"); //try //{ // player.setMemberValue("SProtoSpace.base_msg_id", "name_check_ack_id", 5); //} //catch (ASBinCode.ASRunTimeException e) //{ // Console.WriteLine(e.ToString()); //} //var s = player.invokeMethod("Test", "TTT", 3, 4); //***zip*** //ASRuntime.flash.utils.ByteArray array; //var byteArray = player.createByteArrayObject(out array); //var bytes = System.IO.File.ReadAllBytes(@"F:/code/Protobuf-as3-ILRuntime-master.zip"); //////var bytes = System.IO.File.ReadAllBytes(@"F:/3STOOGES.zip"); //array.writeBytes(bytes, 0, bytes.Length); //array.position = 0; //player.invokeMethod("Main", "showzip", byteArray); ////var by = player.invokeMethod("Main", "saveZip", byteArray); ////System.IO.File.WriteAllBytes("e:/kkk.zip", array.ToArray()); Console.WriteLine(); Console.WriteLine("====程序输出===="); player.run(null); } Console.WriteLine(); } } #if DEBUG Console.WriteLine("按任意键结束"); Console.ReadLine(); #endif }
static void Main(string[] args) { ASTool.Grammar grammar = ASCompiler.Grammar.getGrammar(); string teststring = @"package{ [Doc] //this is document class class Main {} } var a=1; var b=2; trace( a,'+',b,'=', a + b); "; var proj = new ASTool.AS3.AS3Proj(); var srcout = new ASTool.ConSrcOut(); //build AST grammar.hasError = false; var tree = grammar.ParseTree(teststring, ASTool.AS3LexKeywords.LEXKEYWORDS, ASTool.AS3LexKeywords.LEXSKIPBLANKWORDS); if (grammar.hasError) { Console.WriteLine("解析语法树失败!"); Console.ReadLine(); return; } var analyser = new ASTool.AS3FileGrammarAnalyser(proj, "Main.cs"); if (!analyser.Analyse(tree)) //生成项目的语法树 { Console.WriteLine(analyser.err.ToString()); Console.WriteLine("语义分析失败!"); Console.ReadLine(); return; } //build bytecode ASCompiler.compiler.Builder builder = new ASCompiler.compiler.Builder(); builder.options.CheckNativeFunctionSignature = false; builder.Build(proj, null); if (builder.buildErrors.Count == 0) { ASBinCode.CSWC swc = builder.getBuildOutSWC(); //save bytecode byte[] bin = swc.toBytes(); swc = ASBinCode.CSWC.loadFromBytes(bin); if (swc.blocks.Count > 0) { ASRuntime.Player player = new ASRuntime.Player(); //load bytecode player.loadCode(swc); Console.WriteLine(); Console.WriteLine("========"); player.run(null); } Console.ReadLine(); } }
static void Main(string[] args) { //-- 分析命令行参数 var options = new Options(); var parser = new CommandLine.Parser(with => with.HelpWriter = Console.Error); if (!parser.ParseArgumentsStrict(args, options, () => Environment.Exit(-1))) { //-- 执行导出操作 return; } string outputcsfile = options.OutPutCSFile; //@"../../../../HotFixProto/proto.cs"; string outputswcfile = options.OutPutCSWC; //@"../../../../AS3ProtoBuf_Unity/Assets/StreamingAssets/proto.cswc"; ASTool.Grammar grammar = ASCompiler.Grammar.getGrammar(); string teststring = "package{}"; Dictionary <string, string> srcFiles = new Dictionary <string, string>(); string[] protofiles = null; { string path = options.ProtoAS3; if (path.EndsWith(".as")) { path = System.IO.Path.GetDirectoryName(path); } if (string.IsNullOrEmpty(path)) { path = ".\\"; } string[] ps = path.Split(System.IO.Path.DirectorySeparatorChar); if (ps.Length == 2 && string.IsNullOrEmpty(ps[1]) && ps[0].IndexOf(System.IO.Path.VolumeSeparatorChar) > 0) { Console.WriteLine("无法在根目录下搜索.请将as源代码放到一个文件夹内"); return; } else if (System.IO.Directory.Exists(path)) { //Console.WriteLine(path); //teststring = System.IO.File.ReadAllText(args[0]); //files = System.IO.Directory.GetFiles(path, "*.as", System.IO.SearchOption.AllDirectories); AddSrcFiles(path, srcFiles); protofiles = new string[srcFiles.Count]; srcFiles.Keys.CopyTo(protofiles, 0); //(string[])files.Clone(); } } if (srcFiles.Count == 0) { Console.Write("输入as文件所在路径"); return; } //*********加入ProtoBuf API***** //string apidir = @"../../../../as3protobuflib"; //if (System.IO.Directory.Exists(apidir)) //{ // AddSrcFiles(apidir, srcFiles); //} //********************* var proj = new ASTool.AS3.AS3Proj(); var srcout = new ASTool.ConSrcOut(); foreach (var src in srcFiles) { grammar.hasError = false; teststring = System.IO.File.ReadAllText(src.Key); if (string.IsNullOrEmpty(teststring)) { continue; } teststring = teststring.Replace("override com.netease.protobuf.used_by_generated_code final function", "override protected final function"); var tree = grammar.ParseTree(teststring, ASTool.AS3LexKeywords.LEXKEYWORDS, ASTool.AS3LexKeywords.LEXSKIPBLANKWORDS, src.Value); if (grammar.hasError) { Console.WriteLine(src.Key); Console.WriteLine("解析语法树失败!"); Console.ReadLine(); return; } var analyser = new ASTool.AS3FileGrammarAnalyser(proj, src.Value); if (!analyser.Analyse(tree)) //生成项目的语法树 { Console.WriteLine(analyser.err.ToString()); Console.WriteLine("语义分析失败!"); Console.ReadLine(); return; } #if DEBUG //Console.Clear(); #endif } #if DEBUG Console.WriteLine(); Console.WriteLine("====语法树翻译===="); //runtimeCompiler rtLoader = new runtimeCompiler(); foreach (var p in proj.SrcFiles) { p.Write(0, srcout); } #endif //Console.Read(); //return; ASCompiler.compiler.Builder builder = new ASCompiler.compiler.Builder(); builder.LoadLibrary(System.IO.File.ReadAllBytes("as3protobuf.swc")); //builder.LoadLibrary( System.IO.File.ReadAllBytes("astoolglobal.swc")); builder.Build(proj, null); if (builder.buildErrors.Count == 0) { ASBinCode.CSWC swc = builder.getBuildOutSWC(); //System.IO.File.WriteAllBytes("astoolglobal.swc", swc.toBytes()); //System.IO.File.WriteAllBytes("as3protobuf.swc", swc.toBytes()); System.IO.File.WriteAllBytes(outputswcfile, swc.toBytes()); if (swc != null) { ASRuntime.Player player = new ASRuntime.Player(); player.loadCode(swc); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("using System;"); foreach (var cls in swc.classes) { if (cls.staticClass != null) { //判断是否在编译路径中 string fullname = cls.package + (string.IsNullOrEmpty(cls.package)?"": ".") + cls.name + ".as"; foreach (var f in protofiles) { string ff = f.Replace("\\", ".").Replace("/", "."); if (ff.EndsWith(fullname)) { CodeGen codeGen = new CodeGen(cls, swc, player); string cs = codeGen.GetCode(); Console.Write(cs); stringBuilder.AppendLine(cs); break; } } } } System.IO.File.WriteAllText(outputcsfile, stringBuilder.ToString()); } } }
public static ASBinCode.RunTimeValueBase Eval(ASTool.AS3.AS3Expression expression, Builder importBuilder = null ) { try { Builder builder = new Builder(new BuildOptions() { isConsoleOut = false }, true); int bid = builder.getBlockId(); if (importBuilder != null && importBuilder._currentImports.Count > 0) { List <ASBinCode.rtti.Class> imps = new List <ASBinCode.rtti.Class>(); imps.AddRange(importBuilder._currentImports.Peek()); builder._currentImports.Push(imps); bid = importBuilder.bin.blocks.Count; } CompileEnv tempEnv = new CompileEnv(new CodeBlock(bid, "temp", -65535, true), true); tempEnv.block.scope = new ASBinCode.scopes.StartUpBlockScope(); builder.buildExpressNotEval(tempEnv, expression); tempEnv.completSteps(builder); tempEnv.block.totalStackSlots = tempEnv.combieNeedStackSlots(); if (builder.buildErrors.Count == 0) { RightValueBase value = builds.ExpressionBuilder.getRightValue(tempEnv, expression.Value, expression.token, builder); if (player == null) { player = new ASRuntime.Player(null); } CSWC tempswc = new CSWC(); if (importBuilder != null) { tempswc.blocks.AddRange(importBuilder.bin.blocks); tempswc.classes.AddRange(importBuilder.bin.classes); tempswc.functions.AddRange(importBuilder.bin.functions); } tempswc.blocks.Add(tempEnv.block); Variable variableResult = new Variable("@@", tempEnv.block.scope.members.Count, tempEnv.block.id); tempEnv.block.scope.members.Add(variableResult); OpStep step = new OpStep(OpCode.assigning, new SourceToken(0, 0, "")); step.reg = variableResult; step.arg1 = value; tempEnv.block.opSteps.Add(step); tempEnv.block.instructions = tempEnv.block.opSteps.ToArray(); tempEnv.block.opSteps = null; player.loadCode(tempswc, tempEnv.block); RunTimeValueBase result = player.run(variableResult); return(result); //IRunTimeScope scope = player.run(); //if (player.runtimeError ==null) //{ // return value.getValue(scope); //} //else //{ // return null; //} } else { return(null); } } catch (BuildException) { return(null); } }