InterfaceConstructor(ObjectValue* object, std::string iid) :
        constructor(object),
        arguments(new FormalParameterList),
        prototype(new InterfacePrototypeValue),
        iid(iid)
    {
        arguments->add(new Identifier("object"));

        object->setParameterList(arguments);
        object->setScope(getGlobal());

        Reflect::Interface interface = es::getInterface(iid.c_str());
        // PRINTF("interface: %s\n", interface.getName().c_str());
        for (int i = 0; i < interface.getMethodCount(); ++i)
        {
            // Construct Method object
            Reflect::Method method(interface.getMethod(i));
            if (prototype->hasProperty(method.getName()))
            {
                if (method.isOperation())
                {
                    // XXX Currently overloaded functions are just ignored.
                }
                else
                {
                    AttributeValue* attribute = static_cast<AttributeValue*>(prototype->get(method.getName()));
                    if (method.isGetter())
                    {
                        attribute->addGetter(i);
                    }
                    else
                    {
                        attribute->addSetter(i);
                    }
                }
            }
            else
            {
                if (method.isOperation())
                {
                    ObjectValue* function = new ObjectValue;
                    function->setCode(new InterfaceMethodCode(function, iid.c_str(), i));
                    prototype->put(method.getName(), function);
#if 0
                    if (method.isIndexGetter())
                    {
                        AttributeGetterValue* getter = new AttributeGetterValue(iid, i);
                        prototype->setOpObject(InterfacePrototypeValue::IndexGetter, getter);
                    }
                    else if (method.isIndexSetter())
                    {
                        AttributeSetterValue* setter = new AttributeSetterValue(iid, i);
                        prototype->setOpObject(InterfacePrototypeValue::IndexSetter, setter);
                    }
                    else if (method.isNameGetter())
                    {
                        AttributeGetterValue* getter = new AttributeGetterValue(iid, i);
                        prototype->setOpObject(InterfacePrototypeValue::NameGetter, getter);
                    }
                    else if (method.isNameSetter())
                    {
                        AttributeSetterValue* setter = new AttributeSetterValue(iid, i);
                        prototype->setOpObject(InterfacePrototypeValue::NameSetter, setter);
                    }
#endif
                }
                else
                {
                    // method is an attribute
                    AttributeValue* attribute = new AttributeValue(iid.c_str());
                    if (method.isGetter())
                    {
                        attribute->addGetter(i);
                    }
                    else
                    {
                        attribute->addSetter(i);
                    }
                    prototype->put(method.getName(), attribute);
                }
            }
        }

        if (interface.getQualifiedSuperName() == "")
        {
            prototype->setPrototype(getGlobal()->get("InterfaceStore")->getPrototype()->getPrototype());
        }
        else
        {
            Reflect::Interface super = es::getInterface(interface.getQualifiedSuperName().c_str());
            prototype->setPrototype(getGlobal()->get(super.getName())->get("prototype"));
        }

        // Create Interface.prototype
        prototype->put("constructor", object);
        object->put("prototype", prototype);
    }
