Add support for generating stack traces to QV4::ExecutionEngine
This makes it possible to remove the v8::StackTrace API Change-Id: I53eee022a1030f0f6bf9a9268ca7cd3d5975724d Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
parent
3bd678c76d
commit
d7f2868e42
|
@ -106,22 +106,22 @@ public Q_SLOTS:
|
|||
|
||||
QQmlV4Handle callerFile(int frameIndex = 0) const
|
||||
{
|
||||
v8::Handle<v8::StackTrace> stacks = v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
|
||||
int count = stacks->GetFrameCount();
|
||||
if (count >= frameIndex + 1) {
|
||||
v8::Handle<v8::StackFrame> frame = stacks->GetFrame(frameIndex + 1);
|
||||
return QQmlV4Handle(frame->GetScriptNameOrSourceURL()->v4Value());
|
||||
}
|
||||
QQmlEngine *engine = qmlEngine(this);
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine->handle());
|
||||
|
||||
QVector<QV4::ExecutionEngine::StackFrame> stack = v4->stackTrace(frameIndex + 1);
|
||||
if (stack.size() > frameIndex)
|
||||
return QQmlV4Handle(QV4::Value::fromString(v4->newString(stack.at(frameIndex).source.url())));
|
||||
return QQmlV4Handle();
|
||||
}
|
||||
int callerLine(int frameIndex = 0) const
|
||||
{
|
||||
v8::Handle<v8::StackTrace> stacks = v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
|
||||
int count = stacks->GetFrameCount();
|
||||
if (count >= frameIndex + 1) {
|
||||
v8::Handle<v8::StackFrame> frame = stacks->GetFrame(frameIndex + 1);
|
||||
return frame->GetLineNumber();
|
||||
}
|
||||
QQmlEngine *engine = qmlEngine(this);
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine->handle());
|
||||
|
||||
QVector<QV4::ExecutionEngine::StackFrame> stack = v4->stackTrace(frameIndex + 1);
|
||||
if (stack.size() > frameIndex)
|
||||
return stack.at(frameIndex).line;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -540,6 +540,44 @@ Object *ExecutionEngine::qmlContextObject() const
|
|||
return static_cast<CallContext *>(ctx)->activation;
|
||||
}
|
||||
|
||||
QVector<ExecutionEngine::StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
|
||||
{
|
||||
QVector<StackFrame> stack;
|
||||
|
||||
QV4::ExecutionContext *c = current;
|
||||
while (c && frameLimit) {
|
||||
if (CallContext *c = c->asCallContext()) {
|
||||
StackFrame frame;
|
||||
frame.source = c->function->function->sourceFile;
|
||||
frame.function = c->function->name->toQString();
|
||||
frame.line = -1;
|
||||
frame.column = -1;
|
||||
stack.append(frame);
|
||||
--frameLimit;
|
||||
}
|
||||
c = c->parent;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
ExecutionEngine::StackFrame ExecutionEngine::currentStackFrame() const
|
||||
{
|
||||
StackFrame frame;
|
||||
frame.line = -1;
|
||||
frame.column = -1;
|
||||
|
||||
QV4::ExecutionContext *c = current;
|
||||
while (c) {
|
||||
if (CallContext *c = c->asCallContext()) {
|
||||
frame.source = c->function->function->sourceFile;
|
||||
frame.function = c->function->name->toQString();
|
||||
return frame;
|
||||
}
|
||||
c = c->parent;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
void ExecutionEngine::requireArgumentsAccessors(int n)
|
||||
{
|
||||
if (n <= argumentsAccessors.size())
|
||||
|
|
|
@ -271,6 +271,15 @@ struct Q_QML_EXPORT ExecutionEngine
|
|||
|
||||
Object *qmlContextObject() const;
|
||||
|
||||
struct StackFrame {
|
||||
QUrl source;
|
||||
QString function;
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
QVector<StackFrame> stackTrace(int frameLimit = -1) const;
|
||||
StackFrame currentStackFrame() const;
|
||||
|
||||
void requireArgumentsAccessors(int n);
|
||||
|
||||
void markObjects();
|
||||
|
|
|
@ -282,78 +282,6 @@ void Script::SetData(Handle<String> data)
|
|||
}
|
||||
|
||||
|
||||
Handle<StackFrame> StackTrace::GetFrame(uint32_t index) const
|
||||
{
|
||||
if (index >= (uint)frames.size())
|
||||
return Handle<StackFrame>();
|
||||
return frames.at(index);
|
||||
}
|
||||
|
||||
int StackTrace::GetFrameCount() const
|
||||
{
|
||||
return frames.size();
|
||||
}
|
||||
|
||||
Handle<Array> StackTrace::AsArray()
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
return Handle<Array>();
|
||||
}
|
||||
|
||||
Handle<StackTrace> StackTrace::CurrentStackTrace(int frame_limit, StackTrace::StackTraceOptions options)
|
||||
{
|
||||
StackTrace *trace = new StackTrace;
|
||||
QV4::ExecutionEngine *engine = currentEngine();
|
||||
QV4::ExecutionContext *current = engine->current;
|
||||
while (current && frame_limit) {
|
||||
if (CallContext *c = current->asCallContext()) {
|
||||
StackFrame *frame = new StackFrame(QV4::Value::fromString(current, c->currentFileName().url()),
|
||||
QV4::Value::fromString(c->function->name),
|
||||
c->currentLineNumber(), 0);
|
||||
trace->frames.append(v8::Handle<v8::StackFrame>(frame));
|
||||
--frame_limit;
|
||||
}
|
||||
current = current->parent;
|
||||
}
|
||||
|
||||
return Handle<StackTrace>(trace);
|
||||
}
|
||||
|
||||
|
||||
int StackFrame::GetLineNumber() const
|
||||
{
|
||||
return m_lineNumber;
|
||||
}
|
||||
|
||||
int StackFrame::GetColumn() const
|
||||
{
|
||||
return m_columnNumber;
|
||||
}
|
||||
|
||||
Handle<String> StackFrame::GetScriptName() const
|
||||
{
|
||||
return m_scriptName.value();
|
||||
}
|
||||
|
||||
Handle<String> StackFrame::GetScriptNameOrSourceURL() const
|
||||
{
|
||||
return m_scriptName.value();
|
||||
}
|
||||
|
||||
Handle<String> StackFrame::GetFunctionName() const
|
||||
{
|
||||
return m_functionName.value();
|
||||
}
|
||||
|
||||
StackFrame::StackFrame(Handle<String> script, Handle<String> function, int line, int column)
|
||||
: m_lineNumber(line)
|
||||
, m_columnNumber(column)
|
||||
{
|
||||
m_scriptName = script->v4Value();
|
||||
m_functionName = function->v4Value();
|
||||
}
|
||||
|
||||
|
||||
bool Value::IsUndefined() const
|
||||
{
|
||||
return ConstValuePtr(this)->isUndefined();
|
||||
|
|
|
@ -122,8 +122,6 @@ class FunctionTemplate;
|
|||
class ObjectTemplate;
|
||||
class Data;
|
||||
class AccessorInfo;
|
||||
class StackTrace;
|
||||
class StackFrame;
|
||||
class Isolate;
|
||||
class TryCatch;
|
||||
|
||||
|
@ -554,114 +552,6 @@ private:
|
|||
|
||||
DEFINE_REFCOUNTED_HANDLE_OPERATIONS(Script)
|
||||
|
||||
/**
|
||||
* Representation of a JavaScript stack trace. The information collected is a
|
||||
* snapshot of the execution stack and the information remains valid after
|
||||
* execution continues.
|
||||
*/
|
||||
class V8EXPORT StackTrace : public QSharedData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Flags that determine what information is placed captured for each
|
||||
* StackFrame when grabbing the current stack trace.
|
||||
*/
|
||||
enum StackTraceOptions {
|
||||
kLineNumber = 1,
|
||||
kColumnOffset = 1 << 1 | kLineNumber,
|
||||
kScriptName = 1 << 2,
|
||||
kFunctionName = 1 << 3,
|
||||
kIsEval = 1 << 4,
|
||||
kIsConstructor = 1 << 5,
|
||||
kScriptNameOrSourceURL = 1 << 6,
|
||||
kOverview = kLineNumber | kColumnOffset | kScriptName | kFunctionName,
|
||||
kDetailed = kOverview | kIsEval | kIsConstructor | kScriptNameOrSourceURL
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a StackFrame at a particular index.
|
||||
*/
|
||||
Handle<StackFrame> GetFrame(uint32_t index) const;
|
||||
|
||||
/**
|
||||
* Returns the number of StackFrames.
|
||||
*/
|
||||
int GetFrameCount() const;
|
||||
|
||||
/**
|
||||
* Returns StackTrace as a v8::Array that contains StackFrame objects.
|
||||
*/
|
||||
Handle<Array> AsArray();
|
||||
|
||||
/**
|
||||
* Grab a snapshot of the current JavaScript execution stack.
|
||||
*
|
||||
* \param frame_limit The maximum number of stack frames we want to capture.
|
||||
* \param options Enumerates the set of things we will capture for each
|
||||
* StackFrame.
|
||||
*/
|
||||
static Handle<StackTrace> CurrentStackTrace(
|
||||
int frame_limit,
|
||||
StackTraceOptions options = kOverview);
|
||||
|
||||
private:
|
||||
QVector<Handle<StackFrame> > frames;
|
||||
};
|
||||
|
||||
DEFINE_REFCOUNTED_HANDLE_OPERATIONS(StackTrace)
|
||||
|
||||
|
||||
/**
|
||||
* A single JavaScript stack frame.
|
||||
*/
|
||||
class V8EXPORT StackFrame : public QSharedData {
|
||||
public:
|
||||
/**
|
||||
* Returns the number, 1-based, of the line for the associate function call.
|
||||
* This method will return Message::kNoLineNumberInfo if it is unable to
|
||||
* retrieve the line number, or if kLineNumber was not passed as an option
|
||||
* when capturing the StackTrace.
|
||||
*/
|
||||
int GetLineNumber() const;
|
||||
|
||||
/**
|
||||
* Returns the 1-based column offset on the line for the associated function
|
||||
* call.
|
||||
* This method will return Message::kNoColumnInfo if it is unable to retrieve
|
||||
* the column number, or if kColumnOffset was not passed as an option when
|
||||
* capturing the StackTrace.
|
||||
*/
|
||||
int GetColumn() const;
|
||||
|
||||
/**
|
||||
* Returns the name of the resource that contains the script for the
|
||||
* function for this StackFrame.
|
||||
*/
|
||||
Handle<String> GetScriptName() const;
|
||||
|
||||
/**
|
||||
* Returns the name of the resource that contains the script for the
|
||||
* function for this StackFrame or sourceURL value if the script name
|
||||
* is undefined and its source ends with //@ sourceURL=... string.
|
||||
*/
|
||||
Handle<String> GetScriptNameOrSourceURL() const;
|
||||
|
||||
/**
|
||||
* Returns the name of the function associated with this stack frame.
|
||||
*/
|
||||
Handle<String> GetFunctionName() const;
|
||||
|
||||
private:
|
||||
friend class StackTrace;
|
||||
StackFrame(Handle<String> script, Handle<String> function, int line, int column);
|
||||
int m_lineNumber;
|
||||
int m_columnNumber;
|
||||
QV4::PersistentValue m_scriptName;
|
||||
QV4::PersistentValue m_functionName;
|
||||
};
|
||||
|
||||
DEFINE_REFCOUNTED_HANDLE_OPERATIONS(StackFrame)
|
||||
|
||||
// --- Value ---
|
||||
|
||||
|
||||
|
|
|
@ -74,39 +74,22 @@ enum ConsoleLogTypes {
|
|||
Error
|
||||
};
|
||||
|
||||
static void jsContext(QString &file, int *line, QString &function) {
|
||||
v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1);
|
||||
if (stackTrace->GetFrameCount()) {
|
||||
v8::Handle<v8::StackFrame> frame = stackTrace->GetFrame(0);
|
||||
file = frame->GetScriptName()->v4Value().toQString();
|
||||
*line = frame->GetLineNumber();
|
||||
function = frame->GetFunctionName()->v4Value().toQString();
|
||||
}
|
||||
}
|
||||
static QString jsStack(QV4::ExecutionEngine *engine) {
|
||||
QString stack;
|
||||
|
||||
static QString jsStack() {
|
||||
QStringList stackFrames;
|
||||
QVector<QV4::ExecutionEngine::StackFrame> stackTrace = engine->stackTrace(10);
|
||||
|
||||
//The v8 default is currently 10 stack frames.
|
||||
v8::Handle<v8::StackTrace> stackTrace =
|
||||
v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview);
|
||||
int stackCount = stackTrace->GetFrameCount();
|
||||
|
||||
for (int i = 0; i < stackCount; i++) {
|
||||
v8::Handle<v8::StackFrame> frame = stackTrace->GetFrame(i);
|
||||
v8::Handle<v8::String> function(frame->GetFunctionName());
|
||||
v8::Handle<v8::String> script(frame->GetScriptName());
|
||||
int lineNumber = frame->GetLineNumber();
|
||||
int columnNumber = frame->GetColumn();
|
||||
for (int i = 0; i < stackTrace.count(); i++) {
|
||||
const QV4::ExecutionEngine::StackFrame &frame = stackTrace.at(i);
|
||||
|
||||
QString stackFrame =
|
||||
QString::fromLatin1("%1 (%2:%3:%4)").arg(function->v4Value().asString()->toQString(),
|
||||
script->v4Value().asString()->toQString(),
|
||||
QString::number(lineNumber),
|
||||
QString::number(columnNumber));
|
||||
stackFrames.append(stackFrame);
|
||||
QString::fromLatin1("%1 (%2:%3:%4)\n").arg(frame.function,
|
||||
frame.source.url(),
|
||||
QString::number(frame.line),
|
||||
QString::number(frame.column));
|
||||
stack += stackFrame;
|
||||
}
|
||||
return stackFrames.join(QLatin1String("\n"));
|
||||
return stack;
|
||||
}
|
||||
|
||||
QV4::Value console(ConsoleLogTypes logType, const v8::Arguments &args,
|
||||
|
@ -114,6 +97,8 @@ QV4::Value console(ConsoleLogTypes logType, const v8::Arguments &args,
|
|||
{
|
||||
QString result;
|
||||
QV8Engine *engine = V8ENGINE();
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
||||
|
||||
for (int i = 0; i < args.Length(); ++i) {
|
||||
if (i != 0)
|
||||
result.append(QLatin1Char(' '));
|
||||
|
@ -124,16 +109,11 @@ QV4::Value console(ConsoleLogTypes logType, const v8::Arguments &args,
|
|||
|
||||
if (printStack) {
|
||||
result.append(QLatin1String("\n"));
|
||||
result.append(jsStack());
|
||||
result.append(jsStack(v4));
|
||||
}
|
||||
|
||||
QString file;
|
||||
QString function;
|
||||
int line;
|
||||
|
||||
jsContext(file, &line, function);
|
||||
|
||||
QMessageLogger logger(file.toUtf8().constData(), line, function.toUtf8().constData());
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
QMessageLogger logger(frame.source.url().toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
|
||||
switch (logType) {
|
||||
case Log:
|
||||
logger.debug("%s", qPrintable(result));
|
||||
|
@ -180,15 +160,11 @@ QV4::Value consoleProfile(const v8::Arguments &args)
|
|||
//we do not allow that. Hence, we pass an empty(default) title
|
||||
Q_UNUSED(args);
|
||||
QString title;
|
||||
QV8Engine *engine = V8ENGINE();
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
||||
|
||||
|
||||
|
||||
QString file;
|
||||
QString function;
|
||||
int line;
|
||||
jsContext(file, &line, function);
|
||||
|
||||
QMessageLogger logger(file.toUtf8().constData(), line, function.toUtf8().constData());
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
QMessageLogger logger(frame.source.url().toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
|
||||
if (QQmlProfilerService::startProfiling()) {
|
||||
QV8ProfilerService::instance()->startProfiling(title);
|
||||
|
||||
|
@ -208,12 +184,11 @@ QV4::Value consoleProfileEnd(const v8::Arguments &args)
|
|||
Q_UNUSED(args);
|
||||
QString title;
|
||||
|
||||
QString file;
|
||||
QString function;
|
||||
int line;
|
||||
jsContext(file, &line, function);
|
||||
QV8Engine *engine = V8ENGINE();
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
||||
|
||||
QMessageLogger logger(file.toUtf8().constData(), line, function.toUtf8().constData());
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
QMessageLogger logger(frame.source.url().toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
|
||||
|
||||
if (QQmlProfilerService::stopProfiling()) {
|
||||
QV8ProfilerService *profiler = QV8ProfilerService::instance();
|
||||
|
@ -258,23 +233,16 @@ QV4::Value consoleCount(const v8::Arguments &args)
|
|||
if (args.Length() > 0)
|
||||
name = args[0]->v4Value().toQString();
|
||||
|
||||
v8::Handle<v8::StackTrace> stackTrace =
|
||||
v8::StackTrace::CurrentStackTrace(1, v8::StackTrace::kOverview);
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(V8ENGINE());
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
|
||||
if (stackTrace->GetFrameCount()) {
|
||||
v8::Handle<v8::StackFrame> frame = stackTrace->GetFrame(0);
|
||||
QString scriptName = frame.source.url();
|
||||
|
||||
QString scriptName = frame->GetScriptName()->v4Value().toQString();
|
||||
QString functionName = frame->GetFunctionName()->v4Value().toQString();
|
||||
int line = frame->GetLineNumber();
|
||||
int column = frame->GetColumn();
|
||||
int value = V8ENGINE()->consoleCountHelper(scriptName, frame.line, frame.column);
|
||||
QString message = name + QLatin1String(": ") + QString::number(value);
|
||||
|
||||
int value = V8ENGINE()->consoleCountHelper(scriptName, line, column);
|
||||
QString message = name + QLatin1String(": ") + QString::number(value);
|
||||
|
||||
QMessageLogger(qPrintable(scriptName), line,
|
||||
qPrintable(functionName)).debug("%s", qPrintable(message));
|
||||
}
|
||||
QMessageLogger(qPrintable(scriptName), frame.line,
|
||||
qPrintable(frame.function)).debug("%s", qPrintable(message));
|
||||
|
||||
return QV4::Value::undefinedValue();
|
||||
}
|
||||
|
@ -284,14 +252,13 @@ QV4::Value consoleTrace(const v8::Arguments &args)
|
|||
if (args.Length() != 0)
|
||||
V4THROW_ERROR("console.trace(): Invalid arguments");
|
||||
|
||||
QString stack = jsStack();
|
||||
QV8Engine *engine = V8ENGINE();
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
||||
|
||||
QString file;
|
||||
QString function;
|
||||
int line;
|
||||
jsContext(file, &line, function);
|
||||
QString stack = jsStack(v4);
|
||||
|
||||
QMessageLogger logger(file.toUtf8().constData(), line, function.toUtf8().constData());
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
QMessageLogger logger(frame.source.url().toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
|
||||
|
||||
logger.debug("%s", qPrintable(stack));
|
||||
return QV4::Value::undefinedValue();
|
||||
|
@ -307,6 +274,9 @@ QV4::Value consoleAssert(const v8::Arguments &args)
|
|||
if (args.Length() == 0)
|
||||
V4THROW_ERROR("console.assert(): Missing argument");
|
||||
|
||||
QV8Engine *engine = V8ENGINE();
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
||||
|
||||
if (!args[0]->v4Value().booleanValue()) {
|
||||
QString message;
|
||||
for (int i = 1; i < args.Length(); ++i) {
|
||||
|
@ -317,14 +287,10 @@ QV4::Value consoleAssert(const v8::Arguments &args)
|
|||
message.append(value->v4Value().toQString());
|
||||
}
|
||||
|
||||
QString stack = jsStack();
|
||||
QString stack = jsStack(v4);
|
||||
|
||||
QString file;
|
||||
QString function;
|
||||
int line;
|
||||
jsContext(file, &line, function);
|
||||
|
||||
QMessageLogger logger(file.toUtf8().constData(), line, function.toUtf8().constData());
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
QMessageLogger logger(frame.source.url().toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
|
||||
logger.critical("%s\n%s", qPrintable(message), qPrintable(stack));
|
||||
|
||||
}
|
||||
|
|
|
@ -619,15 +619,11 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert
|
|||
QQmlContextData *context = engine->callingContext();
|
||||
v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
|
||||
|
||||
v8::Handle<v8::StackTrace> trace =
|
||||
v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber |
|
||||
v8::StackTrace::kScriptName));
|
||||
v8::Handle<v8::StackFrame> frame = trace->GetFrame(0);
|
||||
int lineNumber = frame->GetLineNumber();
|
||||
int columnNumber = frame->GetColumn();
|
||||
QString url = frame->GetScriptName()->v4Value().toQString();
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
|
||||
newBinding = new QQmlBinding(&function, object, context, url, qmlSourceCoordinate(lineNumber), qmlSourceCoordinate(columnNumber));
|
||||
newBinding = new QQmlBinding(&function, object, context, frame.source.url(),
|
||||
qmlSourceCoordinate(frame.line), qmlSourceCoordinate(frame.column));
|
||||
newBinding->setTarget(object, *property, context);
|
||||
newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
|
||||
QQmlBinding::RequiresThisObject);
|
||||
|
|
|
@ -392,17 +392,11 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Handle<v8::String> propert
|
|||
cacheData.valueTypeCoreIndex = index;
|
||||
cacheData.valueTypePropType = p.userType();
|
||||
|
||||
v8::Handle<v8::StackTrace> trace =
|
||||
v8::StackTrace::CurrentStackTrace(1,
|
||||
(v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber |
|
||||
v8::StackTrace::kScriptName));
|
||||
v8::Handle<v8::StackFrame> frame = trace->GetFrame(0);
|
||||
int lineNumber = frame->GetLineNumber();
|
||||
int columnNumber = frame->GetColumn();
|
||||
QString url = frame->GetScriptName()->v4Value().toQString();
|
||||
QV4::ExecutionEngine *v4 = QV8Engine::getV4(r->engine);
|
||||
QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
|
||||
|
||||
newBinding = new QQmlBinding(&function, reference->object, context,
|
||||
url, qmlSourceCoordinate(lineNumber), qmlSourceCoordinate(columnNumber));
|
||||
frame.source.url(), qmlSourceCoordinate(frame.line), qmlSourceCoordinate(frame.column));
|
||||
newBinding->setTarget(reference->object, cacheData, context);
|
||||
newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
|
||||
QQmlBinding::RequiresThisObject);
|
||||
|
|
Loading…
Reference in New Issue