/// <summary> /// Provides a custom compiler routine for emitting CIL byte code for a specific instruction. /// </summary> /// <param name = "state">The compiler state.</param> /// <param name = "ins">The instruction to compile.</param> void ICilCompilerAware.ImplementInCil(CompilerState state, Instruction ins) { switch (ins.Arguments) { case 0: state.Il.EmitCall(OpCodes.Call, consoleWriteLineMethod_, null); if (!ins.JustEffect) { state.Il.Emit(OpCodes.Ldstr, ""); state.Il.EmitCall(OpCodes.Call, Compiler.Cil.Compiler.GetStringPType, null); state.Il.Emit(OpCodes.Newobj, Compiler.Cil.Compiler.NewPValue); } break; case 1: state.EmitLoadLocal(state.SctxLocal); state.Il.EmitCall(OpCodes.Call, PValueCallToString, null); if (!ins.JustEffect) { state.Il.Emit(OpCodes.Dup); state.Il.EmitCall(OpCodes.Call, Compiler.Cil.Compiler.GetStringPType, null); state.Il.Emit(OpCodes.Newobj, Compiler.Cil.Compiler.NewPValue); state.EmitStoreTemp(0); } state.Il.EmitCall(OpCodes.Call, consoleWriteLineMethod_String, null); if (!ins.JustEffect) { state.EmitLoadTemp(0); } break; default: throw new NotSupportedException(); } }
public void Implement(CompilerState state, Instruction ins, CompileTimeValue[] staticArgv, int dynamicArgc) { var text = String.Concat(staticArgv.Select(StaticPrint._ToString)); state.EmitCall(StaticPrint._StaticPrintTextWriterGetMethod); state.Il.Emit(OpCodes.Ldstr, text); if (!ins.JustEffect) { state.Il.Emit(OpCodes.Dup); state.EmitStoreTemp(0); } state.EmitVirtualCall(_textWriterWriteLineMethod); if (!ins.JustEffect) { state.EmitLoadTemp(0); state.EmitWrapString(); } }
internal static void _ImplementCtorCall(CompilerState state, Instruction ins, CompileTimeValue[] staticArgv, int dynamicArgc, ConstructorInfo partialCallCtor) { //the call subject is not part of argv var argc = staticArgv.Length + dynamicArgc - 1; if (argc == 0) { //there is no subject, just load null state.EmitLoadNullAsPValue(); return; } //We don't actually need static arguments, just emit the corresponding opcodes foreach (var compileTimeValue in staticArgv) compileTimeValue.EmitLoadAsPValue(state); //pack arguments (including static ones) into the argv array, but exclude subject (the first argument) state.FillArgv(argc); state.ReadArgv(argc); //call constructor of FunctionalPartialCall state.Il.Emit(OpCodes.Newobj, partialCallCtor); //wrap in PValue if (ins.JustEffect) { state.Il.Emit(OpCodes.Pop); } else { state.EmitStoreTemp(0); state.EmitLoadLocal(state.SctxLocal); state.EmitLoadTemp(0); state.EmitVirtualCall(Compiler.Cil.Compiler.CreateNativePValue); } }
void ICilCompilerAware.ImplementInCil(CompilerState state, Instruction ins) { var argc = ins.Arguments; if (argc < 2) { state.EmitLoadNullAsPValue(); } else { //pop excessive arguments for (var i = 2; i < argc; i++) state.Il.Emit(OpCodes.Pop); //make pvkvp state.Il.Emit(OpCodes.Newobj, Compiler.Cil.Compiler.NewPValueKeyValuePair); //save pvkvp in temporary variable state.EmitStoreTemp(0); //PType.Object.CreatePValue(temp) state.Il.EmitCall(OpCodes.Call, Compiler.Cil.Compiler.GetObjectPTypeSelector, null); state.EmitLoadTemp(0); state.Il.EmitCall(OpCodes.Call, Compiler.Cil.Compiler.CreatePValueAsObject, null); } }