00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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
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
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
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