Beispiel #2
0
ObjectValue *ValueOwner::newObject(const Value *prototype)
{
    ObjectValue *object = new ObjectValue(this);
    object->setPrototype(prototype);
    return object;
}
static Value* invoke(const char* iid, int number, InterfaceMethod** self, ListValue* list)
{
    if (!self)
    {
        throw getErrorInstance("TypeError");
    }

    Reflect::Interface interface = es::getInterface(iid);
    Reflect::Method method(interface.getMethod(number));
    PRINTF("invoke %s.%s(%p)\n", interface.getName().c_str(), method.getName().c_str(), self);

    // Set up parameters
    Any argv[9];
    Any* argp = argv;
    int ext = 0;    // extra parameter count

    // Set this
    *argp++ = Any(reinterpret_cast<intptr_t>(self));

    // In the following implementation, we assume no out nor inout attribute is
    // used for parameters.

    Reflect::Type returnType = method.getReturnType();
    switch (returnType.getType())
    {
    case Reflect::kAny:
        // Any op(void* buf, int len, ...);
        // FALL THROUGH
    case Reflect::kString:
        // const char* op(xxx* buf, int len, ...);
        *argp++ = Any(reinterpret_cast<intptr_t>(heap));
        *argp++ = Any(sizeof(heap));
        break;
    case Reflect::kSequence:
        // int op(xxx* buf, int len, ...);
        *argp++ = Any(reinterpret_cast<intptr_t>(heap));
        ++ext;
        *argp++ = Any(static_cast<int32_t>(((*list)[0])->toNumber()));
        break;
    case Reflect::kArray:
        // void op(xxx[x] buf, ...);
        *argp++ = Any(reinterpret_cast<intptr_t>(heap));
        break;
    }

    Reflect::Parameter param = method.listParameter();
    for (int i = ext; param.next(); ++i, ++argp)
    {
        Reflect::Type type(param.getType());
        Value* value = (*list)[i];
        switch (type.getType())
        {
        case Reflect::kAny:
            // Any variant, ...
            switch (value->getType()) {
            case Value::BoolType:
                *argp = Any(static_cast<bool>(value->toBoolean()));
                break;
            case Value::StringType:
                *argp = Any(value->toString().c_str());
                break;
            case Value::NumberType:
                *argp = Any(static_cast<double>(value->toNumber()));
                break;
            case Value::ObjectType:
                if (InterfacePointerValue* unknown = dynamic_cast<InterfacePointerValue*>(value))
                {
                    *argp = Any(unknown->getObject());
                }
                else
                {
                    // XXX expose ECMAScript object
                    *argp = Any(static_cast<Object*>(0));
                }
                break;
            default:
                *argp = Any();
                break;
            }
            argp->makeVariant();
            break;
        case Reflect::kSequence:
            // xxx* buf, int len, ...
            // XXX Assume sequence<octet> now...
            *argp++ = Any(reinterpret_cast<intptr_t>(value->toString().c_str()));
            value = (*list)[++i];
            *argp = Any(static_cast<int32_t>(value->toNumber()));
            break;
        case Reflect::kString:
            *argp = Any(value->toString().c_str());
            break;
        case Reflect::kArray:
            // void op(xxx[x] buf, ...);
            // XXX expand data
            break;
        case Reflect::kObject:
            if (InterfacePointerValue* unknown = dynamic_cast<InterfacePointerValue*>(value))
            {
                *argp = Any(unknown->getObject());
            }
            else
            {
                *argp = Any(static_cast<Object*>(0));
            }
            break;
        case Reflect::kBoolean:
            *argp = Any(static_cast<bool>(value->toBoolean()));
            break;
        case Reflect::kPointer:
            *argp = Any(static_cast<intptr_t>(value->toNumber()));
            break;
        case Reflect::kShort:
            *argp = Any(static_cast<int16_t>(value->toNumber()));
            break;
        case Reflect::kLong:
            *argp = Any(static_cast<int32_t>(value->toNumber()));
            break;
        case Reflect::kOctet:
            *argp = Any(static_cast<uint8_t>(value->toNumber()));
            break;
        case Reflect::kUnsignedShort:
            *argp = Any(static_cast<uint16_t>(value->toNumber()));
            break;
        case Reflect::kUnsignedLong:
            *argp = Any(static_cast<uint32_t>(value->toNumber()));
            break;
        case Reflect::kLongLong:
            *argp = Any(static_cast<int64_t>(value->toNumber()));
            break;
        case Reflect::kUnsignedLongLong:
            *argp = Any(static_cast<uint64_t>(value->toNumber()));
            break;
        case Reflect::kFloat:
            *argp = Any(static_cast<float>(value->toNumber()));
            break;
        case Reflect::kDouble:
            *argp = Any(static_cast<double>(value->toNumber()));
            break;
        default:
            break;
        }
    }

    // Invoke method
    Register<Value> value;
    unsigned methodNumber = interface.getInheritedMethodCount() + number;
    int argc = argp - argv;
    switch (returnType.getType())
    {
    case Reflect::kAny:
        {
            Any result = apply(argc, argv, (Any (*)()) ((*self)[methodNumber]));
            switch (result.getType())
            {
            case Any::TypeVoid:
                value = NullValue::getInstance();
                break;
            case Any::TypeBool:
                value = BoolValue::getInstance(static_cast<bool>(result));
                break;
            case Any::TypeOctet:
                value = new NumberValue(static_cast<uint8_t>(result));
                break;
            case Any::TypeShort:
                value = new NumberValue(static_cast<int16_t>(result));
                break;
            case Any::TypeUnsignedShort:
                value = new NumberValue(static_cast<uint16_t>(result));
                break;
            case Any::TypeLong:
                value = new NumberValue(static_cast<int32_t>(result));
                break;
            case Any::TypeUnsignedLong:
                value = new NumberValue(static_cast<uint32_t>(result));
                break;
            case Any::TypeLongLong:
                value = new NumberValue(static_cast<int64_t>(result));
                break;
            case Any::TypeUnsignedLongLong:
                value = new NumberValue(static_cast<uint64_t>(result));
                break;
            case Any::TypeFloat:
                value = new NumberValue(static_cast<float>(result));
                break;
            case Any::TypeDouble:
                value = new NumberValue(static_cast<double>(result));
                break;
            case Any::TypeString:
                if (const char* string = static_cast<const char*>(result))
                {
                    value = new StringValue(string);
                }
                else
                {
                    value = NullValue::getInstance();
                }
                break;
            case Any::TypeObject:
                if (Object* unknown = static_cast<Object*>(result))
                {
                    ObjectValue* instance = new InterfacePointerValue(unknown);
                    instance->setPrototype(getGlobal()->get(es::getInterface(Object::iid()).getName())->get("prototype"));   // XXX Should use IID
                    value = instance;
                }
                else
                {
                    value = NullValue::getInstance();
                }
                break;
            default:
                value = NullValue::getInstance();
                break;
            }
        }
        break;
    case Reflect::kBoolean:
        value = BoolValue::getInstance(static_cast<bool>(apply(argc, argv, (bool (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kOctet:
        value = new NumberValue(static_cast<uint8_t>(apply(argc, argv, (uint8_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kShort:
        value = new NumberValue(static_cast<int16_t>(apply(argc, argv, (int16_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kUnsignedShort:
        value = new NumberValue(static_cast<uint16_t>(apply(argc, argv, (uint16_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kLong:
        value = new NumberValue(static_cast<int32_t>(apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kUnsignedLong:
        value = new NumberValue(static_cast<uint32_t>(apply(argc, argv, (uint32_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kLongLong:
        value = new NumberValue(static_cast<int64_t>(apply(argc, argv, (int64_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kUnsignedLongLong:
        value = new NumberValue(static_cast<uint64_t>(apply(argc, argv, (uint64_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kFloat:
        value = new NumberValue(static_cast<float>(apply(argc, argv, (float (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kDouble:
        value = new NumberValue(apply(argc, argv, (double (*)()) ((*self)[methodNumber])));
        break;
    case Reflect::kPointer:
        value = new NumberValue(static_cast<intptr_t>(apply(argc, argv, (intptr_t (*)()) ((*self)[methodNumber]))));
        break;
    case Reflect::kString:
        {
            heap[0] = '\0';
            Any result = apply(argc, argv, (const char* (*)()) ((*self)[methodNumber]));
            if (const char* string = static_cast<const char*>(result))
            {
                value = new StringValue(string);
            }
            else
            {
                value = NullValue::getInstance();
            }
        }
        break;
    case Reflect::kSequence:
        {
            // XXX Assume sequence<octet> now...
            int32_t count = apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber]));
            if (count < 0)
            {
                count = 0;
            }
            heap[count] = '\0';
            value = new StringValue(heap);
        }
        break;
    case Reflect::kObject:
        if (Object* unknown = apply(argc, argv, (Object* (*)()) ((*self)[methodNumber])))
        {
            ObjectValue* instance = new InterfacePointerValue(unknown);
            // TODO: check Object and others
            instance->setPrototype(getGlobal()->get(es::getInterface(returnType.getQualifiedName().c_str()).getName())->get("prototype"));   // XXX Should use IID
            value = instance;
        }
        else
        {
            value = NullValue::getInstance();
        }
        break;
    case Reflect::kVoid:
        apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber]));
        value = NullValue::getInstance();
        break;
    }
    return value;
}
Beispiel #4
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);
}
void constructGlobalObject()
{
    global = new ObjectValue;

    global->put("undefined", UndefinedValue::getInstance());
    global->put("NaN", new NumberValue(NAN));
    global->put("Infinity", new NumberValue(INFINITY));

    // Register function properties of the Global object
    for (int i = 0; i < GlobalMethod::methodCount(); ++i)
    {
        ObjectValue* function = new ObjectValue;
        GlobalMethod* method = new GlobalMethod(function, i);
        function->setCode(method);
        global->put(method->name(), function);
    }

    // Register Function
    ObjectValue* function = constructFunctionConstructor();
    global->put("Function", function);

    // Register Object
    ObjectValue* object = constructObjectConstructor();
    global->put("Object", object);

    function->getPrototype()->setPrototype(object->get("prototype"));

    // Register Error objects
    ObjectValue* error;

    error = new ObjectValue;
    error->setCode(new ErrorConstructor(error, "Error", function));
    global->put("Error", error);

    error = new ObjectValue;
    error->setCode(new ErrorConstructor(error, "EvalError", function));
    global->put("EvalError", error);

    error = new ObjectValue;
    error->setCode(new ErrorConstructor(error, "RangeError", function));
    global->put("RangeError", error);

    error = new ObjectValue;
    error->setCode(new ErrorConstructor(error, "ReferenceError", function));
    global->put("ReferenceError", error);

    error = new ObjectValue;
    error->setCode(new ErrorConstructor(error, "SyntaxError", function));
    global->put("SyntaxError", error);

    error = new ObjectValue;
    error->setCode(new ErrorConstructor(error, "TypeError", function));
    global->put("TypeError", error);

    error = new ObjectValue;
    error->setCode(new ErrorConstructor(error, "URIError", function));
    global->put("URIError", error);

    // Register String object
    ObjectValue* string = constructStringObject();
    global->put("String", string);

    // Register Math object
    ObjectValue* math = constructMathObject();
    global->put("Math", math);

    // Register Array object
    ObjectValue* array = constructArrayObject();
    global->put("Array", array);

    // Register Boolean object
    ObjectValue* boolean = constructBooleanObject();
    global->put("Boolean", boolean);

    // Register RegExp object
    ObjectValue* regexp = constructRegExpObject();
    global->put("RegExp", regexp);

    // Register Date object
    ObjectValue* date = constructDateObject();
    global->put("Date", date);

    // Register Interface Store object
    global->put("InterfaceStore", constructInterfaceObject());

    // Register System object
    global->put("System", constructSystemObject(0));

    // Register Number object
    global->put("Number", constructNumberObject());
}
void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const {
  // header
  if (pd != NULL) {
    tty->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", pd->real_pc(_code), pd->pc_offset());
  }

  print_value_on(st);
  // decode offsets
  if (WizardMode) {
    st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->content_begin());
    st->print_cr(" offset:     %d",    _decode_offset);
    st->print_cr(" bci:        %d",    bci());
    st->print_cr(" reexecute:  %s",    should_reexecute() ? "true" : "false");
    st->print_cr(" locals:     %d",    _locals_decode_offset);
    st->print_cr(" stack:      %d",    _expressions_decode_offset);
    st->print_cr(" monitor:    %d",    _monitors_decode_offset);
    st->print_cr(" sender:     %d",    _sender_decode_offset);
  }
  // locals
  { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->locals();
    if (l != NULL) {
      tty->print_cr("   Locals");
      for (int index = 0; index < l->length(); index++) {
        st->print("    - l%d: ", index);
        l->at(index)->print_on(st);
        st->cr();
      }
    }
  }
  // expressions
  { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->expressions();
    if (l != NULL) {
      st->print_cr("   Expression stack");
      for (int index = 0; index < l->length(); index++) {
        st->print("   - @%d: ", index);
        l->at(index)->print_on(st);
        st->cr();
      }
    }
  }
  // monitors
  { GrowableArray<MonitorValue*>* l = ((ScopeDesc*) this)->monitors();
    if (l != NULL) {
      st->print_cr("   Monitor stack");
      for (int index = 0; index < l->length(); index++) {
        st->print("    - @%d: ", index);
        l->at(index)->print_on(st);
        st->cr();
      }
    }
  }

#ifdef COMPILER2
  if (DoEscapeAnalysis && is_top() && _objects != NULL) {
    tty->print_cr("Objects");
    for (int i = 0; i < _objects->length(); i++) {
      ObjectValue* sv = (ObjectValue*) _objects->at(i);
      tty->print(" - %d: ", sv->id());
      sv->print_fields_on(tty);
      tty->cr();
    }
  }
#endif // COMPILER2
}
ObjectValue* constructStringObject()
{
    ObjectValue* string = new ObjectValue;
    string->setCode(new StringConstructor(string));
    return string;
}
    StringConstructor(ObjectValue* string) :
        string(string),
        arguments(new FormalParameterList),
        prototype(new ObjectValue)
    {
        ObjectValue* function = static_cast<ObjectValue*>(getGlobal()->get("Function"));

        arguments->add(new Identifier("value"));
        prototype->put("constructor", string);
        prototype->setPrototype(function->getPrototype()->getPrototype());

        for (int i = 0; i < StringMethod::methodCount(); ++i)
        {
            ObjectValue* function = new ObjectValue;
            StringMethod* method = new StringMethod(function, i);
            function->setCode(method);
            prototype->put(method->name(), function);
        }

        string->setParameterList(arguments);
        string->setScope(getGlobal());
        string->put("prototype", prototype);
        string->setPrototype(function->getPrototype());

        for (int i = 0; i < StringConstructorMethod::methodCount(); ++i)
        {
            ObjectValue* function = new ObjectValue;
            StringConstructorMethod* method = new StringConstructorMethod(function, i);
            function->setCode(method);
            string->put(method->name(), function);
        }
    }