00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "rubyscript.h"
00021
00022 #include <ruby.h>
00023 #include <env.h>
00024 #include <rubysig.h>
00025 #include <node.h>
00026
00027 #include <main/scriptcontainer.h>
00028
00029 #include "rubyconfig.h"
00030 #include "rubyextension.h"
00031 #include "rubyinterpreter.h"
00032
00033 extern NODE *ruby_eval_tree;
00034
00035 namespace Kross {
00036
00037 namespace Ruby {
00038
00039 class RubyScriptPrivate {
00040 friend class RubyScript;
00041 RubyScriptPrivate() : m_compile(0) { }
00042 RNode* m_compile;
00043
00044 QStringList m_functions;
00045
00046
00047 QStringList m_classes;
00048 };
00049
00050 RubyScript::RubyScript(Kross::Api::Interpreter* interpreter, Kross::Api::ScriptContainer* scriptcontainer)
00051 : Kross::Api::Script(interpreter, scriptcontainer), d(new RubyScriptPrivate())
00052 {
00053 }
00054
00055
00056 RubyScript::~RubyScript()
00057 {
00058 }
00059
00060 #define selectScript() \
00061 NODE* old_tree = ruby_eval_tree; \
00062 ruby_eval_tree = d->m_compile;
00063 #define unselectScript() \
00064 ruby_eval_tree = old_tree;
00065
00066 void RubyScript::compile()
00067 {
00068 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00069 kdDebug() << "RubyScript::compile()" << endl;
00070 #endif
00071 int critical;
00072
00073 ruby_nerrs = 0;
00074 ruby_errinfo = Qnil;
00075 VALUE src = RubyExtension::toVALUE( m_scriptcontainer->getCode() );
00076 StringValue(src);
00077 critical = rb_thread_critical;
00078 rb_thread_critical = Qtrue;
00079 ruby_in_eval++;
00080 d->m_compile = rb_compile_string((char*) m_scriptcontainer->getName().latin1(), src, 0);
00081 ruby_in_eval--;
00082 rb_thread_critical = critical;
00083
00084 if (ruby_nerrs != 0)
00085 {
00086 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00087 kdDebug() << "Compilation has failed" << endl;
00088 #endif
00089 setException( new Kross::Api::Exception(QString("Failed to compile ruby code: %1").arg(STR2CSTR( rb_obj_as_string(ruby_errinfo) )), 0) );
00090 d->m_compile = 0;
00091 }
00092 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00093 kdDebug() << "Compilation was successfull" << endl;
00094 #endif
00095 }
00096
00097 const QStringList& RubyScript::getFunctionNames()
00098 {
00099 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00100 kdDebug() << "RubyScript::getFunctionNames()" << endl;
00101 #endif
00102 if(d->m_compile == 0)
00103 {
00104 compile();
00105 }
00106 return d->m_functions;
00107 }
00108
00109 Kross::Api::Object::Ptr RubyScript::execute()
00110 {
00111 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00112 kdDebug() << "RubyScript::execute()" << endl;
00113 #endif
00114 if(d->m_compile == 0)
00115 {
00116 compile();
00117 }
00118 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00119 kdDebug() << "Start execution" << endl;
00120 #endif
00121 selectScript();
00122 int result = ruby_exec();
00123 if (result != 0)
00124 {
00125 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00126 kdDebug() << "Execution has failed" << endl;
00127 #endif
00128 setException( new Kross::Api::Exception(QString("Failed to execute ruby code: %1").arg(STR2CSTR( rb_obj_as_string(ruby_errinfo) )), 0) );
00129 d->m_compile = 0;
00130 }
00131
00132 unselectScript();
00133 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00134 kdDebug() << "Execution is finished" << endl;
00135 #endif
00136 return 0;
00137 }
00138
00139 Kross::Api::Object::Ptr RubyScript::callFunction(const QString& name, Kross::Api::List::Ptr args)
00140 {
00141 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00142 kdDebug() << "RubyScript::callFunction()" << endl;
00143 #endif
00144 if(d->m_compile == 0)
00145 {
00146 compile();
00147 }
00148 selectScript();
00149 unselectScript();
00150 return 0;
00151 }
00152
00153 const QStringList& RubyScript::getClassNames()
00154 {
00155 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00156 kdDebug() << "RubyScript::getClassNames()" << endl;
00157 #endif
00158 if(d->m_compile == 0)
00159 {
00160 compile();
00161 }
00162 return d->m_classes;
00163 }
00164
00165 Kross::Api::Object::Ptr RubyScript::classInstance(const QString& name)
00166 {
00167 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00168 kdDebug() << "RubyScript::classInstance()" << endl;
00169 #endif
00170 if(d->m_compile == 0)
00171 {
00172 compile();
00173 }
00174 selectScript();
00175 unselectScript();
00176 return 0;
00177 }
00178
00179
00180 }
00181
00182 }