Le dimanche 18 avril 2010 13:58:39, mobi phil a écrit :
> Sorry to instist....
> 
> is there any way to do memory allocation on the stack?  (please read my
> email below)
> I think there are very few features missing to cover double of the C code
> out there that can be compiled with TCC... and one of them is variable
> length arrays on the stack...
I rebased the patch propose at [1] upon the current master branch. I can't 
guarantee it works as alloca doesn't work on my different machines, even with 
the latest mob.

I attach the patch to this email in case you're interested.
> 
> On Tue, Apr 6, 2010 at 12:57 AM, mobi phil <m...@mobiphil.com> wrote:
> > Hello!!
> >
> >
> > TCC is just amazing. It is the tool I was dreaming ,) . I will move
> > from C++ back to C for several projects as I am tired to wait for even
> > fast computers to get the job done!
> > However as I tried to compile several projects, several fail due to
> > the limitation regarding variable length arrays. Are there already
> > solutions out there?
> 
From 17818cd1bfa09c4e513b4ab465f20291477bf65e Mon Sep 17 00:00:00 2001
From: Thomas Preud'homme <thomas.preudho...@celest.fr>
Date: Mon, 5 Apr 2010 17:39:09 +0200
Subject: [PATCH] Add support for C99 VLA

Add support for C99 Variable-Length Arrays
---
 tcc.h    |    4 +++-
 tccgen.c |   43 ++++++++++++++++++++++++++++++++++++++++---
 tccpp.c  |   33 +++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/tcc.h b/tcc.h
index 3481f64..093b84c 100644
--- a/tcc.h
+++ b/tcc.h
@@ -146,7 +146,7 @@ typedef int BOOL;
 
 #define TOK_HASH_SIZE       8192 /* must be a power of two */
 #define TOK_ALLOC_INCR      512  /* must be a power of two */
-#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
+#define TOK_MAX_SIZE        31 /* token max size in int unit when stored in string */
 
 /* token symbol management */
 typedef struct TokenSym {
@@ -1041,6 +1041,8 @@ ST_FUNC void expr_prod(void);
 ST_FUNC void expr_sum(void);
 ST_FUNC void gexpr(void);
 ST_FUNC int expr_const(void);
+/* varray */
+ST_FUNC int expr_check_const(void);
 ST_FUNC void gen_inline_functions(void);
 ST_FUNC void decl(int l);
 #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
diff --git a/tccgen.c b/tccgen.c
index be8d80f..8359827 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3016,9 +3016,33 @@ static void post_type(CType *type, AttributeDef *ad)
             next();
         n = -1;
         if (tok != ']') {
-            n = expr_const();
-            if (n < 0)
-                error("invalid array size");    
+            /* varray */
+            if (expr_check_const()) {
+                n = vtop->c.i;
+                vpop();
+                if (n < 0)
+                    error("invalid array size");
+            } else {
+                put_user_tok_start();
+                put_user_tok('=');
+                put_user_tok(TOK_alloca);
+                put_user_tok('(');
+                while(tok != ']') {
+                    put_user_tok(tok);
+                    next();
+                }
+                put_user_tok(')');
+                skip(']');
+                if (tok != ';')
+                    error("not support varray type");
+                put_user_tok(tok);
+                put_user_tok_end();
+                next();
+                s = sym_push(SYM_FIELD, type, 0, -1);
+                type->t = (VT_PTR | VT_CONSTANT);
+                type->ref = s;
+                return;
+            }
         }
         skip(']');
         /* parse next post type */
@@ -4041,6 +4065,19 @@ ST_FUNC int expr_const(void)
     return c;
 }
 
+/* varray */
+static int expr_check_const(void)
+{
+    int last_tok = tok;
+    expr_const1();
+    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) {
+        unget_tok(last_tok);
+        return(FALSE);
+    }
+    return(TRUE);
+}
+/* ~varray */
+
 /* return the label token if current token is a label, otherwise
    return zero */
 static int is_label(void)
diff --git a/tccpp.c b/tccpp.c
index f6f8a6a..a3babc4 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -54,6 +54,8 @@ ST_DATA TokenSym **table_ident;
 /* ------------------------------------------------------------------------- */
 
 static int *macro_ptr_allocated;
+static int *user_macro_ptr;
+static int user_saved_buffer[TOK_MAX_SIZE + 1];
 static const int *unget_saved_macro_ptr;
 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
 static int unget_buffer_enabled;
@@ -2960,6 +2962,37 @@ ST_INLN void unget_tok(int last_tok)
     tok = last_tok;
 }
 
+/* varray */
+ST_INLN void put_user_tok_start()
+{
+    user_macro_ptr = user_saved_buffer;
+}
+
+ST_INLN void put_user_tok_end()
+{
+    const int user_tok_size = (uint32_t)user_macro_ptr - (uint32_t)user_saved_buffer;
+
+    *user_macro_ptr = 0;
+    unget_buffer_enabled = 1;
+    if (macro_ptr) {
+        memmove((uint8_t*)macro_ptr+user_tok_size, macro_ptr, user_tok_size-1);
+        memcpy(macro_ptr, user_saved_buffer, user_tok_size-1);
+    } else {
+        macro_ptr = user_saved_buffer;
+    }
+}
+
+ST_INLN void put_user_tok(int last_tok)
+{
+    int i, n;
+
+    *user_macro_ptr++ = last_tok;
+    n = tok_ext_size(tok) - 1;
+    for(i=0;i<n;i++)
+        *user_macro_ptr++ = tokc.tab[i];
+}
+/* ~varray */
+
 
 /* better than nothing, but needs extension to handle '-E' option
    correctly too */
-- 
1.7.0.3

_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to