void mrb_init_uefi_handle(mrb_state *mrb, struct RClass *mrb_uefi) { struct RClass *h_cls; h_cls = mrb_define_class_under(mrb, mrb_uefi, "Handle", mrb->object_class); MRB_SET_INSTANCE_TT(h_cls, MRB_TT_DATA); mrb_define_method(mrb, h_cls, "==", mrb_uefi_handle_eq, ARGS_REQ(1)); mrb_define_method(mrb, h_cls, "to_s", mrb_uefi_handle_to_s, ARGS_NONE()); mrb_define_method(mrb, h_cls, "inspect", mrb_uefi_handle_inspect, ARGS_NONE()); mrb_define_method(mrb, h_cls, "value", mrb_uefi_handle_value, ARGS_NONE()); mrb_const_set(mrb, mrb_obj_value(h_cls), mrb_intern(mrb, "NULL"), mrb_uefi_handle_make_helper(mrb, h_cls, NULL)); }
mrb_value cfunc_pointer_to_pointer(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); void *ptr = NULL; if(data->refer) { ptr = data->value._pointer; } else { ptr = &data->value._pointer; } mrb_value obj = cfunc_pointer_new_with_pointer(mrb, ptr, 0); mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), mrb_intern(mrb, "parent_pointer"), self); // keep for GC return obj; }
static int parser_settings_on_url(http_parser* parser, const char *at, size_t len) { int ai; mrb_http_parser_context *context = (mrb_http_parser_context*) parser->data; mrb_state* mrb = context->mrb; if(http_parser_parse_url(at, len, FALSE, &context->handle) != 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } ai = mrb_gc_arena_save(mrb); mrb_iv_set(mrb, context->instance, mrb_intern(mrb, "buf"), mrb_str_new(mrb, at, len)); mrb_gc_arena_restore(mrb, ai); return 0; }
static mrb_value mrb_http_request_host(mrb_state *mrb, mrb_value self) { mrb_value value_context; mrb_http_parser_context* context; value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context")); Data_Get_Struct(mrb, value_context, &http_parser_context_type, context); if (!context) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } if (context->handle.field_set & (1<<UF_HOST)) { return mrb_str_substr(mrb, PARSER_GET(context, "buf"), context->handle.field_data[UF_HOST].off, context->handle.field_data[UF_HOST].len); } return mrb_nil_value(); }
void* cfunc_rubyvm_open(void *args) { struct cfunc_rubyvm_data *data = args; mrb_state *mrb = mrb_open(); data->state = mrb; data->mrb_state_init(mrb); int n = mrb_read_irep(mrb, data->mrb_data); mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); if (mrb->exc) { return NULL; } while(true) { pthread_mutex_lock(&data->queue_mutex); while(data->queue->length == 0) { pthread_cond_wait(&data->queue_cond, &data->queue_mutex); } struct queue_task *task = vector_dequeue(data->queue); task->status = queue_task_running; mrb_sym taskname = mrb_intern(mrb, task->name); int args_len = task->args_len; mrb_value *args = malloc(sizeof(struct task_arg) * task->args_len); for(int i=0; i<task->args_len; ++i) { args[i] = task_arg_to_mrb_value(data->state, task->args[i]); } pthread_mutex_unlock(&data->queue_mutex); mrb_value result = mrb_funcall_argv(mrb, mrb_top_self(data->state), taskname, args_len, args); task->result = mrb_value_to_task_arg(mrb, result); task->status = queue_task_finished; pthread_cond_signal(&task->sync_cond); free(args); free_queue_task(task); } return NULL; }
static void showcallinfo(mrb_state *mrb) { mrb_callinfo *ci; mrb_int ciidx; const char *filename, *method, *sep; int i, line; printf("trace:\n"); ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "ciidx"))); if (ciidx >= mrb->ciend - mrb->cibase) ciidx = 10; /* ciidx is broken... */ for (i = ciidx; i >= 0; i--) { ci = &mrb->cibase[i]; filename = "(unknown)"; line = -1; if (MRB_PROC_CFUNC_P(ci->proc)) { continue; } else { mrb_irep *irep = ci->proc->body.irep; if (irep->filename != NULL) filename = irep->filename; if (irep->lines != NULL && i+1 <= ciidx) { mrb_code *pc = mrb->cibase[i+1].pc; if (irep->iseq <= pc && pc < irep->iseq + irep->ilen) { line = irep->lines[pc - irep->iseq - 1]; } } } if (ci->target_class == ci->proc->target_class) sep = "."; else sep = "#"; method = mrb_sym2name(mrb, ci->mid); printf("\t[%d] %s:%d%s%s%s%s\n", i, filename, line, method ? ":in " : "", method ? mrb_class_name(mrb, ci->proc->target_class) : "", method ? sep : "", method ? method : ""); } }
/* * call-seq: * global_variables -> array * * Returns an array of the names of global variables. * * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr] */ mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self) { iv_tbl *t = mrb->globals; mrb_value ary = mrb_ary_new(mrb); size_t i; char buf[3]; iv_foreach(mrb, t, gv_i, &ary); buf[0] = '$'; buf[2] = 0; for (i = 1; i <= 9; ++i) { buf[1] = (char)(i + '0'); mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2))); } return ary; }
static mrb_value mrb_struct_set_m(mrb_state *mrb, mrb_value obj) { mrb_value val; const char *name; mrb_int slen; mrb_sym mid; mrb_get_args(mrb, "o", &val); /* get base id */ name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen); mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */ return mrb_struct_aset_sym(mrb, obj, mid, val); }
static struct RClass * mrb_class_from_path(mrb_state *mrb, mrb_value path) { char *path_s; switch (path.tt) { case MRB_TT_SYMBOL : path_s = (char*) mrb_sym2name(mrb, mrb_symbol(path)); break; case MRB_TT_STRING : path_s = (char*) RSTRING_PTR(path); break; default: throw Exception(Exception::ArgumentError, "dump format error for symbol"); } /* If a symbol contains any colons, mrb_sym2name * will return the string with "s around it * (e.g. :Mod::Class => :"Mod::Class"), * so we need to skip those. */ if (path_s[0] == '\"') path_s++; char *p, *pbgn; mrb_value klass = mrb_obj_value(mrb->object_class); p = pbgn = path_s; while (*p && *p != '\"') { while (*p && *p != ':' && *p != '\"') p++; mrb_sym sym = mrb_intern(mrb, pbgn, p-pbgn); klass = mrb_const_get(mrb, klass, sym); if (p[0] == ':') { if (p[1] != ':') return 0; p += 2; pbgn = p; } } return (struct RClass*) mrb_obj_ptr(klass); }
static int read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc) { const uint8_t *bin; ptrdiff_t diff; struct rite_section_debug_header *header; uint16_t i; size_t len = 0; int result; uint16_t filenames_len; mrb_sym *filenames; bin = start; header = (struct rite_section_debug_header *)bin; bin += sizeof(struct rite_section_debug_header); filenames_len = bin_to_uint16(bin); bin += sizeof(uint16_t); filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len); for (i = 0; i < filenames_len; ++i) { uint16_t f_len = bin_to_uint16(bin); bin += sizeof(uint16_t); if (alloc) { filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); } else { filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len); } bin += f_len; } result = read_debug_record(mrb, bin, irep, &len, filenames, filenames_len); if (result != MRB_DUMP_OK) goto debug_exit; bin += len; diff = bin - start; mrb_assert(diff >= 0); mrb_assert(diff <= UINT32_MAX); if ((uint32_t)diff != bin_to_uint32(header->section_size)) { result = MRB_DUMP_GENERAL_FAILURE; } debug_exit: mrb_free(mrb, filenames); return result; }
// nil specific mrb_value cfunc_nil_addr(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); mrb_value ptr; if(data->refer) { ptr = cfunc_pointer_new_with_pointer(mrb, data->value._pointer, false); } else { ptr = cfunc_pointer_new_with_pointer(mrb, &data->value._pointer, false); } mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern(mrb, "parent_pointer"), self); // keep for GC return ptr; }
static mrb_value convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, int raise) { mrb_sym m = 0; m = mrb_intern(mrb, method); if (!mrb_respond_to(mrb, val, m)) { if (raise) { mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", val, mrb_str_new_cstr(mrb, tname)); return mrb_nil_value(); } else { return mrb_nil_value(); } } return mrb_funcall_argv(mrb, val, m, 0, 0); }
mrb_sym mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer) { mrb_value name; name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__classid__")); if (mrb_nil_p(name)) { struct csym_arg arg; arg.c = c; arg.sym = 0; iv_foreach(mrb, outer->iv, csym_i, &arg); return arg.sym; } return SYM2ID(name); }
static mrb_value cfunc_type_class_refer(mrb_state *mrb, mrb_value klass) { struct RClass *c = mrb_class_ptr(klass); struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); data->autofree = false; mrb_value pointer; mrb_get_args(mrb, "o", &pointer); data->refer = true; data->value._pointer = cfunc_pointer_ptr(pointer); struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_type_data, data); mrb_obj_iv_set(mrb, obj, mrb_intern(mrb, "parent_pointer"), pointer); // keep for GC return mrb_obj_value(obj); }
static mrb_value hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql) { if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value(); if (mrb_type(hash2) != MRB_TT_HASH) { if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) { return mrb_false_value(); } if (eql) return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1)); else return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1)); } if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) return mrb_false_value(); if (!RHASH(hash1)->ht || !RHASH(hash2)->ht) return mrb_true_value(); return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, (void*)0); }
void mrb_mruby_process_gem_init(mrb_state *mrb) { struct RClass *p; mrb_define_method(mrb, mrb->kernel_module, "exit", mrb_f_exit, ARGS_OPT(1)); mrb_define_method(mrb, mrb->kernel_module, "sleep", mrb_f_sleep, ARGS_ANY()); mrb_define_method(mrb, mrb->kernel_module, "system", mrb_f_system, ARGS_ANY()); p = mrb_define_module(mrb, "Process"); mrb_define_class_method(mrb, p, "kill", mrb_f_kill, ARGS_ANY()); mrb_define_class_method(mrb, p, "fork", mrb_f_fork, ARGS_NONE()); mrb_define_class_method(mrb, p, "waitpid", mrb_f_waitpid, ARGS_ANY()); mrb_define_class_method(mrb, p, "pid", mrb_f_pid, ARGS_NONE()); mrb_define_class_method(mrb, p, "ppid", mrb_f_ppid, ARGS_NONE()); mrb_gv_set(mrb, mrb_intern(mrb, "$$"), mrb_fixnum_value((mrb_int)getpid())); }
static mrb_sym get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name) { mrb_sym iv_name_id; mrb_assert(mrb_symbol_p(iv_name) || mrb_string_p(iv_name)); if (mrb_string_p(iv_name)) { iv_name_id = mrb_intern(mrb, RSTRING_PTR(iv_name), RSTRING_LEN(iv_name)); valid_iv_name(mrb, iv_name_id, RSTRING_PTR(iv_name), RSTRING_LEN(iv_name)); } else { iv_name_id = mrb_symbol(iv_name); check_iv_name(mrb, iv_name_id); } return iv_name_id; }
/******************************************************************************* * Rect class ******************************************************************************/ static mrb_value mrb_sdl_rect_init (mrb_state *mrb, mrb_value self) { SDL_Rect rect; mrb_get_args(mrb, "|i", &rect.x); mrb_get_args(mrb, "|i", &rect.y); mrb_get_args(mrb, "|i", &rect.w); mrb_get_args(mrb, "|i", &rect.h); mrb_sdl_context* context = sdl_context_alloc(mrb); context->any.rect = ▭ context->instance = mrb_nil_value(); mrb_iv_set(mrb, self, mrb_intern(mrb, "context"), mrb_obj_value( Data_Wrap_Struct(mrb, mrb->object_class, &sdl_context_type, (void*) context) )); return self; }
mrb_sym mrb_id_attrset(mrb_state *mrb, mrb_sym id) { const char *name; char *buf; mrb_int len; mrb_sym mid; name = mrb_sym2name_len(mrb, id, &len); buf = (char *)mrb_malloc(mrb, (size_t)len+2); memcpy(buf, name, (size_t)len); buf[len] = '='; buf[len+1] = '\0'; mid = mrb_intern(mrb, buf, len+1); mrb_free(mrb, buf); return mid; }
/******************************************************************************* * Color class ******************************************************************************/ static mrb_value mrb_sdl_color_init (mrb_state *mrb, mrb_value self) { SDL_Color color; mrb_get_args(mrb, "|i", &color.r); mrb_get_args(mrb, "|i", &color.g); mrb_get_args(mrb, "|i", &color.b); mrb_get_args(mrb, "|i", &color.unused); mrb_sdl_context* context = sdl_context_alloc(mrb); context->any.color = &color; context->instance = mrb_nil_value(); mrb_iv_set(mrb, self, mrb_intern(mrb, "context"), mrb_obj_value( Data_Wrap_Struct(mrb, mrb->object_class, &sdl_context_type, (void*) context) )); return self; }
static mrb_value mrb_http_request_method(mrb_state *mrb, mrb_value self) { mrb_value value_context; mrb_http_parser_context* context; const char* method; value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context")); Data_Get_Struct(mrb, value_context, &http_parser_context_type, context); if (!context) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } method = http_method_str(context->parser.method); ARENA_SAVE; mrb_value str = mrb_str_new(mrb, method, strlen(method)); ARENA_RESTORE; return str; }
struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name) { struct RClass * c; mrb_sym id = mrb_intern(mrb, name); if (mrb_const_defined_at(mrb, outer, id)) { c = mrb_class_from_sym(mrb, outer, id); if (c->tt != MRB_TT_MODULE) { mrb_raise(mrb, E_TYPE_ERROR, "%s is not a module", mrb_sym2name(mrb, id)); } return c; } c = mrb_module_new(mrb); setup_class(mrb, mrb_obj_value(outer), c, id); mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c)); return c; }
int main(int argc, char **argv) { mrb_state *mrb; mrb = mrb_open(); if (mrb == NULL) { fprintf(stderr, "Invalid mrb_state, exiting driver"); return EXIT_FAILURE; } #if 0 mrb_iv_set(mrb, mrb_obj_value(mrb->kernel_module), mrb_intern(mrb, "@loaded_compiled_mrb_handles"), mrb_ary_new(mrb)); #endif mrbb_exec_entry_point_for_mrblib(mrb, mrb_top_self(mrb)); MRBB_EXEC_ENTRY_POINT(mrb, mrb_top_self(mrb)); mrb_close(mrb); return EXIT_SUCCESS; }
mrb_value task_arg_to_mrb_value(mrb_state *mrb, struct task_arg* arg) { mrb_value v; mrb_type(v) = arg->tt; switch (arg->tt) { case MRB_TT_FALSE: case MRB_TT_TRUE: case MRB_TT_FIXNUM: v.value.i = arg->value.i; break; case MRB_TT_FLOAT: v.value.f = arg->value.f; break; case MRB_TT_SYMBOL: v.value.sym = mrb_intern(mrb, arg->value.string.ptr); break; case MRB_TT_STRING: v = mrb_str_new(mrb, arg->value.string.ptr, arg->value.string.len); break; case MRB_TT_ARRAY: { v = mrb_ary_new_capa(mrb, arg->value.array.len); struct RArray *ary = mrb_ary_ptr(v); ary->len = arg->value.array.len; int i; for(i=0; i<arg->value.array.len; i++) { ary->ptr[i] = task_arg_to_mrb_value(mrb, arg->value.array.ptr[i]); } } break; default: mrb_raise(mrb, E_TYPE_ERROR, "cannot pass to other RubyVM"); break; } return v; }
/******************************************************************************* * Palette class ******************************************************************************/ static mrb_value mrb_sdl_palette_init (mrb_state *mrb, mrb_value self) { SDL_Palette palette; mrb_value arg_colors = mrb_nil_value(); mrb_get_args(mrb, "|i", &palette.ncolors); mrb_get_args(mrb, "|o", &arg_colors); palette.colors = mrb_value_to_sdl_color(mrb, arg_colors); mrb_sdl_context* context = sdl_context_alloc(mrb); context->any.palette = &palette; context->instance = mrb_nil_value(); mrb_iv_set(mrb, self, mrb_intern(mrb, "context"), mrb_obj_value( Data_Wrap_Struct(mrb, mrb->object_class, &sdl_context_type, (void*) context) )); return self; }
mrb_value mrb_struct_define(mrb_state *mrb, const char *name, ...) { va_list ar; mrb_value nm, ary; char *mem; if (!name) nm = mrb_nil_value(); else nm = mrb_str_new2(mrb, name); ary = mrb_ary_new(mrb); va_start(ar, name); while ((mem = va_arg(ar, char*)) != 0) { mrb_sym slot = mrb_intern(mrb, mem); mrb_ary_push(mrb, ary, mrb_symbol_value(slot)); } va_end(ar); return make_struct(mrb, nm, ary, struct_class(mrb)); }
static mrb_value mrb_http_url_port(mrb_state *mrb, mrb_value self) { mrb_value value_context; struct http_parser_url* context; value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context")); Data_Get_Struct(mrb, value_context, &http_url_type, context); if (!context) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } if (context->field_set & (1<<UF_PORT)) { return mrb_fixnum_value(context->port); } mrb_value schema = mrb_http_url_schema(mrb, self); if (!mrb_nil_p(schema) && !strncmp("https", (char*) RSTRING_PTR(schema), RSTRING_LEN(schema))) { return mrb_fixnum_value(443); } return mrb_fixnum_value(80); }
static mrb_value mrb_http_parser_parse_request(mrb_state *mrb, mrb_value self) { mrb_value arg_data = mrb_nil_value(); mrb_value value_context; mrb_http_parser_context* context; mrb_value b = mrb_nil_value(); value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context")); Data_Get_Struct(mrb, value_context, &http_parser_context_type, context); if (!context) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } mrb_get_args(mrb, "|&o", &b, &arg_data); if (mrb_nil_p(arg_data)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } context->proc = b; context->parser.data = context; context->was_header_value = TRUE; PARSER_SET(context, "headers", mrb_hash_new(mrb)); http_parser_init(&context->parser, HTTP_REQUEST); context->settings.on_url = parser_settings_on_url; context->settings.on_header_field = parser_settings_on_header_field; context->settings.on_header_value = parser_settings_on_header_value; context->settings.on_headers_complete = parser_settings_on_headers_complete; if (!mrb_nil_p(b)) { context->settings.on_message_complete = parser_settings_on_message_complete; } if (RSTRING_LEN(arg_data) > 0) { char* data = RSTRING_PTR(arg_data); size_t len = RSTRING_LEN(arg_data); http_parser_execute(&context->parser, &context->settings, data, len); } return mrb_nil_value(); }
static mrb_value hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql) { khash_t(ht) *h1, *h2; if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value(); if (!mrb_hash_p(hash2)) { if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) { return mrb_false_value(); } if (eql) return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1)); else return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1)); } h1 = RHASH_TBL(hash1); h2 = RHASH_TBL(hash2); if (!h1) { if (!h2) return mrb_true_value(); return mrb_false_value(); } if (!h2) return mrb_false_value(); if (kh_size(h1) != kh_size(h2)) return mrb_false_value(); else { khiter_t k1, k2; mrb_value key; for (k1 = kh_begin(h1); k1 != kh_end(h1); k1++) { if (!kh_exist(h1, k1)) continue; key = kh_key(h1,k1); k2 = kh_get(ht, h2, key); if (k2 != kh_end(h2)) { if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) { continue; /* next key */ } } return mrb_false_value(); } } return mrb_true_value(); }
MrbData::MrbData(mrb_state *mrb) { int arena = mrb_gc_arena_save(mrb); for (int i = 0; i < excDataN; ++i) exc[excData[i].ind] = mrb_define_class(mrb, excData[i].str, mrb->eException_class); RClass *errnoMod = mrb_define_module(mrb, "Errno"); for (int i = 0; i < enoExcDataN; ++i) exc[enoExcData[i].ind] = mrb_define_class_under(mrb, errnoMod, enoExcData[i].str, mrb->eStandardError_class); exc[TypeError] = mrb_class_get(mrb, "TypeError"); exc[ArgumentError] = mrb_class_get(mrb, "ArgumentError"); for (int i = 0; i < symDataN; ++i) symbols[symData[i].ind] = mrb_intern(mrb, symData[i].str); mrb_gc_arena_restore(mrb, arena); }