Properly dump 64 bit JS values for debugging and tracing.

Made possible to dump the linked code for debugging purpose.
Exposed accessors for more properties.


git-svn-id: http://voip.null.ro/svn/yate@5633 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2013-08-30 10:58:23 +00:00
parent e3592f8081
commit cad5b5eb13
3 changed files with 59 additions and 20 deletions

View File

@ -1439,7 +1439,7 @@ void ExpEvaluator::dump(const ExpOperation& oper, String& res) const
case OpcPush:
case OpcCopy:
if (oper.isInteger())
res << (int)oper.number();
res << oper.number();
else
res << "'" << oper << "'";
break;
@ -1447,7 +1447,7 @@ void ExpEvaluator::dump(const ExpOperation& oper, String& res) const
res << oper.name();
break;
case OpcFunc:
res << oper.name() << "(" << (int)oper.number() << ")";
res << oper.name() << "(" << oper.number() << ")";
break;
default:
{
@ -1458,7 +1458,7 @@ void ExpEvaluator::dump(const ExpOperation& oper, String& res) const
res << "[" << oper.opcode() << "]";
}
if (oper.number() && oper.isInteger())
res << "(" << (int)oper.number() << ")";
res << "(" << oper.number() << ")";
}
}
@ -1472,6 +1472,11 @@ void ExpEvaluator::dump(const ObjList& codes, String& res) const
}
}
void ExpEvaluator::dump(String& res) const
{
return dump(m_opcodes,res);
}
int64_t ExpOperation::valInteger() const
{
return isInteger() ? number() : 0;

View File

@ -82,6 +82,11 @@ public:
inline JsCodeFile(const String& file)
: String(file), m_fileTime(0)
{ File::getFileTime(file,m_fileTime); }
inline JsCodeFile(const String& file, unsigned int fTime)
: String(file), m_fileTime(fTime)
{ }
inline unsigned int fileTime() const
{ return m_fileTime; }
inline bool fileChanged() const
{ unsigned int t = 0; return !(File::getFileTime(c_str(),t) && t == m_fileTime); }
private:
@ -163,6 +168,7 @@ public:
virtual bool evaluate(ScriptRun& runner, ObjList& results) const;
virtual ScriptRun* createRunner(ScriptContext* context, const char* title);
virtual bool null() const;
virtual void dump(String& res) const;
bool link();
inline bool traceable() const
{ return m_traceable; }
@ -2723,12 +2729,26 @@ ScriptRun* JsCode::createRunner(ScriptContext* context, const char* title)
return new JsRunner(this,context,title);
}
bool JsCode::null() const
{
return m_linked.null() && !m_opcodes.skipNull();
}
void JsCode::dump(String& res) const
{
if (m_linked.null())
return ExpEvaluator::dump(res);
for (unsigned int i = 0; i < m_linked.length(); i++) {
const ExpOperation* o = static_cast<const ExpOperation*>(m_linked[i]);
if (!o)
continue;
if (res)
res << " ";
ExpEvaluator::dump(*o,res);
}
}
ScriptRun::Status JsRunner::reset(bool init)
{
Status s = ScriptRun::reset(init);
@ -3217,9 +3237,8 @@ void JsCodeStats::dump(Stream& file)
str << "calls=" << cs->callsCount << " "
<< JsCode::getLineNo(cs->calledLine) << "\n";
}
// TODO: properly write microseconds
str << JsCode::getLineNo(ls->lineNumber) << " " << ls->operations << " "
<< (unsigned int)ls->microseconds << "\n";
<< ls->microseconds << "\n";
}
file.writeData(str);
}
@ -3366,11 +3385,13 @@ bool JsParser::parse(const char* text, bool fragment, const char* file, int len)
setCode(0);
return false;
}
DDebug(DebugAll,"Compiled: %s",code->dump().c_str());
DDebug(DebugAll,"Compiled: %s",code->ExpEvaluator::dump().c_str());
code->simplify();
DDebug(DebugAll,"Simplified: %s",code->dump().c_str());
if (m_allowLink)
DDebug(DebugAll,"Simplified: %s",code->ExpEvaluator::dump().c_str());
if (m_allowLink) {
code->link();
DDebug(DebugAll,"Linked: %s",code->ExpEvaluator::dump().c_str());
}
code->trace(m_allowTrace);
return true;
}

View File

@ -409,8 +409,7 @@ public:
* Dump the postfix expression according to current operators dictionary
* @param res Result string representation of operations
*/
inline void dump(String& res) const
{ return dump(m_opcodes,res); }
virtual void dump(String& res) const;
/**
* Dump a list of operations according to current operators dictionary
@ -1019,6 +1018,19 @@ public:
m_opcode(oper), m_number(nonInteger()), m_lineNo(0), m_barrier(barrier)
{ }
/**
* Constructor from components
* @param oper Operation code
* @param name Optional name of the operation or result
* @param value String value of operation
* @param number Integer value
* @param barrier True if the operation is an expression barrier on the stack
*/
inline ExpOperation(ExpEvaluator::Opcode oper, const char* name, const char* value, int64_t number, bool barrier)
: NamedString(name,value),
m_opcode(oper), m_number(number), m_lineNo(0), m_barrier(barrier)
{ }
/**
* Retrieve the code of this operation
* @return Operation code as declared in the expression evaluator
@ -1128,9 +1140,10 @@ public:
* Constructor
* @param name Name of the function
* @param argc Number of arguments expected by function
* @param barrier True if the function is an expression barrier on the stack
*/
inline ExpFunction(const char* name, long int argc = 0)
: ExpOperation(ExpEvaluator::OpcFunc,name,argc)
inline ExpFunction(const char* name, long int argc = 0, bool barrier = false)
: ExpOperation(ExpEvaluator::OpcFunc,name,argc,barrier)
{ if (name) (*this) << "[function " << name << "()]"; }
/**
@ -2185,6 +2198,13 @@ public:
inline int32_t length() const
{ return m_length; }
/**
* Set the internal length to a specific value
* @param len Length of array to set
*/
inline void setLength(int32_t len)
{ m_length = len; }
/**
* Add an item at the end of the array
* @param item Item to add to array
@ -2236,13 +2256,6 @@ protected:
*/
bool runNative(ObjList& stack, const ExpOperation& oper, GenObject* context);
/**
* Set the internal length and the "length" parameter to a specific value
* @param len Length of array to set
*/
inline void setLength(int32_t len)
{ m_length = len; }
private:
bool runNativeSlice(ObjList& stack, const ExpOperation& oper, GenObject* context);
bool runNativeSplice(ObjList& stack, const ExpOperation& oper, GenObject* context);