summaryrefslogtreecommitdiffstats
path: root/src/script
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-06-23 11:27:33 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-06-23 11:27:33 (GMT)
commit4d3b9fd00e331ef913c375634242915e9e235e3d (patch)
treef678852d4b18f6ae6e2c0d88fb4590b78db4c4d8 /src/script
parentfae12fe2c37f0c849af9eed0e8f54a454be85922 (diff)
downloadQt-4d3b9fd00e331ef913c375634242915e9e235e3d.zip
Qt-4d3b9fd00e331ef913c375634242915e9e235e3d.tar.gz
Qt-4d3b9fd00e331ef913c375634242915e9e235e3d.tar.bz2
make most of the qscriptvalue tests pass
call(), construct() etc.
Diffstat (limited to 'src/script')
-rw-r--r--src/script/api/qscriptengine.cpp11
-rw-r--r--src/script/api/qscriptvalue.cpp207
-rw-r--r--src/script/api/qscriptvalue_p.h2
-rw-r--r--src/script/bridge/qscriptfunction.cpp8
-rw-r--r--src/script/bridge/qscriptvariant_p.h2
5 files changed, 153 insertions, 77 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 857019e..f4ff4b5 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -842,8 +842,8 @@ QScriptValue QScriptEngine::newRegExp(const QRegExp &regexp)
if (regexp.caseSensitivity() == Qt::CaseInsensitive)
flags.append(QLatin1Char('i'));
JSC::UString jscFlags = QScript::qtStringToJSCUString(flags);
- buf[0] = JSC::jsNontrivialString(exec, jscPattern);
- buf[1] = JSC::jsNontrivialString(exec, jscFlags);
+ buf[0] = JSC::jsString(exec, jscPattern);
+ buf[1] = JSC::jsString(exec, jscFlags);
JSC::JSObject* result = JSC::constructRegExp(exec, args);
return d->scriptValueFromJSCValue(result);
}
@@ -1128,8 +1128,8 @@ QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &fla
JSC::ArgList args(buf, sizeof(buf));
JSC::UString jscPattern = QScript::qtStringToJSCUString(pattern);
JSC::UString jscFlags = QScript::qtStringToJSCUString(flags);
- buf[0] = JSC::jsNontrivialString(exec, jscPattern);
- buf[1] = JSC::jsNontrivialString(exec, jscFlags);
+ buf[0] = JSC::jsString(exec, jscPattern);
+ buf[1] = JSC::jsString(exec, jscFlags);
JSC::JSObject* result = JSC::constructRegExp(exec, args);
return d->scriptValueFromJSCValue(result);
}
@@ -1332,6 +1332,7 @@ QScriptValue QScriptEngine::evaluate(const QString &program, const QString &file
JSC::UString jscFileName = QScript::qtStringToJSCUString(fileName);
JSC::ExecState* exec = d->globalObject->globalExec();
+ exec->clearException();
JSC::Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(),
JSC::makeSource(jscProgram, jscFileName, lineNumber));
if ((comp.complType() == JSC::Normal) || (comp.complType() == JSC::ReturnValue)) {
@@ -1801,7 +1802,7 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
#endif
if (value.isVariant() && name.endsWith('*')) {
int valueType = QMetaType::type(name.left(name.size()-1));
- QVariant var = value.toVariant();
+ QVariant &var = QScriptValuePrivate::get(value)->variantValue();
if (valueType == var.userType()) {
*reinterpret_cast<void* *>(ptr) = var.data();
return true;
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index c2b4bd4..41c908d 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -342,6 +342,11 @@ QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const
return eng_p->scriptValueFromJSCValue(result);
}
+QVariant &QScriptValuePrivate::variantValue() const
+{
+ return static_cast<QScript::QVariantWrapperObject*>(JSC::asObject(jscValue))->value();
+}
+
/*!
Constructs an invalid QScriptValue.
*/
@@ -821,8 +826,13 @@ void QScriptValue::setScope(const QScriptValue &scope)
QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine);
JSC::JSValue other = eng_p->scriptValueToJSCValue(scope);
JSC::ExecState *exec = eng_p->globalObject->globalExec();
- // ### make hidden property
- JSC::asObject(d->jscValue)->putDirect(JSC::Identifier(exec, "__qt_scope__"), other);
+ JSC::Identifier id = JSC::Identifier(exec, "__qt_scope__");
+ if (!scope.isValid()) {
+ JSC::asObject(d->jscValue)->removeDirect(id);
+ } else {
+ // ### make hidden property
+ JSC::asObject(d->jscValue)->putDirect(id, other);
+ }
}
/*!
@@ -1076,11 +1086,8 @@ bool QScriptValue::equals(const QScriptValue &other) const
eng_p = QScriptEnginePrivate::get(other.d_ptr->engine);
if (eng_p) {
JSC::ExecState *exec = eng_p->globalObject->globalExec();
- Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
-#if 0
- if (JSC::equal(exec, d->jscValue, other.d_ptr->jscValue))
+ if (JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue))
return true;
-#endif
}
}
return QScript::Equals(*this, other);
@@ -1406,7 +1413,7 @@ QVariant QScriptValue::toVariant() const
case QScriptValuePrivate::JSC:
if (isObject()) {
if (isVariant())
- return static_cast<QScript::QVariantWrapperObject*>(JSC::asObject(d->jscValue))->value();
+ return d->variantValue();
#ifndef QT_NO_QOBJECT
else if (isQObject())
return qVariantFromValue(toQObject());
@@ -1833,22 +1840,47 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject,
Q_D(const QScriptValue);
if (!isFunction())
return QScriptValue();
+
+ if (thisObject.engine() && (thisObject.engine() != engine())) {
+ qWarning("QScriptValue::call() failed: "
+ "cannot call function with thisObject created in "
+ "a different engine");
+ return QScriptValue();
+ }
+
QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine);
JSC::ExecState *exec = eng_p->globalObject->globalExec();
- JSC::ArgList jscArgs;
- for (int i = 0; i < args.size(); ++i) {
- Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
-#if 0
- if (!args.at(i).isValid())
- jscArgs.append(JSC::jsUndefined());
- else
- jscArgs.append(eng_p->scriptValueToJSCValue(args.at(i)));
-#endif
- }
+
JSC::JSValue jscThisObject = eng_p->scriptValueToJSCValue(thisObject);
if (!jscThisObject || !jscThisObject.isObject())
jscThisObject = eng_p->globalObject;
- JSC::JSValue result = JSC::asFunction(d->jscValue)->call(exec, jscThisObject, jscArgs);
+
+ QVector<JSC::JSValue> argsVector;
+ argsVector.resize(args.size());
+ for (int i = 0; i < args.size(); ++i) {
+ const QScriptValue &arg = args.at(i);
+ if (!arg.isValid()) {
+ argsVector[i] = JSC::jsUndefined();
+ } else if (arg.engine() && (arg.engine() != engine())) {
+ qWarning("QScriptValue::call() failed: "
+ "cannot call function with argument created in "
+ "a different engine");
+ return QScriptValue();
+ } else {
+ argsVector[i] = eng_p->scriptValueToJSCValue(arg);
+ }
+ }
+ JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
+
+ JSC::JSValue callee = d->jscValue;
+ JSC::JSValue result;
+ JSC::CallData callData;
+ JSC::CallType callType = callee.getCallData(callData);
+ if (callType == JSC::CallTypeJS) {
+ result = JSC::asFunction(callee)->call(exec, jscThisObject, jscArgs);
+ } else if (callType == JSC::CallTypeHost) {
+ result = callData.native.function(exec, JSC::asObject(callee), jscThisObject, jscArgs);
+ }
if (exec->hadException())
result = exec->exception();
return eng_p->scriptValueFromJSCValue(result);
@@ -1883,6 +1915,14 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject,
Q_D(QScriptValue);
if (!isFunction())
return QScriptValue();
+
+ if (thisObject.engine() && (thisObject.engine() != engine())) {
+ qWarning("QScriptValue::call() failed: "
+ "cannot call function with thisObject created in "
+ "a different engine");
+ return QScriptValue();
+ }
+
QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine);
JSC::ExecState *exec = eng_p->globalObject->globalExec();
@@ -1890,32 +1930,39 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject,
if (!jscThisObject || !jscThisObject.isObject())
jscThisObject = eng_p->globalObject;
- Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
-#if 0
- // copied from kjs/FunctionPrototype.cpp, functionProtoFuncApply()
- JSC::JSValue argArray = eng_p->scriptValueToJSCValue(arguments);
- JSC::ArgList applyArgs;
- if (!argArray.isUndefinedOrNull()) {
- if (argArray.isObject()) {
- if (static_cast<JSC::JSObject*>(argArray.getObject())->classInfo() == &JSC::Arguments::info)
- static_cast<JSC::Arguments*>(asArguments(argArray))->fillArgList(exec, applyArgs);
- else if (exec->interpreter()->isJSArray(argArray))
- static_cast<JSC::JSArray*>(JSC::asArray(argArray))->fillArgList(exec, applyArgs);
- else if (static_cast<JSC::JSObject*>(argArray.getObject())->inherits(&JSC::JSArray::info)) {
- unsigned length = static_cast<JSC::JSObject*>(argArray.getObject())->get(exec, exec->propertyNames().length)->toUInt32(exec);
- for (unsigned i = 0; i < length; ++i)
- applyArgs.append(static_cast<JSC::JSObject*>(argArray.getObject())->get(exec, i));
- } else
- return QScriptValue(); // ### throwError(exec, TypeError);
- } else
- return QScriptValue(); // ### throwError(exec, TypeError);
+ JSC::JSValue array = eng_p->scriptValueToJSCValue(arguments);
+ // copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply()
+ JSC::MarkedArgumentBuffer applyArgs;
+ if (!array.isUndefinedOrNull()) {
+ if (!array.isObject()) {
+ return eng_p->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError));
+ }
+ if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info)
+ JSC::asArguments(array)->fillArgList(exec, applyArgs);
+ else if (JSC::isJSArray(&exec->globalData(), array))
+ JSC::asArray(array)->fillArgList(exec, applyArgs);
+ else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) {
+ unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
+ for (unsigned i = 0; i < length; ++i)
+ applyArgs.append(JSC::asArray(array)->get(exec, i));
+ } else {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
+// return JSC::throwError(exec, JSC::TypeError);
+ }
}
- JSC::JSValue result = static_cast<JSC::JSFunction*>(asFunction(d->jscValue))->call(exec, jscThisObject, applyArgs);
+ JSC::JSValue callee = d->jscValue;
+ JSC::JSValue result;
+ JSC::CallData callData;
+ JSC::CallType callType = callee.getCallData(callData);
+ if (callType == JSC::CallTypeJS) {
+ result = JSC::asFunction(callee)->call(exec, jscThisObject, applyArgs);
+ } else if (callType == JSC::CallTypeHost) {
+ result = callData.native.function(exec, JSC::asObject(callee), jscThisObject, applyArgs);
+ }
if (exec->hadException())
result = exec->exception();
return eng_p->scriptValueFromJSCValue(result);
-#endif
}
/*!
@@ -1943,17 +1990,26 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args)
return QScriptValue();
QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine);
JSC::ExecState *exec = eng_p->globalObject->globalExec();
- JSC::ArgList jscArgs;
+
+ QVector<JSC::JSValue> argsVector;
+ argsVector.resize(args.size());
for (int i = 0; i < args.size(); ++i) {
-#if 0
- Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
if (!args.at(i).isValid())
- jscArgs.append(JSC::jsUndefined());
+ argsVector[i] = JSC::jsUndefined();
else
- jscArgs.append(eng_p->scriptValueToJSCValue(args.at(i)));
-#endif
+ argsVector[i] = eng_p->scriptValueToJSCValue(args.at(i));
+ }
+ JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
+
+ JSC::JSValue callee = d->jscValue;
+ JSC::JSValue result;
+ JSC::ConstructData constructData;
+ JSC::ConstructType constructType = callee.getConstructData(constructData);
+ if (constructType == JSC::ConstructTypeJS) {
+ result = JSC::asFunction(callee)->construct(exec, jscArgs);
+ } else if (constructType == JSC::ConstructTypeHost) {
+ result = constructData.native.function(exec, JSC::asObject(callee), jscArgs);
}
- JSC::JSValue result = JSC::asFunction(d->jscValue)->construct(exec, jscArgs);
if (exec->hadException())
result = exec->exception();
return eng_p->scriptValueFromJSCValue(result);
@@ -1982,32 +2038,40 @@ QScriptValue QScriptValue::construct(const QScriptValue &arguments)
QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine);
JSC::ExecState *exec = eng_p->globalObject->globalExec();
- Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
-#if 0
- // copied from kjs/FunctionPrototype.cpp, functionProtoFuncApply()
- JSC::JSValue argArray = eng_p->scriptValueToJSCValue(arguments);
- JSC::ArgList applyArgs;
- if (!argArray.isUndefinedOrNull()) {
- if (argArray.isObject()) {
- if (static_cast<JSC::JSObject*>(argArray.getObject())->classInfo() == &JSC::Arguments::info)
- static_cast<JSC::Arguments*>(JSC::asArguments(argArray))->fillArgList(exec, applyArgs);
- else if (exec->interpreter()->isJSArray(argArray))
- static_cast<JSC::JSArray*>(JSC::asArray(argArray))->fillArgList(exec, applyArgs);
- else if (static_cast<JSC::JSObject*>(argArray.getObject())->inherits(&JSC::JSArray::info)) {
- unsigned length = static_cast<JSC::JSObject*>(argArray.getObject())->get(exec, exec->propertyNames().length)->toUInt32(exec);
- for (unsigned i = 0; i < length; ++i)
- applyArgs.append(static_cast<JSC::JSObject*>(argArray.getObject())->get(exec, i));
- } else
- return QScriptValue(); // ### throwError(exec, TypeError);
- } else
- return QScriptValue(); // ### throwError(exec, TypeError);
+ JSC::JSValue array = eng_p->scriptValueToJSCValue(arguments);
+ // copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply()
+ JSC::MarkedArgumentBuffer applyArgs;
+ if (!array.isUndefinedOrNull()) {
+ if (!array.isObject()) {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
+// return JSC::throwError(exec, JSC::TypeError);
+ }
+ if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info)
+ JSC::asArguments(array)->fillArgList(exec, applyArgs);
+ else if (JSC::isJSArray(&exec->globalData(), array))
+ JSC::asArray(array)->fillArgList(exec, applyArgs);
+ else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) {
+ unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
+ for (unsigned i = 0; i < length; ++i)
+ applyArgs.append(JSC::asArray(array)->get(exec, i));
+ } else {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
+// return JSC::throwError(exec, JSC::TypeError);
+ }
}
- JSC::JSValue result = JSC::asFunction(d->jscValue)->construct(exec, applyArgs);
+ JSC::JSValue callee = d->jscValue;
+ JSC::JSValue result;
+ JSC::ConstructData constructData;
+ JSC::ConstructType constructType = callee.getConstructData(constructData);
+ if (constructType == JSC::ConstructTypeJS) {
+ result = JSC::asFunction(callee)->construct(exec, applyArgs);
+ } else if (constructType == JSC::ConstructTypeHost) {
+ result = constructData.native.function(exec, JSC::asObject(callee), applyArgs);
+ }
if (exec->hadException())
result = exec->exception();
return eng_p->scriptValueFromJSCValue(result);
-#endif
}
/*!
@@ -2236,8 +2300,13 @@ void QScriptValue::setData(const QScriptValue &data)
QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(d->engine);
JSC::JSValue other = eng_p->scriptValueToJSCValue(data);
JSC::ExecState *exec = eng_p->globalObject->globalExec();
- // ### make hidden property
- JSC::asObject(d->jscValue)->putDirect(JSC::Identifier(exec, "__qt_data__"), other);
+ JSC::Identifier id = JSC::Identifier(exec, "__qt_data__");
+ if (!data.isValid()) {
+ JSC::asObject(d->jscValue)->removeDirect(id);
+ } else {
+ // ### make hidden property
+ JSC::asObject(d->jscValue)->putDirect(id, other);
+ }
}
/*!
diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h
index 31230a6..57c9bfd 100644
--- a/src/script/api/qscriptvalue_p.h
+++ b/src/script/api/qscriptvalue_p.h
@@ -57,6 +57,8 @@ public:
bool isJSC() const;
+ QVariant &variantValue() const;
+
static QScriptValuePrivate *get(const QScriptValue &q);
QScriptValue property(const QString &name, int resolveMode) const;
diff --git a/src/script/bridge/qscriptfunction.cpp b/src/script/bridge/qscriptfunction.cpp
index fd51df1..9634ea7 100644
--- a/src/script/bridge/qscriptfunction.cpp
+++ b/src/script/bridge/qscriptfunction.cpp
@@ -59,6 +59,8 @@ JSC::JSValue FunctionWrapper::proxyCall(JSC::ExecState *, JSC::JSObject *callee,
/*calledAsConstructor=*/false, eng_p);
QScriptContext *ctx = QScriptContextPrivate::create(ctx_p);
QScriptValue result = self->data->function(ctx, self->data->engine);
+ if (!result.isValid())
+ result = QScriptValue(QScriptValue::UndefinedValue);
delete ctx;
return eng_p->scriptValueToJSCValue(result);
}
@@ -73,10 +75,12 @@ JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *, JSC::JSObject *
args, /*calledAsConstructor=*/true, eng_p);
QScriptContext *ctx = QScriptContextPrivate::create(ctx_p);
QScriptValue result = self->data->function(ctx, self->data->engine);
+ if (!result.isValid())
+ result = QScriptValue(QScriptValue::UndefinedValue);
delete ctx;
if (result.isObject())
- return static_cast<JSC::JSObject*>(JSC::asObject(eng_p->scriptValueToJSCValue(result)));
- return static_cast<JSC::JSObject*>(JSC::asObject(eng_p->scriptValueToJSCValue(object)));
+ return JSC::asObject(eng_p->scriptValueToJSCValue(result));
+ return JSC::asObject(eng_p->scriptValueToJSCValue(object));
}
FunctionWithArgWrapper::FunctionWithArgWrapper(QScriptEngine *engine, int length, const JSC::Identifier &name,
diff --git a/src/script/bridge/qscriptvariant_p.h b/src/script/bridge/qscriptvariant_p.h
index da0bb26..6e74a6b 100644
--- a/src/script/bridge/qscriptvariant_p.h
+++ b/src/script/bridge/qscriptvariant_p.h
@@ -49,7 +49,7 @@ public:
virtual const JSC::ClassInfo* classInfo() const { return &info; }
static const JSC::ClassInfo info;
- inline const QVariant &value() const { return data->value; }
+ inline QVariant &value() const { return data->value; }
inline void setValue(const QVariant &value) { data->value = value; }
private: