Beispiel #1
0
Link::Link(const Snapshot &snapshot, const QStringList &importPaths, const LibraryInfo &builtins)
    : d(new LinkPrivate)
{
    d->valueOwner = new ValueOwner;
    d->snapshot = snapshot;
    d->importPaths = importPaths;
    d->builtins = builtins;

    d->diagnosticMessages = 0;
    d->allDiagnosticMessages = 0;

    ModelManagerInterface *modelManager = ModelManagerInterface::instance();
    if (modelManager) {
        ModelManagerInterface::CppDataHash cppDataHash = modelManager->cppData();

        // populate engine with types from C++
        foreach (const ModelManagerInterface::CppData &cppData, cppDataHash) {
            d->valueOwner->cppQmlTypes().load(cppData.exportedTypes);
        }

        // build an object with the context properties from C++
        ObjectValue *cppContextProperties = d->valueOwner->newObject(/* prototype = */ 0);
        foreach (const ModelManagerInterface::CppData &cppData, cppDataHash) {
            QHashIterator<QString, QString> it(cppData.contextProperties);
            while (it.hasNext()) {
                it.next();
                const Value *value = 0;
                const QString cppTypeName = it.value();
                if (!cppTypeName.isEmpty())
                    value = d->valueOwner->cppQmlTypes().objectByCppName(cppTypeName);
                if (!value)
                    value = d->valueOwner->unknownValue();
                cppContextProperties->setMember(it.key(), value);
            }
        }
bool Bind::visit(FunctionExpression *ast)
{
    // ### FIXME: the first declaration counts
    //if (_currentObjectValue->property(ast->name->asString(), 0))
    //    return false;

    ASTFunctionValue *function = new ASTFunctionValue(ast, _doc, &_valueOwner);
    if (_currentObjectValue && !ast->name.isEmpty() && cast<FunctionDeclaration *>(ast))
        _currentObjectValue->setMember(ast->name.toString(), function);

    // build function scope
    ObjectValue *functionScope = _valueOwner.newObject(/*prototype=*/0);
    _attachedJSScopes.insert(ast, functionScope);
    ObjectValue *parent = switchObjectValue(functionScope);

    // The order of the following is important. Example: A function with name "arguments"
    // overrides the arguments object, a variable doesn't.

    // 1. Function formal arguments
    for (FormalParameterList *it = ast->formals; it; it = it->next) {
        if (!it->name.isEmpty())
            functionScope->setMember(it->name.toString(), _valueOwner.unknownValue());
    }

    // 2. Functions defined inside the function body
    // ### TODO, currently covered by the accept(body)

    // 3. Arguments object
    ObjectValue *arguments = _valueOwner.newObject(/*prototype=*/0);
    arguments->setMember(QLatin1String("callee"), function);
    arguments->setMember(QLatin1String("length"), _valueOwner.numberValue());
    functionScope->setMember(QLatin1String("arguments"), arguments);

    // 4. Variables defined inside the function body
    // ### TODO, currently covered by the accept(body)

    // visit body
    accept(ast->body);
    switchObjectValue(parent);

    return false;
}
Beispiel #3
0
SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
    : ValueOwner(this) // need to avoid recursing in ValueOwner ctor
{
    _objectPrototype   = newObject(/*prototype = */ 0);
    _functionPrototype = newObject(_objectPrototype);
    _numberPrototype   = newObject(_objectPrototype);
    _booleanPrototype  = newObject(_objectPrototype);
    _stringPrototype   = newObject(_objectPrototype);
    _arrayPrototype    = newObject(_objectPrototype);
    _datePrototype     = newObject(_objectPrototype);
    _regexpPrototype   = newObject(_objectPrototype);

    // set up the Global object
    _globalObject = newObject();
    _globalObject->setClassName(QLatin1String("Global"));

    ObjectValue *objectInstance = newObject();
    objectInstance->setClassName(QLatin1String("Object"));
    objectInstance->setMember(QLatin1String("length"), numberValue());
    _objectCtor = new Function(this);
    _objectCtor->setMember(QLatin1String("prototype"), _objectPrototype);
    _objectCtor->setReturnValue(objectInstance);
    _objectCtor->addArgument(unknownValue(), QLatin1String("value"));
    _objectCtor->setOptionalNamedArgumentCount(1);

    FunctionValue *functionInstance = new FunctionValue(this);
    _functionCtor = new Function(this);
    _functionCtor->setMember(QLatin1String("prototype"), _functionPrototype);
    _functionCtor->setReturnValue(functionInstance);
    _functionCtor->setVariadic(true);

    ObjectValue *arrayInstance = newObject(_arrayPrototype);
    arrayInstance->setClassName(QLatin1String("Array"));
    arrayInstance->setMember(QLatin1String("length"), numberValue());
    _arrayCtor = new Function(this);
    _arrayCtor->setMember(QLatin1String("prototype"), _arrayPrototype);
    _arrayCtor->setReturnValue(arrayInstance);
    _arrayCtor->setVariadic(true);

    ObjectValue *stringInstance = newObject(_stringPrototype);
    stringInstance->setClassName(QLatin1String("String"));
    stringInstance->setMember(QLatin1String("length"), numberValue());
    _stringCtor = new Function(this);
    _stringCtor->setMember(QLatin1String("prototype"), _stringPrototype);
    _stringCtor->setReturnValue(stringInstance);
    _stringCtor->addArgument(unknownValue(), QLatin1String("value"));
    _stringCtor->setOptionalNamedArgumentCount(1);

    ObjectValue *booleanInstance = newObject(_booleanPrototype);
    booleanInstance->setClassName(QLatin1String("Boolean"));
    _booleanCtor = new Function(this);
    _booleanCtor->setMember(QLatin1String("prototype"), _booleanPrototype);
    _booleanCtor->setReturnValue(booleanInstance);
    _booleanCtor->addArgument(unknownValue(), QLatin1String("value"));

    ObjectValue *numberInstance = newObject(_numberPrototype);
    numberInstance->setClassName(QLatin1String("Number"));
    _numberCtor = new Function(this);
    _numberCtor->setMember(QLatin1String("prototype"), _numberPrototype);
    _numberCtor->setReturnValue(numberInstance);
    _numberCtor->addArgument(unknownValue(), QLatin1String("value"));
    _numberCtor->setOptionalNamedArgumentCount(1);

    ObjectValue *dateInstance = newObject(_datePrototype);
    dateInstance->setClassName(QLatin1String("Date"));
    _dateCtor = new Function(this);
    _dateCtor->setMember(QLatin1String("prototype"), _datePrototype);
    _dateCtor->setReturnValue(dateInstance);
    _dateCtor->setVariadic(true);

    ObjectValue *regexpInstance = newObject(_regexpPrototype);
    regexpInstance->setClassName(QLatin1String("RegExp"));
    regexpInstance->setMember(QLatin1String("source"), stringValue());
    regexpInstance->setMember(QLatin1String("global"), booleanValue());
    regexpInstance->setMember(QLatin1String("ignoreCase"), booleanValue());
    regexpInstance->setMember(QLatin1String("multiline"), booleanValue());
    regexpInstance->setMember(QLatin1String("lastIndex"), numberValue());
    _regexpCtor = new Function(this);
    _regexpCtor->setMember(QLatin1String("prototype"), _regexpPrototype);
    _regexpCtor->setReturnValue(regexpInstance);
    _regexpCtor->addArgument(unknownValue(), QLatin1String("pattern"));
    _regexpCtor->addArgument(unknownValue(), QLatin1String("flags"));

    addFunction(_objectCtor, QLatin1String("getPrototypeOf"), 1);
    addFunction(_objectCtor, QLatin1String("getOwnPropertyDescriptor"), 2);
    addFunction(_objectCtor, QLatin1String("getOwnPropertyNames"), arrayInstance, 1);
    addFunction(_objectCtor, QLatin1String("create"), 1, 1);
    addFunction(_objectCtor, QLatin1String("defineProperty"), 3);
    addFunction(_objectCtor, QLatin1String("defineProperties"), 2);
    addFunction(_objectCtor, QLatin1String("seal"), 1);
    addFunction(_objectCtor, QLatin1String("freeze"), 1);
    addFunction(_objectCtor, QLatin1String("preventExtensions"), 1);
    addFunction(_objectCtor, QLatin1String("isSealed"), booleanValue(), 1);
    addFunction(_objectCtor, QLatin1String("isFrozen"), booleanValue(), 1);
    addFunction(_objectCtor, QLatin1String("isExtensible"), booleanValue(), 1);
    addFunction(_objectCtor, QLatin1String("keys"), arrayInstance, 1);

    addFunction(_objectPrototype, QLatin1String("toString"), stringValue(), 0);
    addFunction(_objectPrototype, QLatin1String("toLocaleString"), stringValue(), 0);
    addFunction(_objectPrototype, QLatin1String("valueOf"), 0); // ### FIXME it should return thisObject
    addFunction(_objectPrototype, QLatin1String("hasOwnProperty"), booleanValue(), 1);
    addFunction(_objectPrototype, QLatin1String("isPrototypeOf"), booleanValue(), 1);
    addFunction(_objectPrototype, QLatin1String("propertyIsEnumerable"), booleanValue(), 1);

    // set up the default Function prototype
    _functionPrototype->setMember(QLatin1String("constructor"), _functionCtor);
    addFunction(_functionPrototype, QLatin1String("toString"), stringValue(), 0);
    addFunction(_functionPrototype, QLatin1String("apply"), 2);
    addFunction(_functionPrototype, QLatin1String("call"), 1, 0, true);
    addFunction(_functionPrototype, QLatin1String("bind"), 1, 0, true);

    // set up the default Array prototype
    addFunction(_arrayCtor, QLatin1String("isArray"), booleanValue(), 1);

    _arrayPrototype->setMember(QLatin1String("constructor"), _arrayCtor);
    addFunction(_arrayPrototype, QLatin1String("toString"), stringValue(), 0);
    addFunction(_arrayPrototype, QLatin1String("toLocalString"), stringValue(), 0);
    addFunction(_arrayPrototype, QLatin1String("concat"), 0, 0, true);
    addFunction(_arrayPrototype, QLatin1String("join"), 1);
    addFunction(_arrayPrototype, QLatin1String("pop"), 0);
    addFunction(_arrayPrototype, QLatin1String("push"), 0, 0, true);
    addFunction(_arrayPrototype, QLatin1String("reverse"), 0);
    addFunction(_arrayPrototype, QLatin1String("shift"), 0);
    addFunction(_arrayPrototype, QLatin1String("slice"), 2);
    addFunction(_arrayPrototype, QLatin1String("sort"), 1);
    addFunction(_arrayPrototype, QLatin1String("splice"), 2);
    addFunction(_arrayPrototype, QLatin1String("unshift"), 0, 0, true);
    addFunction(_arrayPrototype, QLatin1String("indexOf"), numberValue(), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("lastIndexOf"), numberValue(), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("every"), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("some"), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("forEach"), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("map"), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("filter"), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("reduce"), 2, 1);
    addFunction(_arrayPrototype, QLatin1String("reduceRight"), 2, 1);

    // set up the default String prototype
    addFunction(_stringCtor, QLatin1String("fromCharCode"), stringValue(), 0, 0, true);

    _stringPrototype->setMember(QLatin1String("constructor"), _stringCtor);
    addFunction(_stringPrototype, QLatin1String("toString"), stringValue(), 0);
    addFunction(_stringPrototype, QLatin1String("valueOf"), stringValue(), 0);
    addFunction(_stringPrototype, QLatin1String("charAt"), stringValue(), 1);
    addFunction(_stringPrototype, QLatin1String("charCodeAt"), stringValue(), 1);
    addFunction(_stringPrototype, QLatin1String("concat"), stringValue(), 0, 0, true);
    addFunction(_stringPrototype, QLatin1String("indexOf"), numberValue(), 2);
    addFunction(_stringPrototype, QLatin1String("lastIndexOf"), numberValue(), 2);
    addFunction(_stringPrototype, QLatin1String("localeCompare"), booleanValue(), 1);
    addFunction(_stringPrototype, QLatin1String("match"), arrayInstance, 1);
    addFunction(_stringPrototype, QLatin1String("replace"), stringValue(), 2);
    addFunction(_stringPrototype, QLatin1String("search"), numberValue(), 1);
    addFunction(_stringPrototype, QLatin1String("slice"), stringValue(), 2);
    addFunction(_stringPrototype, QLatin1String("split"), arrayInstance, 1);
    addFunction(_stringPrototype, QLatin1String("substring"), stringValue(), 2);
    addFunction(_stringPrototype, QLatin1String("toLowerCase"), stringValue(), 0);
    addFunction(_stringPrototype, QLatin1String("toLocaleLowerCase"), stringValue(), 0);
    addFunction(_stringPrototype, QLatin1String("toUpperCase"), stringValue(), 0);
    addFunction(_stringPrototype, QLatin1String("toLocaleUpperCase"), stringValue(), 0);
    addFunction(_stringPrototype, QLatin1String("trim"), stringValue(), 0);

    // set up the default Boolean prototype
    addFunction(_booleanCtor, QLatin1String("fromCharCode"), 0);

    _booleanPrototype->setMember(QLatin1String("constructor"), _booleanCtor);
    addFunction(_booleanPrototype, QLatin1String("toString"), stringValue(), 0);
    addFunction(_booleanPrototype, QLatin1String("valueOf"), booleanValue(), 0);

    // set up the default Number prototype
    _numberCtor->setMember(QLatin1String("MAX_VALUE"), numberValue());
    _numberCtor->setMember(QLatin1String("MIN_VALUE"), numberValue());
    _numberCtor->setMember(QLatin1String("NaN"), numberValue());
    _numberCtor->setMember(QLatin1String("NEGATIVE_INFINITY"), numberValue());
    _numberCtor->setMember(QLatin1String("POSITIVE_INFINITY"), numberValue());

    addFunction(_numberCtor, QLatin1String("fromCharCode"), 0);

    _numberPrototype->setMember(QLatin1String("constructor"), _numberCtor);
    addFunction(_numberPrototype, QLatin1String("toString"), stringValue(), 1, 1);
    addFunction(_numberPrototype, QLatin1String("toLocaleString"), stringValue(), 0);
    addFunction(_numberPrototype, QLatin1String("valueOf"), numberValue(), 0);
    addFunction(_numberPrototype, QLatin1String("toFixed"), numberValue(), 1);
    addFunction(_numberPrototype, QLatin1String("toExponential"), numberValue(), 1);
    addFunction(_numberPrototype, QLatin1String("toPrecision"), numberValue(), 1);

    // set up the Math object
    _mathObject = newObject();
    _mathObject->setMember(QLatin1String("E"), numberValue());
    _mathObject->setMember(QLatin1String("LN10"), numberValue());
    _mathObject->setMember(QLatin1String("LN2"), numberValue());
    _mathObject->setMember(QLatin1String("LOG2E"), numberValue());
    _mathObject->setMember(QLatin1String("LOG10E"), numberValue());
    _mathObject->setMember(QLatin1String("PI"), numberValue());
    _mathObject->setMember(QLatin1String("SQRT1_2"), numberValue());
    _mathObject->setMember(QLatin1String("SQRT2"), numberValue());

    addFunction(_mathObject, QLatin1String("abs"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("acos"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("asin"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("atan"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("atan2"), numberValue(), 2);
    addFunction(_mathObject, QLatin1String("ceil"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("cos"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("exp"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("floor"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("log"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("max"), numberValue(), 0, 0, true);
    addFunction(_mathObject, QLatin1String("min"), numberValue(), 0, 0, true);
    addFunction(_mathObject, QLatin1String("pow"), numberValue(), 2);
    addFunction(_mathObject, QLatin1String("random"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("round"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("sin"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("sqrt"), numberValue(), 1);
    addFunction(_mathObject, QLatin1String("tan"), numberValue(), 1);

    // set up the default Boolean prototype
    addFunction(_dateCtor, QLatin1String("parse"), numberValue(), 1);
    addFunction(_dateCtor, QLatin1String("UTC"), numberValue(), 7, 5);
    addFunction(_dateCtor, QLatin1String("now"), numberValue(), 0);

    _datePrototype->setMember(QLatin1String("constructor"), _dateCtor);
    addFunction(_datePrototype, QLatin1String("toString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("toDateString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("toTimeString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("toLocaleString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("toLocaleDateString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("toLocaleTimeString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("valueOf"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getTime"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getFullYear"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getUTCFullYear"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getMonth"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getUTCMonth"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getDate"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getUTCDate"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getHours"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getUTCHours"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getMinutes"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getUTCMinutes"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getSeconds"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getUTCSeconds"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getMilliseconds"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getUTCMilliseconds"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("getTimezoneOffset"), numberValue(), 0);
    addFunction(_datePrototype, QLatin1String("setTime"), 1);
    addFunction(_datePrototype, QLatin1String("setMilliseconds"), 1);
    addFunction(_datePrototype, QLatin1String("setUTCMilliseconds"), 1);
    addFunction(_datePrototype, QLatin1String("setSeconds"), 2, 1);
    addFunction(_datePrototype, QLatin1String("setUTCSeconds"), 2, 1);
    addFunction(_datePrototype, QLatin1String("setMinutes"), 3, 2);
    addFunction(_datePrototype, QLatin1String("setUTCMinutes"), 3, 2);
    addFunction(_datePrototype, QLatin1String("setHours"), 4, 3);
    addFunction(_datePrototype, QLatin1String("setUTCHours"), 4, 3);
    addFunction(_datePrototype, QLatin1String("setDate"), 1);
    addFunction(_datePrototype, QLatin1String("setUTCDate"), 1);
    addFunction(_datePrototype, QLatin1String("setMonth"), 2, 1);
    addFunction(_datePrototype, QLatin1String("setUTCMonth"), 2, 1);
    addFunction(_datePrototype, QLatin1String("setFullYear"), 3, 2);
    addFunction(_datePrototype, QLatin1String("setUTCFullYear"), 3, 2);
    addFunction(_datePrototype, QLatin1String("toUTCString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("toISOString"), stringValue(), 0);
    addFunction(_datePrototype, QLatin1String("toJSON"), stringValue(), 1);

    // set up the default Boolean prototype
    _regexpPrototype->setMember(QLatin1String("constructor"), _regexpCtor);
    addFunction(_regexpPrototype, QLatin1String("exec"), arrayInstance, 1);
    addFunction(_regexpPrototype, QLatin1String("test"), booleanValue(), 1);
    addFunction(_regexpPrototype, QLatin1String("toString"), stringValue(), 0);

    // fill the Global object
    _globalObject->setMember(QLatin1String("Math"), _mathObject);
    _globalObject->setMember(QLatin1String("Object"), objectCtor());
    _globalObject->setMember(QLatin1String("Function"), functionCtor());
    _globalObject->setMember(QLatin1String("Array"), arrayCtor());
    _globalObject->setMember(QLatin1String("String"), stringCtor());
    _globalObject->setMember(QLatin1String("Boolean"), booleanCtor());
    _globalObject->setMember(QLatin1String("Number"), numberCtor());
    _globalObject->setMember(QLatin1String("Date"), dateCtor());
    _globalObject->setMember(QLatin1String("RegExp"), regexpCtor());

    Function *f = 0;

    // XMLHttpRequest
    ObjectValue *xmlHttpRequest = newObject();
    xmlHttpRequest->setMember(QLatin1String("onreadystatechange"), functionPrototype());
    xmlHttpRequest->setMember(QLatin1String("UNSENT"), numberValue());
    xmlHttpRequest->setMember(QLatin1String("OPENED"), numberValue());
    xmlHttpRequest->setMember(QLatin1String("HEADERS_RECEIVED"), numberValue());
    xmlHttpRequest->setMember(QLatin1String("LOADING"), numberValue());
    xmlHttpRequest->setMember(QLatin1String("DONE"), numberValue());
    xmlHttpRequest->setMember(QLatin1String("readyState"), numberValue());
    f = addFunction(xmlHttpRequest, QLatin1String("open"));
    f->addArgument(stringValue(), QLatin1String("method"));
    f->addArgument(stringValue(), QLatin1String("url"));
    f->addArgument(booleanValue(), QLatin1String("async"));
    f->addArgument(stringValue(), QLatin1String("user"));
    f->addArgument(stringValue(), QLatin1String("password"));
    f = addFunction(xmlHttpRequest, QLatin1String("setRequestHeader"));
    f->addArgument(stringValue(), QLatin1String("header"));
    f->addArgument(stringValue(), QLatin1String("value"));
    f = addFunction(xmlHttpRequest, QLatin1String("send"));
    f->addArgument(unknownValue(), QLatin1String("data"));
    f = addFunction(xmlHttpRequest, QLatin1String("abort"));
    xmlHttpRequest->setMember(QLatin1String("status"), numberValue());
    xmlHttpRequest->setMember(QLatin1String("statusText"), stringValue());
    f = addFunction(xmlHttpRequest, QLatin1String("getResponseHeader"));
    f->addArgument(stringValue(), QLatin1String("header"));
    f = addFunction(xmlHttpRequest, QLatin1String("getAllResponseHeaders"));
    xmlHttpRequest->setMember(QLatin1String("responseText"), stringValue());
    xmlHttpRequest->setMember(QLatin1String("responseXML"), unknownValue());

    f = addFunction(_globalObject, QLatin1String("XMLHttpRequest"), xmlHttpRequest);
    f->setMember(QLatin1String("prototype"), xmlHttpRequest);
    xmlHttpRequest->setMember(QLatin1String("constructor"), f);

    // Database API
    ObjectValue *db = newObject();
    f = addFunction(db, QLatin1String("transaction"));
    f->addArgument(functionPrototype(), QLatin1String("callback"));
    f = addFunction(db, QLatin1String("readTransaction"));
    f->addArgument(functionPrototype(), QLatin1String("callback"));
    f->setMember(QLatin1String("version"), stringValue());
    f = addFunction(db, QLatin1String("changeVersion"));
    f->addArgument(stringValue(), QLatin1String("oldVersion"));
    f->addArgument(stringValue(), QLatin1String("newVersion"));
    f->addArgument(functionPrototype(), QLatin1String("callback"));

    f = addFunction(_globalObject, QLatin1String("openDatabaseSync"), db);
    f->addArgument(stringValue(), QLatin1String("name"));
    f->addArgument(stringValue(), QLatin1String("version"));
    f->addArgument(stringValue(), QLatin1String("displayName"));
    f->addArgument(numberValue(), QLatin1String("estimatedSize"));
    f->addArgument(functionPrototype(), QLatin1String("callback"));

    // JSON
    ObjectValue *json = newObject();
    f = addFunction(json, QLatin1String("parse"), objectPrototype());
    f->addArgument(stringValue(), QLatin1String("text"));
    f->addArgument(functionPrototype(), QLatin1String("reviver"));
    f->setOptionalNamedArgumentCount(1);
    f = addFunction(json, QLatin1String("stringify"), stringValue());
    f->addArgument(unknownValue(), QLatin1String("value"));
    f->addArgument(unknownValue(), QLatin1String("replacer"));
    f->addArgument(unknownValue(), QLatin1String("space"));
    f->setOptionalNamedArgumentCount(2);
    _globalObject->setMember(QLatin1String("JSON"), json);

    // QML objects
    _qmlFontObject = newObject(/*prototype =*/ 0);
    _qmlFontObject->setClassName(QLatin1String("Font"));
    _qmlFontObject->setMember(QLatin1String("family"), stringValue());
    _qmlFontObject->setMember(QLatin1String("weight"), unknownValue()); // ### make me an object
    _qmlFontObject->setMember(QLatin1String("capitalization"), unknownValue()); // ### make me an object
    _qmlFontObject->setMember(QLatin1String("bold"), booleanValue());
    _qmlFontObject->setMember(QLatin1String("italic"), booleanValue());
    _qmlFontObject->setMember(QLatin1String("underline"), booleanValue());
    _qmlFontObject->setMember(QLatin1String("overline"), booleanValue());
    _qmlFontObject->setMember(QLatin1String("strikeout"), booleanValue());
    _qmlFontObject->setMember(QLatin1String("pointSize"), intValue());
    _qmlFontObject->setMember(QLatin1String("pixelSize"), intValue());
    _qmlFontObject->setMember(QLatin1String("letterSpacing"), realValue());
    _qmlFontObject->setMember(QLatin1String("wordSpacing"), realValue());

    _qmlPointObject = newObject(/*prototype =*/ 0);
    _qmlPointObject->setClassName(QLatin1String("Point"));
    _qmlPointObject->setMember(QLatin1String("x"), numberValue());
    _qmlPointObject->setMember(QLatin1String("y"), numberValue());

    _qmlSizeObject = newObject(/*prototype =*/ 0);
    _qmlSizeObject->setClassName(QLatin1String("Size"));
    _qmlSizeObject->setMember(QLatin1String("width"), numberValue());
    _qmlSizeObject->setMember(QLatin1String("height"), numberValue());

    _qmlRectObject = newObject(/*prototype =*/ 0);
    _qmlRectObject->setClassName(QLatin1String("Rect"));
    _qmlRectObject->setMember(QLatin1String("x"), numberValue());
    _qmlRectObject->setMember(QLatin1String("y"), numberValue());
    _qmlRectObject->setMember(QLatin1String("width"), numberValue());
    _qmlRectObject->setMember(QLatin1String("height"), numberValue());

    _qmlVector3DObject = newObject(/*prototype =*/ 0);
    _qmlVector3DObject->setClassName(QLatin1String("Vector3D"));
    _qmlVector3DObject->setMember(QLatin1String("x"), realValue());
    _qmlVector3DObject->setMember(QLatin1String("y"), realValue());
    _qmlVector3DObject->setMember(QLatin1String("z"), realValue());

    // global Qt object, in alphabetic order
    _qtObject = newObject(new QtObjectPrototypeReference(this));
    addFunction(_qtObject, QLatin1String("atob"), &_stringValue, 1);
    addFunction(_qtObject, QLatin1String("btoa"), &_stringValue, 1);
    addFunction(_qtObject, QLatin1String("createComponent"), 1);
    addFunction(_qtObject, QLatin1String("createQmlObject"), 3);
    addFunction(_qtObject, QLatin1String("darker"), &_colorValue, 1);
    addFunction(_qtObject, QLatin1String("fontFamilies"), 0);
    addFunction(_qtObject, QLatin1String("formatDate"), &_stringValue, 2);
    addFunction(_qtObject, QLatin1String("formatDateTime"), &_stringValue, 2);
    addFunction(_qtObject, QLatin1String("formatTime"), &_stringValue, 2);
    addFunction(_qtObject, QLatin1String("hsla"), &_colorValue, 4);
    addFunction(_qtObject, QLatin1String("include"), 2);
    addFunction(_qtObject, QLatin1String("isQtObject"), &_booleanValue, 1);
    addFunction(_qtObject, QLatin1String("lighter"), &_colorValue, 1);
    addFunction(_qtObject, QLatin1String("md5"), &_stringValue, 1);
    addFunction(_qtObject, QLatin1String("openUrlExternally"), &_booleanValue, 1);
    addFunction(_qtObject, QLatin1String("point"), _qmlPointObject, 2);
    addFunction(_qtObject, QLatin1String("quit"), 0);
    addFunction(_qtObject, QLatin1String("rect"), _qmlRectObject, 4);
    addFunction(_qtObject, QLatin1String("resolvedUrl"), &_urlValue, 1);
    addFunction(_qtObject, QLatin1String("rgba"), &_colorValue, 4);
    addFunction(_qtObject, QLatin1String("size"), _qmlSizeObject, 2);
    addFunction(_qtObject, QLatin1String("tint"), &_colorValue, 2);
    addFunction(_qtObject, QLatin1String("vector3d"), _qmlVector3DObject, 3);
    _globalObject->setMember(QLatin1String("Qt"), _qtObject);

    // firebug/webkit compat
    ObjectValue *consoleObject = newObject(/*prototype */ 0);
    addFunction(consoleObject, QLatin1String("log"), 1, 0, true);
    addFunction(consoleObject, QLatin1String("debug"), 1, 0, true);
    if (kind == Qt5Kind) {
        addFunction(consoleObject, QLatin1String("info"), 1, 0, true);
        addFunction(consoleObject, QLatin1String("warn"), 1, 0, true);
        addFunction(consoleObject, QLatin1String("error"), 1, 0, true);
        addFunction(consoleObject, QLatin1String("assert"), 1, 0, true);
        addFunction(consoleObject, QLatin1String("count"), 0, 1);
        addFunction(consoleObject, QLatin1String("profile"), 0);
        addFunction(consoleObject, QLatin1String("profileEnd"), 0);
        addFunction(consoleObject, QLatin1String("time"), 1);
        addFunction(consoleObject, QLatin1String("timeEnd"), 1);
        addFunction(consoleObject, QLatin1String("trace"), 0);
        addFunction(consoleObject, QLatin1String("exception"), 1, 0, true);
    }
    _globalObject->setMember(QLatin1String("console"), consoleObject);

    // translation functions
    addFunction(_globalObject, QLatin1String("qsTr"), 3);
    addFunction(_globalObject, QLatin1String("QT_TR_NOOP"), 1);
    addFunction(_globalObject, QLatin1String("qsTranslate"), 5);
    addFunction(_globalObject, QLatin1String("QT_TRANSLATE_NOOP"), 2);
    addFunction(_globalObject, QLatin1String("qsTrId"), 2);
    addFunction(_globalObject, QLatin1String("QT_TRID_NOOP"), 1);
}