You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This idea is being registered here for documentation purposes, this is not necessarily a specification.
This feature requires an optimizer to not generate too much redundant code.
Currently, functions in mlogjs are implemented as subroutines, which means that they do not use stack to store their variables, instead referring to them by their unique names. This, however, prevents them from being called recursively (except for tail-call recursion, which degenerates into a loop) and also prevents them from being called dynamically, since the caller must know the name of each of the function's parameters.
Pseudo-code:
a_p0 = 10
a_p1 = 11
a_return_address = <address after jump>
jump <a> always
print(a_return_value)
function a(a_p0, a_p1) {
// compute result ...
a_return_value = result
@counter = a_return_address
}
However, this limits significantly the amount of programs that can be compiled with mlogjs, as well as making writing generic code much harder.
To alliviate this problem function pointers could be used.
Instead of relying on the caller to set the correct parameters when calling the function, the caller writes the parameters into global variables and jumps to the function's address, where the function can read the global variables related to the parameter's positions and copy them into it's own local variables to prevent them from being overwritten when calling another function.
_global_arg_0 = 10
_global_arg_1 = 11
_global_return_address = <address after jump>
jump <a> always
print(_global_return_value)
function a() {
// prevent arguments from being overwritten by another function call
a_p0 = _global_arg_0
a_p1 = _global_arg_0
a_return_address = _global_return_address
// compute result ...
_global_return_value = result
@counter = a_return_address
}
With this new model, it is trivial to support function pointers, since the only thing the caller needs to worry about is knowing the function's address. This is particullarly good for callbacks:
const array = new MutableArray(10)
for(let i = 0; i < array.size; i++) {
array[i] = Math.rand(100);
}
const sum = (prev, curr) => prev + curr;
const multiply = (prev, curr) => prev * curr;
print(fold(1, Math.rand(10) > 5 ? sum : multiply))
function fold(initialValue, callback) {
let result = initalValue
for(let i = 0; i < array.size; i++) {
// what this code does
// result = callback(result, array[i]);
_global_arg_0 = result
_global_arg_1 = array[i]
_global_return_address = <address after jump>
jump <callback> always
result = _global_return_value
}
return result;
}
Although the global parameter read/writes can be optimized away when calling functions known at compile-time, it trades speed for instruction space usage, when compared to function inlining.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This idea is being registered here for documentation purposes, this is not necessarily a specification.
This feature requires an optimizer to not generate too much redundant code.
Currently, functions in mlogjs are implemented as subroutines, which means that they do not use stack to store their variables, instead referring to them by their unique names. This, however, prevents them from being called recursively (except for tail-call recursion, which degenerates into a loop) and also prevents them from being called dynamically, since the caller must know the name of each of the function's parameters.
Pseudo-code:
However, this limits significantly the amount of programs that can be compiled with mlogjs, as well as making writing generic code much harder.
To alliviate this problem function pointers could be used.
Instead of relying on the caller to set the correct parameters when calling the function, the caller writes the parameters into global variables and jumps to the function's address, where the function can read the global variables related to the parameter's positions and copy them into it's own local variables to prevent them from being overwritten when calling another function.
With this new model, it is trivial to support function pointers, since the only thing the caller needs to worry about is knowing the function's address. This is particullarly good for callbacks:
Although the global parameter read/writes can be optimized away when calling functions known at compile-time, it trades speed for instruction space usage, when compared to function inlining.
Beta Was this translation helpful? Give feedback.
All reactions