Store ExpOperations in JsObjects so the value type is preserved.

Automatically convert database results to numbers if possible.
Added faster method ExpOperation::typeOf()


git-svn-id: http://voip.null.ro/svn/yate@5444 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2013-04-12 12:54:30 +00:00
parent e4c9ce4c9a
commit d8759879e5
5 changed files with 58 additions and 46 deletions

View File

@ -893,13 +893,7 @@ ExpOperation* ExpEvaluator::popOne(ObjList& stack)
}
stack.remove(o,false);
#ifdef DEBUG
#ifdef XDEBUG
Debug(DebugAll,"popOne: %p%s%s",o,
(YOBJECT(ExpFunction,o) ? " function" : ""),
(YOBJECT(ExpWrapper,o) ? " wrapper" : ""));
#else
Debug(DebugAll,"popOne: %p",o);
#endif
Debug(DebugAll,"popOne: %p%s%s",o,(o ? " " : ""),(o ? o->typeOf() : ""));
#endif
return o;
}
@ -916,14 +910,8 @@ ExpOperation* ExpEvaluator::popAny(ObjList& stack)
}
stack.remove(o,false);
#ifdef DEBUG
#ifdef XDEBUG
Debug(DebugAll,"popAny: %p%s%s '%s'",o,
(YOBJECT(ExpFunction,o) ? " function" : ""),
(YOBJECT(ExpWrapper,o) ? " wrapper" : ""),
(o ? o->name().safe() : (const char*)0));
#else
Debug(DebugAll,"popAny: %p '%s'",o,(o ? o->name().safe() : (const char*)0));
#endif
Debug(DebugAll,"popAny: %p%s%s '%s'",o,(o ? " " : ""),
(o ? o->typeOf() : ""),(o ? o->name().safe() : (const char*)0));
#endif
return o;
}
@ -1479,6 +1467,19 @@ bool ExpOperation::valBoolean() const
return isInteger() ? (number() != 0) : !null();
}
const char* ExpOperation::typeOf() const
{
switch (opcode()) {
case ExpEvaluator::OpcPush:
case ExpEvaluator::OpcCopy:
return isInteger() ? "number" : "string";
case ExpEvaluator::OpcFunc:
return "function";
default:
return "internal";
}
}
ExpOperation* ExpOperation::clone(const char* name) const
{
ExpOperation* op = new ExpOperation(*this,name);
@ -1521,6 +1522,17 @@ ExpOperation* ExpWrapper::copy(Mutex* mtx) const
return op;
}
const char* ExpWrapper::typeOf() const
{
switch (opcode()) {
case ExpEvaluator::OpcPush:
case ExpEvaluator::OpcCopy:
return object() ? "object" : "undefined";
default:
return ExpOperation::typeOf();
}
}
bool ExpWrapper::valBoolean() const
{
if (!m_object)

View File

@ -794,7 +794,8 @@ bool JsContext::runStringField(GenObject* obj, const String& name, ObjList& stac
bool JsContext::runAssign(ObjList& stack, const ExpOperation& oper, GenObject* context)
{
XDebug(DebugAll,"JsContext::runAssign '%s'='%s' [%p]",oper.name().c_str(),oper.c_str(),this);
XDebug(DebugAll,"JsContext::runAssign '%s'='%s' (%s) [%p]",
oper.name().c_str(),oper.c_str(),oper.typeOf(),this);
String name = oper.name();
GenObject* o = resolve(stack,name,context);
if (o && o != this) {
@ -1988,25 +1989,7 @@ bool JsCode::runOperation(ObjList& stack, const ExpOperation& oper, GenObject* c
ExpOperation* op = popValue(stack,context);
if (!op)
return gotError("Stack underflow",oper.lineNumber());
switch (op->opcode()) {
case OpcPush:
case OpcCopy:
{
const char* txt = "string";
ExpWrapper* w = YOBJECT(ExpWrapper,op);
if (w)
txt = w->object() ? "object" : "undefined";
else if (op->isInteger())
txt = "number";
pushOne(stack,new ExpOperation(txt));
}
break;
case OpcFunc:
pushOne(stack,new ExpOperation("function"));
break;
default:
pushOne(stack,new ExpOperation("internal"));
}
pushOne(stack,new ExpOperation(op->typeOf()));
TelEngine::destruct(op);
}
break;

View File

@ -312,8 +312,13 @@ bool JsObject::runField(ObjList& stack, const ExpOperation& oper, GenObject* con
ExpWrapper* w = YOBJECT(ExpWrapper,param);
if (w)
ExpEvaluator::pushOne(stack,w->clone(oper.name()));
else
ExpEvaluator::pushOne(stack,new ExpOperation(*param,oper.name(),true));
else {
bool num = true;
ExpOperation* o = YOBJECT(ExpOperation,param);
if (o && !o->isInteger())
num = false;
ExpEvaluator::pushOne(stack,new ExpOperation(*param,oper.name(),num));
}
}
}
else
@ -323,8 +328,8 @@ bool JsObject::runField(ObjList& stack, const ExpOperation& oper, GenObject* con
bool JsObject::runAssign(ObjList& stack, const ExpOperation& oper, GenObject* context)
{
XDebug(DebugAll,"JsObject::runAssign() '%s'='%s' in '%s' [%p]",
oper.name().c_str(),oper.c_str(),toString().c_str(),this);
XDebug(DebugAll,"JsObject::runAssign() '%s'='%s' (%s) in '%s' [%p]",
oper.name().c_str(),oper.c_str(),oper.typeOf(),toString().c_str(),this);
if (frozen()) {
Debug(DebugWarn,"Object '%s' is frozen",toString().c_str());
return false;
@ -341,7 +346,7 @@ bool JsObject::runAssign(ObjList& stack, const ExpOperation& oper, GenObject* co
params().setParam(w->clone(oper.name()));
}
else
params().setParam(new NamedString(oper.name(),oper));
params().setParam(oper.clone());
}
return true;
}

View File

@ -976,6 +976,12 @@ public:
*/
virtual bool valBoolean() const;
/**
* Retrieve the name of the type of the value of this operation
* @return Name of the type of the value
*/
virtual const char* typeOf() const;
/**
* Clone and rename method
* @param name Name of the cloned operation
@ -1085,6 +1091,12 @@ public:
*/
virtual bool valBoolean() const;
/**
* Retrieve the name of the type of the value of this operation
* @return Name of the type of the value
*/
virtual const char* typeOf() const;
/**
* Clone and rename method
* @param name Name of the cloned operation

View File

@ -712,7 +712,7 @@ bool JsMessage::runNative(ObjList& stack, const ExpOperation& oper, GenObject* c
switch (oper.number()) {
case 0:
if (m_message)
ExpEvaluator::pushOne(stack,new ExpOperation(m_message->retValue()));
ExpEvaluator::pushOne(stack,new ExpOperation(m_message->retValue(),0,true));
else
ExpEvaluator::pushOne(stack,JsParser::nullClone());
break;
@ -864,7 +864,7 @@ void JsMessage::getColumn(ObjList& stack, const ExpOperation* col, GenObject* co
for (int r = 1; r <= rows; r++) {
GenObject* o = arr->get(idx,r);
if (o)
jsa->push(new ExpOperation(o->toString()));
jsa->push(new ExpOperation(o->toString(),0,true));
else
jsa->push(JsParser::nullClone());
}
@ -883,7 +883,7 @@ void JsMessage::getColumn(ObjList& stack, const ExpOperation* col, GenObject* co
for (int r = 1; r <= rows; r++) {
GenObject* o = arr->get(c,r);
if (o)
jsa->push(new ExpOperation(o->toString()));
jsa->push(new ExpOperation(o->toString(),*name,true));
else
jsa->push(JsParser::nullClone());
}
@ -914,7 +914,7 @@ void JsMessage::getRow(ObjList& stack, const ExpOperation* row, GenObject* conte
continue;
GenObject* o = arr->get(c,idx);
if (o)
jso->params().setParam(new ExpOperation(o->toString(),*name));
jso->params().setParam(new ExpOperation(o->toString(),*name,true));
else
jso->params().setParam((JsParser::nullClone(*name)));
}
@ -934,7 +934,7 @@ void JsMessage::getRow(ObjList& stack, const ExpOperation* row, GenObject* conte
continue;
GenObject* o = arr->get(c,r);
if (o)
jso->params().setParam(new ExpOperation(o->toString(),*name));
jso->params().setParam(new ExpOperation(o->toString(),*name,true));
else
jso->params().setParam((JsParser::nullClone(*name)));
}
@ -970,7 +970,7 @@ void JsMessage::getResult(ObjList& stack, const ExpOperation& row, const ExpOper
if (c >= 0 && c < cols) {
GenObject* o = arr->get(c,r + 1);
if (o) {
ExpEvaluator::pushOne(stack,new ExpOperation(o->toString()));
ExpEvaluator::pushOne(stack,new ExpOperation(o->toString(),0,true));
return;
}
}