public EmitSyntax Build(EmitSyntax emit) { var result = emit.Locals.Generate().GetRef(); emit .Local(result.Def, emit.Types.Import(LanguageBase.Fields.tokenKeyToId.FieldType)) .Newobj(() => new Dictionary<object,int>()) .Stloc(result); foreach (var pair in EnumerateTokenKeyToId()) { emit.Ldloc(result); if (pair.Item1 is string) { emit.Ldstr(new QStr((string)pair.Item1)); } else if (pair.Item1 is Type) { emit .Ldtoken(emit.Types.Import((Type)pair.Item1)) .Call((RuntimeTypeHandle h) => Type.GetTypeFromHandle(h)); } else { throw new InvalidOperationException("Internal error: Unsupported token key type"); } emit .Ldc_I4(pair.Item2) .Call((Dictionary<object, int> self, object _key, int _id) => self.Add(_key, _id)) ; } return emit.Ldloc(result); }
public EmitSyntax Build(EmitSyntax emit) { int rows = table.RowCount; int columns = table.ColumnCount; Ref<Labels> END = emit.Labels.Generate().GetRef(); Ref<Labels>[] labels = new Ref<Labels>[rows]; for (int i = 0; i != rows; ++i) { labels[i] = emit.Labels.Generate().GetRef(); } emit .Do(LdRow) .Switch(labels) .Ldc_I4(-1) .Br(END) ; var columnRange = new IntInterval(0, columns - 1); var columnFrequency = new UniformIntFrequency(columnRange); for (int i = 0; i != rows; ++i) { var switchEmitter = SwitchGenerator.Sparse(table.GetRow(i), columnRange, columnFrequency); emit.Label(labels[i].Def); switchEmitter.Build(emit, LdCol, SwitchGenerator.LdValueAction(END)); } return emit .Label(END.Def); }
public EmitSyntax Build(EmitSyntax emit) { int rows = table.RowCount; int columns = table.ColumnCount; Ref <Labels> END = emit.Labels.Generate().GetRef(); Ref <Labels>[] labels = new Ref <Labels> [rows]; for (int i = 0; i != rows; ++i) { labels[i] = emit.Labels.Generate().GetRef(); } emit .Do(LdRow) .Switch(labels) .Ldc_I4(-1) .Br(END) ; var columnRange = new IntInterval(0, columns - 1); var columnFrequency = new UniformIntFrequency(columnRange); for (int i = 0; i != rows; ++i) { var switchEmitter = SwitchGenerator.Sparse(table.GetRow(i), columnRange, columnFrequency); emit.Label(labels[i].Def); switchEmitter.Build(emit, LdCol, SwitchGenerator.LdValueAction(END)); } return(emit.Label(END.Def)); }
public static EmitSyntax LdMethodDelegate( this EmitSyntax emit, Ref <Types> declaringType, string methodName, Type delegateType) { var method = delegateType.GetMethod("Invoke"); Pipe <WantArgsSigBase> argBuilder = args => { foreach (var param in method.GetParameters()) { var argType = emit.Types.Import(param.ParameterType); args = args.Argument(argType, param.Name); } return(args); }; return(emit.LdMethodDelegate( scope => { return scope.StartSignature .Returning(emit.Types.Import(method.ReturnType)) .DecaringType(declaringType) .Named(methodName) .BeginArgs() .Do(argBuilder) .EndArgs() ; }, delegateType)); }
private IActionCode LdActionArgument(int index) { emit = emit .Do(LdRuleArgs) .Do(LdArgsStart); // Optmization for "+ 0". if (index != 0) { emit .Ldc_I4(index) .Add(); } if (typeof(Msg).IsValueType) { emit = emit .Ldelema(emit.Types.Import(typeof(Msg))); } else { emit = emit .Ldelem_Ref(); } emit = emit .Ldfld((Msg msg) => msg.Value) ; return(this); }
public EmitSyntax Clear(EmitSyntax emit) { return emit .Ldc_I4_0() .Stloc(index.GetRef()) ; }
public EmitSyntax StackLoop(EmitSyntax emit, Action <EmitSyntax, Def <Locals> > emitLoopBody) { var labels = emit.Labels; var START = labels.Generate(); var END = labels.Generate(); var item = emit.Locals.Generate(); emit .Local(item, itemType) .Label(START) .Ldloc(index.GetRef()) .Ldc_I4(0) .Beq(END.GetRef()) .Do(Pop) .Stloc(item.GetRef()) ; emitLoopBody(emit, item); emit .Br(START.GetRef()) .Label(END) .Nop(); return(emit); }
protected override void DoBuild( EmitSyntax emit, Pipe <EmitSyntax> ldvalue, SwitchGeneratorAction action) { this.action = action; #if false var decisionTree = new BinaryDecisionTreeBuilder(intMap.DefaultValue, platformInfo); var node = decisionTree.Build(intMap.Enumerate().ToArray()); #else this.builder = new DecisionTreeBuilder(platformInfo); var node = builder.Build( intMap, possibleBounds, frequency); #endif this.emit = emit; this.ldvalue = ldvalue; this.labels = new List <Ref <Labels> >(); strategy.PlanCode(node); strategy.GenerateCode(); // Debug.Write(node); }
private void LdTid(EmitSyntax emit, CilSymbolRef tid) { if (tid.Type != null) { emit .Ldtoken(emit.Types.Import(tid.Type)) .Call((RuntimeTypeHandle h) => Type.GetTypeFromHandle(h)) ; } else { emit.Ldnull(); } if (tid.Literal == null) { emit.Ldnull(); } else { emit.Ldstr(new QStr(tid.Literal)); } emit .Newobj(() => new CilSymbolRef(default(Type), default(string))); }
public EmitSyntax Clear(EmitSyntax emit) { return(emit .Ldc_I4_0() .Stloc(index.GetRef()) ); }
private static EmitSyntax LdMethodDelegate( this EmitSyntax emit, Pipe <IMethodNs, DoneMethodSig> methodSig, Type delegateType) { return(emit .Ldnull() .Ldftn(emit.Methods.Method(methodSig)) .NewDelegate(delegateType)); }
public static EmitSyntax NewDelegate(this EmitSyntax emit, Type delegateType) { if (!typeof(Delegate).IsAssignableFrom(delegateType)) { throw new ArgumentException("Expected delegate type.", "delegateType"); } var ctor = delegateType.GetConstructor(new[] { typeof(object), typeof(IntPtr) }); return(emit.Newobj(ctor)); }
public static EmitSyntax Swap(this EmitSyntax emit, Def <Locals> x, Def <Locals> y, Def <Locals> tmp) { return (emit .Ldloc(x.GetRef()) .Stloc(tmp.GetRef()) .Ldloc(y.GetRef()) .Stloc(x.GetRef()) .Ldloc(tmp.GetRef()) .Stloc(y.GetRef())); }
public void BuildBody(EmitSyntax emit, LanguageData data, Ref <Args>[] args) { BuildBody( emit, data, ruleId: args[0], ruleArgs: args[1], argsStart: args[2], ctx: args[3], lookbackStart: args[4]); }
private EmitSyntax EmitFactoryCode( EmitSyntax emit, PlannedClass contextPlannedClass, Type type, bool nullAllowed) { if (type == typeof(void)) { } else if (type == typeof(int)) { emit = emit.Ldc_I4_0(); } else if (type.IsValueType) { var resultType = emit.Types.Import(type); var resultLoc = emit.Locals.Generate("result"); emit = emit .Local(resultLoc, resultType) .Ldloca(resultLoc.GetRef()) .Initobj(resultType) .Ldloc(resultLoc.GetRef()) ; } else if (nullAllowed) { emit.Ldnull(); } else if (!type.IsAbstract && !type.IsInterface) { emit = emit.Newobj( emit.Types.Import(type)); } else if (contextPlannedClass != null && contextPlannedClass.Implements(type)) { emit = emit.Ldarg(0); } else if (plan.Exists(e => e.Implements(type))) { var otherEntry = plan.Find(e => e.Implements(type)); emit = emit.Newobj( emit.Types.Class_( ClassName.Parse( otherEntry.ClassName))); } else { throw new InvalidOperationException( "Internal error: non-planned abstract result type"); } return(emit); }
public EmitSyntax EmitFactoryCode( EmitSyntax emit, Type type) { if (type.IsAbstract && !plan.Exists(e => e.Implements(type))) { PlanImplementationOf(type); } return EmitFactoryCode(emit, null, type, false); }
public void BuildBody(EmitSyntax emit, LanguageData data, Ref <Args>[] args) { BuildBody( emit, data, tokenId: args[0], oldValue: args[1], newValue: args[2], ctx: args[3], lookbackStart: args[4]); }
public void BuildBody(EmitSyntax emit, LanguageData data, Ref<Args>[] args) { BuildBody( emit, data, ruleId: args[0], ruleArgs: args[1], argsStart: args[2], ctx: args[3], lookbackStart: args[4]); }
public void BuildBody(EmitSyntax emit, LanguageData data, Ref<Args>[] args) { BuildBody( emit, data, tokenId: args[0], oldValue: args[1], newValue: args[2], ctx: args[3], lookbackStart: args[4]); }
public EmitSyntax EmitFactoryCode( EmitSyntax emit, Type type) { if (type.IsAbstract && !plan.Exists(e => e.Implements(type))) { PlanImplementationOf(type); } return(EmitFactoryCode(emit, null, type, false)); }
/// <summary> /// Create new object using default constructor of the specified type /// </summary> /// <param name="emit"></param> /// <param name="typeRef"></param> /// <returns></returns> public static EmitSyntax Newobj(this EmitSyntax emit, Ref <Types> typeRef) { return(emit.Newobj( emit.Methods.Method( _ => _.StartSignature .Instance .Returning(emit.Types.Void) .DecaringType(typeRef) .Named(".ctor") .BeginArgs() .EndArgs()))); }
/// <summary> /// Pops item and puts on the CLR stack /// </summary> /// <param name="emit"></param> public EmitSyntax Pop(EmitSyntax emit) { return(emit .Ldloc(index.GetRef()) .Ldc_I4_1() .Sub() .Stloc(index.GetRef()) .Ldloc(stack.GetRef()) .Ldloc(index.GetRef()) .Ldelem(itemType) ); }
public EmitSyntax Ld(EmitSyntax emit, Pipe <EmitSyntax> ldFrom) { // Load start value emit = ldFrom(emit); foreach (var getter in path) { emit = emit.Call(getter); } return(emit); }
public StackGenerator(EmitSyntax emit, Type itemType, bool nullContainer = false) { this.itemType = emit.Types.Import(itemType); this.stackType = emit.Types.Import(itemType.MakeArrayType()); this.nullContainer = nullContainer; this.stack = emit.Locals.Generate(); this.index = emit.Locals.Generate(); emit .Local(stack, stackType) .Local(index, emit.Types.Int32) ; }
public static EmitSyntax Call(this EmitSyntax emit, SR.MethodInfo method) { var methodRef = emit.Methods.Import(method); if (method.IsStatic) { return(emit.Call(methodRef)); } else { return(emit.Callvirt(methodRef)); } }
public ProductionCode( EmitSyntax emit, IContextCode contextCode, Pipe <EmitSyntax> ldRuleArgs, Pipe <EmitSyntax> ldArgsStart, Def <Labels> returnLabel) { this.emit = emit; this.contextCode = contextCode; this.LdRuleArgs = ldRuleArgs; this.LdArgsStart = ldArgsStart; this.ReturnLabel = returnLabel; }
public void PushFrom(EmitSyntax emit, Def <Locals> local) { emit .Ldloc(stack.GetRef()) .Ldloc(index.GetRef()) .Ldloc(local.GetRef()) .Stelem(itemType) .Ldloc(index.GetRef()) .Ldc_I4_1() .Add() .Stloc(index.GetRef()) ; }
public ProductionCode( EmitSyntax emit, IContextCode contextCode, Pipe<EmitSyntax> ldRuleArgs, Pipe<EmitSyntax> ldArgsStart, Def<Labels> returnLabel) { this.emit = emit; this.contextCode = contextCode; this.LdRuleArgs = ldRuleArgs; this.LdArgsStart = ldArgsStart; this.ReturnLabel = returnLabel; }
public ContextCode( EmitSyntax emit, Pipe <EmitSyntax> ldGlobalContextProvider, Pipe <EmitSyntax> ldLookback, LanguageData data, ForeignContextProvider contextProvider, LocalContextBinding[] localContexts = null) { this.emit = emit; this.ldGlobalContextProvider = ldGlobalContextProvider; this.ldLookback = ldLookback; this.contextProvider = contextProvider; this.localContexts = localContexts; }
public ContextCode( EmitSyntax emit, Pipe<EmitSyntax> ldGlobalContextProvider, Pipe<EmitSyntax> ldLookback, LanguageData data, ForeignContextProvider contextProvider, LocalContextBinding[] localContexts = null) { this.emit = emit; this.ldGlobalContextProvider = ldGlobalContextProvider; this.ldLookback = ldLookback; this.contextProvider = contextProvider; this.localContexts = localContexts; }
public MatcherCode( EmitSyntax emit, IContextCode contextCode, Pipe <EmitSyntax> ldCursor, Ref <Types> declaringType, ConditionCollection conditions, Ref <Labels> RETURN) { this.emit = emit; this.ldCursor = ldCursor; this.contextCode = contextCode; this.declaringType = declaringType; this.conditions = conditions; this.RETURN = RETURN; }
public MatcherCode( EmitSyntax emit, IContextCode contextCode, Pipe<EmitSyntax> ldCursor, Ref<Types> declaringType, ConditionCollection conditions, Ref<Labels> RETURN) { this.emit = emit; this.ldCursor = ldCursor; this.contextCode = contextCode; this.declaringType = declaringType; this.conditions = conditions; this.RETURN = RETURN; }
public EmitSyntax EmitLoopPass(EmitSyntax emit, bool loop) { emit.Label(START); FetchNext(emit, END); body(emit); if (loop) { emit.Br(START.GetRef()); } return(emit .Label(END) .Nop()); }
private EmitSyntax BuildNodeInvocation(ref int startArgIndex, EmitSyntax emit, Ref <Args>[] args, SppfNode node) { if (node.IsTerminal) { return(emit.Ldarg(args[startArgIndex++])); } int count = node.Children.Length; for (int i = 0; i != count; ++i) { emit = BuildNodeInvocation(ref startArgIndex, emit, args, node.Children[i]); } return(emit); }
public EmitSyntax EmitInitialization(EmitSyntax emit) { var types = emit.Types; var labels = emit.Labels; END = labels.Generate(); START = labels.Generate(); var locals = emit.Locals; count = locals.Generate(); if (Index == null) { Index = locals.Generate(); emit.Local(Index, types.Int32); } if (Value == null) { Value = locals.Generate(); emit .Local(Value, valueType) .Ldc_I4(int.MinValue) .Stloc(Value.GetRef()); } emit // int count; .Local(count, types.Int32); // count = array.Length ldarray(emit); return(emit .Ldlen() .Stloc(count.GetRef()) // Index = 0 .Ldc_I4(-1) .Stloc(Index.GetRef()) // Value = -1 .Ldc_I4(-1) .Stloc(Value.GetRef())); ; }
private void FetchNext(EmitSyntax emit, Def <Labels> END_OF_INPUT) { emit .Ldloc(Index.GetRef()) .Ldc_I4_1() .Add() .Stloc(Index.GetRef()) // ++Index // if (Index == count) goto END .Ldloc(Index.GetRef()) .Ldloc(count.GetRef()) .Beq(END_OF_INPUT.GetRef()) .Do(ldarray) .Ldloc(Index.GetRef()) .Ldelem(valueType) .Stloc(Value.GetRef()) ; }
public EmitSyntax Init(EmitSyntax emit) { emit = emit .Ldc_I4_0() .Stloc(index.GetRef()) ; if (!nullContainer) { emit = emit .Ldc_I4(this.stackSize) .Newarr(itemType) .Stloc(stack.GetRef()) ; } return emit; }
public EmitSyntax Init(EmitSyntax emit) { emit = emit .Ldc_I4_0() .Stloc(index.GetRef()) ; if (!nullContainer) { emit = emit .Ldc_I4(this.stackSize) .Newarr(itemType) .Stloc(stack.GetRef()) ; } return(emit); }
public EmitSyntax EmitInitialization(EmitSyntax emit) { var types = emit.Types; var labels = emit.Labels; END = labels.Generate(); START = labels.Generate(); var locals = emit.Locals; count = locals.Generate(); if (Index == null) { Index = locals.Generate(); emit.Local(Index, types.Int32); } if (Value == null) { Value = locals.Generate(); emit .Local(Value, valueType) .Ldc_I4(int.MinValue) .Stloc(Value.GetRef()); } emit // int count; .Local(count, types.Int32); // count = array.Length ldarray(emit); return emit .Ldlen() .Stloc(count.GetRef()) // Index = 0 .Ldc_I4(-1) .Stloc(Index.GetRef()) // Value = -1 .Ldc_I4(-1) .Stloc(Value.GetRef()); ; }
private static EmitSyntax EmitAst(EmitSyntax emit, AstNode ast, Ref <Args> input) { var settings = new ILCompilerSettings { LdInput = il => il.Ldarg(input), SUCCESS = emit.Labels.Generate(), FAILURE = emit.Labels.Generate(), }; var _ = new ILNfaCompiler(ast, emit, settings); emit .Label(settings.SUCCESS) .Ldc_I4_1() .Ret() .Label(settings.FAILURE) .Ldc_I4_0() .Ret(); return(emit); }
protected override void DoBuild(EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action) { var labels = new Ref<Labels>[map.Length]; for (int i = 0; i != labels.Length; ++i) { labels[i] = emit.Labels.Generate().GetRef(); } emit .Do(ldvalue) .Switch(labels) ; action(emit, defaultValue); for (int i = 0; i != labels.Length; ++i) { emit.Label(labels[i].Def); action(emit, map[i]); } }
protected override void DoBuild(EmitSyntax emit, Pipe <EmitSyntax> ldvalue, SwitchGeneratorAction action) { var labels = new Ref <Labels> [map.Length]; for (int i = 0; i != labels.Length; ++i) { labels[i] = emit.Labels.Generate().GetRef(); } emit .Do(ldvalue) .Switch(labels) ; action(emit, defaultValue); for (int i = 0; i != labels.Length; ++i) { emit.Label(labels[i].Def); action(emit, map[i]); } }
private void FetchNext(EmitSyntax emit, Def<Labels> END_OF_INPUT) { emit .Ldloc(Index.GetRef()) .Ldc_I4_1() .Add() .Stloc(Index.GetRef()) // ++Index // if (Index == count) goto END .Ldloc(Index.GetRef()) .Ldloc(count.GetRef()) .Beq(END_OF_INPUT.GetRef()) .Do(ldarray) .Ldloc(Index.GetRef()) .Ldelem(valueType) .Stloc(Value.GetRef()) ; }
public void LdValue(EmitSyntax emit) { emit.Ldloc(Value.GetRef()); }
public EmitSyntax Build(EmitSyntax emit) { int rows = table.RowCount; int columns = table.ColumnCount; // Dispatch info index Ref<Labels> DISP_INFO = emit.Labels.Generate().GetRef(); // Return no-data result Ref<Labels> RET_NONE = emit.Labels.Generate().GetRef(); // Exit Ref<Labels> END = emit.Labels.Generate().GetRef(); Ref<Labels>[] rowLabels = new Ref<Labels>[rows]; for (int i = 0; i != rows; ++i) { rowLabels[i] = emit.Labels.Generate().GetRef(); } emit .Do(LdRow) .Switch(rowLabels) .Br(RET_NONE) ; for (int i = 0; i != rows; ++i) { emit .Label(rowLabels[i].Def) .Ldc_I4(table.RowToOffset[i]) .Br(DISP_INFO); } int infoCount = table.Info.Count; var infoLabels = new Ref<Labels>[infoCount]; for (int i = 0; i != infoCount; ++i) { infoLabels[i] = emit.Labels.Generate().GetRef(); } emit .Label(DISP_INFO.Def) // Row offset should already be in stack .Do(LdCol) .Add() .Switch(infoLabels) .Br(RET_NONE); for (int i = 0; i != infoCount; ++i) { emit .Label(infoLabels[i].Def) .Do(LdRow) .Ldc_I4(table.Check[i]) .Bne_Un(RET_NONE) .Ldc_I4(table.Info[i]) .Br(END) ; } emit .Label(RET_NONE.Def) .Ldc_I4(0) ; return emit.Label(END.Def); }
public void BuildBody( EmitSyntax emit, LanguageData data, Ref<Args> ruleId, Ref<Args> ruleArgs, Ref<Args> argsStart, Ref<Args> ctx, Ref<Args> lookbackStart) { Def<Labels> returnLabel = emit.Labels.Generate(); var contextCode = new ContextCode( emit, il => il.Ldarg(ctx), il => il.Ldarg(lookbackStart), data, data.Grammar.GlobalContextProvider, data.LocalParseContexts); IActionCode code = new ProductionCode( emit, contextCode, ldRuleArgs: il => il.Ldarg(ruleArgs), ldArgsStart: il => il.Ldarg(argsStart), returnLabel: returnLabel); var defaultLabel = emit.Labels.Generate(); var endWithSingleResultLabel = emit.Labels.Generate(); var jumpTable = new Ref<Labels>[data.Grammar.Productions.Count]; for (int i = 0; i != jumpTable.Length; ++i) { jumpTable[i] = emit.Labels.Generate().GetRef(); } emit .Do(il => il.Ldarg(ruleId)) .Switch(jumpTable) .Br(defaultLabel.GetRef()); foreach (var prod in data.Grammar.Productions) { emit.Label(jumpTable[prod.Index].Def); if (0 == prod.Actions.Count) { // Augumented start rule has null action and should never be invoked. // Also it is possible that for some platforms production may have default // action. emit.Ldnull(); } else { foreach (var action in prod.Actions) { code = GenerateActionCode(code, action); } } emit.Br(endWithSingleResultLabel.GetRef()); } emit .Label(defaultLabel) .Ldnull() .Label(endWithSingleResultLabel) .Label(returnLabel) .Ret(); }
protected override void DoBuild( EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action) { this.action = action; #if false var decisionTree = new BinaryDecisionTreeBuilder(intMap.DefaultValue, platformInfo); var node = decisionTree.Build(intMap.Enumerate().ToArray()); #else this.builder = new DecisionTreeBuilder(platformInfo); var node = builder.Build( intMap, possibleBounds, frequency); #endif this.emit = emit; this.ldvalue = ldvalue; this.labels = new List<Ref<Labels>>(); strategy.PlanCode(node); strategy.GenerateCode(); // Debug.Write(node); }
private static EmitSyntax EmitAst(EmitSyntax emit, AstNode ast, Ref<Args> input) { var settings = new ILCompilerSettings { LdInput = il => il.Ldarg(input), SUCCESS = emit.Labels.Generate(), FAILURE = emit.Labels.Generate(), }; var _ = new ILNfaCompiler(ast, emit, settings); emit .Label(settings.SUCCESS) .Ldc_I4_1() .Ret() .Label(settings.FAILURE) .Ldc_I4_0() .Ret(); return emit; }
public void Build(EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action) { this.END = emit.Labels.Generate(); DoBuild(emit, ldvalue, action); }
public EmitSyntax EmitLoopPass(EmitSyntax emit, bool loop) { emit.Label(START); FetchNext(emit, END); body(emit); if (loop) { emit.Br(START.GetRef()); } return emit .Label(END) .Nop(); }
public void Build( EmitSyntax emit, Pipe<EmitSyntax> ldCursor, Pipe<EmitSyntax> ldTokenPtr) { var labels = emit.Labels; var locals = emit.Locals; var RETURN = labels.Generate(); var valueTmp = locals.Generate(); var tokenId = locals.Generate(); emit .Local(valueTmp, emit.Types.Object) .Ldnull() .Stloc(valueTmp.GetRef()) .Local(tokenId, emit.Types.Int32) .Ldc_I4(-1) .Stloc(tokenId.GetRef()) ; int ruleCount = data.Grammar.Conditions.Sum(cond => cond.Matchers.Count); var action = new Ref<Labels>[ruleCount]; for (int i = 0; i != ruleCount; ++i) { action[i] = labels.Generate().GetRef(); } emit .Do(ldCursor) .Ldfld((ScanCursor c) => c.CurrentActionId) .Switch(action) ; foreach (var cond in data.Grammar.Conditions) { var contextResolver = new ContextCode( emit, il => il .Do(ldCursor) .Ldfld((ScanCursor c) => c.RootContext), null, data, cond.ContextProvider); IActionCode code = new MatcherCode( emit, contextResolver, ldCursor, declaringType, data.Grammar.Conditions, RETURN.GetRef()); foreach (var matcher in cond.Matchers) { emit .Label(action[matcher.Index].Def) .Ldc_I4(matcher.Outcome == null ? -1 : matcher.Outcome.Index) .Stloc(tokenId.GetRef()) ; var productionBinding = matcher.Joint.The<CilMatcher>(); code = code .Do(productionBinding.Context.Load) .Do(productionBinding.ActionBuilder); } } // Load null value for incorrectly implemented actions emit.Ldnull(); emit .Label(RETURN) .Stloc(valueTmp.GetRef()) .Do(ldTokenPtr) .Ldloc(valueTmp.GetRef()) .Stind_Ref() .Ldloc(tokenId.GetRef()) .Ret() ; }
private EmitSyntax EmitFactoryCode( EmitSyntax emit, PlannedClass contextPlannedClass, Type type, bool nullAllowed) { if (type == typeof(void)) { } else if (type == typeof(int)) { emit = emit.Ldc_I4_0(); } else if (type.IsValueType) { var resultType = emit.Types.Import(type); var resultLoc = emit.Locals.Generate("result"); emit = emit .Local(resultLoc, resultType) .Ldloca(resultLoc.GetRef()) .Initobj(resultType) .Ldloc(resultLoc.GetRef()) ; } else if (nullAllowed) { emit.Ldnull(); } else if (!type.IsAbstract && !type.IsInterface) { emit = emit.Newobj( emit.Types.Import(type)); } else if (contextPlannedClass != null && contextPlannedClass.Implements(type)) { emit = emit.Ldarg(0); } else if (plan.Exists(e => e.Implements(type))) { var otherEntry = plan.Find(e => e.Implements(type)); emit = emit.Newobj( emit.Types.Class_( ClassName.Parse( otherEntry.ClassName))); } else { throw new InvalidOperationException( "Internal error: non-planned abstract result type"); } return emit; }
private IActionCode LdActionArgument(int index) { emit = emit .Do(LdRuleArgs) .Do(LdArgsStart); // Optmization for "+ 0". if (index != 0) { emit .Ldc_I4(index) .Add(); } if (typeof(Msg).IsValueType) { emit = emit .Ldelema(emit.Types.Import(typeof(Msg))); } else { emit = emit .Ldelem_Ref(); } emit = emit .Ldfld((Msg msg) => msg.Value) ; return this; }
public void Build(EmitSyntax emit, Ref<Args>[] args, SwitchGeneratorAction action) { Build(emit, il => il.Ldarg(args[0]), action); }
protected abstract void DoBuild(EmitSyntax emit, Pipe<EmitSyntax> ldvalue, SwitchGeneratorAction action);
public void BuildBody( EmitSyntax emit, LanguageData data, Ref<Args> tokenId, Ref<Args> oldValue, Ref<Args> newValue, Ref<Args> ctx, Ref<Args> lookbackStart) { var mergers = data.Grammar.Mergers; if (mergers.Count == 0) { emit .Ldarg(oldValue) .Ret(); return; } var contextResolverCode = new ContextCode( emit, il => il.Ldarg(ctx), il => il.Ldarg(lookbackStart), data, data.Grammar.GlobalContextProvider, data.LocalParseContexts); IActionCode code = new MergeCode(emit, contextResolverCode) { LoadOldValue = il => il.Ldarg(oldValue), LoadNewValue = il => il.Ldarg(newValue), }; var tokenToRuleIndex = new MutableIntMap<int>( mergers.Select( merger => new IntArrow<int>(merger.Symbol.Index, merger.Index))); tokenToRuleIndex.DefaultValue = -1; var ids = mergers.Select(m => m.Symbol.Index); IntInterval possibleBounds = new IntInterval(ids.Min(), ids.Max()); var switchGenerator = SwitchGenerator.Sparse(tokenToRuleIndex, possibleBounds); switchGenerator.Build( emit, il => il.Ldarg(tokenId), (il, value) => { if (value < 0) { emit .Ldarg(newValue) .Ret(); } else { var merger = mergers[value]; var binding = merger.Joint.The<CilMerger>(); code = code .Do(binding.Context.Load) .Do(binding.ActionBuilder) .Emit(il2 => il2.Ret()) ; } }); emit .Ret(); }
public IActionCode Emit(Pipe<EmitSyntax> pipe) { emit = pipe(emit); return this; }
public ILNfaCompiler(AstNode node, EmitSyntax emit, ILCompilerSettings settings) { this.Scanner = new StemScanner(); this.emit = emit; this.settings = settings; var labels = emit.Labels; NEXT_THREAD = labels.Generate(); RESUME_ALL = labels.Generate(); NEXT_INPUT = labels.Generate(); THREAD_SUSPEND = labels.Generate(); THREAD_DISPATCH = labels.Generate(); var LABEL0 = labels.Generate(); var LABEL1 = labels.Generate(); var POSTCOMPILEINIT = labels.Generate(); var POSTCOMPILEINIT_BACK = labels.Generate(); var locals = emit.Locals; slots = locals.Generate(); labelIndexToLocation = locals.Generate(); intTmp = locals.Generate(); threadTmp = locals.Generate(); INfaVM code = this; this.inputPump = new ArrayLoopGenerator( valueType: emit.Types.Int32, ldarray: settings.LdInput, body: il => il .Do(matchedStack.Clear) .Br(RESUME_ALL.GetRef()) ); this.runningStack = new StackGenerator(emit, typeof(Thread)); this.suspendedStack = new StackGenerator(emit, typeof(Thread)); this.matchedStack = new StackGenerator(emit, typeof(Thread)); this.tmpStack = new StackGenerator(emit, typeof(Thread), nullContainer: true); emit .Local(intTmp, emit.Types.Int32) .Local(slots, emit.Types.Import(typeof(int[]))) .Local(labelIndexToLocation, emit.Types.Import(typeof(int[]))) .Br(POSTCOMPILEINIT.GetRef()) .Label(POSTCOMPILEINIT_BACK) .Local(threadTmp, emit.Types.Import(typeof(Thread))) .Ldloca(threadTmp.GetRef()) .Initobj(emit.Types.Import(typeof(Thread))) .Do(inputPump.EmitInitialization) ; new RegularNfaVMCompiler().Compile(node, code); int LabelCount = Math.Max(1, indexToLabel.Count); this.runningStack.SetSize(LabelCount); this.suspendedStack.SetSize(LabelCount); this.matchedStack.SetSize(LabelCount); this.tmpStack.SetSize(LabelCount); emit .Label(POSTCOMPILEINIT) .Do(runningStack.Init) .Do(suspendedStack.Init) .Do(matchedStack.Init) .Do(tmpStack.Init) .Ldc_I4(slotCount) .Newarr(emit.Types.Int32) .Stloc(slots.GetRef()) .Ldc_I4(LabelCount) .Newarr(emit.Types.Int32) .Stloc(labelIndexToLocation.GetRef()) // Fill labelIndexToLocation with -1 : .Ldc_I4(LabelCount).Stloc(intTmp.GetRef()) .Label(LABEL1) .Ldloc(intTmp.GetRef()) .Ldc_I4_0() .Beq(LABEL0.GetRef()) .Ldloc(intTmp.GetRef()) .Ldc_I4(1) .Sub() .Stloc(intTmp.GetRef()) .Ldloc(labelIndexToLocation.GetRef()) .Ldloc(intTmp.GetRef()) .Ldc_I4(int.MinValue) .Stelem_I4() .Br(LABEL1.GetRef()) .Label(LABEL0) .Br(POSTCOMPILEINIT_BACK.GetRef()); // Save thread as suspended (stack should already contain label index to suspend) emit.Label(THREAD_SUSPEND); StThreadValueByRuntimeLabelIndex(); emit // Don't add thread if same thread (same label index // with current input location) already exists in a list. .Ldloc(labelIndexToLocation.GetRef()) .Ldloca(threadTmp.GetRef()) .Ldfld(LabelIndexField) .Ldelem_I4() .Ldloc(inputPump.Index.GetRef()) .Beq(NEXT_THREAD.GetRef()) // Mark label index as visited .Ldloc(labelIndexToLocation.GetRef()) .Ldloca(threadTmp.GetRef()) .Ldfld(LabelIndexField) .Ldloc(inputPump.Index.GetRef()) .Stelem_I4() ; suspendedStack.PushFrom(emit, threadTmp); emit .Br(NEXT_THREAD.GetRef()) .Label(RESUME_ALL) .Swap(suspendedStack.Stack, runningStack.Stack, tmpStack.Stack) .Swap(suspendedStack.Index, runningStack.Index, tmpStack.Index) .Label(NEXT_THREAD) ; runningStack .StackLoop( emit, (emit2, thread) => { emit2 .Ldloca(thread.GetRef()) .Ldfld(LabelIndexField) .Label(THREAD_DISPATCH) .Switch(indexToLabel.Select(def => def.GetRef()).ToArray()) .Br(settings.FAILURE.GetRef()); }) ; emit .Br(NEXT_INPUT.GetRef()) ; emit .Label(NEXT_INPUT) ; inputPump.EmitLoopPass(emit, false); emit // Check if there are matched threads: .Do(matchedStack.LdCount) .Ldc_I4_0() .Beq(settings.FAILURE.GetRef()) .Br(settings.SUCCESS.GetRef()); }