Merge pull request #1587 from marauder2k9-torque/development
Some checks failed
Linux Build / ${{matrix.config.name}} (map[build_type:Release cc:gcc cxx:g++ generator:Ninja name:Ubuntu Latest GCC]) (push) Has been cancelled
MacOSX Build / ${{matrix.config.name}} (map[build_type:Release cc:clang cxx:clang++ generator:Ninja name:MacOSX Latest Clang]) (push) Has been cancelled
Windows Build / ${{matrix.config.name}} (map[build_type:Release cc:cl cxx:cl environment_script:C:/Program Files (x86)/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat generator:Visual Studio 17 2022 name:Windows Latest MSVC]) (push) Has been cancelled

Placeholder function argument vars
This commit is contained in:
Brian Roberts 2025-11-26 02:08:42 -06:00 committed by GitHub
commit 9fe2eec813
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 1378 additions and 1209 deletions

View file

@ -105,5 +105,5 @@ jobs:
name: Linux test results
path: "**/My Projects/Torque3D/game/test_detail.xml"
reporter: java-junit
fail-on-error: false
fail-on-error: true
if: github.event_name != 'pull_request'

View file

@ -75,5 +75,5 @@ jobs:
name: MacOS Test results
path: "**/My Projects/Torque3D/game/test_detail.xml"
reporter: java-junit
fail-on-error: false
fail-on-error: true
if: github.event_name != 'pull_request'

View file

@ -71,5 +71,5 @@ jobs:
name: Windows test results
path: "**/My Projects/Torque3D/game/test_detail.xml"
reporter: java-junit
fail-on-error: false
fail-on-error: true
if: github.event_name != 'pull_request'

View file

@ -671,10 +671,15 @@ Namespace::Entry::Entry()
mNext = NULL;
mPackage = StringTable->EmptyString();
mToolOnly = false;
VECTOR_SET_ASSOCIATION(mArgFlags);
VECTOR_SET_ASSOCIATION(mDefaultValues);
}
void Namespace::Entry::clear()
{
mArgFlags.clear();
mDefaultValues.clear();
if (mModule)
{
mModule->decRefCount();

View file

@ -130,6 +130,10 @@ public:
/// The offset in the compiled script code at which this function begins.
U32 mFunctionOffset;
// Offsets to get default values for arguments.
Vector<U32> mArgFlags;
Vector<ConsoleValue> mDefaultValues;
/// If it's a script function, this is the line of the declaration in code.
/// @note 0 for functions read from legacy DSOs that have no line number information.
U32 mFunctionLineNumber;

View file

@ -138,6 +138,7 @@ struct Token
%type <slot> slot_acc
%type <intslot> intslot_acc
%type <stmt> expression_stmt
%type <var> param
%type <var> var_list
%type <var> var_list_decl
%type <asn> assign_op_struct
@ -242,12 +243,31 @@ var_list_decl
;
var_list
: VAR
{ $$ = VarNode::alloc( $1.lineNumber, $1.value, NULL ); }
| var_list ',' VAR
{ $$ = $1; ((StmtNode*)($1))->append((StmtNode*)VarNode::alloc( $3.lineNumber, $3.value, NULL ) ); }
: param
{ $$ = $1; }
| var_list ',' param
{ $$ = $1; ((StmtNode*)($1))->append((StmtNode*)$3 ); }
;
param
: VAR
{
$$ = VarNode::allocParam($1.lineNumber, $1.value, NULL);
}
| VAR '?'
{
$$ = VarNode::allocParam($1.lineNumber, $1.value, NULL);
}
| VAR '=' expr
{
$$ = VarNode::allocParam($1.lineNumber, $1.value, $3);
}
| VAR '?' '=' expr
{
$$ = VarNode::allocParam($1.lineNumber, $1.value, $4);
}
;
datablock_decl
: rwDATABLOCK class_name_expr '(' expr parent_block ')' '{' slot_assign_list_opt '}' ';'
{ $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, NULL, $5.value, $8, NULL, true, false, false); }

View file

@ -311,8 +311,13 @@ struct VarNode : ExprNode
StringTableEntry varName;
ExprNode* arrayIndex;
ExprNode* defaultValue; // optional expression
static VarNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex);
// function params initialization.
static VarNode* allocParam(S32 lineNumber, StringTableEntry varName, ExprNode* defaultValue);
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type) override;
TypeReq getPreferredType() override;
ExprNodeName getExprNodeNameEnum() const override { return NameVarNode; }

View file

@ -206,6 +206,19 @@ VarNode* VarNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arra
ret->optimizedNode = NULL;
ret->varName = varName;
ret->arrayIndex = arrayIndex;
ret->defaultValue = NULL;
return ret;
}
VarNode* VarNode::allocParam(S32 lineNumber, StringTableEntry varName, ExprNode* defaultValue)
{
VarNode* ret = (VarNode*)consoleAlloc(sizeof(VarNode));
constructInPlace(ret);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->varName = varName;
ret->arrayIndex = NULL;
ret->defaultValue = defaultValue;
return ret;
}

View file

@ -1529,6 +1529,19 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
CodeBlock::smInFunction = false;
// check for argument setup
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
{
if (walk->defaultValue)
{
TypeReq walkType = walk->defaultValue->getPreferredType();
if (walkType == TypeReqNone)
walkType = TypeReqString;
ip = walk->defaultValue->compile(codeStream, ip, walkType);
}
}
codeStream.emit(OP_FUNC_DECL);
codeStream.emitSTE(fnName);
codeStream.emitSTE(nameSpace);
@ -1538,11 +1551,22 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
const U32 endIp = codeStream.emit(0);
codeStream.emit(argc);
const U32 localNumVarsIP = codeStream.emit(0);
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
{
StringTableEntry name = walk->varName;
codeStream.emit(getFuncVars(dbgLineNumber)->lookup(name, dbgLineNumber));
}
// check for argument setup
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
{
U32 flags = 0;
if (walk->defaultValue) flags |= 0x1;
codeStream.emit(flags);
}
CodeBlock::smInFunction = true;
ip = compileBlock(stmts, codeStream, ip);

File diff suppressed because it is too large Load diff

View file

@ -614,7 +614,22 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
ConsoleValue& value = argv[i + 1];
Script::gEvalState.moveConsoleValue(reg, (value));
}
ip = ip + fnArgc + (2 + 6 + 1 + 1);
if (wantedArgc < fnArgc)
{
Namespace::Entry* temp = thisNamespace->lookup(thisFunctionName);
for (; i < fnArgc; i++)
{
S32 reg = code[ip + (2 + 6 + 1 + 1) + i];
if (temp->mArgFlags[i] & 0x1)
{
ConsoleValue& value = temp->mDefaultValues[i];
Script::gEvalState.moveConsoleValue(reg, (value));
}
}
}
ip = ip + fnArgc + (2 + 6 + 1 + 1) + fnArgc;
curFloatTable = functionFloats;
curStringTable = functionStrings;
curStringTableLen = functionStringsMaxLen;
@ -736,8 +751,39 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
curNSDocBlock = NULL;
}
}
Namespace::relinkPackages();
U32 fnArgc = code[ip + 2 + 6];
// Compute pointer to the register mapping like exec() does.
U32 readPtr = ip + 2 + 6 + 1; // points to the slot after argc (localNumVarsIP)
readPtr += 1; // skip localNumVarsIP
readPtr += fnArgc; // skip register mapping
Namespace::Entry* temp = ns->lookup(fnName);
temp->mArgFlags.setSize(fnArgc);
temp->mDefaultValues.setSize(fnArgc);
// Read flags sequentially
for (U32 fa = 0; fa < fnArgc; ++fa)
{
temp->mArgFlags[fa] = code[readPtr++];
}
// this might seem weird but because of the order
// the stack accumulates consoleValues we cant be sure
// all args have a console value, and we need to pop
// the stack, do this in reverse order.
for (S32 fa = S32(fnArgc - 1); fa >= 0; fa--)
{
if (temp->mArgFlags[fa] & 0x1)
{
temp->mDefaultValues[fa] = stack[_STK--];
}
}
Namespace::relinkPackages();
// If we had a docblock, it's definitely not valid anymore, so clear it out.
curFNDocBlock = NULL;