Example #1
0
/* cleanup all static data used during compilation */
static void tcc_cleanup(void)
{
	int i, n;
	if (NULL == tcc_state) {
		return;
	}
	tcc_state = NULL;

	/* free -D defines */
	free_defines (NULL);

	/* free tokens */
	n = tok_ident - TOK_IDENT;
	for (i = 0; i < n; i++) {
		free (table_ident[i]);
	}
	free (table_ident);

	/* free sym_pools */
	dynarray_reset (&sym_pools, &nb_sym_pools);
	/* string buffer */
	cstr_free (&tokcstr);
	/* reset symbol stack */
	sym_free_first = NULL;
	/* cleanup from error/setjmp */
	macro_ptr = NULL;
}
Example #2
0
void 
end_new_file(void)
{
    while (inctop)
    {
	struct incstate *p;
	p = inctop;
	(void)fclose(yyin);
	free(current_file);
	current_file = p->file;
	yyin = p->yyin;
	inctop = p->next;
	
	if (p->outp != NULL)
	{
	    free((char *)p->outp);
	}
	
	free((char *)p);
    }
    while (iftop)
    {
	struct ifstate *p;
	
	p = iftop;
	iftop = p->next;
	free((char *)p);
    }
    free_defines();
}
Example #3
0
void
start_new_file(FILE *f)
{
    struct lpc_predef_s *tmpf;
    free_defines();
    add_define("_FUNCTION", -1, "");
    add_define("LPC4", -1, "");   /* Tell coders this is LPC ver 4.0 */
    add_define("CD_DRIVER", -1, "");
#ifdef DEBUG
    add_define("DEBUG_DRIVER", -1, "");
#endif
    add_define("T_INTEGER" , -1, ltoa(T_NUMBER));
    add_define("T_FLOAT"   , -1, ltoa(T_FLOAT));
    add_define("T_STRING"  , -1, ltoa(T_STRING));
    add_define("T_OBJECT"  , -1, ltoa(T_OBJECT));
    add_define("T_FUNCTION", -1, ltoa(T_FUNCTION));
    add_define("T_ARRAY"   , -1, ltoa(T_POINTER));
    add_define("T_MAPPING" , -1, ltoa(T_MAPPING));

    for (tmpf = lpc_predefs; tmpf; tmpf = tmpf->next) 
    {
	char namebuf[NSIZE];
	char mtext[MLEN];
	
	*mtext='\0';
	(void)sscanf(tmpf->flag, "%[^=]=%[ -~=]", namebuf, mtext);
	if (strlen(namebuf) >= NSIZE)
	    fatal("NSIZE exceeded\n");
	if (strlen(mtext) >= MLEN)
	    fatal("MLEN exceeded\n");
	add_define(namebuf,-1,mtext);
    }
    keep1.token = keep2.token = keep3.token = -47;
    yyin = f;
    slast = '\n';
    lastchar = '\n';
    inctop = 0;         /* If not here, where? */
    num_incfiles = 0;
    current_incfile = 0;
    current_line = 1;
    lex_fatal = 0;
    incdepth = 0;
    nbuf = 0;
    outp = defbuf+DEFMAX;
    pragma_strict_types = 0;        
    pragma_no_inherit = pragma_no_clone = pragma_no_shadow = pragma_resident = 0;
    nexpands = 0;
}
Example #4
0
/*-------------------------------------------------------------------------*/
Bool
assert_simul_efun_object (void)

/* (Re)load the simul_efun object and extract all information we need.
 * Result is TRUE if either the simul_efun object could be loaded, or if
 * master::get_simul_efun() did not return a string/string vector to
 * name the simul efun object. The result is FALSE if master::get_simul_efun()
 * specified a simul efun object, which couldn't be found.
 *
 * In other words: after calling assert_simul_efun_object(), the caller
 * still has to check if simul_efun_object is NULL.
 *
 * At the time of call, simul_efun_object must be NULL.
 */

