Exemplo n.º 1
0
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();
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
// 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;
}
Exemplo n.º 6
0
// 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();
}
Exemplo n.º 7
0
// 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();
}
Exemplo n.º 8
0
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();
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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;
}