diff --git a/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MRubyCompiler.cs b/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MRubyCompiler.cs index 1d9d826..27cdd50 100644 --- a/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MRubyCompiler.cs +++ b/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MRubyCompiler.cs @@ -79,6 +79,9 @@ public RFiber LoadSourceCodeAsFiber(string source) public MrbNativeBytesHandle CompileToBinaryFormat(ReadOnlySpan utf8Source) => CompileToBytecode(utf8Source); + public unsafe MrbNativeBytesHandle CompileToBytecode(string source) => + CompileToBytecode(Encoding.UTF8.GetBytes(source)); + public unsafe MrbNativeBytesHandle CompileToBytecode(ReadOnlySpan utf8Source) { var mrbPtr = compileStateHandle.DangerousGetPtr(); diff --git a/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MrbNativeBytesHandle.cs b/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MrbNativeBytesHandle.cs index ea262ec..00cb0ef 100644 --- a/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MrbNativeBytesHandle.cs +++ b/src/MRubyCS.Compiler.Unity/Assets/MRubyCS.Compiler/Runtime/MrbNativeBytesHandle.cs @@ -6,7 +6,6 @@ namespace MRubyCS.Compiler public class MrbNativeBytesHandle : SafeHandle { readonly MrbStateHandle stateHandle1; - readonly int length1; internal MrbNativeBytesHandle( MrbStateHandle stateHandle, @@ -14,13 +13,13 @@ internal MrbNativeBytesHandle( int length) : base(ptr, true) { stateHandle1 = stateHandle; - length1 = length; + Length = length; } public override bool IsInvalid => handle == IntPtr.Zero; - public int Length => length1; + public int Length { get; } - public unsafe ReadOnlySpan GetNativeData() + public unsafe ReadOnlySpan AsSpan() { return new ReadOnlySpan(DangerousGetHandle().ToPointer(), Length); } diff --git a/src/MRubyCS/Internals/Operands.cs b/src/MRubyCS/Internals/Operands.cs index 8df350d..e669d5d 100644 --- a/src/MRubyCS/Internals/Operands.cs +++ b/src/MRubyCS/Internals/Operands.cs @@ -46,7 +46,7 @@ internal struct Operand [StructLayout(LayoutKind.Explicit)] internal struct OperandZ { - public static void Read(in ReadOnlySpan sequence, ref int pc) + public static void Read(ref byte sequence, ref int pc) { pc += 1; } @@ -58,10 +58,10 @@ internal struct OperandB [FieldOffset(0)] public byte A; - public static OperandB Read(in ReadOnlySpan sequence, ref int pc) + public static OperandB Read(ref byte sequence, ref int pc) { pc += 2; - var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(sequence), (pc - 1))); + var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref sequence, (pc - 1))); return result; } @@ -76,10 +76,10 @@ internal struct OperandBB [FieldOffset(1)] public byte B; - public static OperandBB Read(in ReadOnlySpan sequence, ref int pc) + public static OperandBB Read(ref byte sequence, ref int pc) { pc += 3; - var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(sequence), (pc - 2))); + var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref sequence, (pc - 2))); return result; } @@ -95,10 +95,10 @@ internal unsafe struct OperandS fixed byte bytesA[2]; - public static OperandS Read(in ReadOnlySpan sequence, ref int pc) + public static OperandS Read(ref byte sequence, ref int pc) { pc += 3; - var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(sequence), (pc - 2))); + var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref sequence, (pc - 2))); result.A = (short)((result.bytesA[0] << 8) | result.bytesA[1]); return result; } @@ -117,10 +117,10 @@ internal unsafe struct OperandBS fixed byte bytesB[2]; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OperandBS Read(in ReadOnlySpan sequence, ref int pc) + public static OperandBS Read(ref byte sequence, ref int pc) { pc += 4; - var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(sequence), (pc - 3))); + var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref sequence, (pc - 3))); result.B = (short)((result.bytesB[0] << 8) | result.bytesB[1]); return result; } @@ -138,10 +138,10 @@ internal struct OperandBBB [FieldOffset(2)] public byte C; - public static OperandBBB Read(in ReadOnlySpan sequence, ref int pc) + public static OperandBBB Read(ref byte sequence, ref int pc) { pc += 4; - var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(sequence), (pc - 3))); + var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref sequence, (pc - 3))); return result; } } @@ -165,10 +165,10 @@ internal unsafe struct OperandBSS fixed byte bytesC[2]; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OperandBSS Read(in ReadOnlySpan sequence, ref int pc) + public static OperandBSS Read(ref byte sequence, ref int pc) { pc += 6; - var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(sequence), (pc - 5))); + var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref sequence, (pc - 5))); result.B = (short)((result.bytesB[0] << 8) | result.bytesB[1]); result.C = (short)((result.bytesC[0] << 8) | result.bytesC[1]); @@ -183,10 +183,10 @@ internal unsafe struct OperandW public int A => (Bytes[0] << 16) | (Bytes[1] << 8) | Bytes[2]; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static OperandW Read(in ReadOnlySpan sequence, ref int pc) + public static OperandW Read(ref byte sequence, ref int pc) { pc += 4; - var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref MemoryMarshal.GetReference(sequence), (pc - 3))); + var result = Unsafe.ReadUnaligned(ref Unsafe.Add(ref sequence, (pc - 3))); return result; } } \ No newline at end of file diff --git a/src/MRubyCS/Irep.cs b/src/MRubyCS/Irep.cs index 5787bce..96c62de 100644 --- a/src/MRubyCS/Irep.cs +++ b/src/MRubyCS/Irep.cs @@ -1,3 +1,5 @@ +using System.Runtime.CompilerServices; + namespace MRubyCS; public enum CatchHandlerType : byte diff --git a/src/MRubyCS/MRubyState.Dump.cs b/src/MRubyCS/MRubyState.Dump.cs index fec77e9..ab1ff0b 100644 --- a/src/MRubyCS/MRubyState.Dump.cs +++ b/src/MRubyCS/MRubyState.Dump.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using MRubyCS.Internals; using static Utf8StringInterpolation.Utf8String; @@ -213,6 +214,7 @@ void WriteLocalVariableAB(short a, short b) { var pc = 0; var endPc = irep.Sequence.Length; + ref var sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); while (pc < endPc) { //TODO: Irep debug info @@ -237,12 +239,12 @@ void WriteLocalVariableAB(short a, short b) break; case OpCode.Move: - var bb = OperandBB.Read(irep.Sequence, ref pc); + var bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tR{bb.B}\n"); break; case OpCode.LoadL: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}"); var value = irep.PoolValues[bb.B]; switch (value.VType) @@ -262,27 +264,27 @@ void WriteLocalVariableAB(short a, short b) break; } case OpCode.LoadI8: - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{bb.B}\t"); WriteLocalVariableA(bb.A); break; case OpCode.LoadINeg: - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t-{bb.B}\t"); WriteLocalVariableA(bb.A); break; case OpCode.LoadI16: - var bs = OperandBS.Read(irep.Sequence, ref pc); + var bs = OperandBS.Read(ref sequence, ref pc); Format(writer, $"R{bs.A}\t{bs.B}\t"); WriteLocalVariableA(bs.A); break; case OpCode.LoadI32: - var bss = OperandBSS.Read(irep.Sequence, ref pc); + var bss = OperandBSS.Read(ref sequence, ref pc); Format(writer, $"R{bss.A}\t{((ushort)bss.B << 16) | (ushort)bss.C}\t"); WriteLocalVariableA(bss.A); break; case OpCode.LoadI__1: - var b = OperandB.Read(irep.Sequence, ref pc); + var b = OperandB.Read(ref sequence, ref pc); Format(writer, $"tR{b.A}\t(-1)\t"); WriteLocalVariableA(b.A); break; @@ -295,7 +297,7 @@ void WriteLocalVariableAB(short a, short b) case OpCode.LoadI_6: case OpCode.LoadI_7: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); var value = (int)opcode - (int)OpCode.LoadI_0; Format(writer, $"R{b.A}\t{value}\t"); WriteLocalVariableA(b.A); @@ -303,111 +305,111 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.LoadSym: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t:{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.LoadNil: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t(nil)\t"); WriteLocalVariableA(b.A); break; } case OpCode.LoadSelf: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t(R0)\t"); WriteLocalVariableA(b.A); break; } case OpCode.LoadT: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t(true)\t"); WriteLocalVariableA(b.A); break; } case OpCode.LoadF: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t(false)\t"); WriteLocalVariableA(b.A); break; } case OpCode.GetGV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.SetGV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"{symbolTable.NameOf(irep.Symbols[bb.B])}\tR{bb.A}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.GetSV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.SetSV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"{symbolTable.NameOf(irep.Symbols[bb.B])}\tR{bb.A}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.GetConst: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.SetConst: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"{symbolTable.NameOf(irep.Symbols[bb.B])}\tR{bb.A}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.GetMCnst: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tR{bb.A}::{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.SetMCnst: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}::{symbolTable.NameOf(irep.Symbols[bb.B])}\tR{bb.A}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.GetIV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.SetIV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"{symbolTable.NameOf(irep.Symbols[bb.B])}\tR{bb.A}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.GetUpVar: - var bbb = OperandBBB.Read(irep.Sequence, ref pc); + var bbb = OperandBBB.Read(ref sequence, ref pc); { Format(writer, $"R{bbb.A}\t{bbb.B}\t{bbb.C}\t"); WriteLocalVariableA(bbb.A); @@ -415,54 +417,54 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.SetUpVar: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\t{bbb.B}\t{bbb.C}\t"); WriteLocalVariableA(bbb.A); break; } case OpCode.GetCV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.SetCV: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"{symbolTable.NameOf(irep.Symbols[bb.B])}\tR{bb.A}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.GetIdx: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\tR{b.A + 1}\n"); break; } case OpCode.SetIdx: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\tR{b.A + 1}\tR{b.A + 2}\n"); break; } case OpCode.Jmp: { - var s = OperandS.Read(irep.Sequence, ref pc); + var s = OperandS.Read(ref sequence, ref pc); var i = pc; Format(writer, $"{i + s.A}\n"); break; } case OpCode.JmpUw: { - var s = OperandS.Read(irep.Sequence, ref pc); + var s = OperandS.Read(ref sequence, ref pc); var i = pc; Format(writer, $"{i + s.A}\n"); break; } case OpCode.JmpIf: { - bs = OperandBS.Read(irep.Sequence, ref pc); + bs = OperandBS.Read(ref sequence, ref pc); var i = pc; Format(writer, $"R{bs.A}\t{i + bs.B}\t"); WriteLocalVariableA(bs.A); @@ -470,7 +472,7 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.JmpNot: { - bs = OperandBS.Read(irep.Sequence, ref pc); + bs = OperandBS.Read(ref sequence, ref pc); var i = pc; Format(writer, $"R{bs.A}\t{i + bs.B}\t"); WriteLocalVariableA(bs.A); @@ -478,7 +480,7 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.JmpNil: { - bs = OperandBS.Read(irep.Sequence, ref pc); + bs = OperandBS.Read(ref sequence, ref pc); var i = pc; Format(writer, $"R{bs.A}\t{i + bs.B}\t"); WriteLocalVariableA(bs.A); @@ -486,28 +488,28 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.SSend: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\t:{symbolTable.NameOf(irep.Symbols[bbb.B])}\t"); WriteLocalVariableA(bbb.A); break; } case OpCode.SSendB: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\t:{symbolTable.NameOf(irep.Symbols[bbb.B])}\t"); WriteLocalVariableA(bbb.A); break; } case OpCode.Send: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\t:{symbolTable.NameOf(irep.Symbols[bbb.B])}\t"); WriteLocalVariableA(bbb.A); break; } case OpCode.SendB: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\t:{symbolTable.NameOf(irep.Symbols[bbb.B])}\t"); WriteLocalVariableA(bbb.A); break; @@ -518,116 +520,116 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.Super: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.ArgAry: { - bs = OperandBS.Read(irep.Sequence, ref pc); + bs = OperandBS.Read(ref sequence, ref pc); Format(writer, $"R{bs.A}\t{(bs.B >> 11) & 0x3f}:{(bs.B >> 10) & 0x1}:{(bs.B >> 5) & 0x1f}:{(bs.B >> 4) & 0x1f} ({bs.B & 0xf})\t"); WriteLocalVariableA(bs.A); break; } case OpCode.Enter: { - var a = OperandW.Read(irep.Sequence, ref pc).A; + var a = OperandW.Read(ref sequence, ref pc).A; Format(writer, $"{(a >> 18) & 0x1f}:{(a >> 13) & 0x1f}:{(a >> 12) & 0x1}:{(a >> 7) & 0x1f}:{(a >> 2) & 0x1f}:{(a >> 1) & 0x1}:{a & 1} (0x{a:x})\n"); break; } case OpCode.KeyP: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t:{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.KeyEnd: { - OperandZ.Read(irep.Sequence, ref pc); + OperandZ.Read(ref sequence, ref pc); break; } case OpCode.KArg: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t:{symbolTable.NameOf(irep.Symbols[bb.B])}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.Return: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t\t"); WriteLocalVariableA(b.A); break; } case OpCode.ReturnBlk: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t\t"); WriteLocalVariableA(b.A); break; } case OpCode.Break: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t\t"); WriteLocalVariableA(b.A); break; } case OpCode.BlkPush: { - bs = OperandBS.Read(irep.Sequence, ref pc); + bs = OperandBS.Read(ref sequence, ref pc); Format(writer, $"R{bs.A}\t{(bs.B >> 11) & 0x3f}:{(bs.B >> 10) & 0x1}:{(bs.B >> 5) & 0x1f}:{(bs.B >> 4) & 0x1} ({(bs.B >> 0) & 0xf})\t"); WriteLocalVariableA(bs.A); break; } case OpCode.Lambda: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tI[{bb.B}]\n"); break; } case OpCode.Block: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tI[{bb.B}]\n"); break; } case OpCode.Method: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tI[{bb.B}]\n"); break; } case OpCode.RangeInc: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\n"); break; } case OpCode.RangeExc: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\n"); break; } case OpCode.Def: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t:{symbolTable.NameOf(irep.Symbols[bb.B])}\t(R{bb.A + 1})\n"); break; } case OpCode.Undef: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $":{symbolTable.NameOf(irep.Symbols[b.A])}\n"); break; } case OpCode.Alias: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $":{symbolTable.NameOf(irep.Symbols[bb.A])}\t:{symbolTable.NameOf(irep.Symbols[bb.B])}\n"); break; } @@ -637,7 +639,7 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.AddI: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{bb.B}\t"); WriteLocalVariableA(bb.A); break; @@ -648,7 +650,7 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.SubI: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{bb.B}\t"); WriteLocalVariableA(bb.A); break; @@ -661,160 +663,160 @@ void WriteLocalVariableAB(short a, short b) case OpCode.GE: case OpCode.EQ: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\tR{b.A + 1}\n"); break; } case OpCode.Array: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tR{bb.A}\t{bb.B}"); WriteLocalVariableA(bb.A); break; } case OpCode.Array2: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\tR{bbb.B}\t{bbb.C}"); WriteLocalVariableA(bbb.A); break; } case OpCode.AryCat: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\tR{b.A + 1}\t"); WriteLocalVariableA(b.A); break; } case OpCode.AryPush: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{bb.B}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.ArySplat: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t"); WriteLocalVariableA(b.A); break; } case OpCode.ARef: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\tR{bbb.B}\t{bbb.C}"); WriteLocalVariableA(bbb.A); break; } case OpCode.ASet: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\tR{bbb.B}\t{bbb.C}"); WriteLocalVariableAB(bbb.A, bbb.B); break; } case OpCode.APost: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"R{bbb.A}\t{bbb.B}\t{bbb.C}"); WriteLocalVariableA(bbb.A); break; } case OpCode.Intern: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t"); WriteLocalVariableA(b.A); break; } case OpCode.Symbol: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tL[{bb.B}]\t; {irep.PoolValues[bb.B].As().AsSpan()}"); WriteLocalVariableA(bb.A); break; } case OpCode.String: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tL[{bb.B}]\t; {irep.PoolValues[bb.B].As().AsSpan()}"); WriteLocalVariableA(bb.A); break; } case OpCode.StrCat: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\tR{b.A + 1}\t"); WriteLocalVariableA(b.A); break; } case OpCode.Hash: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{bb.B}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.HashAdd: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t{bb.B}\t"); WriteLocalVariableA(bb.A); break; } case OpCode.HashCat: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\tR{b.A + 1}\t"); WriteLocalVariableA(b.A); break; } case OpCode.OClass: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t"); WriteLocalVariableA(b.A); break; } case OpCode.Class: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t:{symbolTable.NameOf(irep.Symbols[bb.B])}"); WriteLocalVariableA(bb.A); break; } case OpCode.Module: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\t:{symbolTable.NameOf(irep.Symbols[bb.B])}"); WriteLocalVariableA(bb.A); break; } case OpCode.Exec: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tI[{bb.B}]"); WriteLocalVariableA(bb.A); break; } case OpCode.SClass: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t"); WriteLocalVariableA(b.A); break; } case OpCode.TClass: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t\t"); WriteLocalVariableA(b.A); break; } case OpCode.Err: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); var message = irep.PoolValues[b.A]; if (message.Object is RString) Format(writer, $"{message.As().AsSpan()}\n"); @@ -823,49 +825,49 @@ void WriteLocalVariableAB(short a, short b) } case OpCode.Except: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t\t"); WriteLocalVariableA(b.A); break; } case OpCode.Rescue: { - bb = OperandBB.Read(irep.Sequence, ref pc); + bb = OperandBB.Read(ref sequence, ref pc); Format(writer, $"R{bb.A}\tR{bb.B}"); WriteLocalVariableAB(bb.A, bb.B); break; } case OpCode.RaiseIf: { - b = OperandB.Read(irep.Sequence, ref pc); + b = OperandB.Read(ref sequence, ref pc); Format(writer, $"R{b.A}\t\t"); WriteLocalVariableA(b.A); break; } case OpCode.Debug: { - bbb = OperandBBB.Read(irep.Sequence, ref pc); + bbb = OperandBBB.Read(ref sequence, ref pc); Format(writer, $"{bbb.A}\t{bbb.B}\t{bbb.C}\n"); break; } case OpCode.Stop: { - OperandZ.Read(irep.Sequence, ref pc); + OperandZ.Read(ref sequence, ref pc); break; } case OpCode.EXT1: { - OperandZ.Read(irep.Sequence, ref pc); + OperandZ.Read(ref sequence, ref pc); break; } case OpCode.EXT2: { - OperandZ.Read(irep.Sequence, ref pc); + OperandZ.Read(ref sequence, ref pc); break; } case OpCode.EXT3: { - OperandZ.Read(irep.Sequence, ref pc); + OperandZ.Read(ref sequence, ref pc); break; } // ReSharper restore UnreachableSwitchCaseDueToIntegerAnalysis diff --git a/src/MRubyCS/MRubyState.Vm.cs b/src/MRubyCS/MRubyState.Vm.cs index bf01325..7063faf 100644 --- a/src/MRubyCS/MRubyState.Vm.cs +++ b/src/MRubyCS/MRubyState.Vm.cs @@ -340,7 +340,7 @@ internal MRubyValue Execute(Irep irep, int pc, int stackKeep) // } // } - ReadOnlySpan sequence = irep.Sequence; + ref var sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); ref var callInfo = ref Context.CurrentCallInfo; Context.ExtendStack(callInfo.StackPointer + registerVariableCount); @@ -353,7 +353,7 @@ internal MRubyValue Execute(Irep irep, int pc, int stackKeep) { try { - var opcode = (OpCode)sequence[callInfo.ProgramCounter]; + var opcode = (OpCode)Unsafe.Add(ref sequence, callInfo.ProgramCounter); switch (opcode) { case OpCode.Nop: @@ -364,22 +364,22 @@ internal MRubyValue Execute(Irep irep, int pc, int stackKeep) } case OpCode.Move: Markers.Move(); - var bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + var bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = registers[bb.B]; goto Next; case OpCode.LoadL: Markers.LoadL(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = irep.PoolValues[bb.B]; goto Next; case OpCode.LoadI8: Markers.LoadI8(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = MRubyValue.From(bb.B); goto Next; case OpCode.LoadINeg: Markers.LoadINeg(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = MRubyValue.From(-bb.B); goto Next; case OpCode.LoadI__1: @@ -392,52 +392,52 @@ internal MRubyValue Execute(Irep irep, int pc, int stackKeep) case OpCode.LoadI_6: case OpCode.LoadI_7: Markers.LoadI__1(); - int a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + int a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = MRubyValue.From((int)opcode - (int)OpCode.LoadI_0); goto Next; case OpCode.LoadI16: Markers.LoadI16(); - var bs = OperandBS.Read(sequence, ref callInfo.ProgramCounter); + var bs = OperandBS.Read(ref sequence, ref callInfo.ProgramCounter); registers[bs.A] = MRubyValue.From(bs.B); goto Next; case OpCode.LoadI32: Markers.LoadI32(); - var bss = OperandBSS.Read(sequence, ref callInfo.ProgramCounter); + var bss = OperandBSS.Read(ref sequence, ref callInfo.ProgramCounter); registers[bss.A] = MRubyValue.From((bss.B << 16) + bss.C); goto Next; case OpCode.LoadSym: Markers.LoadSym(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = MRubyValue.From(irep.Symbols[bb.B]); goto Next; case OpCode.LoadNil: Markers.LoadNil(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = default; goto Next; case OpCode.LoadSelf: Markers.LoadSelf(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = registers[0]; goto Next; case OpCode.LoadT: Markers.LoadT(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = MRubyValue.True; goto Next; case OpCode.LoadF: Markers.LoadF(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = MRubyValue.False; goto Next; case OpCode.GetGV: Markers.GetGV(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = globalVariables.Get(irep.Symbols[bb.B]); goto Next; case OpCode.SetGV: Markers.SetGV(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); globalVariables.Set(irep.Symbols[bb.B], registers[bb.A]); goto Next; case OpCode.GetSV: @@ -447,28 +447,28 @@ internal MRubyValue Execute(Irep irep, int pc, int stackKeep) goto Next; case OpCode.GetIV: Markers.GetIV(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = registers[0].As().InstanceVariables.Get(irep.Symbols[bb.B]); goto Next; case OpCode.SetIV: Markers.SetIV(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[0].As().InstanceVariables.Set(irep.Symbols[bb.B], registers[bb.A]); goto Next; case OpCode.GetCV: Markers.GetCV(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registers[bb.A] = GetClassVariable(irep.Symbols[bb.B]); goto Next; case OpCode.SetCV: Markers.SetCV(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); SetClassVariable(irep.Symbols[bb.B], registers[bb.A]); goto Next; case OpCode.GetConst: Markers.GetConst(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); ref var registerA = ref registers[bb.A]; { var id = irep.Symbols[bb.B]; @@ -518,7 +518,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.SetConst: { Markers.SetConst(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); //var id = irep.Symbols[bb.B]; var c = callInfo.Proc?.Scope?.TargetClass ?? ObjectClass; SetConst(irep.Symbols[bb.B], c, registers[bb.A]); @@ -526,7 +526,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu } case OpCode.GetMCnst: Markers.GetMCnst(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[bb.A]; { //var mod = registers[bb.A]; @@ -537,7 +537,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.SetMCnst: { Markers.SetMCnst(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[bb.A]; //var mod = registers[bb.A + 1]; var name = irep.Symbols[bb.B]; @@ -547,7 +547,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.GetIdx: { Markers.GetIdx(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[a]; var valueB = Unsafe.Add(ref registerA, 1); switch (registerA.Object) @@ -581,7 +581,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.SetIdx: { Markers.SetIdx(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a + 3] = default; // push nil after arguments // Jump to send :[]= @@ -598,7 +598,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu Markers.GetUpVar(); OperandBBB bbb; { - bbb = OperandBBB.Read(sequence, ref callInfo.ProgramCounter); + bbb = OperandBBB.Read(ref sequence, ref callInfo.ProgramCounter); var env = callInfo.Proc?.FindUpperEnvTo(bbb.C); if (env != null && bbb.B < env.Stack.Length) { @@ -613,7 +613,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.SetUpVar: { Markers.SetUpVar(); - bbb = OperandBBB.Read(sequence, ref callInfo.ProgramCounter); + bbb = OperandBBB.Read(ref sequence, ref callInfo.ProgramCounter); var env = callInfo.Proc?.FindUpperEnvTo(bbb.C); if (env != null && bbb.B < env.Stack.Length) { @@ -623,12 +623,12 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu } case OpCode.Jmp: Markers.Jmp(); - var s = ReadOperandS(sequence, ref callInfo.ProgramCounter); + var s = ReadOperandS(ref sequence, ref callInfo.ProgramCounter); callInfo.ProgramCounter += s; goto Next; case OpCode.JmpIf: Markers.JmpIf(); - bs = OperandBS.Read(sequence, ref callInfo.ProgramCounter); + bs = OperandBS.Read(ref sequence, ref callInfo.ProgramCounter); if (registers[bs.A].Truthy) { callInfo.ProgramCounter += bs.B; @@ -636,7 +636,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu goto Next; case OpCode.JmpNot: Markers.JmpNot(); - bs = OperandBS.Read(sequence, ref callInfo.ProgramCounter); + bs = OperandBS.Read(ref sequence, ref callInfo.ProgramCounter); if (registers[bs.A].Falsy) { callInfo.ProgramCounter += bs.B; @@ -644,7 +644,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu goto Next; case OpCode.JmpNil: Markers.JmpNil(); - bs = OperandBS.Read(sequence, ref callInfo.ProgramCounter); + bs = OperandBS.Read(ref sequence, ref callInfo.ProgramCounter); if (registers[bs.A].IsNil) { callInfo.ProgramCounter += bs.B; @@ -653,7 +653,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.JmpUw: { Markers.JmpUw(); - s = ReadOperandS(sequence, ref callInfo.ProgramCounter); + s = ReadOperandS(ref sequence, ref callInfo.ProgramCounter); var newProgramCounter = callInfo.ProgramCounter + s; if (irep.TryFindCatchHandler(callInfo.ProgramCounter, CatchHandlerType.Ensure, out var catchHandler)) { @@ -672,7 +672,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu } case OpCode.Except: Markers.Except(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = Exception switch { MRubyRaiseException x => MRubyValue.From(x.ExceptionObject), @@ -684,7 +684,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.Rescue: { Markers.Rescue(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var exceptionObjectValue = registers[bb.A]; var exceptionClassValue = registers[bb.B]; switch (exceptionClassValue.VType) @@ -710,7 +710,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.RaiseIf: { Markers.RaiseIf(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); var exceptionValue = registers[a]; switch (exceptionValue.Object) { @@ -773,7 +773,7 @@ static void GetConstSlowPath(MRubyState state, ref MRubyValue registerA, ref MRu case OpCode.SendB: { Markers.SSend(); - bbb = OperandBBB.Read(sequence, ref callInfo.ProgramCounter); + bbb = OperandBBB.Read(ref sequence, ref callInfo.ProgramCounter); var currentStackPointer = callInfo.StackPointer; callInfo = ref Context.PushCallStack(); @@ -858,15 +858,16 @@ static void PackKeywordArguments(MRubyState state, ref MRubyCallInfo callInfo, r if (method.Kind == MRubyMethodKind.CSharpFunc) { - if (CallCSharpFunc(this, method, self, ref irep, ref sequence, ref registers, out var result)) + if (CallCSharpFunc(this, method, self, ref irep, ref registers, out var result)) { return result; } + sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); callInfo = ref Context.CurrentCallInfo; goto Next; - static bool CallCSharpFunc(MRubyState state, MRubyMethod method, MRubyValue self, ref Irep irep, ref ReadOnlySpan sequence, ref Span registers, out MRubyValue result) + static bool CallCSharpFunc(MRubyState state, MRubyMethod method, MRubyValue self, ref Irep irep, ref Span registers, out MRubyValue result) { result = method.Invoke(state, self); @@ -889,7 +890,6 @@ static bool CallCSharpFunc(MRubyState state, MRubyMethod method, MRubyValue self callInfo = ref state.Context.CurrentCallInfo; irep = callInfo.Proc!.Irep; registers = state.Context.Stack.AsSpan(callInfo.StackPointer); - sequence = irep.Sequence.AsSpan(); return false; } } @@ -900,18 +900,18 @@ static bool CallCSharpFunc(MRubyState state, MRubyMethod method, MRubyValue self Context.ExtendStack(callInfo.StackPointer + (irep.RegisterVariableCount < 4 ? 4 : irep.RegisterVariableCount) + 1); registers = Context.Stack.AsSpan(callInfo.StackPointer); - sequence = irep.Sequence.AsSpan(); + sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); goto Next; // pop on OpCode.Return } case OpCode.Call: // modify program counter { - registers = Call(this, out irep, ref callInfo, registers, out sequence); - + registers = Call(this, out irep, ref callInfo, registers); + sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); goto Next; - static Span Call(MRubyState state, out Irep irep, ref MRubyCallInfo callInfo, Span registers, out ReadOnlySpan sequence) + static Span Call(MRubyState state, out Irep irep, ref MRubyCallInfo callInfo, Span registers) { callInfo.ProgramCounter += 1; // read opcode var receiver = registers[0]; @@ -923,7 +923,6 @@ static Span Call(MRubyState state, out Irep irep, ref MRubyCallInfo // setup environment for calling method irep = proc.Irep; - sequence = irep.Sequence.AsSpan(); callInfo.ProgramCounter = proc.ProgramCounter; var currentSize = callInfo.BlockArgumentOffset + 1; @@ -947,13 +946,13 @@ static Span Call(MRubyState state, out Irep irep, ref MRubyCallInfo { Markers.Super(); - Super(this, ref callInfo, registers, sequence); + Super(this, ref callInfo, registers, ref sequence); callInfo = ref Context.CurrentCallInfo; goto case OpCode.SendInternal; - static void Super(MRubyState state, ref MRubyCallInfo callInfo, Span registers, ReadOnlySpan sequence) + static void Super(MRubyState state, ref MRubyCallInfo callInfo, Span registers, ref byte sequence) { - var bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + var bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var targetClass = callInfo.Scope.TargetClass; var methodId = callInfo.MethodId; if (methodId == default || targetClass == null!) @@ -986,7 +985,7 @@ static void Super(MRubyState state, ref MRubyCallInfo callInfo, Span { Markers.Enter(); - bbb = OperandBBB.Read(sequence, ref callInfo.ProgramCounter); + bbb = OperandBBB.Read(ref sequence, ref callInfo.ProgramCounter); var bits = (uint)bbb.A << 16 | (uint)bbb.B << 8 | bbb.C; var aspec = new ArgumentSpec(bits); @@ -1187,7 +1186,7 @@ void SlowPath(ref MRubyCallInfo callInfo, Span argv, Spansyms[b]); var key = MRubyValue.From(irep.Symbols[bb.B]); var kargOffset = callInfo.KeywordArgumentOffset; @@ -1216,7 +1215,7 @@ void RaiseMissingKeywordError(MRubyValue keyValue) case OpCode.KeyP: { Markers.KeyP(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var key = MRubyValue.From(irep.Symbols[bb.B]); var kdict = registers[callInfo.KeywordArgumentOffset]; registers[bb.A] = MRubyValue.From(kdict.As().TryGetValue(key, out _)); @@ -1244,7 +1243,7 @@ void RaiseUnknownKeyword(MRubyValue keyValue) case OpCode.Return: { Markers.Return(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); var returnValue = registers[a]; if (TryReturnJump(ref callInfo, Context.CallDepth, returnValue)) { @@ -1261,7 +1260,7 @@ void RaiseUnknownKeyword(MRubyValue keyValue) goto case OpCode.Return; } - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); var dest = callInfo.Proc.FindReturningDestination(out var env); if (dest.Scope is not REnv destEnv || destEnv.Context == Context) { @@ -1291,7 +1290,7 @@ void RaiseUnknownKeyword(MRubyValue keyValue) goto case OpCode.Return; } - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); if (callInfo.Proc is { } proc && !proc.HasFlag(MRubyObjectFlags.ProcOrphan) && proc.Scope is REnv env && env.Context == Context) @@ -1316,11 +1315,11 @@ void RaiseUnknownKeyword(MRubyValue keyValue) case OpCode.BlkPush: { Markers.BlkPush(); - BlkPush(this, ref callInfo, registers, sequence); + BlkPush(this, ref callInfo, registers, ref sequence); - static void BlkPush(MRubyState state, ref MRubyCallInfo callInfo, Span registers, ReadOnlySpan sequence) + static void BlkPush(MRubyState state, ref MRubyCallInfo callInfo, Span registers, ref byte sequence) { - var bs = OperandBS.Read(sequence, ref callInfo.ProgramCounter); + var bs = OperandBS.Read(ref sequence, ref callInfo.ProgramCounter); var b = bs.B; var m1 = (b >> 11) & 0x3f; var r = (b >> 10) & 0x1; @@ -1364,7 +1363,7 @@ static void BlkPush(MRubyState state, ref MRubyCallInfo callInfo, Span(); array[bbb.C] = registers[bbb.A]; goto Next; @@ -1598,7 +1597,7 @@ static void BlkPush(MRubyState state, ref MRubyCallInfo callInfo, Span())); goto Next; case OpCode.Symbol: { Markers.Symbol(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); //var name = irep.PoolValues[bb.B].As(); registers[bb.A] = MRubyValue.From(Intern(irep.PoolValues[bb.B].As())); goto Next; @@ -1678,21 +1677,21 @@ static void APostLong(MRubyState state, RArray array, int pre, int post, ref MRu case OpCode.String: { Markers.String(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var str = irep.PoolValues[bb.B].As(); registers[bb.A] = MRubyValue.From(str.Dup()); goto Next; } case OpCode.StrCat: Markers.StrCat(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[a]; registerA.As().Concat(Stringify(Unsafe.Add(ref registerA, 1))); goto Next; case OpCode.Hash: { Markers.Hash(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[bb.A]; var hash = NewHash(bb.B); var lastIndex = bb.B * 2; @@ -1707,7 +1706,7 @@ static void APostLong(MRubyState state, RArray array, int pre, int post, ref MRu case OpCode.HashAdd: { Markers.HashAdd(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[bb.A]; var hashValue = registerA; var lastIndex = bb.B * 2 + 1; @@ -1722,7 +1721,7 @@ static void APostLong(MRubyState state, RArray array, int pre, int post, ref MRu } case OpCode.HashCat: Markers.HashCat(); - a = sequence[++callInfo.ProgramCounter]; + a = Unsafe.Add(ref sequence, ++callInfo.ProgramCounter); ++callInfo.ProgramCounter; registerA = ref registers[a]; EnsureNotFrozen(registerA); @@ -1733,7 +1732,7 @@ static void APostLong(MRubyState state, RArray array, int pre, int post, ref MRu case OpCode.Method: { Markers.Lambda(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); RProc proc; if (opcode == OpCode.Method) { @@ -1754,7 +1753,7 @@ static void APostLong(MRubyState state, RArray array, int pre, int post, ref MRu case OpCode.RangeInc: case OpCode.RangeExc: Markers.RangeInc(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[a]; { var begin = registerA; @@ -1766,19 +1765,19 @@ static void APostLong(MRubyState state, RArray array, int pre, int post, ref MRu } case OpCode.OClass: Markers.OClass(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = MRubyValue.From(ObjectClass); goto Next; case OpCode.Class: { Markers.Class(); - Class(this, irep, registers, sequence, ref callInfo); + Class(this, irep, registers, ref sequence, ref callInfo); goto Next; - static void Class(MRubyState state, Irep irep, Span registers, ReadOnlySpan sequence, ref MRubyCallInfo callInfo) + static void Class(MRubyState state, Irep irep, Span registers, ref byte sequence, ref MRubyCallInfo callInfo) { - var bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + var bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var id = irep.Symbols[bb.B]; var outer = registers[bb.A]; var super = registers[bb.A + 1]; @@ -1858,7 +1857,7 @@ void RaiseSuperClassMismatch(MRubyValue oldValue) case OpCode.Module: { Markers.Module(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[bb.A]; var id = irep.Symbols[bb.B]; RClass outerClass; @@ -1898,7 +1897,7 @@ void RaiseNotAModule(MRubyValue oldValue) case OpCode.Exec: { Markers.Exec(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var receiver = registers[bb.A]; var targetIrep = irep.Children[bb.B]; @@ -1921,7 +1920,7 @@ void RaiseNotAModule(MRubyValue oldValue) callInfo = ref nextCallInfo; irep = callInfo.Proc!.Irep; - sequence = irep.Sequence.AsSpan(); + sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); Context.ExtendStack(callInfo.StackPointer + irep.RegisterVariableCount + 1); Context.ClearStack(callInfo.StackPointer + 1, irep.RegisterVariableCount - 1); @@ -1932,7 +1931,7 @@ void RaiseNotAModule(MRubyValue oldValue) case OpCode.Def: { Markers.Def(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var target = registers[bb.A].As(); var proc = registers[bb.A + 1].As(); var methodId = irep.Symbols[bb.B]; @@ -1945,7 +1944,7 @@ void RaiseNotAModule(MRubyValue oldValue) case OpCode.Alias: { Markers.Alias(); - bb = OperandBB.Read(sequence, ref callInfo.ProgramCounter); + bb = OperandBB.Read(ref sequence, ref callInfo.ProgramCounter); var c = callInfo.Scope.TargetClass; var newMethodId = irep.Symbols[bb.A]; var oldMethodId = irep.Symbols[bb.B]; @@ -1956,7 +1955,7 @@ void RaiseNotAModule(MRubyValue oldValue) case OpCode.Undef: { Markers.Undef(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); var c = callInfo.Scope.TargetClass; var methodId = irep.Symbols[a]; UndefMethod(c, methodId); @@ -1965,7 +1964,7 @@ void RaiseNotAModule(MRubyValue oldValue) case OpCode.SClass: { Markers.SClass(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registerA = ref registers[a]; var result = SingletonClassOf(registerA); registerA = MRubyValue.From(result); @@ -1974,14 +1973,14 @@ void RaiseNotAModule(MRubyValue oldValue) case OpCode.TClass: { Markers.TClass(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); registers[a] = MRubyValue.From(callInfo.Scope.TargetClass); goto Next; } case OpCode.Err: { Markers.Err(); - a = ReadOperandB(sequence, ref callInfo.ProgramCounter); + a = ReadOperandB(ref sequence, ref callInfo.ProgramCounter); var message = irep.PoolValues[a]; Raise(Names.LocalJumpError, message.As()); goto Next; @@ -2020,7 +2019,7 @@ static void ThrowInvalidOpCode(OpCode opcode) callInfo = ref Context.CurrentCallInfo; irep = callInfo.Proc!.Irep; registers = Context.Stack.AsSpan(callInfo.StackPointer); - sequence = irep.Sequence.AsSpan(); + sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); } catch (MRubyRaiseException ex) { @@ -2030,7 +2029,7 @@ static void ThrowInvalidOpCode(OpCode opcode) callInfo = ref Context.CurrentCallInfo; irep = callInfo.Proc!.Irep; registers = Context.Stack.AsSpan(callInfo.StackPointer); - sequence = irep.Sequence.AsSpan(); + sequence = ref MemoryMarshal.GetArrayDataReference(irep.Sequence); } else { @@ -2053,18 +2052,18 @@ ref MRubyCallInfo GetNextCallInfo(int nextStackPointer, OpCode code, byte argCou } [MethodImpl(MethodImplOptions.AggressiveInlining)] - static byte ReadOperandB(ReadOnlySpan sequence, ref int pc) + static byte ReadOperandB(ref byte sequence, ref int pc) { pc += 2; - var result = Unsafe.Add(ref MemoryMarshal.GetReference(sequence), pc - 1); + var result = Unsafe.Add(ref sequence, pc - 1); return result; } /// I don't know why, but introducing this method makes the code faster. [MethodImpl(MethodImplOptions.AggressiveInlining)] - static short ReadOperandS(ReadOnlySpan sequence, ref int pc) + static short ReadOperandS(ref byte sequence, ref int pc) { - return OperandS.Read(sequence, ref pc).A; + return OperandS.Read(ref sequence, ref pc).A; } bool TryReturnJump(ref MRubyCallInfo callInfo, int returnDepth, MRubyValue returnValue)