Skip to content
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

Function Reference Parameters (Extending the 'outer' system) #293

Open
Peach1 opened this issue Sep 13, 2024 · 3 comments
Open

Function Reference Parameters (Extending the 'outer' system) #293

Peach1 opened this issue Sep 13, 2024 · 3 comments

Comments

@Peach1
Copy link

Peach1 commented Sep 13, 2024

So Squirrel language already has 'outers' which act like references:

local x = 0; function mod() { x = 5; } mod(); print(x) // x is now 5

Squirrel "Outers" are almost references, but Squirrel's outers are limited to local variables in the _parent function.

So, with some modification of Squirrel's outer system, how can we implement this feature:

function mod(&x) { x = 5; }  local x = 0; mod(x); print(x);

For Syntax: Parsing & in CreateFunction would need to call something like MarkLocalAsOuter() for each & reference parameter

Then for runtime

Possibly take this code fromSQVM::CLOSURE_OP()...

    if((nouters = func->_noutervalues)) {
        for(SQInteger i = 0; i<nouters; i++) {
            SQOuterVar &v = func->_outervalues[i];
            switch(v._type){
            case otLOCAL: // outer local stack target, might be possible to use for general references
                FindOuter(closure->_outervalues[i], &STK(_integer(v._src)));
                break;
            case otOUTER:
                closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)];
                break;
            }
        }
    }

And setup "references" in _OP_PREPCALL so the reference stack is setup before the function gets called,

Any idea for how to extend the outer system and implement references?
It would be really cool for Squirrel.

@Peach1 Peach1 changed the title Function References Parameters (Extending the 'outer' system) Function Reference Parameters (Extending the 'outer' system) Sep 13, 2024
@RizzoRat
Copy link

No need to, see WEAKREF.
Also Squirrel always works with references by default for arrays, tables, class instances and classes. Hence. put your variable in a table, pass the table and you have your reference including all variables and objects in that table. If you want to protect other objects, uses classes instead of tables. If you don't want to reference, use CLONE (which can get costly BTW)
Note that basically even the code always is in a table, including its variables (see for example THIS and BIND) unless they're declared LOCAL (which are on the stack, that's why there's outers)

@Peach1
Copy link
Author

Peach1 commented Sep 13, 2024

No need to, see WEAKREF.

Weakref cannot work because obj_delegate_weakref simply copies integers. SQOBJECT_REF_COUNTED is false for integer and float types, meaning integer references aren't possible in default Squirrel.


We will modify Squirrel to make the VM instructions support arbitrary references.

function mod(&x) { x = 5; }  local x = 0; mod(x); print(x);

will output:

5

We know existing-Squirrel cannot do this, but Squirrel is open source so we're looking for comments on how to implement integer references natively in Squirrel's C++ code.

Our users want to directly modify integers by reference, without using a wrapper.

Again, the closest thing is _OP_SETOUTER _OP_GETOUTER.

Using Squirrel's Outer system, we can extend Squirrel to support general references. It requires editing sqvm.cpp and sqcompiler.cpp

Take Squirrel's Outer and extend it to full references on integers and any script local.

local x = 0; function mod() { x = 5; } mod(); print(x) // x is now 5

With some modification true references can be added on top of Squirrel's Outer system:

function mod(&x) { x = 5; }  local x = 0; mod(x); print(x);
  • Closures already implement (partial) references to modify outer local integers

  • It might be possible to extend Squirrel to support modifying arbitrary outer locals

  • We're looking for the best way to implement it in sqvm.cpp and sqcompiler.cpp

We will redesign Squirrel's C++ code to accommodate this feature.

function mod
-----OUTERS
0 x
-----Instructions
    [000]         _OP_LOADINT 5
    [001]        _OP_SETOUTER 255 0[x]  // could be extended to support true references
    [002]       _OP_LOADNULLS 1 1
    [003]          _OP_RETURN 255 0
local x = 0; function mod() { x = 5; } mod(); print(x) // x is now 5

@albertodemichelis
Copy link
Owner

I can see this working for local variables but it wouldn't work for variables that are not in the stack. Also I can't imagine what we would pass as parameter so that the called function would recognize that is a reference. It is more complicated that it sounds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants