Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit c6d97ec

Browse files
author
runrevali
committed
[[ ArrayElementRefParams ]] All parameters are now containers to allow the passing of array elemen
ts by reference
1 parent c8fd47b commit c6d97ec

File tree

9 files changed

+187
-82
lines changed

9 files changed

+187
-82
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Array element pass by reference
2+
3+
It is now possible to pass parts of an array by reference. For example, the following
4+
5+
`on mouseUp
6+
local tArray
7+
put "" into tArray[1][2]
8+
passByRef tArray[1]
9+
put tArray[1][2]
10+
end mouseUp
11+
12+
on passByRef @rArray
13+
put "changed" into rArray[2]
14+
end passByRef`
15+
16+
in the script of a button will result in "changed" appearing in the message box when the button is pressed.
17+
18+
This allows users to reduce the overhead associated with passing sub-arrays to handlers, as this would no longer require copying the sub-array internally.

engine/src/cmdse.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,12 +1092,11 @@ void MCDispatchCmd::exec_ctxt(MCExecContext &ctxt)
10921092
MCParameter *tptr = params;
10931093
while (tptr != NULL)
10941094
{
1095-
// Get the pointer to the variable this parameter maps to or NULL
1096-
// if it is an expression.
1097-
MCVariable* t_var;
1098-
t_var = tptr -> evalvar(ctxt);
1099-
1100-
if (t_var == NULL)
1095+
// AL-2014-08-20: [[ ArrayElementRefParams ]] Use containers for potential reference parameters
1096+
MCContainer *t_container;
1097+
if (tptr -> evalcontainer(ctxt, t_container))
1098+
tptr -> set_argument_container(t_container);
1099+
else
11011100
{
11021101
MCExecValue t_value;
11031102
tptr -> clear_argument();
@@ -1118,8 +1117,6 @@ void MCDispatchCmd::exec_ctxt(MCExecContext &ctxt)
11181117

11191118
tptr->give_exec_argument(t_value);
11201119
}
1121-
else
1122-
tptr->set_argument_var(t_var);
11231120

11241121
tptr = tptr->getnext();
11251122
}

engine/src/exec-keywords.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,20 +153,19 @@ void MCKeywordsExecCommandOrFunction(MCExecContext& ctxt, bool resolved, MCHandl
153153
MCParameter *tptr = params;
154154
while (tptr != NULL)
155155
{
156-
MCVariable* t_var;
157-
t_var = tptr -> evalvar(ctxt);
158-
159-
if (t_var == NULL)
160-
{
161-
tptr -> clear_argument();
156+
// AL-2014-08-20: [[ ArrayElementRefParams ]] Use containers for potential reference parameters
157+
MCContainer *t_container;
158+
if (tptr -> evalcontainer(ctxt, t_container))
159+
tptr -> set_argument_container(t_container);
160+
else
161+
{
162+
tptr -> clear_argument();
162163
MCExecValue t_value;
163164
//HERE
164-
if (!ctxt . TryToEvaluateParameter(tptr, line, pos, is_function ? EE_FUNCTION_BADSOURCE : EE_STATEMENT_BADPARAM, t_value))
165+
if (!ctxt . TryToEvaluateParameter(tptr, line, pos, is_function ? EE_FUNCTION_BADSOURCE : EE_STATEMENT_BADPARAM, t_value))
165166
return;
166-
tptr->give_exec_argument(t_value);
167-
}
168-
else
169-
tptr->set_argument_var(t_var);
167+
tptr->give_exec_argument(t_value);
168+
}
170169

171170
tptr = tptr->getnext();
172171
}

engine/src/handler.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,13 @@ Exec_stat MCHandler::exec(MCExecContext& ctxt, MCParameter *plist)
314314
for (npassedparams = 0 ; tptr != NULL ; npassedparams++)
315315
tptr = tptr->getnext();
316316
uint2 newnparams = MCU_max(npassedparams, npnames);
317-
MCVariable **newparams;
317+
318+
// AL-2014-08-20: [[ ArrayElementRefParams ]] All handler params are now containers
319+
MCContainer **newparams;
318320
if (newnparams == 0)
319321
newparams = NULL;
320322
else
321-
newparams = new MCVariable *[newnparams];
323+
newparams = new MCContainer *[newnparams];
322324

323325
Boolean err = False;
324326
for (i = 0 ; i < newnparams ; i++)
@@ -327,7 +329,7 @@ Exec_stat MCHandler::exec(MCExecContext& ctxt, MCParameter *plist)
327329
{
328330
if (i < npnames && pinfo[i].is_reference)
329331
{
330-
if ((newparams[i] = plist->eval_argument_var()) == NULL)
332+
if ((newparams[i] = plist->eval_argument_container()) == NULL)
331333
{
332334
err = True;
333335
break;
@@ -341,7 +343,11 @@ Exec_stat MCHandler::exec(MCExecContext& ctxt, MCParameter *plist)
341343
err = True;
342344
break;
343345
}
344-
/* UNCHECKED */ MCVariable::createwithname(i < npnames ? pinfo[i] . name : kMCEmptyName, newparams[i]);
346+
347+
MCVariable *t_new_var;
348+
/* UNCHECKED */ MCVariable::createwithname(i < npnames ? pinfo[i] . name : kMCEmptyName, t_new_var);
349+
/* UNCHECKED */ MCContainer::createwithvariable(t_new_var, newparams[i]);
350+
345351
newparams[i]->give_value(ctxt, t_value);
346352
}
347353
plist = plist->getnext();
@@ -353,7 +359,9 @@ Exec_stat MCHandler::exec(MCExecContext& ctxt, MCParameter *plist)
353359
err = True;
354360
break;
355361
}
356-
/* UNCHECKED */ MCVariable::createwithname(i < npnames ? pinfo[i] . name : kMCEmptyName, newparams[i]);
362+
MCVariable *t_new_var;
363+
/* UNCHECKED */ MCVariable::createwithname(i < npnames ? pinfo[i] . name : kMCEmptyName, t_new_var);
364+
/* UNCHECKED */ MCContainer::createwithvariable(t_new_var, newparams[i]);
357365
}
358366
}
359367
if (err)
@@ -366,7 +374,7 @@ Exec_stat MCHandler::exec(MCExecContext& ctxt, MCParameter *plist)
366374
return ES_ERROR;
367375
}
368376

369-
MCVariable **oldparams = params;
377+
MCContainer **oldparams = params;
370378
MCVariable **oldvars = vars;
371379
uint2 oldnparams = nparams;
372380
uint2 oldnvnames = nvnames;
@@ -724,6 +732,16 @@ Exec_stat MCHandler::exec(MCExecPoint &ep, MCParameter *plist)
724732
}
725733
#endif
726734

735+
MCVariable *MCHandler::getvar(uint2 index, Boolean isparam)
736+
{
737+
return isparam ? nil : vars[index];
738+
}
739+
740+
MCContainer *MCHandler::getcontainer(uint2 index, Boolean isparam)
741+
{
742+
return isparam ? params[index] : nil;
743+
}
744+
727745
integer_t MCHandler::getnparams(void)
728746
{
729747
return npassedparams;
@@ -738,7 +756,7 @@ MCValueRef MCHandler::getparam(uindex_t p_index)
738756
else if (p_index > nparams)
739757
return kMCEmptyString;
740758
else
741-
return params[p_index - 1]->getvalueref();
759+
return params[p_index - 1]->get_valueref();
742760
}
743761

744762
// MW-2013-11-08: [[ RefactorIt ]] Changed to return the 'm_it' varref we always have now.

engine/src/handler.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class MCHandler
4545
MCStatement *statements;
4646
MCVariable **vars;
4747
MCVariable **globals;
48-
MCVariable **params;
48+
MCContainer **params;
4949
MCParameter *paramlist;
5050
MCHandlerVarInfo *vinfo;
5151
MCHandlerParamInfo *pinfo;
@@ -101,10 +101,9 @@ class MCHandler
101101
Exec_stat exec(MCExecContext &, MCParameter *);
102102
void compile(MCSyntaxFactoryRef factory);
103103

104-
MCVariable *getvar(uint2 index, Boolean isparam)
105-
{
106-
return isparam ? params[index] : vars[index];
107-
}
104+
MCVariable *getvar(uint2 index, Boolean isparam);
105+
MCContainer *getcontainer(uint2 index, Boolean isparam);
106+
108107
integer_t getnparams(void);
109108
MCValueRef getparam(uindex_t p_index);
110109
Parse_stat findvar(MCNameRef name, MCVarref **);
@@ -169,7 +168,7 @@ class MCHandler
169168
r_var_count = nvnames;
170169
}
171170

172-
void getparamlist(MCVariable**& r_vars, uint32_t& r_param_count)
171+
void getparamlist(MCContainer**& r_vars, uint32_t& r_param_count)
173172
{
174173
r_vars = params;
175174
r_param_count = npnames;

engine/src/param.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ bool MCParameter::eval_argument_ctxt(MCExecContext &ctxt, MCExecValue &r_value)
217217
if (var != NULL)
218218
return var -> eval_ctxt(ctxt, r_value);
219219

220+
if (container != nil)
221+
return container -> eval_ctxt(ctxt, r_value);
222+
220223
MCExecTypeCopy(value, r_value);
221224
return true;
222225
}
@@ -239,6 +242,11 @@ MCVariable *MCParameter::eval_argument_var(void)
239242
return var;
240243
}
241244

245+
MCContainer *MCParameter::eval_argument_container(void)
246+
{
247+
return container;
248+
}
249+
242250
/////////
243251

244252
void MCParameter::set_argument(MCExecContext& ctxt, MCValueRef p_value)
@@ -275,6 +283,11 @@ void MCParameter::set_argument_var(MCVariable* p_var)
275283
var = p_var;
276284
}
277285

286+
void MCParameter::set_argument_container(MCContainer* p_container)
287+
{
288+
container = p_container;
289+
}
290+
278291
////////////////////////////////////////////////////////////////////////////////
279292

280293
void MCParameter::compile(MCSyntaxFactoryRef ctxt)

engine/src/param.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class MCParameter
3131
exp = nil;
3232
next = nil;
3333
var = nil;
34+
container = nil;
3435
value . type = kMCExecValueTypeNone;
3536
value . valueref_value = nil;
3637
}
@@ -79,7 +80,8 @@ class MCParameter
7980
Exec_stat eval_argument(MCExecPoint& ep);
8081
#endif
8182
MCVariable *eval_argument_var(void);
82-
83+
MCContainer *eval_argument_container(void);
84+
8385
bool eval_argument(MCExecContext& ctxt, MCValueRef &r_value);
8486
bool eval_argument_ctxt(MCExecContext& ctxt, MCExecValue &r_value);
8587

@@ -90,6 +92,7 @@ class MCParameter
9092
void set_argument(MCExecPoint& ep);
9193
#endif
9294
void set_argument_var(MCVariable* var);
95+
void set_argument_container(MCContainer* container);
9396

9497
// Evaluate the value of the given parameter in the context of
9598
// <ep>.
@@ -124,6 +127,7 @@ class MCParameter
124127
// Parameter as value (i.e. value of the argument when
125128
// passed to a function/command).
126129
MCVariable *var;
130+
MCContainer *container;
127131
MCExecValue value;
128132
};
129133

0 commit comments

Comments
 (0)