-
Notifications
You must be signed in to change notification settings - Fork 0
test: lift new-code coverage on Disassembler, GrobValue, GrobStruct, … #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
0b780a9
test: lift new-code coverage on Disassembler, GrobValue, GrobStruct, …
kwakker35 d92368d
refactor(vm): address PR review on Peek guard, Run reset, exception s…
kwakker35 b36b1bd
feat(vm): add source column to Chunk + GrobRuntimeException
kwakker35 23f3696
chore(vm): suppress S1244/S3776 on intentional VM dispatch patterns
kwakker35 3ed929c
chore(vm): suppress S4487 on _trace (read only inside #if DEBUG)
kwakker35 48e7d75
fix(core): address open CodeRabbit review threads
kwakker35 2c6bf81
fix(core): enforce line >= 1 at Chunk write boundary
kwakker35 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| namespace Grob.Core; | ||
|
|
||
| /// <summary> | ||
| /// Arithmetic runtime error: integer overflow, division by zero, modulo by | ||
| /// zero, math domain violations. Maps to the Grob <c>ArithmeticError</c> | ||
| /// exception type (D-284). | ||
| /// </summary> | ||
| public sealed class GrobArithmeticException : GrobRuntimeException { | ||
| /// <summary> | ||
| /// Initialises a new <see cref="GrobArithmeticException"/> with the | ||
| /// supplied error <paramref name="code"/>, source <paramref name="line"/>, | ||
| /// and human-readable <paramref name="message"/>. <see cref="GrobRuntimeException.Column"/> | ||
| /// is recorded as <c>0</c>. | ||
| /// </summary> | ||
| public GrobArithmeticException(string code, int line, string message) | ||
| : base(code, line, message) { } | ||
|
|
||
| /// <summary> | ||
| /// Initialises a new <see cref="GrobArithmeticException"/> with the | ||
| /// supplied error <paramref name="code"/>, source <paramref name="line"/>, | ||
| /// 1-based <paramref name="column"/>, and human-readable | ||
| /// <paramref name="message"/>. | ||
| /// </summary> | ||
| public GrobArithmeticException(string code, int line, int column, string message) | ||
| : base(code, line, column, message) { } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| namespace Grob.Core; | ||
|
|
||
| /// <summary> | ||
| /// Base type for Grob runtime errors raised by the VM. The two-mode error | ||
| /// model (D-284): the compiler/checker collect all errors; the VM stops on | ||
| /// the first runtime error. Carries the error code from grob-error-codes.md | ||
| /// and the source position (line + column) from the chunk's per-instruction | ||
| /// position arrays. <see cref="Column"/> is <c>0</c> when no column was | ||
| /// recorded for the failing instruction. | ||
| /// </summary> | ||
| public class GrobRuntimeException : Exception { | ||
| /// <summary>The grob-error-codes.md identifier (e.g. <c>E5001</c>).</summary> | ||
| public string Code { get; } | ||
|
|
||
| /// <summary>The source line attributed to the failing instruction.</summary> | ||
| public int Line { get; } | ||
|
|
||
| /// <summary> | ||
| /// The 1-based source column attributed to the failing instruction. | ||
| /// <c>0</c> indicates the chunk byte was written without a column | ||
| /// (e.g. hand-built test bytecode or synthetic prologue). | ||
| /// </summary> | ||
| public int Column { get; } | ||
|
|
||
| /// <summary> | ||
| /// Initialises a new <see cref="GrobRuntimeException"/> with the supplied | ||
| /// error <paramref name="code"/>, source <paramref name="line"/>, and | ||
| /// human-readable <paramref name="message"/>. <see cref="Column"/> is | ||
| /// recorded as <c>0</c> ("unknown"); prefer the four-argument constructor | ||
| /// when a column is available. | ||
| /// </summary> | ||
| public GrobRuntimeException(string code, int line, string message) | ||
| : this(code, line, 0, message) { } | ||
|
|
||
| /// <summary> | ||
| /// Initialises a new <see cref="GrobRuntimeException"/> with the supplied | ||
| /// error <paramref name="code"/>, source <paramref name="line"/>, | ||
| /// 1-based <paramref name="column"/>, and human-readable | ||
| /// <paramref name="message"/>. | ||
| /// </summary> | ||
| public GrobRuntimeException(string code, int line, int column, string message) | ||
| : base(message) { | ||
| Code = code; | ||
| Line = line; | ||
| Column = column; | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| using Grob.Core; | ||
|
|
||
| namespace Grob.Vm; | ||
|
|
||
| /// <summary> | ||
| /// The VM operand stack: a fixed-capacity array of <see cref="GrobValue"/> | ||
| /// slots. Pushing a primitive (Bool/Int/Float) is a 24-byte struct copy with | ||
| /// no allocation (D-303, D-304). | ||
| /// | ||
| /// Authority: grob-vm-architecture.md — value stack section. | ||
| /// </summary> | ||
| public sealed class ValueStack { | ||
| /// <summary> | ||
| /// Maximum simultaneous live values on the operand stack. Chosen to comfortably | ||
| /// exceed Sprint 2's needs (no call frames yet) while leaving headroom for | ||
| /// future locals and intermediate computation. The value-stack overflow | ||
| /// path surfaces as a runtime error, not an unguarded array write. | ||
| /// </summary> | ||
| public const int Capacity = 16384; | ||
|
|
||
| private readonly GrobValue[] _values = new GrobValue[Capacity]; | ||
| private int _top; | ||
|
|
||
| /// <summary>Number of values currently on the stack.</summary> | ||
| public int Count => _top; | ||
|
|
||
| /// <summary> | ||
| /// Push <paramref name="value"/> onto the top of the stack. On overflow | ||
| /// throws <see cref="GrobRuntimeException"/> carrying <paramref name="line"/> | ||
| /// rather than an unguarded array write. | ||
| /// </summary> | ||
| public void Push(GrobValue value, int line) { | ||
| if (_top == _values.Length) | ||
| throw new GrobRuntimeException("E5903", line, "value stack overflow"); | ||
| _values[_top++] = value; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Pop and return the top of the stack. Underflow is a compiler/VM bug, | ||
| /// not a user-reachable runtime error — surfaces as | ||
| /// <see cref="GrobInternalException"/>. | ||
| /// </summary> | ||
| public GrobValue Pop() { | ||
| if (_top == 0) | ||
| throw new GrobInternalException("value stack underflow"); | ||
| var value = _values[--_top]; | ||
| _values[_top] = default; // release reference slots for GC (D-304) | ||
| return value; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Read the value at <paramref name="distance"/> below the top without | ||
| /// popping. <c>distance == 0</c> is the top. Negative distances and | ||
| /// distances past the bottom of the live region are compiler/VM bugs | ||
| /// and surface as <see cref="GrobInternalException"/>. | ||
| /// </summary> | ||
| public GrobValue Peek(int distance = 0) { | ||
| if (distance < 0) | ||
| throw new GrobInternalException("value stack peek with negative distance"); | ||
| int index = _top - 1 - distance; | ||
| if (index < 0) | ||
| throw new GrobInternalException("value stack peek underflow"); | ||
| return _values[index]; | ||
|
kwakker35 marked this conversation as resolved.
|
||
| } | ||
|
|
||
| /// <summary> | ||
| /// Logically empty the stack. Sets the top pointer to zero without | ||
| /// clearing slots — the next <see cref="Push"/> will overwrite, and | ||
| /// any reference values left over are released by the per-<see cref="Pop"/> | ||
| /// slot clear once <see cref="Pop"/> is invoked. Used by | ||
|
kwakker35 marked this conversation as resolved.
Outdated
|
||
| /// <c>VirtualMachine.Run</c> to start each invocation from a clean | ||
| /// operand stack regardless of any leftovers from a prior | ||
| /// exception-terminated run. | ||
| /// </summary> | ||
| internal void Reset() { | ||
| if (_top > 0) | ||
| Array.Clear(_values, 0, _top); // release reference slots for GC (D-304) | ||
| _top = 0; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Snapshot the live region of the stack — used by the | ||
| /// <c>#if DEBUG</c> trace hook to render the stack each iteration. | ||
| /// </summary> | ||
| internal ReadOnlySpan<GrobValue> AsSpan() => _values.AsSpan(0, _top); | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.