kjsembed
static_binding.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2005, 2006 Ian Reinhart Geiser <geiseri@kde.org> 00003 Copyright (C) 2005, 2006 Matt Broadstone <mbroadst@gmail.com> 00004 Copyright (C) 2005, 2006 Richard J. Moore <rich@kde.org> 00005 Copyright (C) 2005, 2006 Erik L. Bunce <kde@bunce.us> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 #include "static_binding.h" 00023 #include <kjs/interpreter.h> 00024 #include <kjs/function_object.h> 00025 #include <QtCore/QDebug> 00026 00027 namespace KJSEmbed { 00028 static QHash<QString,const Constructor*> g_ctorHash; 00029 } 00030 00031 using namespace KJSEmbed; 00032 00033 StaticBinding::StaticBinding(KJS::ExecState *exec, const Method *method ) 00034 : KJS::InternalFunctionImp(static_cast<KJS::FunctionPrototype*>(exec->lexicalInterpreter()->builtinFunctionPrototype()), 00035 method->name), 00036 m_method(method) 00037 { 00038 putDirect( exec->propertyNames().length, m_method->argc, LengthFlags ); 00039 } 00040 00041 KJS::JSValue *StaticBinding::callAsFunction( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args ) 00042 { 00043 if( m_method->call == 0 ) 00044 { 00045 //throwError(exec, "Bad method id"); // NOTE: fix 00046 KJS::throwError(exec, KJS::GeneralError, "Bad method id"); 00047 return KJS::jsNull(); 00048 } 00049 00050 KJS::JSValue *retValue = (*m_method->call)(exec,self,args); 00051 00052 if( exec->hadException() ) 00053 { 00054 return KJS::jsNull(); 00055 } 00056 return retValue; 00057 00058 } 00059 00060 void StaticBinding::publish( KJS::ExecState *exec, KJS::JSObject *object, const Method *methods ) 00061 { 00062 int idx = 0; 00063 while( methods[idx].name != 0 ) 00064 { 00065 object->put(exec, methods[idx].name, new StaticBinding(exec, &methods[idx]), methods[idx].flags); 00066 idx++; 00067 } 00068 } 00069 00070 StaticConstructor::StaticConstructor(KJS::ExecState *exec, const Constructor *constructor ) 00071 : KJS::InternalFunctionImp(static_cast<KJS::FunctionPrototype*>(exec->lexicalInterpreter()->builtinFunctionPrototype()), 00072 constructor->name), 00073 m_constructor( constructor ) 00074 { 00075 putDirect( exec->propertyNames().length, m_constructor->argc, LengthFlags ); 00076 m_default = KJS::jsNull(); 00077 } 00078 00079 KJS::JSObject *StaticConstructor::construct( KJS::ExecState *exec, const KJS::List &args ) 00080 { 00081 return (*m_constructor->construct)(exec,args); 00082 } 00083 00084 void StaticConstructor::setDefaultValue( KJS::JSValue *value ) 00085 { 00086 m_default = value; 00087 } 00088 00089 KJS::JSValue *StaticConstructor::defaultValue( KJS::ExecState * exec, KJS::JSType hint ) const 00090 { 00091 Q_UNUSED(exec); 00092 Q_UNUSED(hint); 00093 return m_default; 00094 } 00095 00096 KJS::JSObject *StaticConstructor::add( KJS::ExecState *exec, KJS::JSObject *object, const Constructor *constructor ) 00097 { 00098 KJS::JSObject *obj = new StaticConstructor(exec, constructor ); 00099 object->put(exec, constructor->name, obj); 00100 if( constructor->staticMethods ) 00101 { 00102 StaticBinding::publish( exec, obj, constructor->staticMethods ); 00103 } 00104 /* crashes for some reason */ 00105 if( constructor->enumerators ) 00106 { 00107 int idx = 0; 00108 while( constructor->enumerators[idx].name != 0 ) 00109 { 00110 obj->put( exec, constructor->enumerators[idx].name, 00111 KJS::jsNumber(constructor->enumerators[idx].value), KJS::DontDelete|KJS::ReadOnly); 00112 idx++; 00113 } 00114 } 00115 // publish methods 00116 KJSEmbed::g_ctorHash[constructor->name] = constructor; 00117 return obj; 00118 } 00119 00120 const Method *StaticConstructor::methods( const KJS::UString &className ) 00121 { 00122 return KJSEmbed::g_ctorHash[toQString(className)]->methods; 00123 } 00124 00125 const Constructor *StaticConstructor::constructor( const KJS::UString &className ) 00126 { 00127 return KJSEmbed::g_ctorHash[toQString(className)]; 00128 } 00129 00130 KJS::JSObject* StaticConstructor::bind(KJS::ExecState* exec, const QString& className, PointerBase& objPtr) 00131 { 00132 KJSEmbed::callBind mybind = KJSEmbed::g_ctorHash[className]->bind; 00133 // qDebug() << "StaticConstructor::bind() className=" << className << " mybind=" << mybind; 00134 if (mybind) 00135 return (*mybind)(exec, objPtr); 00136 00137 return 0; 00138 } 00139 00140 KJS::JSObject *StaticConstructor::construct( KJS::ExecState *exec, KJS::JSObject *parent, const KJS::UString &className, const KJS::List &args ) 00141 { 00142 // qDebug("StaticConstructor::construct('%s')", className.ascii() ); 00143 if( parent->hasProperty( exec, className.ascii() ) ) 00144 { 00145 KJS::JSObject *ctor = parent->get(exec,className.ascii())->toObject(exec); 00146 if( ctor ) 00147 { 00148 return ctor->construct( exec, args ); 00149 } 00150 } 00151 qDebug("cannot create '%s'", className.ascii() ); 00152 return KJS::throwError( exec, KJS::TypeError, toUString(QString("Cannot create %1 objects from javascript.").arg(toQString(className)) )); 00153 } 00154 00155 //kate: indent-spaces on; indent-width 4; replace-tabs on; indent-mode cstyle;
KDE 4.6 API Reference