Skip to content

Commit 2d4ad3e

Browse files
feat: optimize evaluator control flow and data handling for scalars
1 parent f48cf44 commit 2d4ad3e

15 files changed

+162
-102
lines changed

modules/interpreter/src/cpp/EvaluatorControlFlow.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,32 @@ Evaluator::ifStatement(AbstractSyntaxTreePtr t)
161161
}
162162
}
163163
}
164+
165+
// Early return if condition is true - avoids checking elseOrElseIf unnecessarily
166+
if (conditionedStatement(t)) {
167+
return;
168+
}
169+
164170
AbstractSyntaxTreePtr elseOrElseIf = t->right;
165-
if (!conditionedStatement(t)) {
166-
if (elseOrElseIf != nullptr && elseOrElseIf->opNum == OP_ELSEIFBLOCK) {
167-
AbstractSyntaxTreePtr s = elseOrElseIf->down;
168-
while (s != nullptr) {
169-
if (conditionedStatement(s)) {
170-
return;
171-
}
172-
s = s->right;
171+
if (elseOrElseIf == nullptr) {
172+
return;
173+
}
174+
175+
if (elseOrElseIf->opNum == OP_ELSEIFBLOCK) {
176+
AbstractSyntaxTreePtr s = elseOrElseIf->down;
177+
while (s != nullptr) {
178+
if (conditionedStatement(s)) {
179+
return;
173180
}
174-
elseOrElseIf = elseOrElseIf->right;
181+
s = s->right;
175182
}
176-
if (elseOrElseIf != nullptr) {
177-
block(elseOrElseIf);
183+
elseOrElseIf = elseOrElseIf->right;
184+
if (elseOrElseIf == nullptr) {
185+
return;
178186
}
179187
}
188+
189+
block(elseOrElseIf);
180190
}
181191
//=============================================================================
182192
//!

modules/interpreter/src/cpp/EvaluatorDebug.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,16 @@ Evaluator::stepBreakpointExists(const Breakpoint& bp)
253253
bool
254254
Evaluator::onBreakpoint(AbstractSyntaxTreePtr t)
255255
{
256+
if (breakpoints.empty() && !bpActive) {
257+
return false;
258+
}
256259
std::string currentFunctionName = context->getCurrentScope()->getName();
257260
// Fast path: if we are in step-next mode and the line changed, break immediately
258261
if (bpActive && stepMode && stepBreakpoint.has_value() && stepBreakpoint->stepNext) {
259262
const Breakpoint& sb = *stepBreakpoint;
260-
std::wstring sbFile = sb.filename;
263+
const std::wstring& sbFile = sb.filename;
261264
if (!sbFile.empty() && filenamesMatch(sbFile, context->getCurrentScope()->getFilename())) {
262-
std::string currentFunction = context->getCurrentScope()->getName();
265+
const std::string& currentFunction = context->getCurrentScope()->getName();
263266
// For step-over: ONLY break in the same function (no depth check to avoid confusion)
264267
bool inSameFunction = !sb.functionName.empty() && sb.functionName == currentFunction;
265268
bool shouldBreak = sb.stepInto || inSameFunction;

modules/interpreter/src/cpp/MacroFunctionDef.cpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,12 @@ MacroFunctionDef::evaluateMFunction(Evaluator* eval, const ArrayOfVector& inputs
169169

170170
uint64 tic = 0;
171171
try {
172-
insertLocalFunctions(context);
172+
// Only insert local functions on first entry (they don't change during recursion).
173+
if (recursionDepth == 1) {
174+
insertLocalFunctions(context);
175+
} else if (this->nextFunction != nullptr || this->prevFunction != nullptr) {
176+
insertLocalFunctions(context);
177+
}
173178
setInputArgumentNames(context, inputs);
174179
bindInputs(context, inputs);
175180
context->getCurrentScope()->setNargOut(nargout);
@@ -202,12 +207,15 @@ MacroFunctionDef::evaluateMFunction(Evaluator* eval, const ArrayOfVector& inputs
202207

203208
outputs = prepareOutputs(context, nargout);
204209

205-
onCleanup(eval);
206-
210+
if (!cleanupTasks.empty()) {
211+
onCleanup(eval);
212+
}
207213
context->popScope();
208214
eval->callstack.popDebug();
209215
} catch (const Exception&) {
210-
onCleanup(eval);
216+
if (!cleanupTasks.empty()) {
217+
onCleanup(eval);
218+
}
211219
if (recursionDepth == 1 && tic != 0) {
212220
internalProfileFunction stack
213221
= computeProfileStack(eval, getCompleteName(), this->getFilename(), false);
@@ -283,12 +291,26 @@ MacroFunctionDef::evaluateMScript(Evaluator* eval, const ArrayOfVector& inputs,
283291
ArrayOfVector
284292
MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs, int nargout)
285293
{
286-
lock();
287-
updateCode();
288-
if (isScript) {
289-
return evaluateMScript(eval, inputs, nargout);
294+
// Skip lock/updateCode on recursive calls � code cannot change mid-recursion.
295+
static thread_local int evaluateFunctionDepth = 0;
296+
if (evaluateFunctionDepth == 0) {
297+
lock();
298+
updateCode();
299+
}
300+
++evaluateFunctionDepth;
301+
ArrayOfVector result;
302+
try {
303+
if (isScript) {
304+
result = evaluateMScript(eval, inputs, nargout);
305+
} else {
306+
result = evaluateMFunction(eval, inputs, nargout);
307+
}
308+
} catch (...) {
309+
--evaluateFunctionDepth;
310+
throw;
290311
}
291-
return evaluateMFunction(eval, inputs, nargout);
312+
--evaluateFunctionDepth;
313+
return result;
292314
}
293315
//=============================================================================
294316
std::string

modules/types/src/cpp/ArrayOf.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,11 @@ ArrayOf::ArrayOf(
470470
dp = new Data(type, dims, data, sparse, fnames);
471471
}
472472
//=============================================================================
473+
ArrayOf::ArrayOf(NelsonType type, const Dimensions& dims, const void* scalarData, size_t dataSize)
474+
{
475+
dp = new Data(type, dims, scalarData, dataSize);
476+
}
477+
//=============================================================================
473478
ArrayOf::ArrayOf(NelsonType type) { dp = new Data(type, Dimensions(0, 0), nullptr); }
474479
//=============================================================================
475480
/**

modules/types/src/cpp/ArrayOf_Constructors.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ ArrayOf
115115
ArrayOf::emptyCell(const Dimensions& dim)
116116
{
117117
if (dim.getElementCount() == 0) {
118-
return ArrayOf(NLS_CELL_ARRAY, dim, nullptr, false);
118+
return ArrayOf(NLS_CELL_ARRAY, dim, (void*)nullptr, false);
119119
}
120120
Error(_W("Invalid dimensions."));
121121
return {};
@@ -125,7 +125,7 @@ ArrayOf
125125
ArrayOf::emptyConstructor(const Dimensions& dim, bool bIsSparse)
126126
{
127127
if (dim.getElementCount() == 0) {
128-
return ArrayOf(NLS_DOUBLE, dim, nullptr, bIsSparse);
128+
return ArrayOf(NLS_DOUBLE, dim, (void*)nullptr, bIsSparse);
129129
}
130130
Error(_W("Invalid dimensions."));
131131

@@ -137,7 +137,7 @@ ArrayOf::emptyConstructor(indexType m, indexType n, bool bIsSparse)
137137
{
138138
if (((m == 0) && (n == 0)) || ((m == 0) && (n != 0)) || ((m != 0) && (n == 0))) {
139139
Dimensions dim(m, n);
140-
return ArrayOf(NLS_DOUBLE, dim, nullptr, bIsSparse);
140+
return ArrayOf(NLS_DOUBLE, dim, (void*)nullptr, bIsSparse);
141141
}
142142
Error(_W("Invalid dimensions."));
143143

modules/types/src/cpp/ArrayOf_DoubleType.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ ArrayOf::isNdArrayDoubleType(bool realOnly) const
5252
ArrayOf
5353
ArrayOf::doubleConstructor(double aval)
5454
{
55-
double* data = static_cast<double*>(allocateArrayOf(NLS_DOUBLE, 1, stringVector(), false));
56-
*data = aval;
57-
return ArrayOf(NLS_DOUBLE, Dimensions(1, 1), data);
55+
return ArrayOf(NLS_DOUBLE, Dimensions(1, 1), static_cast<const void*>(&aval), sizeof(double));
5856
}
5957
//=============================================================================
6058
ArrayOf
@@ -94,10 +92,8 @@ ArrayOf::doubleMatrix2dConstructor(indexType m, indexType n)
9492
ArrayOf
9593
ArrayOf::dcomplexConstructor(double aval, double bval)
9694
{
97-
double* data = static_cast<double*>(allocateArrayOf(NLS_DCOMPLEX, 1, stringVector(), false));
98-
data[0] = aval;
99-
data[1] = bval;
100-
return ArrayOf(NLS_DCOMPLEX, Dimensions(1, 1), data);
95+
double data[2] = { aval, bval };
96+
return ArrayOf(NLS_DCOMPLEX, Dimensions(1, 1), static_cast<const void*>(data), sizeof(data));
10197
}
10298
//=============================================================================
10399
std::vector<double>

modules/types/src/cpp/ArrayOf_HandleType.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,16 @@ ArrayOf::isHandle() const
2828
ArrayOf
2929
ArrayOf::handleConstructor(nelson_handle hl)
3030
{
31-
nelson_handle* ptrObject = static_cast<nelson_handle*>(
32-
ArrayOf::allocateArrayOf(NLS_HANDLE, 1, stringVector(), false));
3331
Dimensions dims(1, 1);
34-
ptrObject[0] = hl;
35-
return ArrayOf(NLS_HANDLE, dims, (void*)ptrObject);
32+
return ArrayOf(NLS_HANDLE, dims, static_cast<const void*>(&hl), sizeof(nelson_handle));
3633
}
3734
//=============================================================================
3835
ArrayOf
3936
ArrayOf::handleConstructor(HandleGenericObject* ptr)
4037
{
41-
nelson_handle* ptrObject = static_cast<nelson_handle*>(
42-
ArrayOf::allocateArrayOf(NLS_HANDLE, 1, stringVector(), false));
4338
Dimensions dims(1, 1);
44-
ptrObject[0] = HandleManager::getInstance()->addHandle(ptr);
45-
return ArrayOf(NLS_HANDLE, dims, (void*)ptrObject);
39+
nelson_handle hl = HandleManager::getInstance()->addHandle(ptr);
40+
return ArrayOf(NLS_HANDLE, dims, static_cast<const void*>(&hl), sizeof(nelson_handle));
4641
}
4742
//=============================================================================
4843
HandleGenericObject*

modules/types/src/cpp/ArrayOf_IntegersType.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ scalarConstructor(NelsonType type, T value)
2424
{
2525
Dimensions dim;
2626
dim.makeScalar();
27-
T* data = static_cast<T*>(ArrayOf::allocateArrayOf(type, 1, stringVector(), false));
28-
*data = value;
29-
return ArrayOf(type, dim, data);
27+
return ArrayOf(type, dim, static_cast<const void*>(&value), sizeof(T));
3028
}
3129
//=============================================================================
3230
template <typename T>
@@ -329,19 +327,19 @@ ArrayOf::integerRangeConstructor(indexType minval, indexType stepsize, indexType
329327
if (stepsize == 0) {
330328
Cdim[0] = 1;
331329
Cdim[1] = 0;
332-
return ArrayOf(classC, Cdim, nullptr, false);
330+
return ArrayOf(classC, Cdim, (void*)nullptr, false);
333331
}
334332
if (minval < maxval) {
335333
if (stepsize < 0) {
336334
Cdim[0] = 1;
337335
Cdim[1] = 0;
338-
return ArrayOf(classC, Cdim, nullptr, false);
336+
return ArrayOf(classC, Cdim, (void*)nullptr, false);
339337
}
340338
}
341339
if (minval > maxval) {
342340
Cdim[0] = 0;
343341
Cdim[1] = 1;
344-
return ArrayOf(classC, Cdim, nullptr, false);
342+
return ArrayOf(classC, Cdim, (void*)nullptr, false);
345343
}
346344
auto dn = static_cast<double>((((maxval - minval) / stepsize) + 1));
347345
#ifdef NLS_INDEX_TYPE_64

modules/types/src/cpp/ArrayOf_LogicalType.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ ArrayOf::logicalConstructor(bool aval)
3838
{
3939
Dimensions dim;
4040
dim.makeScalar();
41-
logical* data = static_cast<logical*>(allocateArrayOf(NLS_LOGICAL, 1, stringVector(), false));
42-
*data = static_cast<logical>(aval);
43-
return ArrayOf(NLS_LOGICAL, dim, data);
41+
logical val = static_cast<logical>(aval);
42+
return ArrayOf(NLS_LOGICAL, dim, static_cast<const void*>(&val), sizeof(logical));
4443
}
4544
//=============================================================================
4645
logical

modules/types/src/cpp/ArrayOf_MissingType.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ ArrayOf::missingScalarConstructor()
3737
{
3838
Dimensions dim;
3939
dim.makeScalar();
40-
double* data
41-
= static_cast<double*>(allocateArrayOf(NLS_MISSING_ARRAY, 1, stringVector(), false));
42-
*data = std::nan("");
43-
return ArrayOf(NLS_MISSING_ARRAY, dim, data);
40+
double val = std::nan("");
41+
return ArrayOf(NLS_MISSING_ARRAY, dim, static_cast<const void*>(&val), sizeof(double));
4442
}
4543
//=============================================================================
4644
} // namespace Nelson

0 commit comments

Comments
 (0)