Skip to content

Commit

Permalink
- fixed caching of custom JS []-operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoph Hart committed Dec 26, 2023
1 parent 36c57bb commit c6dace3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -280,48 +280,6 @@ hiseSpecialData(this)
#endif





void HiseJavascriptEngine::RootObject::ArraySubscript::cacheIndex(AssignableObject *instance, const Scope &s) const
{
if (cachedIndex == -1)
{
if (dynamic_cast<LiteralValue*>(index.get()) != nullptr ||
dynamic_cast<ConstReference*>(index.get()) != nullptr ||
dynamic_cast<DotOperator*>(index.get()) ||
dynamic_cast<ApiConstant*>(index.get()))
{
if (DotOperator* dot = dynamic_cast<DotOperator*>(index.get()))
{
if (dynamic_cast<ConstReference*>(dot->parent.get()) != nullptr)
{
if (ConstScriptingObject* cso = dynamic_cast<ConstScriptingObject*>(dot->parent->getResult(s).getObject()))
{
int constantIndex = cso->getConstantIndex(dot->child);
var possibleIndex = cso->getConstantValue(constantIndex);
if (possibleIndex.isInt() || possibleIndex.isInt64())
{
cachedIndex = (int)possibleIndex;
}
else location.throwError("[]- access only possible with int values");
}
else location.throwError("[]-access using dot operator only valid with const objects as parent");
}
else location.throwError("[]-access using dot operator only valid with const objects as parent");
}
else
{
const var i = index->getResult(s);
cachedIndex = instance->getCachedIndex(i);

if (cachedIndex == -1) location.throwError("Property " + i.toString() + " not found");
}
}
}
}


var HiseJavascriptEngine::RootObject::FunctionCall::getResult(const Scope& s) const
{
try
Expand Down
69 changes: 41 additions & 28 deletions hi_scripting/scripting/engine/JavascriptEngineExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ struct HiseJavascriptEngine::RootObject::ArraySubscript : public Expression
{
ArraySubscript(const CodeLocation& l) noexcept : Expression(l) {}



var getResult(const Scope& s) const override
{
var result = object->getResult(s);
Expand All @@ -122,29 +124,32 @@ struct HiseJavascriptEngine::RootObject::ArraySubscript : public Expression
}
else if (AssignableObject * instance = dynamic_cast<AssignableObject*>(result.getObject()))
{
cacheIndex(instance, s);

if(cachedIndex != -1)
return instance->getAssignedValue(cachedIndex);
else
{
auto idx = index->getResult(s);
return instance->getAssignedValue(idx);
}
const int i = index->getResult(s);
return instance->getAssignedValue(i);
}
else if (const Array<var>* array = result.getArray())
return (*array)[static_cast<int> (index->getResult(s))];

else if (const DynamicObject* obj = result.getDynamicObject())
{
const String name = index->getResult(s).toString();
auto hasConstIndex = index->isConstant();

if(name.isNotEmpty())
if(cachedId.isNull() || !hasConstIndex)
{
return obj->getProperty(Identifier(name));
WARN_IF_AUDIO_THREAD(true, ScriptAudioThreadGuard::DynamicObjectAccess);

const String name = index->getResult(s).toString();
auto idToUse = Identifier(name);

if(hasConstIndex)
cachedId = idToUse;

return obj->getProperty(idToUse);
}
else
{
return obj->getProperty(cachedId);
}


}

return var::undefined();
Expand All @@ -167,8 +172,6 @@ struct HiseJavascriptEngine::RootObject::ArraySubscript : public Expression
{
const int i = index->getResult(s);



WARN_IF_AUDIO_THREAD(i >= ar->getNumAllocated(), ScriptAudioThreadGuard::ArrayResizing);

while (ar->size() < i)
Expand All @@ -179,18 +182,30 @@ struct HiseJavascriptEngine::RootObject::ArraySubscript : public Expression
}
else if (AssignableObject * instance = dynamic_cast<AssignableObject*>(result.getObject()))
{
cacheIndex(instance, s);

instance->assign(cachedIndex, newValue);

const int i = index->getResult(s);
instance->assign(i, newValue);
return;
}
else if (DynamicObject* obj = result.getDynamicObject())
{
WARN_IF_AUDIO_THREAD(true, ScriptAudioThreadGuard::DynamicObjectAccess);

const String name = index->getResult(s).toString();
return obj->setProperty(Identifier(name), newValue);
auto hasConstIndex = index->isConstant();

if(cachedId.isNull() || !hasConstIndex)
{
WARN_IF_AUDIO_THREAD(true, ScriptAudioThreadGuard::DynamicObjectAccess);

const String name = index->getResult(s).toString();
auto idToUse = Identifier(name);

if(hasConstIndex)
cachedId = idToUse;

return obj->setProperty(idToUse, newValue);
}
else
{
return obj->setProperty(cachedId, newValue);
}
}

Expression::assign(s, newValue);
Expand All @@ -208,11 +223,9 @@ struct HiseJavascriptEngine::RootObject::ArraySubscript : public Expression
return swapIf(n, r, object) || swapIf(n, r, index);
}

void cacheIndex(AssignableObject *instance, const Scope &s) const;

ExpPtr object, index;

mutable int cachedIndex = -1;
mutable Identifier cachedId;
};

#define DECLARE_ID(x) const juce::Identifier x(#x);
Expand Down

0 comments on commit c6dace3

Please sign in to comment.