From bd55d43cf87cf93de4fb4cb8b43bf1d550f8490b Mon Sep 17 00:00:00 2001 From: Ivory Date: Sat, 18 May 2024 23:49:47 +0200 Subject: [PATCH 1/3] Create proc-extern-setting.md --- docs/proc-extern-setting.md | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/proc-extern-setting.md diff --git a/docs/proc-extern-setting.md b/docs/proc-extern-setting.md new file mode 100644 index 0000000..adfac5a --- /dev/null +++ b/docs/proc-extern-setting.md @@ -0,0 +1,72 @@ +# Proc External Implementation Setting + +| Lead Author(s) | Implemented | GitHub Links | +|---|---|---| +| distributivgesetz | :x: No | TBD | + +## Overview + +This document proposes an alternative method of binding external implementations of code into DM codebases with the help of two new proc settings: `extern_lib` and `extern_func`. + +## Motivation + +The current method of calling external functions through `call_ext` feels very disordered. In order to bring external calls in line with modern practices of writing DM code, many codebases opt to hide `call_ext` syntax behind macros, which leads to macro pollution. The syntax also cannot account for the type of the input parameters, making static type checking impossible in this regard. + +## Design + +The proposal includes two new proc settings: + +- `extern_lib` + This setting holds to the name of the library the function was defined in. The same name schema as `call_ext` is used here. +- `extern_name` + This setting holds the name of the exported function in the library. + +Example: + +``` +/proc/foo_bar_extern() + set extern_lib = "foo" // points to libfoo.so or foo.dll + set extern_name = "bar" // points to exported function named "bar" + + // this is a stub proc, any proc implementation will be ignored by the compiler + return +``` + +Defining these in any proc will inform the compiler and runtime to treat the proc as externally implemented. + +- When using either setting, the other setting must also be defined, otherwise a compiler error is raised. +- Only global procs may have these settings. If a setting is set on an instance proc, a compiler error is raised. +- Externally defined procs are not allowed to be used as verbs, otherwise a compiler or runtime error is raised. +- When a proc is defined as external, the proc is not allowed to have code in its body, otherwise a compiler warning/error is raised. + +``` +/proc/foo_bar() // compiler error, incomplete extern proc definition + //set extern_lib = "foo" + set extern_name = "bar" + +/datum/proc/foo_bar() // compiler error, instance proc defined as extern + set extern_lib = "foo" + set extern_name = "bar" + +/verb/foo_bar() // compiler error, verb defined as extern + set extern_lib = "foo" + set extern_name = "bar" + +/verb/foo_bar() + set extern_lib = "foo" + set extern_name = "bar" + + return 1 // compiler warning, code here is ignored +``` + +The proc arguments may map to the arguments of the external function. The types of the arguments and the return value can be defined in order to facilitate static type checking. + +DM library maintainers may choose to use this syntax as an alternative to `call_ext`. Practically this only allows for static type checking, and less macro pollution if a maintainer wishes to only target OpenDream with their library. + + + +## Considerations & Drawbacks + +In order to keep parity with BYOND, library maintainers opting to use this feature would either need to obscure extern procs behind a macro, or they would need to add a conditional codeblock inside the proc that includes `call_ext`. Performance in this regard would stay the same to `call_ext` or be worse due to proc caling overhead when keeping the proc in BYOND. + +This is optional developer facing syntax, therefore no impact on users or developers migrating to OpenDream with this feature. From 63c4b1c29c7979e47e05b035dc81d2004ea4ac9a Mon Sep 17 00:00:00 2001 From: Ivory Date: Mon, 3 Jun 2024 00:49:16 +0200 Subject: [PATCH 2/3] revise proposed syntax, add optimization note --- docs/proc-extern-setting.md | 54 ++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/docs/proc-extern-setting.md b/docs/proc-extern-setting.md index adfac5a..3065dcd 100644 --- a/docs/proc-extern-setting.md +++ b/docs/proc-extern-setting.md @@ -6,67 +6,59 @@ ## Overview -This document proposes an alternative method of binding external implementations of code into DM codebases with the help of two new proc settings: `extern_lib` and `extern_func`. +This document proposes an alternative method of binding external implementations of code into DM codebases with the help of a new proc setting: `opendream_extern_impl`. ## Motivation -The current method of calling external functions through `call_ext` feels very disordered. In order to bring external calls in line with modern practices of writing DM code, many codebases opt to hide `call_ext` syntax behind macros, which leads to macro pollution. The syntax also cannot account for the type of the input parameters, making static type checking impossible in this regard. +The current method of calling external functions through `call_ext` feels very clunky. In order to bring external calls in line with modern practices of writing DM code, many codebases opt to hide `call_ext` syntax behind macros. Also, `call_ext` syntax cannot account for the type of the input parameters, making static type checking impossible in this regard. + +Additionally, since external functions cannot be determined at compile time with `call_ext`, ahead-of-time or just-in-time optimizations such as external call inlining cannot be implemented, because `call_ext` implies late-bound external calls. + +Overall, the main motivation of `opendream_extern_impl` is to provide neater and more robust syntax for external calls, as well as the ability for the compiler to determine which external functions an OpenDream executable will use, to allow for external call optimizations. ## Design -The proposal includes two new proc settings: +The proposal includes a new proc settings: -- `extern_lib` - This setting holds to the name of the library the function was defined in. The same name schema as `call_ext` is used here. -- `extern_name` - This setting holds the name of the exported function in the library. +- `opendream_extern_impl` + This defines the name and library of the external function, stored in a list tuple. The same naming schema as `call_ext` is used here. Example: ``` /proc/foo_bar_extern() - set extern_lib = "foo" // points to libfoo.so or foo.dll - set extern_name = "bar" // points to exported function named "bar" - + set opendream_extern_impl = list("foo", "bar") // points to a function called bar in libfoo.so or foo.dll // this is a stub proc, any proc implementation will be ignored by the compiler - return ``` Defining these in any proc will inform the compiler and runtime to treat the proc as externally implemented. -- When using either setting, the other setting must also be defined, otherwise a compiler error is raised. - Only global procs may have these settings. If a setting is set on an instance proc, a compiler error is raised. - Externally defined procs are not allowed to be used as verbs, otherwise a compiler or runtime error is raised. -- When a proc is defined as external, the proc is not allowed to have code in its body, otherwise a compiler warning/error is raised. +- When a proc is defined as external, the proc is not allowed to have code in its body, otherwise a compiler error is raised. ``` -/proc/foo_bar() // compiler error, incomplete extern proc definition - //set extern_lib = "foo" - set extern_name = "bar" - /datum/proc/foo_bar() // compiler error, instance proc defined as extern - set extern_lib = "foo" - set extern_name = "bar" + set opendream_extern_impl = list("foo", "bar") /verb/foo_bar() // compiler error, verb defined as extern - set extern_lib = "foo" - set extern_name = "bar" - + set opendream_extern_impl = list("foo", "bar") + +/mob/New() + verbs += /proc/foobar // runtime error, cannot add extern proc as verb + /verb/foo_bar() - set extern_lib = "foo" - set extern_name = "bar" + set opendream_extern_impl = list("foo", "bar") - return 1 // compiler warning, code here is ignored + return 1 // compiler error, code here is ignored ``` -The proc arguments may map to the arguments of the external function. The types of the arguments and the return value can be defined in order to facilitate static type checking. - -DM library maintainers may choose to use this syntax as an alternative to `call_ext`. Practically this only allows for static type checking, and less macro pollution if a maintainer wishes to only target OpenDream with their library. +The proc arguments should map to the arguments of the external function. The types of the arguments and the return value can be defined in order to facilitate static type checking. - +DM library maintainers may choose to use this syntax as an alternative to `call_ext`. At compile time this allows for static type checking and less macro pollution if a maintainer wishes to only target OpenDream with their code. ## Considerations & Drawbacks -In order to keep parity with BYOND, library maintainers opting to use this feature would either need to obscure extern procs behind a macro, or they would need to add a conditional codeblock inside the proc that includes `call_ext`. Performance in this regard would stay the same to `call_ext` or be worse due to proc caling overhead when keeping the proc in BYOND. +In order to keep parity with BYOND, library maintainers opting to use this feature would either need to obscure extern procs behind a macro, or they would need to add a conditional codeblock inside the proc that includes `call_ext`. Performance would stay the same or worse compared to `call_ext` in BYOND due to proc call overhead when moving the external call behind a proc . -This is optional developer facing syntax, therefore no impact on users or developers migrating to OpenDream with this feature. +This is optional developer facing syntax, therefore there is no impact on users or developers migrating to OpenDream with this feature. From c907bdb40acc897d2a5ee848044da314acc508fc Mon Sep 17 00:00:00 2001 From: Ivory Date: Mon, 3 Jun 2024 00:50:21 +0200 Subject: [PATCH 3/3] setting --- docs/proc-extern-setting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/proc-extern-setting.md b/docs/proc-extern-setting.md index 3065dcd..97bab6f 100644 --- a/docs/proc-extern-setting.md +++ b/docs/proc-extern-setting.md @@ -18,7 +18,7 @@ Overall, the main motivation of `opendream_extern_impl` is to provide neater and ## Design -The proposal includes a new proc settings: +The proposal includes a new proc setting: - `opendream_extern_impl` This defines the name and library of the external function, stored in a list tuple. The same naming schema as `call_ext` is used here.