{
    svalue_t           *svp;
    object_t           *ob;
    program_t          *progp;
    CBool              *visible; /* Flag for every function: visible or not */
    string_t           *name;
    int                 i, j, num_fun;

    invalidate_simul_efuns(); /* Invalidate the simul_efun information */

    free_defines(); /* to prevent #defines hideing places for globals */

    /* Get the name(s) of the simul_efun  object. */
    svp = apply_master(STR_GET_SEFUN, 0);

    /* If a simul_efun_object appears during the GET_SEFUN call, it
     * might have been due to a recursive get_simul_efun() call which may
     * have gotten an old backup copy. This can lead to hard-to-debug
     * variable and function definition inconsistencies.
     */
    if (simul_efun_object)
    {
        printf("%s simul_efun object appeared while asking for it.\n", time_stamp());
        return MY_TRUE;
    }

    if (svp == NULL)
    {
        printf("%s No simul_efun\n", time_stamp());
        return MY_TRUE;
    }

    if (svp->type == T_POINTER)
    {
        simul_efun_vector = svp->u.vec;
        svp->type = T_NUMBER;
        if (VEC_SIZE(svp->u.vec))
            svp = svp->u.vec->item;
    }

    if (svp->type != T_STRING)
    {
        printf("%s No simul_efun\n", time_stamp());
        return MY_TRUE;
    }

    /* Make the (primary) simul_efun name */
    name = del_slash(svp->u.str);
    if (simul_efun_file_name)
        free_mstring(simul_efun_file_name);
    simul_efun_file_name = make_tabled(name);

    /* Get the object and load the program */
    ob = find_object(simul_efun_file_name);
    if (ob == NULL)
    {
        fprintf(stderr, "%s The simul_efun file %s was not loaded.\n"
               , time_stamp(), get_txt(simul_efun_file_name));
        fprintf(stderr, "%s The function get_simul_efun() in the master must load it.\n"
               , time_stamp());
        return MY_FALSE;
    }
    if (O_PROG_SWAPPED(ob) && load_ob_from_swap(ob) < 0)
    {
        fprintf(stderr, "%s Out of memory (unswap object '%s') ==> "
                        "No simul_efun\n", time_stamp(), get_txt(ob->name));
        return MY_TRUE;
    }
    reference_prog( (simul_efun_program = ob->prog), "get_simul_efun");

    num_fun = ob->prog->num_function_names;
    if (num_fun == 0)
        return MY_TRUE;
    if (!simul_efunp)
    {
        simul_efunp = xalloc(sizeof (function_t) * num_fun);
    }
    else
        num_fun = total_simul_efun;

    free_defines(); /* to prevent #defines hideing places for globals */

    /* locals and defines are freed now. There are still reserved words,
     * but it is impossible to define a function with the name being
     * a reserved word, thus, there will be no clashes with higher-priority
     * shared identifiers.
     */

    progp = ob->prog;
    visible = alloca((i = ob->prog->num_functions) * sizeof(*visible));
    memset(visible, 0, i);
    i = ob->prog->num_function_names;
    while (--i >= 0)
        visible[progp->function_names[i]] = MY_TRUE;
    /* The functions .num_function_names+1 .. .num_functions are not
     * visible by definition.
     */

    /* Loop over the functions in the simul_efun object and
     * copy the salient information.
     */
    for (i = 0; i < ob->prog->num_functions; i++)
    {
        int        ix;
        funflag_t  flags, flags2;
        bytecode_p funstart;
        mp_int     fun_ix_offs, var_ix_offs;
        program_t *inherit_progp;
        function_t*funheader;

        if (!visible[i])
            continue;

        ix = i;
        flags2 = flags = progp->functions[ix];
        flags &= ~FUNSTART_MASK;

        /* Pinpoint the function, resolving inheritance where
         * necessary.
         */
        fun_ix_offs = ix;
        var_ix_offs = 0;
        inherit_progp = progp;
        while (flags2 & NAME_INHERITED)
        {
            inherit_t *inheritp;

            inheritp = &inherit_progp->inherit[flags2 & INHERIT_MASK];
            ix -= inheritp->function_index_offset;
            var_ix_offs += inheritp->variable_index_offset;
            inherit_progp = inheritp->prog;
            flags2 = inherit_progp->functions[ix];
        }
        fun_ix_offs -= ix;

        funstart = inherit_progp->program + (flags2 & FUNSTART_MASK);
        funheader = inherit_progp->function_headers + FUNCTION_HEADER_INDEX(funstart);

        /* Don't stumble over undefined functions */
        if (is_undef_function(funstart))
        {
            flags |= NAME_UNDEFINED;
        }

        /* If the function is __INIT, pretend it's a private function */
        if ( !(flags & (TYPE_MOD_STATIC|TYPE_MOD_PRIVATE|NAME_UNDEFINED)) )
        {
            if (mstreq(funheader->name, STR_VARINIT))
                flags |= TYPE_MOD_PRIVATE;
        }

        /* If the function is indeed visible, get its information */
        if ( !(flags & (TYPE_MOD_STATIC|TYPE_MOD_PROTECTED|TYPE_MOD_PRIVATE|NAME_UNDEFINED)) )
        {
            string_t *function_name;
            ident_t *p;
            unsigned char num_arg;

            function_name = funheader->name;
            num_arg = funheader->num_arg;

            /* Find or make the identifier for the function */
            p = make_shared_identifier_mstr(function_name, I_TYPE_GLOBAL, 0);
            if (p->type == I_TYPE_UNKNOWN)
            {
                init_global_identifier(p, /* bVariable: */ MY_FALSE);
                p->next_all = all_simul_efuns;
                all_simul_efuns = p;
            }

            if (flags & TYPE_MOD_VARARGS)
                num_arg = SIMUL_EFUN_VARARGS;

            /* Find the proper index in simul_efunp[] */
            switch(0) { default: /* TRY... */

                /* Try to find a discarded sefun entry with matching
                 * name, number of arguments and XVARARGS flag to reuse.
                 */
                if (all_discarded_simul_efun >= 0)
                {
                    int last;

                    j = all_discarded_simul_efun;
                    while ( (j = simul_efunp[last = j].offset.next_sefun) >= 0)
                    {
                        if (num_arg != simul_efunp[j].num_arg
                         || 0 != ((simul_efunp[j].flags ^ flags) & TYPE_MOD_XVARARGS)
                           )
                            continue;
                        if (!mstreq(function_name, simul_efunp[j].name))
                            continue;

                        /* Found one: remove it from the 'discarded' list */
                        simul_efunp[last].offset.next_sefun =
                              simul_efunp[j].offset.next_sefun;
                        break;
                    }
                    if (j >= 0)
                        break; /* switch */
                }

                /* New simul_efun: make a new entry */
                (void)ref_mstring(function_name);
                j = num_simul_efun++;
                if (num_simul_efun > num_fun)
                {
                    num_fun = num_simul_efun + 12;
                    simul_efunp = rexalloc(simul_efunp
                                          , sizeof (function_t) * num_fun
                      );
                }
                simul_efunp[j].name    = function_name;
                simul_efunp[j].num_arg = num_arg;
            } /* switch() */

            /* j now indexes the simul_efunp[] entry to use */

            p->u.global.sim_efun = j;
            simul_efunp[j].flags      = funheader->flags;
            simul_efunp[j].type       = funheader->type;
            simul_efunp[j].num_locals = funheader->num_locals;

            /* If possible, make an entry in the simul_efun table */
            if ((size_t)j < SEFUN_TABLE_SIZE)
            {
                simul_efun_table[j].funstart = funstart;
                simul_efun_table[j].program = inherit_progp;
                simul_efun_table[j].function_index_offset = fun_ix_offs;
                simul_efun_table[j].variable_index_offset = var_ix_offs;
            }
        } /* if (function visible) */
    } /* for ( all functions) */

    total_simul_efun = num_fun;
    simul_efun_object = ob;

    return MY_TRUE;
} /* get_simul_efun_object() */
Example #5
0
/* compile the C file opened in 'file'. Return non zero if errors. */
static int tcc_compile(TCCState *s1)
{
	Sym *define_start;

#ifdef INC_DEBUG
	printf ("%s: **** new file\n", file->filename);
#endif
	preprocess_init (s1);

	funcname = "";

	/* define some often used types */
	int8_type.t = VT_INT8;
	int16_type.t = VT_INT16;
	int32_type.t = VT_INT32;
	int64_type.t = VT_INT64;

	char_pointer_type.t = VT_INT8;
	mk_pointer (&char_pointer_type);

	if (tcc_state->bits != 64) {
		size_type.t = VT_INT32;
	} else {
		size_type.t = VT_INT64;
	}

	func_old_type.t = VT_FUNC;
	func_old_type.ref = sym_push (SYM_FIELD, &int32_type, FUNC_CDECL, FUNC_OLD);

// FIXME: Should depend on the target options too
#ifdef TCC_TARGET_ARM
	arm_init_types ();
#endif

#if 0
	/* define 'void *alloca(unsigned int)' builtin function */
	{
		Sym *s1;

		p = anon_sym++;
		sym = sym_push (p, mk_pointer (VT_VOID), FUNC_CDECL, FUNC_NEW);
		s1 = sym_push (SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
		s1->next = NULL;
		sym->next = s1;
		sym_push (TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
	}
#endif

	define_start = define_stack;
	nocode_wanted = 1;

	if (setjmp (s1->error_jmp_buf) == 0) {
		s1->nb_errors = 0;
		s1->error_set_jmp_enabled = 1;

		ch = file->buf_ptr[0];
		tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
		parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
		// pvtop = vtop;
		next ();
		decl (VT_CONST);
		if (tok != TOK_EOF) {
			expect ("declaration");
		}
#if 0
		if (pvtop != vtop) {
			fprintf (stderr, "internal compiler error:"
				" vstack leak? (%d)", vtop - pvtop);
		}
#endif
	}

	s1->error_set_jmp_enabled = 0;

	/* reset define stack, but leave -Dsymbols (may be incorrect if
	   they are undefined) */
	free_defines (define_start);

	sym_pop (&global_stack, NULL);
	sym_pop (&local_stack, NULL);

	return s1->nb_errors != 0? -1: 0;
}