Пример #1
0
                internal InstrStream(ILInstructionsAttribute atrib)
                {
                    for (Int32 i = 0; i < atrib.instructions.Length; ++i)
                    {
                        var c = atrib.instructions[i];

                        if (c.GetType() == typeof(String) && c is String str && str.StartsWith("::"))
                        {
                            this.str.Add((typeof(LabelToken), new LabelToken(c as String)));
                        }
Пример #2
0
                internal ILData(ILInstructionsAttribute atrib, FieldBinder fields, MethodBinder methods, LocalBinder locals, ArgBinder args, Pass pass)
                {
                    //int ct = 0;
                    this.canEmit             = false;
                    this.localDatas          = new();
                    this.instructionEmitters = new();
                    foreach (var v in locals.arr)
                    {
                        this.localDatas.Add(v);
                    }
                    var stream      = new InstrStream(atrib);
                    var bindContext = new BindContext(fields, methods, locals, args);

                    var labelManager = this.lblMgr = new LabelManager();

                    labelManager.logger = pass.logger;
                    var currentLabels = new List <String>();

                    while (!stream.IsFinished())
                    {
                        while (stream.Read(out LabelToken tok))
                        {
                            stream.Advance(1);
                            currentLabels.Add(tok.name);
                        }

                        if (stream.Read(out Op op))
                        {
                            stream.Advance(1);
                            var emitter = pass.OpToEmitter(op, stream, labelManager.AddCallback, bindContext);
                            if (emitter is null)
                            {
                                //pass.logger.Error("No emitter produced");
                                return;
                            }
                            //pass.logger.Message($"Successfully got emitter");
                            var ctx = new EmitterContext(emitter);
                            //pass.logger.Message($"Successfully got emitcontext");
                            this.instructionEmitters.Add(ctx);
                            //pass.logger.Message($"Successfully added emitcontext, handling labels");
                            foreach (var l in currentLabels)
                            {
                                //pass.logger.Message($"Applying label {l}");
                                if (!labelManager.LabelCreated(l, ctx))
                                {
                                    pass.logger.Error("Duplicate label");
                                    return;
                                }
                            }
                            currentLabels.Clear();
                        }
                        else
                        {
                            pass.logger.Error("Expected Op or Label");
                            return;
                        }
                    }
                    //pass.logger.Message($"{ct++}");
                    pass.logger.Message($"Building emit data successful");
                    this.canEmit = true;
                }