diff --git a/libs/yscript/javascript.cpp b/libs/yscript/javascript.cpp index aa3c4ebb..9e277251 100644 --- a/libs/yscript/javascript.cpp +++ b/libs/yscript/javascript.cpp @@ -187,7 +187,7 @@ private: JsFunction* func, bool constr) const; bool callFunction(ObjList& stack, const ExpOperation& oper, GenObject* context, long int retIndex, JsFunction* func, ObjList& args, - ExpOperation* thisObj, ExpOperation* scopeObj) const; + JsObject* thisObj, JsObject* scopeObj) const; inline JsFunction* getGlobalFunction(const String& name) const { return YOBJECT(JsFunction,m_globals[name]); } long int m_label; @@ -2090,7 +2090,11 @@ bool JsCode::callFunction(ObjList& stack, const ExpOperation& oper, GenObject* c Debug(this,DebugWarn,"Oops! Could not find return point!"); return false; } - ExpOperation* thisObj = constr ? popOne(stack) : 0; + ExpOperation* op = constr ? popOne(stack) : 0; + JsObject* thisObj = YOBJECT(JsObject,op); + if (thisObj && !thisObj->ref()) + thisObj = 0; + TelEngine::destruct(op); ObjList args; JsObject::extractArgs(func,stack,oper,context,args); return callFunction(stack,oper,context,index,func,args,thisObj,0); @@ -2098,11 +2102,11 @@ bool JsCode::callFunction(ObjList& stack, const ExpOperation& oper, GenObject* c bool JsCode::callFunction(ObjList& stack, const ExpOperation& oper, GenObject* context, long int retIndex, JsFunction* func, ObjList& args, - ExpOperation* thisObj, ExpOperation* scopeObj) const + JsObject* thisObj, JsObject* scopeObj) const { pushOne(stack,new ExpOperation(OpcFunc,0,retIndex,true)); if (scopeObj) - pushOne(stack,new ExpWrapper(scopeObj,scopeObj->name())); + pushOne(stack,new ExpWrapper(scopeObj,"()")); JsObject* ctxt = JsObject::buildCallContext(func->mutex(),thisObj); for (unsigned int idx = 0; ; idx++) { const String* name = func->formalName(idx); @@ -2188,10 +2192,18 @@ ScriptRun::Status JsRunner::call(const String& name, ObjList& args, TelEngine::destruct(scopeObj); return Failed; } + JsObject* jsThis = YOBJECT(JsObject,thisObj); + if (jsThis && !jsThis->ref()) + jsThis = 0; + JsObject* jsScope = YOBJECT(JsObject,scopeObj); + if (jsScope && !jsScope->ref()) + jsScope = 0; + TelEngine::destruct(thisObj); + TelEngine::destruct(scopeObj); reset(); // prepare a function call stack ExpOperation oper(ExpEvaluator::OpcFunc,name,args.count()); - if (!c->callFunction(stack(),oper,this,-1,func,args,thisObj,scopeObj)) + if (!c->callFunction(stack(),oper,this,-1,func,args,jsThis,jsScope)) return Failed; mylock.drop(); // continue normal execution like in run() diff --git a/libs/yscript/jsobjects.cpp b/libs/yscript/jsobjects.cpp index 450ca41e..719dce77 100644 --- a/libs/yscript/jsobjects.cpp +++ b/libs/yscript/jsobjects.cpp @@ -209,10 +209,10 @@ void JsObject::printRecursive(const GenObject* obj) Output("%s",buf.c_str()); } -JsObject* JsObject::buildCallContext(Mutex* mtx, ExpOperation* thisObj) +JsObject* JsObject::buildCallContext(Mutex* mtx, JsObject* thisObj) { JsObject* ctxt = new JsObject(mtx,"()"); - if (thisObj) + if (thisObj && thisObj->ref()) ctxt->params().addParam(new ExpWrapper(thisObj,"this")); return ctxt; } diff --git a/libs/yscript/yatescript.h b/libs/yscript/yatescript.h index 6cb4b0ac..dd40e558 100644 --- a/libs/yscript/yatescript.h +++ b/libs/yscript/yatescript.h @@ -1805,7 +1805,7 @@ public: * @param thisObj Optional object that will be set as "this" * @return New empty object usable as call context */ - static JsObject* buildCallContext(Mutex* mtx, ExpOperation* thisObj = 0); + static JsObject* buildCallContext(Mutex* mtx, JsObject* thisObj = 0); /** * Initialize the standard global objects in a context diff --git a/modules/javascript.cpp b/modules/javascript.cpp index f0d42d62..ddff1343 100644 --- a/modules/javascript.cpp +++ b/modules/javascript.cpp @@ -482,12 +482,12 @@ void JsEngine::initialize(ScriptContext* context) bool JsMessage::runAssign(ObjList& stack, const ExpOperation& oper, GenObject* context) { + XDebug(&__plugin,DebugAll,"JsMessage::runAssign '%s'='%s'",oper.name().c_str(),oper.c_str()); if (ScriptContext::hasField(stack,oper.name(),context)) return JsObject::runAssign(stack,oper,context); if (!m_message) return false; - ExpWrapper* w = YOBJECT(ExpWrapper,&oper); - if (w && !w->object()) + if (JsParser::isUndefined(oper)) m_message->clearParam(oper.name()); else m_message->setParam(new NamedString(oper.name(),oper)); @@ -1019,8 +1019,12 @@ bool JsAssist::init() ExpWrapper wrap(jsm,"message"); chan->runAssign(m_runner->stack(),wrap,m_runner); } - if (jsm && jsm->ref()) + if (jsm && jsm->ref()) { + JsObject* cc = JsObject::buildCallContext(ctx->mutex(),jsm); + ExpEvaluator::pushOne(m_runner->stack(),new ExpWrapper(cc,cc->toString(),true)); + jsm->ref(); ExpEvaluator::pushOne(m_runner->stack(),new ExpWrapper(jsm,"(message)")); + } } if (!m_runner->callable("onLoad")) return true;