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; }
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; }
QDateTime convertDateToDateTime(KJS::ExecState *exec, KJS::JSValue *value) { KJS::List args; QDateTime returnDateTime; KJS::JSObject *obj = value->toObject(exec); if (toQString(obj->className()) == "Date") { int seconds = int(obj->get(exec, KJS::Identifier("getSeconds"))->toObject(exec)->call(exec, obj, args)->toInteger(exec)); int minutes = int(obj->get(exec, KJS::Identifier("getMinutes"))->toObject(exec)->call(exec, obj, args)->toInteger(exec)); int hours = int(obj->get(exec, KJS::Identifier("getHours"))->toObject(exec)->call(exec, obj, args)->toInteger(exec)); int month = int(obj->get(exec, KJS::Identifier("getMonth"))->toObject(exec)->call(exec, obj, args)->toInteger(exec)); int day = int(obj->get(exec, KJS::Identifier("getDate"))->toObject(exec)->call(exec, obj, args)->toInteger(exec)); int year = int(obj->get(exec, KJS::Identifier("getFullYear"))->toObject(exec)->call(exec, obj, args)->toInteger(exec)); returnDateTime.setDate(QDate(year, month + 1, day)); returnDateTime.setTime(QTime(hours, minutes, seconds)); } else { // Throw error } return returnDateTime; }
QMap<QString, QVariant> KJSEmbed::convertArrayToMap(KJS::ExecState *exec, KJS::JSValue *value) { QMap<QString, QVariant> returnMap; KJS::JSObject *obj = value->toObject(exec); KJS::PropertyNameArray lst; obj->getPropertyNames(exec, lst); KJS::PropertyNameArrayIterator idx = lst.begin(); for (; idx != lst.end(); idx++) { KJS::Identifier id = *idx; KJS::JSValue *val = obj->get(exec, id); returnMap[toQString(id)] = convertToVariant(exec, val); } return returnMap; }
KJS::JSValue *Engine::callMethod( const KJS::UString &methodName, const KJS::List &args ) { KJS::JSObject *global = dptr->m_interpreter->globalObject(); KJS::ExecState *exec = dptr->m_interpreter->globalExec(); KJS::Identifier id = KJS::Identifier( KJS::UString( methodName ) ); KJS::JSObject *fun = global->get( exec, id )->toObject( exec ); KJS::JSValue *retValue; if ( !fun->implementsCall() ) { QString msg = i18n( "%1 is not a function and cannot be called.", toQString(methodName) ); return throwError( exec, KJS::TypeError, msg ); } retValue = fun->call( exec, global, args ); if( exec->hadException() ) return exec->exception(); return retValue; }
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; } }
QModelIndex KJSObjectModel::index(int row, int column, const QModelIndex &parent ) const { KJS::JSObject *parentInstance = 0; Node *childItem = 0; KJS::ExecState *exec = m_js->globalExec(); if (!parent.isValid()) { if (m_root) parentInstance = m_root; else return QModelIndex(); } else parentInstance = static_cast<Node*>(parent.internalPointer())->instance; int idx = 0; KJS::PropertyNameArray props; parentInstance->getPropertyNames(exec, props); for( KJS::PropertyNameArrayIterator ref = props.begin(); ref != props.end(); ref++) { if( idx == row) { childItem = new Node; childItem->name = ref->ascii(); //### M.O.: this is wrong, can be unicode. childItem->instance = parentInstance->get( exec, childItem->name.constData() )->toObject(exec); childItem->parent = static_cast<Node*>(parent.internalPointer()); break; } ++idx; } if (childItem) return createIndex(row, column, childItem); return QModelIndex(); }
// 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; }