slint_t sort_counting_get_counts(elements_t *s, elements_t *d, slint_t ncounts, slint_t *counts) /* sl_proto, sl_func sort_counting_get_counts */ { slint_t r; slint_t *displs = NULL; if (counts == NULL) { displs = sl_alloc(ncounts, sizeof(slint_t)); make_counts(s, ncounts, displs); make_counts2displs(ncounts, displs); } else { if (ncounts < 0) { ncounts *= -1; displs = counts + ncounts; } else displs = sl_alloc(ncounts, sizeof(slint_t)); make_counts(s, ncounts, counts); make_displs(ncounts, counts, displs); } r = sort_counting_use_displs(s, d, ncounts, displs); if (counts == NULL || displs != counts + ncounts) sl_free(displs); return r; }
static void setup_request_object(sl_vm_t* vm, request_rec* r) { struct iter_args ia; sl_request_opts_t opts; opts.method = (char*)r->method; opts.uri = r->uri; opts.path_info = r->path_info; opts.query_string = r->args; opts.remote_addr = r->connection->remote_ip; opts.content_type = (char*)apr_table_get(r->headers_in, "content-type"); ia.count = 0; ia.capacity = 4; ia.kvs = sl_alloc(vm->arena, sizeof(sl_request_key_value_t) * ia.capacity); ia.vm = vm; apr_table_do(iterate_apr_table, &ia, r->headers_in, NULL); opts.header_count = ia.count; opts.headers = ia.kvs; ap_add_common_vars(r); ap_add_cgi_vars(r); ia.count = 0; ia.capacity = 4; ia.kvs = sl_alloc(vm->arena, sizeof(sl_request_key_value_t) * ia.capacity); ia.vm = vm; apr_table_do(iterate_apr_table, &ia, r->subprocess_env, NULL); opts.env_count = ia.count; opts.env = ia.kvs; read_post_data(vm, &opts, r); sl_request_set_opts(vm, &opts); }
static void init_compile_state(sl_compile_state_t* cs, sl_vm_t* vm, sl_compile_state_t* parent, size_t init_registers) { size_t i; cs->vm = vm; cs->vars = sl_st_init_table(vm, &sl_string_hash_type); cs->parent = parent; cs->section = sl_alloc(vm->arena, sizeof(sl_vm_section_t)); if(parent) { cs->section->filename = parent->section->filename; } cs->section->max_registers = init_registers; cs->section->req_registers = 0; cs->section->arg_registers = 0; cs->section->insns_cap = 16; cs->section->insns_count = 0; cs->section->insns = sl_alloc(vm->arena, sizeof(sl_vm_insn_t) * cs->section->insns_cap); cs->section->line_mappings_cap = 2; cs->section->line_mappings_count = 0; cs->section->line_mappings = sl_alloc_buffer(vm->arena, sizeof(sl_vm_line_mapping_t) * cs->section->line_mappings_cap); cs->section->can_stack_alloc_frame = true; cs->section->has_try_catch = false; cs->section->opt_skip = NULL; cs->registers = sl_alloc(vm->arena, cs->section->max_registers); for(i = 0; i < init_registers; i++) { cs->registers[i] = 1; } cs->next_last_frames = NULL; }
static sl_method_t* method_dup(sl_vm_t* vm, sl_method_t* method) { sl_method_t* new_method = sl_alloc(vm->arena, sizeof(sl_method_t)); memcpy(new_method, method, sizeof(*method)); new_method->extra = sl_alloc(vm->arena, sizeof(*new_method->extra)); memcpy(new_method->extra, method->extra, sizeof(*method->extra)); return new_method; }
static sl_object_t* allocate_method(sl_vm_t* vm) { sl_method_t* method = sl_alloc(vm->arena, sizeof(sl_method_t)); method->extra = sl_alloc(vm->arena, sizeof(*method->extra)); method->base.primitive_type = SL_T_METHOD; method->extra->doc = vm->lib.nil; return (sl_object_t*)method; }
static void setup_request_object(sl_vm_t* vm, FCGX_Request* request, char** script_filename) { sl_request_opts_t opts; size_t i, j, env_i = 0, header_i = 0; char* value; opts.method = "GET"; opts.uri = ""; opts.path_info = NULL; opts.query_string = NULL; opts.remote_addr = ""; for(i = 0; request->envp[i]; i++) { env_i++; } opts.env = sl_alloc(vm->arena, sizeof(sl_request_key_value_t) * env_i); opts.headers = sl_alloc(vm->arena, sizeof(sl_request_key_value_t) * env_i); env_i = 0; for(i = 0; request->envp[i]; i++) { value = strchr(request->envp[i], '='); if(!value) { continue; } *value++ = 0; opts.env[env_i].name = request->envp[i]; opts.env[env_i].value = value; env_i++; if(memcmp(request->envp[i], "HTTP_", 5) == 0) { opts.headers[header_i].name = sl_alloc(vm->arena, strlen(request->envp[i])); for(j = 0; request->envp[i][j + 5]; j++) { if(request->envp[i][j + 5] == '_') { opts.headers[header_i].name[j] = '-'; } else { if(request->envp[i][j + 5 - 1] == '_') { opts.headers[header_i].name[j] = request->envp[i][j + 5]; } else { opts.headers[header_i].name[j] = tolower(request->envp[i][j + 5]); } } } opts.headers[header_i].value = value; header_i++; } if(strcmp(request->envp[i], "REQUEST_METHOD") == 0) { opts.method = value; } if(strcmp(request->envp[i], "REQUEST_URI") == 0) { opts.uri = value; } if(strcmp(request->envp[i], "PATH_INFO") == 0) { opts.path_info = value; } if(strcmp(request->envp[i], "QUERY_STRING") == 0) { opts.query_string = value; } if(strcmp(request->envp[i], "REMOTE_ADDR") == 0) { opts.remote_addr = value; } if(strcmp(request->envp[i], "CONTENT_TYPE") == 0) { opts.content_type = value; } if(strcmp(request->envp[i], "SCRIPT_FILENAME") == 0) { *script_filename = value; } } opts.header_count = header_i; opts.env_count = env_i; opts.post_data = ""; opts.post_length = 0; sl_request_set_opts(vm, &opts); }
static sl_object_t* allocate_class(sl_vm_t* vm) { sl_class_t* klass = sl_alloc(vm->arena, sizeof(sl_class_t)); klass->extra = sl_alloc(vm->arena, sizeof(*klass->extra)); klass->base.primitive_type = SL_T_CLASS; klass->constants = sl_st_init_table(vm, &sl_id_hash_type); klass->extra->class_variables = sl_st_init_table(vm, &sl_id_hash_type); klass->instance_methods = sl_st_init_table(vm, &sl_id_hash_type); klass->super = vm->lib.Object; klass->extra->name.id = 0; klass->extra->in = vm->lib.Object; klass->extra->doc = vm->lib.nil; return (sl_object_t*)klass; }
static sl_node_base_t* send_with_args_expression(sl_parse_state_t* ps, sl_node_base_t* recv, SLID id) { size_t argc = 0, cap = 2; sl_node_base_t** argv = sl_alloc(ps->vm->arena, sizeof(sl_node_base_t*) * cap); bool splat_last = false; expect_token(ps, SL_TOK_OPEN_PAREN); while(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) { if(argc >= cap) { cap *= 2; argv = sl_realloc(ps->vm->arena, argv, sizeof(sl_node_base_t*) * cap); } if(peek_token(ps)->type == SL_TOK_TIMES) { next_token(ps); splat_last = true; argv[argc++] = expression(ps); break; } argv[argc++] = expression(ps); if(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) { expect_token(ps, SL_TOK_COMMA); } } expect_token(ps, SL_TOK_CLOSE_PAREN); return sl_make_send_node(ps, recv, id, argc, argv, splat_last); }
static sl_object_t* allocate_string(sl_vm_t* vm) { sl_object_t* obj = (sl_object_t*)sl_alloc(vm->arena, sizeof(sl_string_t)); obj->primitive_type = SL_T_STRING; return obj; }
static sl_object_t* allocate_method(sl_vm_t* vm) { sl_object_t* method = sl_alloc(vm->arena, sizeof(sl_method_t)); method->primitive_type = SL_T_METHOD; return method; }
static sl_object_t* allocate_bound_method(sl_vm_t* vm) { sl_object_t* bound_method = sl_alloc(vm->arena, sizeof(sl_bound_method_t)); bound_method->primitive_type = SL_T_BOUND_METHOD; return bound_method; }
SLVAL sl_do_file(sl_vm_t* vm, char* filename) { filename = sl_realpath(vm, filename); FILE* f = fopen(filename, "rb"); uint8_t* src; size_t file_size; SLVAL err; if(!f) { err = sl_make_cstring(vm, "Could not load file: "); err = sl_string_concat(vm, err, sl_make_cstring(vm, filename)); err = sl_string_concat(vm, err, sl_make_cstring(vm, " - ")); err = sl_string_concat(vm, err, sl_make_cstring(vm, strerror(errno))); sl_throw(vm, sl_make_error2(vm, vm->lib.Error, err)); } fseek(f, 0, SEEK_END); file_size = ftell(f); fseek(f, 0, SEEK_SET); src = sl_alloc(vm->arena, file_size); if(file_size && !fread(src, file_size, 1, f)) { fclose(f); err = sl_make_cstring(vm, "Could not load file: "); err = sl_string_concat(vm, err, sl_make_cstring(vm, filename)); err = sl_string_concat(vm, err, sl_make_cstring(vm, " - ")); err = sl_string_concat(vm, err, sl_make_cstring(vm, strerror(errno))); sl_throw(vm, sl_make_error2(vm, vm->lib.Error, err)); } fclose(f); return sl_do_string(vm, src, file_size, filename, 0); }
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); }
static sl_object_t* allocate_float(sl_vm_t* vm) { sl_object_t* obj = sl_alloc(vm->arena, sizeof(sl_float_t)); obj->primitive_type = SL_T_FLOAT; return obj; }
static sl_request_key_value_list_t* sl_request_key_value_list_new(sl_vm_t* vm, size_t capacity) { sl_request_key_value_list_t* list = sl_alloc(vm->arena, sizeof(sl_request_key_value_list_t)); if(list) { list->kvs = sl_alloc(vm->arena, sizeof(sl_request_key_value_t) * capacity); list->count = 0; list->capacity = capacity; list->vm = vm; } return list; }
static sl_object_t* allocate_true(sl_vm_t* vm) { sl_object_t* obj = sl_alloc(vm->arena, sizeof(sl_object_t)); obj->primitive_type = SL_T_TRUE; return obj; }
static sl_node_base_t* switch_expression(sl_parse_state_t* ps) { expect_token(ps, SL_TOK_SWITCH); sl_node_base_t* value = expression(ps); expect_token(ps, SL_TOK_OPEN_BRACE); size_t case_count = 0, case_cap = 2; sl_node_switch_case_t* cases = sl_alloc(ps->vm->arena, sizeof(sl_node_switch_case_t) * case_cap); sl_node_base_t* else_body = NULL; while(peek_token(ps)->type != SL_TOK_CLOSE_BRACE) { if(peek_token(ps)->type == SL_TOK_ELSE) { next_token(ps); else_body = body_expression(ps); break; } if(case_count + 1 >= case_cap) { case_cap *= 2; cases = sl_realloc(ps->vm->arena, cases, sizeof(sl_node_switch_case_t) * case_cap); } cases[case_count].value = expression(ps); cases[case_count].body = body_expression(ps); case_count++; } expect_token(ps, SL_TOK_CLOSE_BRACE); return sl_make_switch_node(ps, value, case_count, cases, else_body); }
static sl_object_t* allocate_regexp(sl_vm_t* vm) { sl_object_t* re = sl_alloc(vm->arena, sizeof(sl_regexp_t)); sl_gc_set_finalizer(re, (void(*)(void*))free_regexp); return re; }
void sl_response_set_opts(sl_vm_t* vm, sl_response_opts_t* opts) { sl_response_internal_opts_t* iopts = sl_alloc(vm->arena, sizeof(sl_response_internal_opts_t)); iopts->status = 200; iopts->buffered = opts->buffered; iopts->output_cap = 4; iopts->output_len = 0; iopts->output = sl_alloc(vm->arena, sizeof(SLVAL) * iopts->output_cap); iopts->write = opts->write; iopts->header_cap = 2; iopts->header_count = 0; iopts->headers = sl_alloc(vm->arena, sizeof(sl_response_key_value_t) * iopts->header_cap); iopts->descriptive_error_pages = opts->descriptive_error_pages; sl_vm_store_put(vm, &Response_opts, sl_make_ptr((sl_object_t*)iopts)); }
static sl_object_t* allocate_nil(sl_vm_t* vm) { sl_object_t* nil = sl_alloc(vm->arena, sizeof(sl_object_t)); nil->primitive_type = SL_T_NIL; return nil; }
static sl_object_t* allocate_gcrypt_algorithm(sl_vm_t* vm) { gcrypt_algorithm_t* algo = sl_alloc(vm->arena, sizeof(gcrypt_algorithm_t)); algo->algo = 0; algo->name = sl_make_cstring(vm, "(Invalid)"); return (sl_object_t*)algo; }
static sl_node_base_t* sl_make_node(sl_parse_state_t* ps, sl_node_type_t type, size_t size) { sl_node_base_t* node = sl_alloc(ps->vm->arena, size); node->type = type; node->line = 0; return node; }
static sl_object_t* allocate_range_enumerator(sl_vm_t* vm) { sl_range_enumerator_t* range_enum = sl_alloc(vm->arena, sizeof(sl_range_enumerator_t)); range_enum->current = vm->lib.nil; range_enum->right = vm->lib.nil; range_enum->state = ES_DONE; return (sl_object_t*)range_enum; }
static sl_object_t* allocate_range(sl_vm_t* vm) { sl_range_t* range = sl_alloc(vm->arena, sizeof(sl_range_t)); range->left = vm->lib.nil; range->right = vm->lib.nil; range->exclusive = 0; return (sl_object_t*)range; }
static sl_object_t* alloc_ruby_object(sl_vm_t* vm) { sl_ruby_object_t* obj = sl_alloc(vm->arena, sizeof(sl_ruby_object_t)); obj->obj = Qnil; rb_gc_register_address(&obj->obj); sl_gc_set_finalizer(obj, free_ruby_object); return (sl_object_t*)obj; }
static SLVAL sl_mysql_escape(sl_vm_t* vm, SLVAL self, SLVAL str) { mysql_t* mysql = get_mysql(vm, self); sl_string_t* s = sl_get_string(vm, str); char* esc = sl_alloc(vm->arena, s->buff_len * 2 + 1); size_t esc_len = mysql_real_escape_string(&mysql->mysql, esc, (char*)s->buff, s->buff_len); return sl_make_string(vm, (uint8_t*)esc, esc_len); }
static sl_object_t* slash_alloc(sl_vm_t* vm) { slash_t* sl = sl_alloc(vm->arena, sizeof(*sl)); sl->vm = NULL; sl->host_vm = vm; sl->output_handler = vm->lib.nil; sl_gc_set_finalizer(sl, slash_free); return (sl_object_t*)sl; }
SLVAL sl_do_string(sl_vm_t* vm, uint8_t* src, size_t src_len, char* filename, int start_in_slash) { size_t token_count; sl_token_t* tokens; sl_node_base_t* ast; sl_vm_exec_ctx_t* ctx = sl_alloc(vm->arena, sizeof(sl_vm_exec_ctx_t)); sl_vm_section_t* section; tokens = sl_lex(vm, (uint8_t*)filename, src, src_len, &token_count, start_in_slash); ast = sl_parse(vm, tokens, token_count, (uint8_t*)filename); section = sl_compile(vm, ast, (uint8_t*)filename); ctx->vm = vm; ctx->section = section; ctx->registers = sl_alloc(vm->arena, sizeof(SLVAL) * section->max_registers); ctx->self = vm->lib.Object; ctx->parent = NULL; return sl_vm_exec(ctx, 0); }
static void emit_send_self(sl_compile_state_t* cs, SLID id, size_t arg_base, size_t arg_size, size_t return_reg) { sl_vm_inline_method_cache_t* imc = sl_alloc(cs->vm->arena, sizeof(sl_vm_inline_method_cache_t)); imc->argc = arg_size; imc->id = id; imc->call = NULL; op_send_self(cs, imc, arg_base, return_reg); }
static SLVAL sl_json_parse(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv) { sl_string_t* str = sl_get_string(vm, argv[0]); json_parse_t json; yajl_alloc_funcs alloc_funcs = { sl_yajl_alloc, sl_yajl_realloc, sl_yajl_free, NULL }; alloc_funcs.ctx = vm->arena; json.vm = vm; json.max_depth = 32; json.stack_len = 0; json.stack_cap = 32; json.stack = sl_alloc(vm->arena, sizeof(SLVAL) * json.stack_cap); json.type_stack = sl_alloc(vm->arena, json.stack_cap); if(argc > 1) { json.max_depth = sl_get_int(sl_expect(vm, argv[1], vm->lib.Int)); } json.yajl = yajl_alloc(&callbacks, &alloc_funcs, &json); sl_json_parse_check_error(vm, str, &json, yajl_parse(json.yajl, str->buff, str->buff_len)); sl_json_parse_check_error(vm, str, &json, yajl_complete_parse(json.yajl)); yajl_free(json.yajl); /* must've been OK! */ return json.stack[0]; (void)self; }