示例#1
0
            internal void WriteFrame(StackMapFrame frame)
            {
                _writer.WriteU1(frame.Tag);

                switch (frame)
                {
                case SameLocals1StackItemFrame sameLocals1StackItemFrame:
                    WriteFrame(sameLocals1StackItemFrame);
                    break;

                case SameLocals1StackItemFrameExtended sameLocals1StackItemFrameExtended:
                    WriteFrame(sameLocals1StackItemFrameExtended);
                    break;

                case ChopFrame chopFrame:
                    WriteFrame(chopFrame);
                    break;

                case SameFrameExtended sameFrameExtended:
                    WriteFrame(sameFrameExtended);
                    break;

                case AppendFrame appendFrame:
                    WriteFrame(appendFrame);
                    break;
                }
            }
示例#2
0
        public StackMapFrame[] ReadStackMapFrames(ushort numberOfEntries)
        {
            var stackMapFrames = new StackMapFrame[numberOfEntries];

            for (var i = 0; i < numberOfEntries; i++)
            {
                stackMapFrames[i] = new StackMapFrame().Read(_classData);
            }

            return(stackMapFrames);
        }
        private StackMapFrame GetInitialFrame()
        {
            var frame = new StackMapFrame();

            var argTypes = Method.Parameters.Select(x => x.Type).ToList();

            var len = argTypes.Count;
            var count = 0;

            if (!Method.Modifiers.HasFlag(Modifier.Static))
            {
                Type thisType = Method.DeclaringType;

                frame.Locals = new Type[len + 1];
                if (Method.Name == "<init>" && thisType.GetDescriptor(true) != "java/lang/Object")
                {
                    frame.Locals[count++] = UninitializedType.UninitializedThis(thisType);
                }
                else
                {
                    frame.Locals[count++] = thisType;
                }
            }
            else
            {
                frame.Locals = new Type[len];
            }

            foreach (var argType in argTypes)
            {
                frame.Locals[count++] = argType;
            }

            frame.PC = -1;
            frame.Stack = null;

            return frame;
        }
        private void EmitStackMapFrame()
        {
            if (lastFrame == null)
            {
                // first frame
                lastFrame = GetInitialFrame();
            }
            else if (lastFrame.PC == length)
            {
                // drop existing stackmap at this offset
                stackMapTableBuffer[--stackMapBufferSize] = null;
                lastFrame = frameBeforeLast;
                frameBeforeLast = null;
            }

            var frame = new StackMapFrame { PC = length };

            var localCount = 0;
            var locals = new Type[variableCount];
            for (var i = 0; i < variableCount; i++, localCount++)
            {
                var variable = GetVariable(i);

                if (variable == null || !variable.IsDefined) continue;

                var vtype = variable.Type;

                locals[i] = vtype;
                if (TypeCodeHelper.Width(vtype) > 1) i++;
            }

            frame.Locals = new Type[localCount];
            for (int i = 0, j = 0; i < variableCount; i++, j++)
            {
                Debug.Assert(j < localCount);
                frame.Locals[j] = locals[i];
                if (TypeCodeHelper.Width(locals[i]) > 1) i++;
            }

            var stackCount = 0;
            for (var i = 0; i < state.StackSize; i++)
            {
                if (state.GetStack(i) != null)
                {
                    stackCount++;
                }
            }

            frame.Stack = new Type[stackCount];
            stackCount = 0;
            for (var i = 0; i < state.StackSize; i++)
            {
                if (state.GetStack(i) != null)
                {
                    frame.Stack[stackCount++] = state.GetStack(i);
                }
            }

            if (stackMapTableBuffer == null)
            {
                stackMapTableBuffer = new CompileAttributeStackMapTable.StackMapFrame[20];
            }
            else if (stackMapTableBuffer.Length == stackMapBufferSize)
            {
                var newStackMapTableBuffer = new CompileAttributeStackMapTable.StackMapFrame[stackMapBufferSize << 1];

                Array.Copy(stackMapTableBuffer, 0, newStackMapTableBuffer, 0, stackMapBufferSize);

                stackMapTableBuffer = newStackMapTableBuffer;
            }
            stackMapTableBuffer[stackMapBufferSize++] = CompileAttributeStackMapTable.StackMapFrame.GetInstance(this, frame, lastFrame.PC, lastFrame.Locals);

            frameBeforeLast = lastFrame;
            lastFrame = frame;
        }
        public override CompileAttribute Read(EndianBinaryReader reader, List<CompileConstant> constants, int length)
        {
            Entries = new List<StackMapFrame>();

            short entryCount = reader.ReadInt16();
            for (int i = 0; i < entryCount; i++)
            {
                var entry = new StackMapFrame();

                entry.Type = reader.ReadByte();
                if (entry.Type <= 63)
                {
                    // SAME
                }
                else if (entry.Type >= 64 && entry.Type <= 127)
                {
                    // SAME_LOCALS_1_STACK_ITEM
                    var item = new VerificationTypeInfo();
                    item.Read(reader);

                    entry.Stack.Add(item);
                }
                else if (entry.Type == 247)
                {
                    // SAME_LOCALS_1_STACK_ITEM_EXTENDED
                    entry.OffsetDelta = reader.ReadInt16();

                    var item = new VerificationTypeInfo();
                    item.Read(reader);

                    entry.Stack.Add(item);
                }
                else if (entry.Type >= 248 && entry.Type <= 250)
                {
                    // CHOP
                    entry.OffsetDelta = reader.ReadInt16();
                }
                else if (entry.Type == 251)
                {
                    // SAME_FRAME_EXTENDED
                    entry.OffsetDelta = reader.ReadInt16();
                }
                else if (entry.Type >= 252 && entry.Type <= 254)
                {
                    // APPEND
                    entry.OffsetDelta = reader.ReadInt16();

                    var type = (short)entry.Type;
                    for (int x = 251; x < type; x++)
                    {
                        var item = new VerificationTypeInfo();
                        item.Read(reader);

                        entry.Locals.Add(item);
                    }
                }
                else if (entry.Type == 255)
                {
                    // FULL_FRAME
                    entry.OffsetDelta = reader.ReadInt16();

                    short localCount = reader.ReadInt16();
                    for (int x = 0; x < localCount; x++)
                    {
                        var item = new VerificationTypeInfo();
                        item.Read(reader);

                        entry.Locals.Add(item);
                    }

                    short stackCount = reader.ReadInt16();
                    for (int x = 0; x < stackCount; x++)
                    {
                        var item = new VerificationTypeInfo();
                        item.Read(reader);

                        entry.Stack.Add(item);
                    }
                }

                Entries.Add(entry);
            }

            return this;
        }