Beispiel #1
0
void destroy_result(lily_value *v)
{
    close_result(v);
    lily_free(v->value.generic);
}
Beispiel #2
0
void lily_free_options(lily_options *o)
{
    lily_free(o);
}
Beispiel #3
0
static void free_lily_main(lily_function_val *fv)
{
    lily_free(fv->reg_info);
    lily_free(fv->code);
    lily_free(fv);
}
Beispiel #4
0
/* scan_seed_arg
   This takes a seed that defines a signature and creates the appropriate sig
   for it. This is able to handle complex signatures nested inside of each
   other. */
static lily_sig *scan_seed_arg(lily_symtab *symtab, const int *arg_ids,
        int *pos, int *ok)
{
    lily_sig *ret;
    int arg_id = arg_ids[*pos];
    int seed_pos = *pos + 1;
    *ok = 1;

    if (arg_id == -1)
        ret = NULL;
    else {
        lily_class *arg_class = lily_class_by_id(symtab, arg_id);
        if (arg_class->sig)
            ret = arg_class->sig;
        else {
            lily_sig *complex_sig = lily_try_sig_for_class(symtab, arg_class);
            lily_sig **siglist;
            int siglist_size;
            int flags = 0;

            if (arg_id == SYM_CLASS_TEMPLATE) {
                if (complex_sig)
                    complex_sig->template_pos = arg_ids[seed_pos];
                else
                    *ok = 0;

                seed_pos++;
                siglist = NULL;
                siglist_size = 0;
            }
            else {
                if (arg_class->template_count == -1) {
                    /* -1 means it takes a specified number of values. */
                    siglist_size = arg_ids[seed_pos];
                    seed_pos++;
                    /* Function needs flags in case the thing is varargs. */
                    if (arg_id == SYM_CLASS_FUNCTION) {
                        flags = arg_ids[seed_pos];
                        seed_pos++;
                    }
                }
                else {
                    siglist_size = arg_class->template_count;
                    flags = 0;
                }

                siglist = lily_malloc(siglist_size * sizeof(lily_sig *));
                if (siglist) {
                    int i;
                    for (i = 0;i < siglist_size;i++) {
                        siglist[i] = scan_seed_arg(symtab, arg_ids, &seed_pos,
                                ok);

                        if (*ok == 0)
                            break;
                    }

                    if (*ok == 0) {
                        /* This isn't tied to anything, so free it. Inner args
                           have already been ensured, so don't touch them. */
                        lily_free(siglist);
                        siglist = NULL;
                        *ok = 0;
                    }
                }
                else
                    *ok = 0;
            }

            if (*ok == 1 && complex_sig != NULL) {
                complex_sig->siglist = siglist;
                complex_sig->siglist_size = siglist_size;
                complex_sig->flags = flags;
                complex_sig = lily_ensure_unique_sig(symtab, complex_sig);
                ret = complex_sig;
            }
            else
                ret = NULL;
        }
    }

    *pos = seed_pos;
    return ret;
}
Beispiel #5
0
/* lily_ensure_unique_sig
   This looks through the symtab's current signatures to see if any describe the
   same thing as the given signature.
   * If a match is not found, the input_sig is returned.
   * If a match is found, input_sig is destroyed and removed from symtab's sig
     chain. The matching signature is returned. Because of this, the return of
     this function must NEVER be ignored, unless no var is currently using
     input_sig.
   As the name suggests, this ensures that each signature describes a unique
   thing.
   It is expected that inner signatures will be ensured before outer signatures
   are: a list[list[list[list[integer]]]] first checking that list[integer] is
   unique, then list[list[integer]] is unique, and so on.
   Because of this, it is not necessary to do deep comparisons.
   Additionally, signatures can be compared by pointer, and a deep matching
   function is no longer necessary. */
lily_sig *lily_ensure_unique_sig(lily_symtab *symtab, lily_sig *input_sig)
{
    lily_sig *iter_sig = symtab->root_sig;
    lily_sig *previous_sig = NULL;
    int match = 0;

    /* This just means that input_sig was the last signature created. */
    if (iter_sig == input_sig)
        iter_sig = iter_sig->next;

    while (iter_sig) {
        if (iter_sig->cls == input_sig->cls) {
            if (iter_sig->siglist      != NULL &&
                iter_sig->siglist_size == input_sig->siglist_size &&
                iter_sig               != input_sig) {
                int i;
                match = 1;
                for (i = 0;i < iter_sig->siglist_size;i++) {
                    if (iter_sig->siglist[i] != input_sig->siglist[i]) {
                        match = 0;
                        break;
                    }
                }

                if (match == 1)
                    break;
            }
        }

        if (iter_sig->next == input_sig)
            previous_sig = iter_sig;

        iter_sig = iter_sig->next;
    }

    finalize_sig(input_sig);

    if (match) {
        /* Remove input_sig from the symtab's sig chain. */
        if (symtab->root_sig == input_sig)
            /* It is the root, so just advance the root. */
            symtab->root_sig = symtab->root_sig->next;
        else {
            /* Make the sig before it link to the node after it. This is
               theoretically safe because the chain goes from recent to least
               recent. So this should find the input signature before it finds
               one that equals it (and set previous_sig to something valid). */
            previous_sig->next = input_sig->next;
        }

        /* This is either NULL or something that only this sig uses. Don't free
           what's inside of the siglist though, since that's other signatures
           still in the chain. */
        lily_free(input_sig->siglist);
        lily_free(input_sig);

        input_sig = iter_sig;
    }

    return input_sig;
}