/*
 * call-seq:
 *   node.eval(Object) => Object
 *
 * Evaluate a node with the given object as self and returns the result.
 */
static VALUE node_eval(VALUE node, VALUE self)
{
  NODE * n = unwrap_node(node);

  if(ruby_safe_level >= 2)
  {
    /* evaluating a node can cause a crash */
    rb_raise(rb_eSecurityError, "Insecure: can't add method");
  }

#ifdef RUBY_HAS_YARV
  {
    VALUE iseq = rb_iseq_new(
        n,
        rb_str_new2("<compiled>"),
        Qnil,
        self,
        ISEQ_TYPE_TOP);
    return rb_iseq_eval(iseq);
  }
#else
  {
    /* Ruby doesn't give us access to rb_eval, so we have to fake it. */
    struct BLOCK * b;
    VALUE proc;

    proc = create_proc(rb_cProc, Qnil, n, 0);
    Data_Get_Struct(proc, struct BLOCK, b);
    b->self = self;
    return rb_funcall(proc, rb_intern("call"), 0);
  }
#endif
}