public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter) { var loopLabel = emiter.DefineLabel(); var outLabel = emiter.DefineLabel(); emiter.MarkLabel(loopLabel); Condition.EmitByteCode(context, emiter); emiter.BranchIfFalse(outLabel); BlockStmt.EmitByteCode(context, emiter); emiter.Branch(loopLabel); emiter.MarkLabel(outLabel); return(emiter); }
public void EmitSerialize(Emit <Action <BinaryWriter, object> > emiter, Local value) { var write = emiter.DefineLabel(nameof(StringSerializer) + "Write" + Guid.NewGuid()); // if (value != null) goto write emiter.LoadLocal(value); emiter.LoadNull(); emiter.CompareEqual(); emiter.BranchIfFalse(write); // value = string.Empty emiter.LoadField(typeof(string).GetField(nameof(string.Empty))); emiter.StoreLocal(value); // ProudNetBinaryWriterExtensions.WriteProudString(writer, value, false) emiter.MarkLabel(write); emiter.LoadArgument(1); emiter.LoadLocal(value); emiter.LoadConstant(false); emiter.Call(typeof(ProudNetBinaryWriterExtensions).GetMethod(nameof(ProudNetBinaryWriterExtensions.WriteProudString))); }
private void GenerateFunctionInner(Emit<MuftecFunction> funcDef, Queue<MuftecStackItem> execStack, Local runtimeStack, MuftecStackItem lastItem = default(MuftecStackItem)) { DebugMsg("- Call stack -> {0}", String.Join(", ", execStack.ToArray())); var stackPush = typeof (Stack<MuftecStackItem>).GetMethod("Push"); while (execStack.Count > 0) { var currStackItem = execStack.Dequeue(); DebugMsg("- Popping stack item: " + currStackItem.ToDebugString()); switch (currStackItem.Type) { // Run a user defined function case MuftecType.Function: // Find the function and create an IL call var funcName = currStackItem.Item.ToString(); DebugMsg(" -- Call function {0}", funcName); var func = _funcCache[funcName]; funcDef.LoadArgument(0); // Load OpCodeData into stack funcDef.Call(func); break; // Execute a library opcode case MuftecType.OpCode: // Translate opcode into direct call var opCodeName = currStackItem.Item.ToString(); DebugMsg(" >> Call opcode {0}", opCodeName); var opCode = _system.FindOpCode(opCodeName); // If this is an internal opcode, we need to handle it at this level if (opCode.Attribute.Extern) { switch (opCode.Attribute.OpCodeName) { case "!": case "@": throw new MuftecCompilerException("Variables not supported in the fabricator at line " + currStackItem.LineNumber); case "loadlibdll": funcDef.LoadLocal(runtimeStack); funcDef.Call(typeof (Shared).GetMethod("PopStr")); _system.AddLibrary(lastItem.ToString()); break; } } else { funcDef.LoadArgument(0); // Load OpCodeData into the stack funcDef.Call(opCode.Pointer.Method); // Call OpCode function } // Handle post-execution magic var magic = opCode.Attribute.Magic; switch (magic) { case MagicOpcodes.Abort: // End exeuction DebugMsg(" ---- Abort"); funcDef.LoadConstant(0); funcDef.Call(typeof (Environment).GetMethod("Exit")); return; case MagicOpcodes.Exit: DebugMsg(" ---- Exit"); // Exit out of this loop return; } break; // Handle a conditional container case MuftecType.Conditional: var container = currStackItem.Item as ConditionalContainer; if (container == null) throw new MuftecCompilerException("Unable to process conditional statement at line " + currStackItem.LineNumber); DebugMsg(" -- Container"); var ltLabel = funcDef.DefineLabel(); var endLabel = funcDef.DefineLabel(); funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack funcDef.Call(typeof (Shared).GetMethod("PopInt")); // Call PopInt on RuntimeStack funcDef.BranchIfFalse(ltLabel); // GT operations DebugMsg(" -- Starting true condition"); GenerateFunctionInner(funcDef, container.TrueQueue, runtimeStack, lastItem); funcDef.Branch(endLabel); // LT operations funcDef.MarkLabel(ltLabel); DebugMsg(" -- Starting false condition"); GenerateFunctionInner(funcDef, container.FalseQueue, runtimeStack, lastItem); funcDef.MarkLabel(endLabel); DebugMsg(" -- Conditions done"); break; // Add item to the runtime stack case MuftecType.Integer: DebugMsg(" -- Pushing int {0} to RS", currStackItem.ToString()); funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack funcDef.LoadConstant((int)currStackItem.Item); funcDef.LoadConstant(currStackItem.LineNumber); funcDef.NewObject<MuftecStackItem, int, int>(); funcDef.Call(stackPush); break; case MuftecType.Float: DebugMsg(" -- Pushing float {0} to RS", currStackItem.ToString()); funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack funcDef.LoadConstant((double)currStackItem.Item); funcDef.LoadConstant(currStackItem.LineNumber); funcDef.NewObject<MuftecStackItem, double, int>(); funcDef.Call(stackPush); break; case MuftecType.String: DebugMsg(" -- Pushing string {0} to RS", currStackItem.ToString()); funcDef.LoadLocal(runtimeStack); // Get the RuntimeStackp = funcDef.LoadConstant((string)currStackItem.Item); funcDef.LoadConstant(currStackItem.LineNumber); funcDef.NewObject<MuftecStackItem, string, int>(); funcDef.Call(stackPush); break; case MuftecType.ArrayMarker: DebugMsg(" -- Pushing array marker to RS"); funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack funcDef.LoadConstant((int)currStackItem.Item); funcDef.Call(typeof(MuftecStackItem).GetMethod("CreateArrayMarker")); funcDef.Call(stackPush); break; } lastItem = currStackItem; } }
public override void Emit <T>(Emit <T> emitter) { emitter.BranchIfFalse(_label); }