Draft: Enhancement #7127 scriptfu late binding to PDB
State of the MR
The MR is fully functional and tested.
How ScriptFu binds to the PDB now
Now, at initialization ScriptFu binds all names of PDB procedures, so they are defined. Each name is bound to its own small Scheme script that calls one foreign function that eventually calls the PDB via the run_procedure method of the PDB. Because it does this at initialization, it slows down startup.
Description of the enhancement
Late binding is a technique where a symbol is not defined until it is referenced. Not defined means "unbound" in the theory of programming languages. An unbound symbol is usually declared a programmer error. When using late binding, you try to bind an unbound symbol before declaring an error. Often you late bind to a dynamically loaded library. In this case, we try to bind an unbound symbol to a PDB call. Once bound, it stays bound, for the life of the ScriptFu extension, even through calls to different plugins by GIMP.
One complication is that in this case, the binding is to a foreign function that requires an argument that is the name of the called PDB procedure. You can think of the mechanism (the foreign function and the run_procedure method) as dispatching on the procedure name. Because of this requirement, on every evaluation of a symbol, you must check whether it is a call to the PDB, and insert an extra argument that is the bound name. So the enhancement does mess with the evaluation cycle of the TinyScheme interpreter. The checking is fast since TinyScheme has functions for determining whether symbols are bound to foreign functions.
Another complication is that a script author can use deprecated PDB names.
Discussion
The enhancement is not as simple as the description. The enhancement doesn't simplify the code, but it is not hard to understand. The concepts of binding and late-binding are well known.
The enhancement doesn't enlarge the code. Some code is added but much code is deleted.
Late binding defers work. Less work is done early at initialization, and more work is done later at runtime. Some of the deferred work need never be done, since many PDB procedures are not called during a session of GIMP. This is not important except that GIMP startup waits on ScriptFu.
It is possible that deferring work increases the elapsed time of some scripts. Any looping, computationally intensive scripts might be slowed. But most ScriptFu scripts are not computationally intensive, only simple sequences of GIMP commands.
More details
You can skip reading this section. It elaborates, for readers who are not familiar with ScriptFu implementation.
ScriptFu is a plug-in that wraps an inner TinyScheme interpreter. ScriptFu is an extension kind of plugin, it stays resident. Scriptfu causes all GIMP PDB procedures to appear in the role of functions in the Scheme language. Scriptfu does not use introspection, and doesn't let a script use libgimp functions.
Now, because each of a thousand PDB procedures is bound to a small script ( e.g. '''(apply -gimp-proc-db-call "gimp-drawable-get-image" args))''' ) it adds an extra layer of interpretation and adds volume to the interpreter state. But probably this is not a concern and doesn't materially affect script runtime performance, only startup time.
At initialization, the ScriptFu extension also reads all plugin script files in the Scheme language and stores their text in the ScriptFu interpreter to be later interpreted by the TinyScheme interpreter, when called. That's related, and might be changed, but is another matter.
Extent of changes
Minor changes are made to the core TinyScheme interpreter. That has not been changed much since it was forked into GIMP. It is not ideal to change the TinyScheme interpreter. But I think GIMP rarely, if ever, updates from the practically frozen TinyScheme repository. And there is also a proposal to eliminate the TinyScheme foundation altogether, replacing it with Guile and GI introspection.
More extensive changes, mostly deletions, are to ScriptFu proper, the outer interpreter, in scheme-wrapper.c and a few other files.
The remaining changes are mostly in a new file, script-fu-late-bind.c.
The enhancement is easy to revert to the original because the changes are mostly additions contained in one file.