<commit_before>#include "builtin/class.hpp"
#include "builtin/exception.hpp"
#include "builtin/proc.hpp"
#include "builtin/string.hpp"

#include "exception_point.hpp"

#include "capi/capi.hpp"
#include "capi/ruby.h"

using namespace rubinius;

extern "C" {
#define RB_EXC_BUFSIZE   256

  void rb_raise(VALUE error_handle, const char* format_string, ...) {
    va_list args;
    char reason[RB_EXC_BUFSIZE];

    va_start(args, format_string);
    vsnprintf(reason, RB_EXC_BUFSIZE, format_string, args);
    va_end(args);

    capi::capi_raise_backend(error_handle, reason);

    rubinius::bug("rb_raise failed");
    exit(1);  // compiler snack.
  }

  void rb_throw_obj(VALUE obj, VALUE result) {
    rb_funcall(rb_mKernel, rb_intern("throw"), 2, obj, result);
    rubinius::bug("rb_throw failed");
    exit(1);  // compiler snack.
  }

  void rb_throw(const char* symbol, VALUE result) {
    rb_throw_obj(ID2SYM(rb_intern(symbol)), result);
    exit(1);  // compiler snack.
  }

  VALUE rb_catch_obj(VALUE tag, VALUE (*func)(ANYARGS), VALUE data) {
    VALUE proc = rb_proc_new(func, data);
    return rb_funcall2b(rb_mKernel, rb_intern("catch"), 1, &tag, proc);
  }

  VALUE rb_catch(const char* tag, VALUE(*func)(ANYARGS), VALUE data) {
    return rb_catch_obj(ID2SYM(rb_intern(tag)), func, data);
  }

  VALUE rb_rescue2(VALUE (*func)(ANYARGS), VALUE arg1,
                   VALUE (*raise_func)(ANYARGS), VALUE arg2, ...)
  {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();
    VALUE ret = Qnil;
    ExceptionPoint ep(env);
    va_list exc_classes;

    PLACE_EXCEPTION_POINT(ep);
    if(unlikely(ep.jumped_to())) {
      ep.pop(env);

      if(env->state()->thread_state()->raise_reason() != cException) {
        //Something bad happened, we shouldn't be here.
        return Qnil;
      }

      VALUE exc_handle = env->get_handle(env->state()->thread_state()->current_exception());
      bool handle_exc = false;

      va_start(exc_classes, arg2);
      while(VALUE eclass = va_arg(exc_classes, VALUE)) {
        if(RTEST(rb_obj_is_kind_of(exc_handle, eclass))) {
          handle_exc = true;
          break;
        }
      }
      va_end(exc_classes);

      if(handle_exc) {
        ret = (*raise_func)(arg2, exc_handle);
        env->state()->thread_state()->clear_raise();
      } else {
        env->current_ep()->return_to(env);
      }

    } else {
      ret = (*func)(arg1);<commit_msg>Make rb_rescue returns the break value when passed function yields to a block with a break<commit_after>#include "builtin/class.hpp"
#include "builtin/exception.hpp"
#include "builtin/proc.hpp"
#include "builtin/string.hpp"

#include "exception_point.hpp"

#include "capi/capi.hpp"
#include "capi/ruby.h"

using namespace rubinius;

extern "C" {
#define RB_EXC_BUFSIZE   256

  void rb_raise(VALUE error_handle, const char* format_string, ...) {
    va_list args;
    char reason[RB_EXC_BUFSIZE];

    va_start(args, format_string);
    vsnprintf(reason, RB_EXC_BUFSIZE, format_string, args);
    va_end(args);

    capi::capi_raise_backend(error_handle, reason);

    rubinius::bug("rb_raise failed");
    exit(1);  // compiler snack.
  }

  void rb_throw_obj(VALUE obj, VALUE result) {
    rb_funcall(rb_mKernel, rb_intern("throw"), 2, obj, result);
    rubinius::bug("rb_throw failed");
    exit(1);  // compiler snack.
  }

  void rb_throw(const char* symbol, VALUE result) {
    rb_throw_obj(ID2SYM(rb_intern(symbol)), result);
    exit(1);  // compiler snack.
  }

  VALUE rb_catch_obj(VALUE tag, VALUE (*func)(ANYARGS), VALUE data) {
    VALUE proc = rb_proc_new(func, data);
    return rb_funcall2b(rb_mKernel, rb_intern("catch"), 1, &tag, proc);
  }

  VALUE rb_catch(const char* tag, VALUE(*func)(ANYARGS), VALUE data) {
    return rb_catch_obj(ID2SYM(rb_intern(tag)), func, data);
  }

  VALUE rb_rescue2(VALUE (*func)(ANYARGS), VALUE arg1,
                   VALUE (*raise_func)(ANYARGS), VALUE arg2, ...)
  {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();
    VALUE ret = Qnil;
    ExceptionPoint ep(env);
    va_list exc_classes;

    PLACE_EXCEPTION_POINT(ep);
    if(unlikely(ep.jumped_to())) {
      ep.pop(env);

      if(env->state()->thread_state()->raise_reason() != cException) {
        env->current_ep()->return_to(env);
      }

      VALUE exc_handle = env->get_handle(env->state()->thread_state()->current_exception());
      bool handle_exc = false;

      va_start(exc_classes, arg2);
      while(VALUE eclass = va_arg(exc_classes, VALUE)) {
        if(RTEST(rb_obj_is_kind_of(exc_handle, eclass))) {
          handle_exc = true;
          break;
        }
      }
      va_end(exc_classes);

      if(handle_exc) {
        ret = (*raise_func)(arg2, exc_handle);
        env->state()->thread_state()->clear_raise();
      } else {
        env->current_ep()->return_to(env);
      }

    } else {
      ret = (*func)(arg1);
{'fraction_non_alphanumeric': 0.14349867319861195, 'fraction_numerical': 0.00694019187589304, 'mean_word_length': 3.3946188340807173, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5857338', 'n_tokens_mistral': 1755, 'n_tokens_neox': 1689, 'n_words': 328}