/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="data"></param> /// <returns></returns> private TinyView CreateView(IControllerContext context, IViewData data) { string templateName = context.ViewPath + ".tiny"; Resource resource = _provider.Get(templateName); if (resource == null) { _logger.Warning("Failed to load " + templateName); return(null); } // Add all namespaces and assemblies needed. var compiler = new Compiler(); compiler.Add(typeof(IView)); compiler.Add(typeof(string)); compiler.Add(typeof(TextWriter)); foreach (var parameter in data) { compiler.Add(parameter.Value.GetType()); } using (resource.Stream) { var buffer = new byte[resource.Stream.Length]; resource.Stream.Read(buffer, 0, buffer.Length); TextReader reader = new StreamReader(resource.Stream); var sb = new StringBuilder(); // parse Parse(reader, sb); // and add it in the type. string code = ClassContents; code = code.Replace("{body}", sb.ToString()); // add view data types. string types = string.Empty; foreach (var parameter in data) { types = Compiler.GetTypeName(parameter.Value.GetType()) + " " + parameter.Key + " = (" + Compiler.GetTypeName(parameter.Value.GetType()) + ")viewData[\"" + parameter.Key + "\"];"; } code = code.Replace("{viewDataTypes}", types); try { compiler.Compile(code); } catch (Exception err) { _logger.Error("Failed to compile template " + templateName + ", reason: " + err); } return(compiler.CreateInstance <TinyView>()); } }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="data"></param> /// <returns></returns> private TinyView CreateView(IControllerContext context, IViewData data) { string templateName = context.ViewPath + ".tiny"; Resource resource = _provider.Get(templateName); if (resource == null) { _logger.Warning("Failed to load " + templateName); return null; } // Add all namespaces and assemblies needed. var compiler = new Compiler(); compiler.Add(typeof (IView)); compiler.Add(typeof (string)); compiler.Add(typeof (TextWriter)); foreach (var parameter in data) compiler.Add(parameter.Value.GetType()); using (resource.Stream) { var buffer = new byte[resource.Stream.Length]; resource.Stream.Read(buffer, 0, buffer.Length); TextReader reader = new StreamReader(resource.Stream); var sb = new StringBuilder(); // parse Parse(reader, sb); // and add it in the type. string code = ClassContents; code = code.Replace("{body}", sb.ToString()); // add view data types. string types = string.Empty; foreach (var parameter in data) { types = Compiler.GetTypeName(parameter.Value.GetType()) + " " + parameter.Key + " = (" + Compiler.GetTypeName(parameter.Value.GetType()) + ")viewData[\"" + parameter.Key + "\"];"; } code = code.Replace("{viewDataTypes}", types); try { compiler.Compile(code); } catch (Exception err) { _logger.Error("Failed to compile template " + templateName + ", reason: " + err); } return compiler.CreateInstance<TinyView>(); } }
/// <summary> /// 进行语法检查 /// </summary> /// <returns></returns> public List <CompilationException> Check() { HasChecked = true; foreach (var item in _builderCache) { Compiler.Add(item); } return(Compiler.SyntaxInfos.SyntaxExceptions); }
private void Init(StreamingContext c) { // Handlers = new ItemEventHandlerList(); Compiler.Options.Combine(Options); // Set temporarily DefaultClass.Items to this ItemList temp = DefaultClass.Items; DefaultClass.Items = this; // compile libraries first foreach (Item x in this) { x.RaiseAddedToList(this); if (x is ICompilableLibrary) { x.TypeIndex = 0; Compiler.Add(x); } } foreach (Item x in this) { if (x is ICompilableLibrary && !x.Compiled) { Compiler.Compile(x); } } // compile others foreach (Item x in this) { if (!(x is ICompilableLibrary) && !x.Compiled) { Compiler.Compile(x); } } DefaultClass.Items = temp; Invalidate(); }
private void EmitWriteArrayLoop(Compiler.CompilerContext ctx, Compiler.Local i, Compiler.Local arr) { // i = 0 ctx.LoadValue(0); ctx.StoreValue(i); // range test is last (to minimise branches) Compiler.CodeLabel loopTest = ctx.DefineLabel(), processItem = ctx.DefineLabel(); ctx.Branch(loopTest, false); ctx.MarkLabel(processItem); // {...} ctx.LoadArrayValue(arr, i); if (SupportNull) { Tail.EmitWrite(ctx, null); } else { ctx.WriteNullCheckedTail(itemType, Tail, null); } // i++ ctx.LoadValue(i); ctx.LoadValue(1); ctx.Add(); ctx.StoreValue(i); // i < arr.Length ctx.MarkLabel(loopTest); ctx.LoadValue(i); ctx.LoadLength(arr, false); ctx.BranchIfLess(processItem, false); }
/// <summary> /// Create a new template compiler /// </summary> public TemplateCompiler() { _compiler = new Compiler(); _compiler.Add(GetType()); _compiler.Add(typeof(ITinyTemplate)); }
private void EmitReadEndPacked(Compiler.CompilerContext ctx, Compiler.Local list, Compiler.Local oldArr, Compiler.Local newArr, Type listType) { // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList using(Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, typeof(int)) : null) { Type[] copyToArrayInt32Args = new Type[] { typeof(Array), typeof(int) }; if (AppendToCollection) { ctx.LoadLength(oldArr, true); ctx.CopyValue(); ctx.StoreValue(oldLen); ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.Add(); ctx.CreateArray(itemType, null); // length is on the stack ctx.StoreValue(newArr); ctx.LoadValue(oldLen); Compiler.CodeLabel nothingToCopy = ctx.DefineLabel(); ctx.BranchIfFalse(nothingToCopy, true); ctx.LoadValue(oldArr); ctx.LoadValue(newArr); ctx.LoadValue(0); // index in target ctx.EmitCall(ExpectedType.GetMethod("CopyTo", copyToArrayInt32Args)); ctx.MarkLabel(nothingToCopy); ctx.LoadValue(list); ctx.LoadValue(newArr); ctx.LoadValue(oldLen); } else { ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.CreateArray(itemType, null); ctx.StoreValue(newArr); ctx.LoadAddress(list, listType); ctx.LoadValue(newArr); ctx.LoadValue(0); } copyToArrayInt32Args[0] = ExpectedType; // // prefer: CopyTo(T[], int) MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); if (copyTo == null) { // fallback: CopyTo(Array, int) copyToArrayInt32Args[1] = typeof(Array); copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); } ctx.EmitCall(copyTo); } ctx.LoadValue(newArr); }
public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local incoming) { bool issueReferenceDirectives = !baseTupleAsReference && asReference; Compiler.CodeLabel @end = ctx.DefineLabel(); using (Compiler.Local tupleKey = new Compiler.Local(ctx, typeof(int))) using (Compiler.Local oldTuple = new Compiler.Local(ctx, typeof(object))) using (Compiler.Local objValue = ctx.GetLocalWithValue(ExpectedType, incoming)) { Compiler.Local[] locals = new Compiler.Local[members.Length]; try { if (issueReferenceDirectives) { //int tupleKey = 0; ctx.LoadValue(0); ctx.StoreValue(tupleKey); //object oldTuple = null; ctx.LoadNullRef(); ctx.StoreValue(oldTuple); //tupleKey = (int)source.ReadUInt32(); ctx.LoadReaderWriter(); ctx.EmitCall(typeof (ProtoReader).GetMethod("ReadUInt32")); //ctx.CastToObject(typeof (int)); ctx.StoreValue(tupleKey); Compiler.CodeLabel @objectNotFound = ctx.DefineLabel(); ctx.LoadValue(tupleKey); ctx.LoadValue(0); ctx.BranchIfEqual(@objectNotFound, true); //// return source.NetCache.GetKeyedObject(tupleKey); ctx.LoadReaderWriter(); ctx.LoadValue(typeof (ProtoReader).GetProperty("NetCache")); ctx.LoadValue(tupleKey); ctx.EmitCall(typeof (NetObjectCache).GetMethod("GetKeyedObject")); ctx.CastFromObject(ExpectedType); ctx.StoreValue(objValue); ctx.Branch(@end, false); ctx.MarkLabel(@objectNotFound); ctx.EmitCtor(typeof (object)); ctx.StoreValue(oldTuple); // tupleKey = source.NetCache.AddObjectKey(oldTuple, out dummy); using (Compiler.Local dummy = new Compiler.Local(ctx, typeof (bool))) { ctx.LoadReaderWriter(); ctx.LoadValue(typeof (ProtoReader).GetProperty("NetCache")); ctx.LoadValue(oldTuple); ctx.LoadAddress(dummy, typeof (bool)); ctx.EmitCall(typeof (NetObjectCache).GetMethod("AddObjectKey", new Type[] { typeof(object), typeof(bool).MakeByRefType() })); ctx.StoreValue(tupleKey); } } for (int i = 0; i < locals.Length; i++) { Type type = GetMemberType(i); bool store = true; locals[i] = new Compiler.Local(ctx, type); if (!ExpectedType.IsValueType) { // value-types always read the old value if (type.IsValueType) { switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Boolean: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: case ProtoTypeCode.SByte: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: ctx.LoadValue(0); break; case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: ctx.LoadValue(0L); break; case ProtoTypeCode.Single: ctx.LoadValue(0.0F); break; case ProtoTypeCode.Double: ctx.LoadValue(0.0D); break; case ProtoTypeCode.Decimal: ctx.LoadValue(0M); break; case ProtoTypeCode.Guid: ctx.LoadValue(Guid.Empty); break; default: ctx.LoadAddress(locals[i], type); ctx.EmitCtor(type); store = false; break; } } else { ctx.LoadNullRef(); } if (store) { ctx.StoreValue(locals[i]); } } } Compiler.CodeLabel skipOld = ExpectedType.IsValueType ? new Compiler.CodeLabel() : ctx.DefineLabel(); if (!ExpectedType.IsValueType) { ctx.LoadAddress(objValue, ExpectedType); ctx.BranchIfFalse(skipOld, false); } for (int i = 0; i < members.Length; i++) { ctx.LoadAddress(objValue, ExpectedType); switch (members[i].MemberType) { case MemberTypes.Field: ctx.LoadValue((FieldInfo) members[i]); break; case MemberTypes.Property: ctx.LoadValue((PropertyInfo) members[i]); break; } ctx.StoreValue(locals[i]); } if (!ExpectedType.IsValueType) ctx.MarkLabel(skipOld); using (Compiler.Local fieldNumber = new Compiler.Local(ctx, typeof (int))) using (Compiler.Local j = new Compiler.Local(ctx, typeof (int))) { // j = 0 ctx.LoadValue(0); ctx.StoreValue(j); Compiler.CodeLabel @continue = ctx.DefineLabel(), processField = ctx.DefineLabel(), notRecognised = ctx.DefineLabel(), @endWhileLoop = ctx.DefineLabel(); ctx.Branch(@continue, false); Compiler.CodeLabel[] handlers = new Compiler.CodeLabel[members.Length]; for (int i = 0; i < members.Length; i++) { handlers[i] = ctx.DefineLabel(); } ctx.MarkLabel(processField); ctx.LoadValue(fieldNumber); ctx.LoadValue(1); ctx.Subtract(); // jump-table is zero-based ctx.Switch(handlers); // and the default: ctx.Branch(notRecognised, false); for (int i = 0; i < handlers.Length; i++) { ctx.MarkLabel(handlers[i]); IProtoSerializer tail = tails[i]; Compiler.Local oldValIfNeeded = tail.RequiresOldValue ? locals[i] : null; ctx.ReadNullCheckedTail(locals[i].Type, tail, oldValIfNeeded); if (tail.ReturnsValue) { if (locals[i].Type.IsValueType) { ctx.StoreValue(locals[i]); } else { Compiler.CodeLabel hasValue = ctx.DefineLabel(), allDone = ctx.DefineLabel(); ctx.CopyValue(); ctx.BranchIfTrue(hasValue, true); // interpret null as "don't assign" ctx.DiscardValue(); ctx.Branch(allDone, true); ctx.MarkLabel(hasValue); ctx.StoreValue(locals[i]); ctx.MarkLabel(allDone); } } ctx.Branch(@continue, false); } ctx.MarkLabel(notRecognised); ctx.LoadReaderWriter(); ctx.EmitCall(typeof (ProtoReader).GetMethod("SkipField")); ctx.MarkLabel(@continue); // j < values.Length ctx.LoadValue(j); ctx.LoadValue(members.Length); ctx.BranchIfGreaterOrEqual(@endWhileLoop, false); //j++ ctx.LoadValue(j); ctx.LoadValue(1); ctx.Add(); ctx.StoreValue(j); // source.ReadNextFieldHack() > 0 ctx.LoadReaderWriter(); ctx.EmitCall(typeof (ProtoReader).GetMethod("ReadNextFieldHack")); ctx.LoadValue(0); ctx.BranchIfLessOrEqual(@endWhileLoop, true); // field = source.ReadFieldHeader(); ctx.LoadReaderWriter(); ctx.EmitCall(typeof (ProtoReader).GetMethod("ReadFieldHeader")); ctx.StoreValue(fieldNumber); ctx.Branch(processField, false); ctx.MarkLabel(@endWhileLoop); } for (int i = 0; i < locals.Length; i++) { ctx.LoadValue(locals[i]); } ctx.EmitCtor(ctor); ctx.StoreValue(objValue); if (issueReferenceDirectives) { //source.NetCache.UpdateKeyedObject(tupleKey, oldTuple, result); ctx.LoadReaderWriter(); ctx.LoadValue(typeof (ProtoReader).GetProperty("NetCache")); ctx.LoadValue(tupleKey); ctx.LoadValue(oldTuple); ctx.LoadValue(objValue); ctx.CastToObject(ExpectedType); ctx.EmitCall(typeof (NetObjectCache).GetMethod("UpdateKeyedObject")); } if (forceIssueFakeHeader) { //source.ReadEndGroupFieldHeaderHack(); ctx.LoadReaderWriter(); ctx.EmitCall(typeof (ProtoReader).GetMethod("ReadEndGroupFieldHeaderHack")); } ctx.MarkLabel(@end); ctx.LoadValue(objValue); } finally { for (int i = 0; i < locals.Length; i++) { if (locals[i] != null) locals[i].Dispose(); // release for re-use } } } }
/// <summary> /// Adds the specified type. /// </summary> /// <param name="type">The type.</param> public void Add(Type type) { _compiler.Add(type); }
/// <summary> /// 直接添加一个合法的类/接口/结构体/枚举 /// </summary> /// <param name="script">脚本代码</param> /// <returns></returns> public CompilationException AddScript(string script) { return(Compiler.Add(script)); }