/// <summary>An initialiser expression.</summary> public object InitExpression() { // Opcode: OpCode opcode = OpCodes.Get(ReadByte()); if (opcode.AllowedInInit) { // Read its immediates: object imms = opcode.ReadImmediates(this); if (ReadByte() != 0x0b) { throw new Exception("Init expr did not end with the 'end' opcode."); } return(imms); } throw new Exception("unexpected opcode in initializer expression (" + opcode.Code + ")."); }
private FullOpcode Parse(string line) { if (string.IsNullOrEmpty(line)) { return(null); } line = line.Trim(); var parts = Tokenize(line); if (parts[0].Length < 0) { return(null); } if (Enum.TryParse(parts[0], true, out OpcodeEnum opcode)) { ushort parameter = 0; var mode = AddressingMode.Implied; if (parts.Length > 1) { //All indirect modes if (parts[1] == "(") { parameter = ParseNumber(parts[2], out mode); if (parts.Length == 5) { mode = parts[3].ToUpper() == "X" ? AddressingMode.IndexedIndirect : AddressingMode.IndirectIndexed; } else if (parts.Length == 4) { mode = AddressingMode.Indirect; } } else { parameter = ParseNumber(parts[1], out mode); bool?X = null; if (mode == AddressingMode.Implied) { if (parts.Length == 3) { X = parts[2].ToUpper() == "X"; } if (parameter > 255) { if (!X.HasValue) { mode = AddressingMode.Absolute; } else if (X == false) { mode = AddressingMode.AbsoluteY; } else { mode = AddressingMode.AbsoluteX; } } else { if (!X.HasValue) { mode = AddressingMode.ZeroPage; } else if (X == false) { mode = AddressingMode.ZeroPageY; } else { mode = AddressingMode.ZeroPageX; } } } } } return(new FullOpcode(_opcodes.Get(opcode, mode), parameter, 0)); } else { Console.WriteLine("Invalid opcode"); } return(null); }
public FunctionBody(Reader reader, int index) { // Apply current body: reader.FunctionBody = this; // Clear the block stack: reader.BlockStack.Count = 0; // Get the sig: Signature = reader.Module.FunctionSection.Types[index]; // Sizes: int bodySize = (int)reader.VarUInt32(); // Max (bodySize includes locals); -1 to exclude the final byte: long max = reader.Position + bodySize - 1; // Locals: int localCount = (int)reader.VarUInt32(); List <FunctionLocal> ilLocal = new List <FunctionLocal>(localCount); Locals = ilLocal; for (int i = 0; i < localCount; i++) { // # of this and its type: int count = (int)reader.VarUInt32(); Type type = reader.ValueTypeConverted(); for (int c = 0; c < count; c++) { // Define it: ilLocal.Add(new FunctionLocal(type)); } } // Create the root block instruction (no opcode): Root = new CompilerStack <Instruction>(); // While there is more code.. while (reader.Position < max) { // Opcode: OpCode opcode = OpCodes.Get(reader.ReadByte()); if (opcode == null || opcode.OnOutputIL == null) { throw new Exception("WebAssembly function body went out of alignment (Function " + Signature.Index + ")"); } if (opcode.Ignored) { // Don't create - just load immediates: if (opcode.HasImmediates) { opcode.ReadImmediates(reader); } } else { // Create an instruction: Instruction instruction = new Instruction(); instruction.OpCode = opcode; // Apply default in/out: instruction.InputCount = opcode.InputCount; instruction.ReturnType = opcode.ReturnType; reader.Instruction = instruction; // Add all of its immediates: if (opcode.HasImmediates) { // Load the immediates now: instruction.Immediates = opcode.ReadImmediates(reader); } // Manage the stack now - if it has a fixed number of inputs // we pop those from the stack and add them to the instruction: for (int i = 0; i < instruction.InputCount; i++) { // Add the input to the front of the input set: instruction.PrependInput(Root.Pop()); } if (instruction.ReturnType != typeof(void)) { // Push to Root: Root.Push(instruction); } } } if (reader.ReadByte() != 0x0b) { throw new Exception("A function body did not end correctly."); } }