}
}
ScopedValue n(scope, name);
- return throwReferenceError(n);
-}
-
-
-ReturnedValue ExecutionContext::throwError(const ValueRef value)
-{
- return d()->engine->throwException(value);
+ return engine()->throwReferenceError(n);
}
-ReturnedValue ExecutionContext::throwError(const QString &message)
+
- Scope scope(this);
- ScopedValue v(scope, d()->engine->newString(message));
- v = d()->engine->newErrorObject(v);
- return throwError(v);
-}
-
-ReturnedValue ExecutionContext::throwSyntaxError(const QString &message, const QString &fileName, int line, int column)
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newSyntaxErrorObject(message, fileName, line, column));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwSyntaxError(const QString &message)
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newSyntaxErrorObject(message));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwTypeError()
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newTypeErrorObject(QStringLiteral("Type error")));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwTypeError(const QString &message)
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newTypeErrorObject(message));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwUnimplemented(const QString &message)
-{
- Scope scope(this);
- ScopedValue v(scope, d()->engine->newString(QStringLiteral("Unimplemented ") + message));
- v = d()->engine->newErrorObject(v);
- return throwError(v);
-}
-
-ReturnedValue ExecutionContext::catchException(StackTrace *trace)
-{
- return d()->engine->catchException(this, trace);
-}
-
-ReturnedValue ExecutionContext::throwReferenceError(const ValueRef value)
-{
- Scope scope(this);
- Scoped<String> s(scope, value->toString(this));
- QString msg = s->toQString() + QStringLiteral(" is not defined");
- Scoped<Object> error(scope, d()->engine->newReferenceErrorObject(msg));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwReferenceError(const QString &message, const QString &fileName, int line, int column)
-{
- Scope scope(this);
- QString msg = message;
- Scoped<Object> error(scope, d()->engine->newReferenceErrorObject(msg, fileName, line, column));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwRangeError(const ValueRef value)
-{
- Scope scope(this);
- ScopedString s(scope, value->toString(this));
- QString msg = s->toQString() + QStringLiteral(" out of range");
- ScopedObject error(scope, d()->engine->newRangeErrorObject(msg));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwRangeError(const QString &message)
-{
- Scope scope(this);
- ScopedObject error(scope, d()->engine->newRangeErrorObject(message));
- return throwError(error);
-}
++Heap::FunctionObject *ExecutionContext::getFunctionObject() const
+ {
-ReturnedValue ExecutionContext::throwURIError(const ValueRef msg)
-{
- Scope scope(this);
- ScopedObject error(scope, d()->engine->newURIErrorObject(msg));
- return throwError(error);
++ Scope scope(d()->engine);
++ ScopedContext it(scope, this->d());
++ for (; it; it = it->d()->parent) {
++ if (const CallContext *callCtx = it->asCallContext())
++ return callCtx->d()->function;
++ else if (it->asCatchContext() || it->asWithContext())
++ continue; // look in the parent context for a FunctionObject
++ else
++ break;
++ }
+
++ return 0;
+ }
void setProperty(String *name, const ValueRef value);
ReturnedValue getProperty(String *name);
- ReturnedValue getPropertyAndBase(String *name, Object *&base);
+ ReturnedValue getPropertyAndBase(String *name, Heap::Object **base);
bool deleteProperty(String *name);
- // Can only be called from within catch(...), rethrows if no JS exception.
- ReturnedValue catchException(StackTrace *trace = 0);
-
inline CallContext *asCallContext();
inline const CallContext *asCallContext() const;
- inline FunctionObject *getFunctionObject() const;
+ inline const CatchContext *asCatchContext() const;
+ inline const WithContext *asWithContext() const;
+
++ Heap::FunctionObject *getFunctionObject() const;
- static void markObjects(Managed *m, ExecutionEngine *e);
+ static void markObjects(Heap::Base *m, ExecutionEngine *e);
};
struct CallContext : public ExecutionContext
inline const CallContext *ExecutionContext::asCallContext() const
{
- return d()->type >= Type_SimpleCallContext ? static_cast<const CallContext *>(this) : 0;
+ return d()->type >= Heap::ExecutionContext::Type_SimpleCallContext ? static_cast<const CallContext *>(this) : 0;
}
- return d()->type == Type_CatchContext ? static_cast<const CatchContext *>(this) : 0;
+ inline const CatchContext *ExecutionContext::asCatchContext() const
+ {
- return d()->type == Type_WithContext ? static_cast<const WithContext *>(this) : 0;
-}
-
-inline FunctionObject *ExecutionContext::getFunctionObject() const
-{
- for (const ExecutionContext *it = this; it; it = it->d()->parent) {
- if (const CallContext *callCtx = it->asCallContext())
- return callCtx->d()->function;
- else if (it->asCatchContext() || it->asWithContext())
- continue; // look in the parent context for a FunctionObject
- else
- break;
- }
-
- return 0;
-}
-
-inline void ExecutionEngine::pushContext(CallContext *context)
-{
- context->d()->parent = current;
- current = context;
-}
-
-inline ExecutionContext *ExecutionEngine::popContext()
-{
- Q_ASSERT(current->d()->parent);
- current = current->d()->parent;
- return current;
-}
-
-struct ExecutionContextSaver
-{
- ExecutionEngine *engine;
- ExecutionContext *savedContext;
-
- ExecutionContextSaver(ExecutionContext *context)
- : engine(context->d()->engine)
- , savedContext(context)
- {
- }
- ~ExecutionContextSaver()
- {
- engine->current = savedContext;
- }
-};
-
-inline Scope::Scope(ExecutionContext *ctx)
- : engine(ctx->d()->engine)
-#ifndef QT_NO_DEBUG
- , size(0)
-#endif
-{
- mark = engine->jsStackTop;
++ return d()->type == Heap::ExecutionContext::Type_CatchContext ? static_cast<const CatchContext *>(this) : 0;
+ }
+
+ inline const WithContext *ExecutionContext::asWithContext() const
+ {
++ return d()->type == Heap::ExecutionContext::Type_WithContext ? static_cast<const WithContext *>(this) : 0;
+ }
+
/* Function *f, int argc */
#define requiredMemoryForExecutionContect(f, argc) \
((sizeof(CallContext::Data) + 7) & ~7) + sizeof(Value) * (f->varCount() + qMax((uint)argc, f->formalParameterCount())) + sizeof(CallData)
if (m_pauseRequested) { // Serve debugging requests from the agent
m_pauseRequested = false;
pauseAndWait(PauseRequest);
- } else if (m_haveBreakPoints && reallyHitTheBreakPoint(getFunction()->sourceFile(), lineNumber)) {
- pauseAndWait(BreakPoint);
+ } else if (m_haveBreakPoints) {
+ if (Function *f = getFunction()) {
- const int lineNumber = engine()->currentContext()->d()->lineNumber;
++ const int lineNumber = engine()->currentContext()->lineNumber;
+ if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber))
+ pauseAndWait(BreakPoint);
+ }
}
}
Function *Debugger::getFunction() const
{
- ExecutionContext *context = m_engine->currentContext();
- if (const FunctionObject *function = context->getFunctionObject())
+ Scope scope(m_engine);
+ ScopedContext context(scope, m_engine->currentContext());
- if (CallContext *callCtx = context->asCallContext())
- return callCtx->d()->function->function;
- else {
- Q_ASSERT(context->d()->type == QV4::Heap::ExecutionContext::Type_GlobalContext);
++ ScopedFunctionObject function(scope, context->getFunctionObject());
++ if (function)
+ return function->function();
+ else
return context->d()->engine->globalCode;
- }
}
void Debugger::pauseAndWait(PauseReason reason)
ScopedString name(scope);
QVector<StackFrame> stack;
- QV4::ExecutionContext *c = currentContext();
+ ScopedContext c(scope, currentContext());
++ ScopedFunctionObject function(scope);
while (c && frameLimit) {
- CallContext *callCtx = c->asCallContext();
- if (callCtx && callCtx->d()->function) {
- if (FunctionObject *function = c->getFunctionObject()) {
++ function = c->getFunctionObject();
++ if (function) {
StackFrame frame;
- ScopedFunctionObject function(scope, callCtx->d()->function);
- if (function->function())
- frame.source = function->function()->sourceFile();
+ if (const Function *f = function->function())
+ frame.source = f->sourceFile();
name = function->name();
frame.function = name->toQString();
frame.line = -1;
StackFrame frame;
frame.source = globalCode->sourceFile();
frame.function = globalCode->name()->toQString();
- frame.line = rootContext->d()->lineNumber;
+ frame.line = rootContext()->lineNumber;
frame.column = -1;
-
stack.append(frame);
}
return stack;
}
f->call(callData);
- if (scope.hasException() && v4->v8Engine) {
- QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx);
+ if (scope.hasException()) {
++ QQmlError error = v4->catchExceptionAsQmlError();
+ if (error.description().isEmpty()) {
+ QV4::ScopedString name(scope, f->name());
+ error.setDescription(QString::fromLatin1("Unknown exception occurred during evaluation of connected function: %1").arg(name->toQString()));
+ }
- if (QQmlEngine *qmlEngine = v4->v8Engine->engine()) {
+ if (QQmlEngine *qmlEngine = v4->qmlEngine()) {
- QQmlError error = v4->catchExceptionAsQmlError();
- if (error.description().isEmpty()) {
- QV4::ScopedString name(scope, f->name());
- error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(name->toQString()));
- }
QQmlEnginePrivate::get(qmlEngine)->warning(error);
+ } else {
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).warning().noquote()
+ << error.toString();
}
}
}
void main(void)
{
lowp vec4 c = color;
- c.xyz += pow(max(sin(pos.x + pos.y), 0.0), 2.0) * pattern * 0.1;
- c.xyz += pow(max(sin(pos.x + pos.y), 0.0), 2.0) * tweak.z * 0.25;
++ c.xyz += pow(max(sin(pos.x + pos.y), 0.0), 2.0) * pattern * 0.25;
gl_FragColor = c;
}
void privateMethods();
+ void engineForObject();
+ void intConversion_QTBUG43309();
signals:
void testSignal();
}
}
+void tst_QJSEngine::engineForObject()
+{
+ QObject object;
+ {
+ QJSEngine engine;
+ QVERIFY(!qjsEngine(&object));
+ QJSValue wrapper = engine.newQObject(&object);
+ QQmlEngine::setObjectOwnership(&object, QQmlEngine::CppOwnership);
+ QCOMPARE(qjsEngine(&object), wrapper.engine());
+ }
+ QVERIFY(!qjsEngine(&object));
+}
+
+ void tst_QJSEngine::intConversion_QTBUG43309()
+ {
+ // This failed in the interpreter:
+ QJSEngine engine;
+ QString jsCode = "var n = 0.1; var m = (n*255) | 0; m";
+ QJSValue result = engine.evaluate( jsCode );
+ QVERIFY(result.isNumber());
+ QCOMPARE(result.toNumber(), 25.0);
+ }
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"