nim-lang / RFCs

A repository for your Nim proposals.
136 stars 26 forks source link

Nim VM Execute Loop Hooks #249

Closed dsrw closed 9 months ago

dsrw commented 3 years ago

Nim VM Execute Loop Hooks

Abstract

Support hooking into the Nim VM execute loop, to enable things like suspend/resume, breakpoints and watches.

Motivation

Enu is a live-coding/IDE for game development in Nim that uses the VM extensively. I'm currently using a Nim fork to enable pausing and resuming script execution, and in the future I'd like to support breakpoints and watches.

Description

This needs consideration from people more knowledgable than myself, but I'm looking at providing 3 hooks:

enterHook - Run at the top of the interpreter loop. This could be used to bail out of the loop for breakpoints, or start a timer for profiling. leaveHook - Run at the bottom of the interpreter loop. This could be used to capture variable values for watches, and stop the profiling timer. exitHook - Run when the interpreter loop exits. This could be used to capture the stack and program counter, for suspend/resume support.

The hooks should be inside when blocks, or some similar mechanism to ensure they have no performance cost if they're not being used.

I have an initial implementation that is working for me for suspend/resume, but I haven't tried breakpoints or watches yet. It needs tests and docs, but I'll provide those if there's interest in merging it.

The cost to supporting this should be small, but it's also pretty ad-hoc, and requires a fair bit of work by the user to be used for anything useful. It would be better to spec out a real breakpoint/watchpoint/suspend/resume API, but I don't think I can take that on right now.

cooldome commented 3 years ago

I was thinking towards more general solution of extending Nim plugin infrastructure to be able to extend VM not just sempass. All done with hooks. Number of hooks available to plugin developers will extend with time. Sempass and VM for a start.

The idea that plugins should be as easy to use as: nim --plugin:a,b,c

Nim uses standard library path resolution to find plugins a, b, c to compile them and load them before compiling your project.

Araq commented 3 years ago

I have an initial implementation that is working for me for suspend/resume

I found your initial implementation which uses exceptions from callbacks quite elegant. I wonder if that can be extended to your other "hooks", no runtime penalty, no when statements required.

github-actions[bot] commented 10 months ago

This RFC is stale because it has been open for 1095 days with no activity. Contribute a fix or comment on the issue, or it will be closed in 30 days.