Ejemplo n.º 1
0
KJS::JSValue *SlotProxy::callMethod(const QByteArray &methodName, void **_a)
{
#ifdef DEBUG_SLOTPROXY
    qDebug() << "SlotProxy::callMethod(" << methodName << ",_a) obj=" << this;
#endif
    KJS::ExecState *exec = m_interpreter->globalExec();
    exec->clearException();

    // Crash
    // KJS::Interpreter::globalExec()->context().thisValue()
    KJS::List args = convertArguments(exec, _a);
    KJS::Identifier id = KJS::Identifier(KJS::UString(methodName.data()));
    KJS::JSObject *fun = m_object->get(exec, id)->toObject(exec);
    KJS::JSValue *retValue;
    if (!fun->implementsCall()) {
#ifdef DEBUG_SLOTPROXY
        qDebug() << "SlotProxy::callMethod got bad handler";
#endif
        QString msg = i18n("Bad slot handler: Object %1 Identifier %2 Method %3 Signature: %4.",
                           m_object->className().ascii(),
                           id.ascii(),
                           methodName.data(),
                           QString(m_signature));

        retValue = throwError(exec, KJS::TypeError, msg);
    } else {
        retValue = fun->call(exec, m_object, args);
    }

    if (exec->hadException()) {
#ifdef DEBUG_SLOTPROXY
        qDebug() << "SlotProxy::callMethod had exception";
#endif
        if (m_interpreter->shouldPrintExceptions()) {
            KJS::JSLock lock;
            KJS::JSObject *exceptObj = exec->exception()->toObject(exec);//retValue->toObject(exec);
            QString message = toQString(exceptObj->toString(exec));
            QString sourceURL = toQString(exceptObj->get(exec, "sourceURL")->toString(exec));
            int sourceId = exceptObj->get(exec, "sourceId")->toUInt32(exec);
            // would include the line number, but it's always last line of file
            int line = exceptObj->get(exec, "line")->toUInt32(exec);
            (*KJSEmbed::conerr()) << i18n("Exception calling '%1' slot from %2:%3:%4", QString(methodName), !sourceURL.isEmpty() ? sourceURL : QString::number(sourceId), line, message) << endl;
        }

        // clear it so it doesn't stop other things
        exec->clearException();

        return KJS::jsNull();
    } else {
        if (retValue->type() == 1 || retValue->type() == 0) {
            return KJS::jsNull();
        }
    }
    return retValue;
}
Ejemplo n.º 2
0
bool EventProxy::callHandler( QEvent *e )
{
// Be careful enabling this as if there are a lot of events then the event loop times
// out and the app crashes with 'Alarm Clock'.
//    qDebug("JSObjectEventProxy::callHandler() event type %d" , e->type() );

    KJS::ExecState *exec = m_interpreter->globalExec();
    KJS::Identifier id = JSEventMapper::mapper()->findEventHandler( e->type() );

    KJS::JSObject *jsobj(m_watch);
    KJS::JSObject *fun = jsobj->get(exec, id )->toObject( exec );

    KJS::JSValue *retValue;
    if ( !fun->implementsCall() )
    {
        QString msg = i18n( "Bad event handler: Object %1 Identifier %2 Method %3 Type: %4.",
          jsobj->className().ascii(),
          id.ascii(),
          fun->className().ascii(),
          e->type());
        retValue = throwError(exec, KJS::TypeError, msg);
    }
    else
    {
        // Process args
        KJS::List args;
        args.append( JSEventUtils::event(exec, e) );
        
        // Call handler
        retValue = fun->call( exec, jsobj, args );
    }
    
    if ( exec->hadException() ) 
    {
        if (m_interpreter->shouldPrintExceptions())
        {
            KJS::JSLock lock;
            KJS::JSObject* exceptObj = retValue->toObject(exec);
            QString message = toQString(exceptObj->toString(exec));
            QString sourceURL = toQString(exceptObj->get(exec, "sourceURL")->toString(exec));
            int sourceId = exceptObj->get(exec, "sourceId")->toUInt32(exec);
            int line = exceptObj->get(exec, "line")->toUInt32(exec);
            (*KJSEmbed::conerr()) << i18n("Exception calling '%1' function from %2:%3:%4", id.ascii(), !sourceURL.isEmpty() ? sourceURL : QString::number(sourceId), line, message) << endl;
        }
        
        
        // clear it so it doesn't stop other things
        exec->clearException();
        return false;
    }
  
    return true;
}
Ejemplo n.º 3
0
void SVGScriptElement::executeScript(Document *document, StringImpl *jsCode)
{
    if(!document || !jsCode)
        return;
#if 0
    Ecma *ecmaEngine = document->ecmaEngine();
    if(!ecmaEngine)
        return;
                
    KJS::Interpreter::lock();

    // Run script
    KJS::Completion comp = ecmaEngine->evaluate(jsCode.deprecatedString(), ecmaEngine->globalObject());
    if(comp.complType() == KJS::Throw)
    {
        KJS::ExecState *exec = ecmaEngine->globalExec();
        KJS::JSValue *exVal = comp.value();

        int lineno = -1;
        if(exVal->isObject())
        {
            KJS::JSValue *lineVal = static_cast<KJS::JSObject *>(exVal)->get(exec, "line");
            if(lineVal->type() == KJS::NumberType)
                lineno = int(lineVal->toNumber(exec));
        }

        // Fire ERROR_EVENT upon errors...
        SVGDocument *svgDocument = static_cast<SVGDocument *>(document);
        if(svgDocument && document->hasListenerType(ERROR_EVENT))
        {
            RefPtr<Event> event = svgDocument->createEvent("SVGEvents");
            event->initEvent(EventNames::errorEvent, false, false);
            svgDocument->dispatchRecursiveEvent(event.get(), svgDocument->lastChild());
        }

        kdDebug() << "[SVGScriptElement] Evaluation error, line " << (lineno != -1 ? DeprecatedString::number(lineno) : DeprecatedString::fromLatin1("N/A"))  << " " << exVal->toString(exec).deprecatedString() << endl;
    }
    else if(comp.complType() == KJS::ReturnValue)
        kdDebug() << "[SVGScriptElement] Return value: " << comp.value()->toString(ecmaEngine->globalExec()).deprecatedString() << endl;
    else if(comp.complType() == KJS::Normal)
        kdDebug() << "[SVGScriptElement] Evaluated ecma script!" << endl;
    
    KJS::Interpreter::unlock();
#else
    if (jsCode)
        // Hack to close memory leak due to #if 0
        String(jsCode);
#endif
}
Ejemplo n.º 4
0
KJS::JSValue *GlobalObject::get(KJS::ExecState *exec, const KJS::Identifier &p) const
{
    kdDebug(26004) << "WebCore::GlobalObject (" << this << ")::get " << p.deprecatedString() << endl;

    KJS::JSValue *ret = GlobalObject::get(exec, p);
    if(ret->type() != KJS::UndefinedType)
        return ret;

    const KJS::HashEntry *entry = KJS::Lookup::findEntry(&GlobalObject::s_hashTable, p);
    if(entry)
    {
        switch(entry->value)
        {
            case GlobalObjectConstants::SVGException:
                return getSVGExceptionConstructor(exec);
            case GlobalObjectConstants::SVGLength:
                return getSVGLengthConstructor(exec);
            case GlobalObjectConstants::SVGAngle:
                return getSVGAngleConstructor(exec);
            case GlobalObjectConstants::SVGColor:
                return getSVGColorConstructor(exec);
            case GlobalObjectConstants::SVGPaint:
                return getSVGPaintConstructor(exec);
            case GlobalObjectConstants::SVGUnitTypes:
                return getSVGUnitTypesConstructor(exec);
            case GlobalObjectConstants::SVGTransform:
                return getSVGTransformConstructor(exec);
            case GlobalObjectConstants::SVGGradientElement:
                return getSVGGradientElementConstructor(exec);
            case GlobalObjectConstants::SVGPreserveAspectRatio:
                return getSVGPreserveAspectRatioConstructor(exec);
            case GlobalObjectConstants::SVGZoomAndPan:
                return getSVGZoomAndPanConstructor(exec);
            case GlobalObjectConstants::SVGMarkerElement:
                return getSVGMarkerElementConstructor(exec);
        }
    }

    // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
    // But it can also mean something isn't loaded or implemented...
    kdDebug(26004) << "GlobalObject::get property not found: " << p.deprecatedString() << endl;
    return KJS::jsUndefined();
}
Ejemplo n.º 5
0
JavaScriptArrayType checkArray(KJS::ExecState *exec, KJS::JSValue *val)
{
    KJS::JSObject *obj = val->toObject(exec);
    if (toQString(obj->className()) == "Array") {
        if (!obj->hasProperty(exec, KJS::Identifier("length"))) {
            return Map;
        }
        KJS::JSValue *jslen = obj->get(exec, KJS::Identifier("length"));
        const int len = jslen->toNumber(exec);
        if (len > 0) {
            QByteArray buff;
            buff.setNum(len - 1);
            if (!obj->hasProperty(exec, KJS::Identifier(buff.data()))) {
                return Map;
            }
        }
        return List;
    } else {
        return None;
    }
}
Ejemplo n.º 6
0
JSType JSValueGetType(JSContextRef, JSValueRef value)
{
    KJS::JSValue* jsValue = toJS(value);
    switch (jsValue->type()) {
        case KJS::UndefinedType:
            return kJSTypeUndefined;
        case KJS::NullType:
            return kJSTypeNull;
        case KJS::BooleanType:
            return kJSTypeBoolean;
        case KJS::NumberType:
            return kJSTypeNumber;
        case KJS::StringType:
            return kJSTypeString;
        case KJS::ObjectType:
            return kJSTypeObject;
        default:
            ASSERT(!"JSValueGetType: unknown type code.\n");
            return kJSTypeUndefined;
    }
}
Ejemplo n.º 7
0
bool JSDOMWindow::customGetOwnPropertySlot(KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::PropertySlot& slot)
{
    // we don't want any properties other than "closed" on a closed window
    if (!impl()->frame()) {
        if (propertyName == "closed") {
            const KJS::HashEntry* entry = KJS::Lookup::findEntry(classInfo()->propHashTable, propertyName);
            ASSERT(entry);
            if (entry) {
                slot.setStaticEntry(this, entry, KJS::staticValueGetter<JSDOMWindow>);
                return true;
            }
        }
        if (propertyName == "close") {
            KJS::JSValue* proto = prototype();
            if (proto->isObject()) {
                const KJS::HashEntry* entry = KJS::Lookup::findEntry(static_cast<KJS::JSObject*>(proto)->classInfo()->propHashTable, propertyName);
                ASSERT(entry);
                if (entry) {
                    slot.setStaticEntry(this, entry, KJS::staticFunctionGetter<JSDOMWindowPrototypeFunction>);
                    return true;
                }
            }
        }

        slot.setUndefined(this);
        return true;
    }

    // Look for overrides first
    KJS::JSValue** val = getDirectLocation(propertyName);
    if (val) {
        if (!isSafeScript(exec)) {
            slot.setUndefined(this);
            return true;
        }

        // FIXME: Come up with a way of having JavaScriptCore handle getters/setters in this case
        if (_prop.hasGetterSetterProperties() && val[0]->type() == KJS::GetterSetterType)
            fillGetterPropertySlot(slot, val);
        else
            slot.setValueSlot(this, val);
        return true;
    }

    // FIXME: We need this to work around the blanket isSafeScript check in KJS::Window.  Once we remove that, we
    // can move this to JSDOMWindowPrototype.
    KJS::JSValue* proto = prototype();
    if (proto->isObject()) {
        const KJS::HashEntry* entry = KJS::Lookup::findEntry(static_cast<KJS::JSObject*>(proto)->classInfo()->propHashTable, propertyName);
        if (entry) {
            if (entry->attr & KJS::Function) {
                switch (entry->value) {
                    case FocusFuncNum:
                    case BlurFuncNum:
                    case CloseFuncNum:
                        slot.setStaticEntry(this, entry, KJS::staticFunctionGetter<JSDOMWindowPrototypeFunction>);
                        return true;
                    default:
                        if (!isSafeScript(exec))
                            slot.setUndefined(this);
                        else
                            slot.setStaticEntry(this, entry, KJS::staticFunctionGetter<JSDOMWindowPrototypeFunction>);
                        return true;
                }
            }
        }
    }

    return false;
}
Ejemplo n.º 8
0
KJS::JSValue *KJSEmbed::convertToValue(KJS::ExecState *exec, const QVariant &value)
{
#ifdef KJSEMBED_VARIANT_DEBUG
    qDebug() << "KJSEmbed::convertToValue typeid=" << value.type() << "typename=" << value.typeName() << "toString=" << value.toString();
#endif

    KJS::JSValue *returnValue;
    switch (value.type()) {
    case QVariant::Invalid:
        returnValue = KJS::jsNull();
        break;
    case QVariant::Int:
        returnValue = KJS::jsNumber(value.value<int>());
        break;
    case QVariant::UInt:
        returnValue = KJS::jsNumber(value.value<unsigned int>());
        break;
    case QVariant::LongLong:
        returnValue = KJS::jsNumber(value.value<qlonglong>());
        break;
    case QVariant::ULongLong:
        returnValue = KJS::jsNumber(value.value<qulonglong>());
        break;
    case QVariant::Double:
        returnValue = KJS::jsNumber(value.value<double>());
        break;
    case QVariant::Bool:
        returnValue = KJS::jsBoolean(value.value<bool>());
        break;
    case QVariant::ByteArray:
        returnValue = KJS::jsString(QString(value.value<QByteArray>()));
        break;
    case QVariant::String:
        returnValue = KJS::jsString(value.value<QString>());
        break;
    case QVariant::StringList: {
        KJS::List items;
        QStringList lst = value.value<QStringList>();
        QStringList::Iterator idx = lst.begin();
        for (; idx != lst.end(); ++idx) {
            items.append(KJS::jsString((*idx)));
        }
        returnValue = exec->lexicalInterpreter()->builtinArray()->construct(exec, items);
        break;
    }
    case QVariant::Date: // fall through
    case QVariant::DateTime: // fall through
    case QVariant::Time: {
        QDateTime dt = QDateTime::currentDateTime();
        if (value.type() == QVariant::Date) {
            dt.setDate(value.toDate());
        } else if (value.type() == QVariant::Time) {
            dt.setTime(value.toTime());
        } else {
            dt = value.toDateTime();
        }

        KJS::List items;
        items.append(KJS::jsNumber(dt.date().year()));
        items.append(KJS::jsNumber(dt.date().month() - 1));
        items.append(KJS::jsNumber(dt.date().day()));
        items.append(KJS::jsNumber(dt.time().hour()));
        items.append(KJS::jsNumber(dt.time().minute()));
        items.append(KJS::jsNumber(dt.time().second()));
        items.append(KJS::jsNumber(dt.time().msec()));
        returnValue = exec->lexicalInterpreter()->builtinDate()->construct(exec, items);
        break;
    }
    case QVariant::List: {
        KJS::List items;
        QList<QVariant> lst = value.toList();
        foreach (const QVariant &item, lst) {
            items.append(convertToValue(exec, item));
        }
        returnValue = exec->lexicalInterpreter()->builtinArray()->construct(exec, items);
        break;
    }
    case QVariant::Map: {
        QMap<QString, QVariant> map = value.toMap();
        QMap<QString, QVariant>::Iterator idx = map.begin();
        KJS::JSObject *obj = exec->lexicalInterpreter()->builtinObject()->construct(exec, KJS::List());
        for (; idx != map.end(); ++idx) {
            obj->put(exec, KJS::Identifier(toUString(idx.key())), convertToValue(exec,  idx.value()));
        }
        returnValue =  obj;
        break;
    }
    default: {
        if (value.canConvert< QWidget * >()) {
            QWidget *widget = qvariant_cast< QWidget * >(value);
            returnValue = widget ? createQObject(exec, widget, KJSEmbed::ObjectBinding::CPPOwned) : KJS::jsNull();
        } else if (value.canConvert< QObject * >()) {
            QObject *object = qvariant_cast< QObject * >(value);
            returnValue = object ? createQObject(exec, object, KJSEmbed::ObjectBinding::CPPOwned) : KJS::jsNull();
        } else {
            returnValue = createVariant(exec, value.typeName(), value);
            if (returnValue->isNull()) {
                returnValue = KJS::jsString(value.value<QString>());
            }
        }
        break;
    }
    }
Ejemplo n.º 9
0
// from khtml/ecma/debugger/debugwindow.cpp
static QString exceptionToString(KJS::ExecState* exec, KJS::JSValue* exceptionObj)
{
    QString exceptionMsg = valueToString(exceptionObj);

    // Since we purposefully bypass toString, we need to figure out
    // string serialization ourselves.
    //### might be easier to export class info for ErrorInstance ---

    KJS::JSObject* valueObj = exceptionObj->getObject();
    KJS::JSValue*  protoObj = valueObj ? valueObj->prototype() : 0;

    bool exception   = false;
    bool syntaxError = false;
    if (protoObj == exec->lexicalInterpreter()->builtinSyntaxErrorPrototype())
    {
        exception   = true;
        syntaxError = true;
    }

    if (protoObj == exec->lexicalInterpreter()->builtinErrorPrototype()          ||
        protoObj == exec->lexicalInterpreter()->builtinEvalErrorPrototype()      ||
        protoObj == exec->lexicalInterpreter()->builtinReferenceErrorPrototype() ||
        protoObj == exec->lexicalInterpreter()->builtinRangeErrorPrototype()     ||
        protoObj == exec->lexicalInterpreter()->builtinTypeErrorPrototype()      ||
        protoObj == exec->lexicalInterpreter()->builtinURIErrorPrototype())
    {
        exception = true;
    }

    if (!exception)
        return exceptionMsg;

    // Clear exceptions temporarily so we can get/call a few things.
    // We memorize the old exception first, of course. Note that
    // This is not always the same as exceptionObj since we may be
    //  asked to translate a non-active exception
    KJS::JSValue* oldExceptionObj = exec->exception();
    exec->clearException();

    // We want to serialize the syntax errors ourselves, to provide the line number.
    // The URL is in "sourceURL" and the line is in "line"
    // ### TODO: Perhaps we want to use 'sourceId' in case of eval contexts.
    if (syntaxError)
    {
        KJS::JSValue* lineValue = valueObj->get(exec, "line");
        KJS::JSValue* urlValue  = valueObj->get(exec, "sourceURL");

        int      line = lineValue->toNumber(exec);
        QString  url  = urlValue->toString(exec).qstring();
        exceptionMsg = i18n("Parse error at %1 line %2",
                            url, line + 1);
    }
    else
    {
        // ### it's still not 100% safe to call toString here, even on
        // native exception objects, since someone might have changed the toString property
        // of the exception prototype, but I'll punt on this case for now.
        exceptionMsg = exceptionObj->toString(exec).qstring();
    }
    exec->setException(oldExceptionObj);
    return exceptionMsg;
}