value_t assembler_push_map_scope(assembler_t *assm, map_scope_o *scope) { TRY_SET(scope->map, new_heap_id_hash_map(assm->runtime, 8)); scope->super.vtable.lookup = (scope_lookup_m) map_scope_lookup; scope->outer = assembler_set_scope(assm, (scope_o*) scope); scope->assembler = assm; return success(); }
static value_t lambda_scope_lookup(lambda_scope_o *self, value_t symbol, binding_info_t *info_out) { size_t capture_count_before = get_array_buffer_length(self->captures); // See if we've captured this variable before. for (size_t i = 0; i < capture_count_before; i++) { value_t captured = get_array_buffer_at(self->captures, i); if (value_identity_compare(captured, symbol)) { // Found it. Record that we did if necessary and return success. if (info_out != NULL) binding_info_set(info_out, btLambdaCaptured, i, 0); return success(); } } // We haven't seen this one before so look it up outside. value_t value = scope_lookup(self->outer, symbol, info_out); if (info_out != NULL && !in_condition_cause(ccNotFound, value)) { // We found something and this is a read. Add it to the list of captures. runtime_t *runtime = self->assembler->runtime; if (get_array_buffer_length(self->captures) == 0) { // The first time we add something we have to create a new array buffer // since all empty capture scopes share the singleton empty buffer. TRY_SET(self->captures, new_heap_array_buffer(runtime, 2)); } TRY(add_to_array_buffer(runtime, self->captures, symbol)); binding_info_set(info_out, btLambdaCaptured, capture_count_before, 0); } return value; }
value_t build_fragment_entry_map(binding_context_t *context, value_t modules) { runtime_t *runtime = get_ambience_runtime(context->ambience); TRY_SET(context->fragment_entry_map, new_heap_id_hash_map(runtime, 16)); TRY(build_real_fragment_entries(context, modules)); TRY(build_synthetic_fragment_entries(context)); return context->fragment_entry_map; }
value_t get_or_create_methodspace_selector_slice(runtime_t *runtime, value_t self, value_t selector) { value_t cache_ptr = get_methodspace_cache_ptr(self); value_t cache = get_freeze_cheat_value(cache_ptr); // Create the cache if it doesn't exist. if (is_nothing(cache)) { TRY_SET(cache, new_heap_id_hash_map(runtime, 128)); set_freeze_cheat_value(cache_ptr, cache); } // Create the selector-specific cache if it doesn't exits. value_t slice = get_id_hash_map_at(cache, selector); if (in_condition_cause(ccNotFound, slice)) { TRY_SET(slice, create_methodspace_selector_slice(runtime, self, selector)); TRY(set_id_hash_map_at(runtime, cache, selector, slice)); } return slice; }
// Gets the code from a method object, compiling the method if necessary. static value_t ensure_method_code(runtime_t *runtime, value_t method) { value_t code = get_method_code(method); if (is_nothing(code)) { TRY_SET(code, compile_method(runtime, method)); set_method_code(method, code); } return code; }
// Creates and binds modules and fragments according to the given schedule. static value_t execute_binding_schedule(binding_context_t *context, value_t schedule) { runtime_t *runtime = get_ambience_runtime(context->ambience); for (size_t i = 0; i < get_array_buffer_length(schedule); i++) { value_t next = get_array_buffer_at(schedule, i); TOPIC_INFO(Library, "About to bind %v", next); value_t path = get_identifier_path(next); value_t stage = get_identifier_stage(next); // Create the bound module if it doesn't already exist. value_t bound_module = get_id_hash_map_at(context->bound_module_map, path); if (in_condition_cause(ccNotFound, bound_module)) { TRY_SET(bound_module, new_heap_empty_module(runtime, path)); TRY(set_id_hash_map_at(runtime, context->bound_module_map, path, bound_module)); } // Create the bound fragment. value_t bound_fragment = get_module_fragment_at(bound_module, stage); if (in_condition_cause(ccNotFound, bound_fragment)) { TRY_SET(bound_fragment, new_empty_module_fragment(runtime, stage, bound_module)); TRY(add_module_fragment(runtime, bound_module, bound_fragment)); } else { // An earlier phase needed a reference to this fragment so it has already // been created but not initialized yet. CHECK_EQ("Unexpected phase", get_module_fragment_epoch(bound_fragment), feUninitialized); TRY(init_empty_module_fragment(runtime, bound_fragment)); set_module_fragment_epoch(bound_fragment, feUnbound); } if (is_present_core(runtime, next)) { // TODO: this is a hack, there should be some other mechanism for // identifying the core module. This way of binding it also means it // gets bound at a time that's not particularly well-defined which is // also an issue. TOPIC_INFO(Library, "Binding present core to %v", bound_fragment); set_ambience_present_core_fragment(context->ambience, bound_fragment); } // Grab the unbound fragment we'll use to create the bound fragment. value_t module_entries = get_id_hash_map_at(context->fragment_entry_map, path); value_t fragment_entry = get_id_hash_map_at(module_entries, stage); // Bind the fragment based on the data from the entry. TRY(bind_module_fragment(context, fragment_entry, bound_fragment)); TOPIC_INFO(Library, "Done binding %v", next); } return success(); }
// Initialize serialization state. static value_t serialize_state_init(serialize_state_t *state, runtime_t *runtime, value_mapping_t *resolver, byte_buffer_t *buf) { state->buf = buf; state->object_offset = 0; state->runtime = runtime; state->resolver = resolver; TRY_SET(state->ref_map, new_heap_id_hash_map(runtime, 16)); return success(); }
value_t assembler_init(assembler_t *assm, runtime_t *runtime, value_t fragment, scope_o *scope) { CHECK_FALSE("no scope callback", scope == NULL); CHECK_FAMILY_OPT(ofModuleFragment, fragment); TRY(assembler_init_stripped_down(assm, runtime)); TRY_SET(assm->value_pool, new_heap_id_hash_map(runtime, 16)); assm->scope = scope; assm->fragment = fragment; return success(); }
value_t build_bound_module(value_t ambience, value_t unbound_module) { runtime_t *runtime = get_ambience_runtime(ambience); binding_context_t context; binding_context_init(&context, ambience); TRY_SET(context.bound_module_map, new_heap_id_hash_map(runtime, 16)); TRY_DEF(modules, build_transitive_module_array(runtime, unbound_module)); TRY(build_fragment_entry_map(&context, modules)); TRY_DEF(schedule, build_binding_schedule(&context)); TRY(execute_binding_schedule(&context, schedule)); value_t path = get_unbound_module_path(unbound_module); value_t result = get_id_hash_map_at(context.bound_module_map, path); CHECK_FALSE("module missing", in_condition_cause(ccNotFound, result)); return result; }
value_t add_methodspace_inheritance(runtime_t *runtime, value_t self, value_t subtype, value_t supertype) { CHECK_FAMILY(ofMethodspace, self); CHECK_MUTABLE(self); CHECK_FAMILY(ofType, subtype); CHECK_FAMILY(ofType, supertype); value_t inheritance = get_methodspace_inheritance(self); value_t parents = get_id_hash_map_at(inheritance, subtype); if (in_condition_cause(ccNotFound, parents)) { // Make the parents buffer small since most types don't have many direct // parents. If this fails nothing has happened. TRY_SET(parents, new_heap_array_buffer(runtime, 4)); // If this fails we've wasted some space allocating the parents array but // otherwise nothing has happened. TRY(set_id_hash_map_at(runtime, inheritance, subtype, parents)); } // If this fails we may have set the parents array of the subtype to an empty // array which is awkward but okay. invalidate_methodspace_caches(self); return add_to_array_buffer(runtime, parents, supertype); }
int pam_set_item (pam_handle_t *pamh, int item_type, const void *item) { int retval; D(("called")); IF_NO_PAMH("pam_set_item", pamh, PAM_SYSTEM_ERR); retval = PAM_SUCCESS; switch (item_type) { case PAM_SERVICE: /* Setting handlers_loaded to 0 will cause the handlers * to be reloaded on the next call to a service module. */ pamh->handlers.handlers_loaded = 0; TRY_SET(pamh->service_name, item); { char *tmp; for (tmp=pamh->service_name; *tmp; ++tmp) *tmp = tolower(*tmp); /* require lower case */ } break; case PAM_USER: TRY_SET(pamh->user, item); pamh->former.fail_user = PAM_SUCCESS; break; case PAM_USER_PROMPT: TRY_SET(pamh->prompt, item); pamh->former.fail_user = PAM_SUCCESS; break; case PAM_TTY: D(("setting tty to %s", item)); TRY_SET(pamh->tty, item); break; case PAM_RUSER: TRY_SET(pamh->ruser, item); break; case PAM_RHOST: TRY_SET(pamh->rhost, item); break; case PAM_AUTHTOK: /* * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from * modules. */ if (__PAM_FROM_MODULE(pamh)) { if (pamh->authtok != item) { _pam_overwrite(pamh->authtok); TRY_SET(pamh->authtok, item); } } else { retval = PAM_BAD_ITEM; } break; case PAM_OLDAUTHTOK: /* * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from * modules. */ if (__PAM_FROM_MODULE(pamh)) { if (pamh->oldauthtok != item) { _pam_overwrite(pamh->oldauthtok); TRY_SET(pamh->oldauthtok, item); } } else { retval = PAM_BAD_ITEM; } break; case PAM_CONV: /* want to change the conversation function */ if (item == NULL) { pam_syslog(pamh, LOG_ERR, "pam_set_item: attempt to set conv() to NULL"); retval = PAM_PERM_DENIED; } else { struct pam_conv *tconv; if ((tconv= (struct pam_conv *) malloc(sizeof(struct pam_conv)) ) == NULL) { pam_syslog(pamh, LOG_CRIT, "pam_set_item: malloc failed for pam_conv"); retval = PAM_BUF_ERR; } else { memcpy(tconv, item, sizeof(struct pam_conv)); _pam_drop(pamh->pam_conversation); pamh->pam_conversation = tconv; pamh->former.fail_user = PAM_SUCCESS; } } break; case PAM_FAIL_DELAY: pamh->fail_delay.delay_fn_ptr = item; break; case PAM_XDISPLAY: TRY_SET(pamh->xdisplay, item); break; case PAM_XAUTHDATA: if (&pamh->xauth == item) break; if (pamh->xauth.namelen) { _pam_overwrite(pamh->xauth.name); free(pamh->xauth.name); } if (pamh->xauth.datalen) { _pam_overwrite_n(pamh->xauth.data, (unsigned int) pamh->xauth.datalen); free(pamh->xauth.data); } pamh->xauth = *((const struct pam_xauth_data *) item); if ((pamh->xauth.name=_pam_strdup(pamh->xauth.name)) == NULL) { memset(&pamh->xauth, '\0', sizeof(pamh->xauth)); return PAM_BUF_ERR; } if ((pamh->xauth.data=_pam_memdup(pamh->xauth.data, pamh->xauth.datalen)) == NULL) { _pam_overwrite(pamh->xauth.name); free(pamh->xauth.name); memset(&pamh->xauth, '\0', sizeof(pamh->xauth)); return PAM_BUF_ERR; } break; /* begin: add by yangguang */ default: if (item_type > PAM_EXT_BASE) { retval = pam_set_extern_item_value (pamh, item_type, item); } else { retval = PAM_BAD_ITEM; } }/* end switch */ /* end: add by yangguang */ return retval; }