Ejemplo n.º 1
0
    void RubyEvaluator::Evaluate(const ValueList& args, KValueRef result)
    {
        args.VerifyException("evaluate", "s s s o");
        
        //const char *mimeType = args.GetString(0).c_str();
        std::string name = args.GetString(1);
        std::string code = args.GetString(2);
        global_object = args.GetObject(3);

        VALUE ctx = this->GetContext(global_object);

        VALUE rargs = rb_ary_new();
        rb_ary_push(rargs, ctx);
        rb_ary_push(rargs, rb_str_new2(code.c_str()));

        int error;
        VALUE returnValue = rb_protect(reval_do_call, rargs, &error);
        RubyEvaluator::ContextToGlobal(ctx, global_object);

        if (error != 0)
        {
            std::string error("An error occured while parsing Ruby (");
            error += name;
            error += "): ";

            // Display a stringified version of the exception.
            VALUE exception = rb_gv_get("$!");
            KValueRef v = RubyUtils::ToKrollValue(exception);
            SharedString ss = v->DisplayString();
            error.append(ss->c_str());

            // Try to make a nice backtrace for the user.
            VALUE backtrace = rb_funcall(exception,
                rb_intern("backtrace"), 0);
            VALUE rBacktraceString = rb_funcall(backtrace,
                rb_intern("join"), 1, rb_str_new2("\n"));
            if (TYPE(rBacktraceString) == T_STRING)
            {
                error.append("\n");
                error.append(StringValuePtr(rBacktraceString));
            }

            Logger *logger = Logger::Get("Ruby");
            logger->Error(error);

            result->SetUndefined();
            return;
        }

        result->SetValue(RubyUtils::ToKrollValue(returnValue));
    }