SLVAL sl_regexp_match(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv) { sl_regexp_t* re = get_regexp_check(vm, self); sl_string_t* str = sl_get_string(vm, argv[0]); int offset = 0, rc, ncaps; int* caps; sl_regexp_match_t* match; if(argc > 1) { offset = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int)); } offset = sl_string_byte_offset_for_index(vm, argv[0], offset); if(offset < 0) { return vm->lib.nil; } pcre_fullinfo(re->re, re->study, PCRE_INFO_CAPTURECOUNT, &ncaps); ncaps += 1; ncaps *= 3; caps = sl_alloc(vm->arena, sizeof(int) * ncaps); rc = pcre_exec(re->re, re->study, (char*)str->buff, str->buff_len, offset, PCRE_NEWLINE_LF, caps, ncaps); if(rc == PCRE_ERROR_NOMATCH) { return vm->lib.nil; } check_pcre_error(vm, rc); match = (sl_regexp_match_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Regexp_Match)); match->re = re; match->match_string = argv[0]; match->capture_count = ncaps / 3; match->captures = caps; return sl_make_ptr((sl_object_t*)match); }
SLVAL sl_make_float(sl_vm_t* vm, double d) { SLVAL fl = sl_allocate(vm, vm->lib.Float); get_float(vm, fl)->d = d; return fl; }
SLVAL sl_make_regexp(sl_vm_t* vm, uint8_t* re_buff, size_t re_len, uint8_t* opts_buff, size_t opts_len) { SLVAL rev = sl_allocate(vm, vm->lib.Regexp); sl_regexp_t* re_ptr = get_regexp(vm, rev); sl_setup_regexp(vm, re_ptr, re_buff, re_len, opts_buff, opts_len); return rev; }
static SLVAL make_ruby_object(sl_vm_t* vm, VALUE ruby_value) { SLVAL Ruby_Object = sl_vm_store_get(vm, &cRuby_Object); SLVAL robj = sl_allocate(vm, Ruby_Object); ((sl_ruby_object_t*)sl_get_ptr(robj))->obj = ruby_value; return robj; }
static void make_algorithm_object(sl_vm_t* vm, SLVAL GCrypt, SLVAL Algorithm, char* name, int algo) { SLVAL obj = sl_allocate(vm, Algorithm); gcrypt_algorithm_t* ptr = (gcrypt_algorithm_t*)sl_get_ptr(obj); ptr->name = sl_make_cstring(vm, name); ptr->algo = algo; sl_class_set_const2(vm, GCrypt, ptr->name, obj); }
void sl_init_true(sl_vm_t* vm) { vm->lib.True = sl_define_class(vm, "True", vm->lib.Object); sl_class_set_allocator(vm, vm->lib.True, allocate_true); sl_define_method(vm, vm->lib.True, "to_s", 0, true_to_s); sl_define_method(vm, vm->lib.True, "inspect", 0, true_to_s); sl_define_method(vm, vm->lib.True, "==", 1, true_eq); vm->lib._true = sl_allocate(vm, vm->lib.True); }
SLVAL sl_make_range_exclusive(sl_vm_t* vm, SLVAL lower, SLVAL upper) { SLVAL rangev = sl_allocate(vm, vm->lib.Range); sl_range_t* range = get_range(vm, rangev); range->left = lower; range->right = upper; range->exclusive = 1; return rangev; }
static SLVAL range_enumerate(sl_vm_t* vm, SLVAL self) { sl_range_t* range = get_range(vm, self); sl_range_enumerator_t* range_enum = get_range_enumerator(vm, sl_allocate(vm, vm->lib.Range_Enumerator)); range_enum->current = range->left; range_enum->right = range->right; range_enum->method = range->exclusive ? vm->id.op_lt : vm->id.op_lte; range_enum->state = ES_BEFORE; return sl_make_ptr((sl_object_t*)range_enum); }
static SLVAL bound_method_unbind(sl_vm_t* vm, SLVAL bmethod) { sl_bound_method_t* bmethp = (sl_bound_method_t*)sl_get_ptr(bmethod); sl_method_t* methp = (sl_method_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Method)); methp->name = bmethp->method.name; methp->is_c_func = bmethp->method.is_c_func; methp->arity = bmethp->method.arity; methp->klass = bmethp->method.klass; methp->as = bmethp->method.as; methp->initialized = 1; return sl_make_ptr((sl_object_t*)methp); }
SLVAL sl_make_string_no_copy(sl_vm_t* vm, uint8_t* buff, size_t buff_len) { ensure_utf8(vm, buff, buff_len); SLVAL vstr = sl_allocate(vm, vm->lib.String); sl_string_t* str = (sl_string_t*)sl_get_ptr(vstr); str->char_len = sl_utf8_strlen(vm, buff, buff_len); str->buff = buff; str->buff_len = buff_len; str->hash_set = 0; return vstr; }
SLVAL sl_make_c_func(sl_vm_t* vm, SLVAL klass, SLID name, int arity, SLVAL(*c_func)()) { SLVAL method = sl_allocate(vm, vm->lib.Method); sl_method_t* methp = (sl_method_t*)sl_get_ptr(method); methp->name = name; methp->is_c_func = 1; methp->arity = arity; methp->klass = sl_expect(vm, klass, vm->lib.Class); methp->as.c.func = c_func; methp->initialized = 1; return method; }
SLVAL sl_make_c_func(sl_vm_t* vm, SLVAL klass, SLID name, int arity, SLVAL(*c_func)()) { SLVAL method = sl_allocate(vm, vm->lib.Method); sl_method_t* methp = (sl_method_t*)sl_get_ptr(method); methp->extra->name = name; methp->arity = arity; methp->extra->klass = sl_expect(vm, klass, vm->lib.Class); methp->as.c.func = c_func; methp->base.user_flags |= SL_FLAG_METHOD_INITIALIZED | SL_FLAG_METHOD_IS_C_FUNC; return method; }
static void sl_ruby_protect(sl_vm_t* vm, void(*func)(sl_vm_t*,void*), void* data) { struct sl_ruby_protect_args args = { vm, data, func, 0, { 0 } }; sl_vm_frame_t frame; pthread_mutex_lock(&sl_ruby_lock); SL_ENSURE(frame, { rb_rescue2(sl_ruby_protect_try, (VALUE)&args, sl_ruby_protect_catch, (VALUE)&args, rb_eException, 0); pthread_mutex_unlock(&sl_ruby_lock); if(args.exception) { SLVAL Ruby_Exception = sl_vm_store_get(vm, &cRuby_Exception); SLVAL err = sl_allocate(vm, Ruby_Exception); sl_error_set_message(vm, err, sl_ruby_to_slash(vm, rb_obj_as_string(args.exception))); sl_set_ivar(vm, err, sl_intern(vm, "object"), make_ruby_object(vm, args.exception)); args.sl_exception = err; } }, {
static SLVAL sl_mysql_prepare(sl_vm_t* vm, SLVAL self, SLVAL query) { mysql_t* mysql = get_mysql(vm, self); SLVAL stmtv = sl_allocate(vm, vm->store[cMySQL_Statement]); mysql_stmt_t* stmt = sl_data_get_ptr(vm, &mysql_stmt_data_type, stmtv); stmt->mysql = mysql; if(!(stmt->stmt = mysql_stmt_init(&mysql->mysql))) { sl_mysql_check_error(vm, &mysql->mysql); } sl_string_t* str = sl_get_string(vm, query); if(mysql_stmt_prepare(stmt->stmt, (char*)str->buff, str->buff_len)) { sl_mysql_stmt_check_error(vm, stmt->stmt); } return stmtv; }
SLVAL sl_make_method(sl_vm_t* vm, SLVAL klass, SLID name, sl_vm_section_t* section, sl_vm_exec_ctx_t* parent_ctx) { SLVAL method = sl_allocate(vm, vm->lib.Method); sl_method_t* methp = (sl_method_t*)sl_get_ptr(method); methp->name = name; methp->is_c_func = 0; if(section->req_registers < section->arg_registers) { methp->arity = -section->req_registers - 1; } else { methp->arity = (int)section->arg_registers; } methp->klass = sl_expect(vm, klass, vm->lib.Class); methp->as.sl.section = section; methp->as.sl.parent_ctx = parent_ctx; methp->initialized = 1; return method; }
SLVAL sl_make_string(sl_vm_t* vm, uint8_t* buff, size_t buff_len) { SLVAL vstr = sl_allocate(vm, vm->lib.String); sl_string_t* str = (sl_string_t*)sl_get_ptr(vstr); if(sl_is_valid_utf8(buff, buff_len)) { str->encoding = "UTF-8"; str->char_len = sl_utf8_strlen(vm, buff, buff_len); } else { str->encoding = "CP1252"; str->char_len = buff_len; } str->buff = sl_alloc_buffer(vm->arena, buff_len + 1); memcpy(str->buff, buff, buff_len); str->buff[buff_len] = 0; str->buff_len = buff_len; str->hash_set = 0; return vstr; }
SLVAL sl_make_method(sl_vm_t* vm, SLVAL klass, SLID name, sl_vm_section_t* section, sl_vm_exec_ctx_t* parent_ctx) { SLVAL method = sl_allocate(vm, vm->lib.Method); sl_method_t* methp = (sl_method_t*)sl_get_ptr(method); methp->extra->name = name; if(section->req_registers < section->arg_registers) { methp->arity = -section->req_registers - 1; } else if(section->has_extra_rest_arg) { methp->arity = -(int)section->req_registers - 1; } else { methp->arity = (int)section->req_registers; } methp->extra->klass = sl_expect(vm, klass, vm->lib.Class); methp->as.sl.section = section; methp->as.sl.parent_ctx = parent_ctx; methp->base.user_flags |= SL_FLAG_METHOD_INITIALIZED; return method; }
SLVAL sl_method_bind(sl_vm_t* vm, SLVAL method, SLVAL receiver) { sl_method_t* methp = (sl_method_t*)sl_get_ptr(method); sl_bound_method_t* bmethp = (sl_bound_method_t*)sl_get_ptr(sl_allocate(vm, vm->lib.BoundMethod)); if(!methp->initialized) { sl_throw_message2(vm, vm->lib.TypeError, "Can't bind uninitialized Method"); } bmethp->method.initialized = 1; bmethp->method.name = methp->name; bmethp->method.klass = methp->klass; bmethp->method.is_c_func = methp->is_c_func; bmethp->method.arity = methp->arity; bmethp->method.as = methp->as; bmethp->self = sl_expect(vm, receiver, methp->klass); return sl_make_ptr((sl_object_t*)bmethp); }
SLVAL sl_string_lower(sl_vm_t* vm, SLVAL selfv) { sl_string_t* self = sl_get_string(vm, selfv); sl_string_t* retn = sl_get_string(vm, sl_allocate(vm, vm->lib.String)); memcpy(retn, self, sizeof(sl_string_t)); retn->buff = sl_alloc_buffer(vm->arena, retn->buff_len); size_t len = self->buff_len; uint8_t* buff = self->buff; size_t out_offset = 0; uint32_t lower_c; while(len) { uint32_t c = sl_utf8_each_char(vm, &buff, &len); lower_c = sl_unicode_tolower(c); out_offset += sl_utf32_char_to_utf8(vm, lower_c, retn->buff + out_offset); } return sl_make_ptr((sl_object_t*)retn); }
SLVAL sl_regexp_match(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv) { sl_regexp_t* re = get_regexp_check(vm, self); sl_string_t* str = sl_get_string(vm, argv[0]); int offset = 0, rc, ncaps; int* caps; char err_buff[256]; sl_regexp_match_t* match; if(argc > 1) { offset = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int)); } offset = sl_string_byte_offset_for_index(vm, argv[0], offset); if(offset < 0) { return vm->lib.nil; } pcre_fullinfo(re->re, re->study, PCRE_INFO_CAPTURECOUNT, &ncaps); ncaps += 1; ncaps *= 3; caps = sl_alloc(vm->arena, sizeof(int) * ncaps); rc = pcre_exec(re->re, re->study, (char*)str->buff, str->buff_len, offset, PCRE_NEWLINE_LF, caps, ncaps); if(rc < 0) { if(rc == PCRE_ERROR_NOMATCH) { return vm->lib.nil; } if(rc == PCRE_ERROR_BADUTF8) { sl_throw_message2(vm, vm->lib.EncodingError, "Invalid UTF-8 in regular expression or match text"); } sprintf(err_buff, "PCRE error (%d)", rc); sl_throw_message2(vm, vm->lib.Error, err_buff); } match = (sl_regexp_match_t*)sl_get_ptr(sl_allocate(vm, vm->lib.Regexp_Match)); match->re = re; match->match_string = argv[0]; match->capture_count = ncaps / 3; match->captures = caps; return sl_make_ptr((sl_object_t*)match); }