diff --git a/src/array.c b/src/array.c index b1274c4b26ffab34dc8d034072995c53ea457d11..3bda19735a273dbd25dce0d860053ae2a51772df 100644 --- a/src/array.c +++ b/src/array.c @@ -20,8 +20,9 @@ #include "gc.h" #include "main.h" #include "security.h" +#include "stuff.h" -RCSID("$Id: array.c,v 1.53 1999/08/21 23:21:06 noring Exp $"); +RCSID("$Id: array.c,v 1.54 1999/09/16 23:56:08 hubbe Exp $"); struct array empty_array= { @@ -1349,7 +1350,26 @@ int check_that_array_is_constant(struct array *a) { array_fix_type_field(a); if(a->type_field & (BIT_FUNCTION | BIT_OBJECT)) - return 0; + { + int e; + for(e=0;e<a->size;e++) + { + switch(ITEM(a)[e].type) + { + case T_FUNCTION: + if(ITEM(a)[e].subtype == FUNCTION_BUILTIN) continue; + /* Fall through */ + case T_OBJECT: + if(ITEM(a)[e].u.object -> next == ITEM(a)[e].u.object) + { + /* This is a fake object used during the + * compilation! + */ + return 0; + } + } + } + } return 1; } @@ -1359,6 +1379,9 @@ node *make_node_from_array(struct array *a) INT32 e; array_fix_type_field(a); + if(!a->size) + return mkefuncallnode("aggregate",0); + if(a->type_field == BIT_INT) { for(e=0; e<a->size; e++) @@ -1369,6 +1392,40 @@ node *make_node_from_array(struct array *a) return mkefuncallnode("allocate",mkintnode(a->size)); } } + if(!is_more_than_one_bit(a->type_field)) + { + e=0; + switch(a->type_field) + { + case BIT_INT: + for(e=1; e<a->size; e++) + if(ITEM(a)[e].u.integer != ITEM(a)[0].u.integer) + break; + if(e==a->size && ITEM(a)[0].u.integer==0) + return mkefuncallnode("allocate",mkintnode(a->size)); + break; + + case BIT_STRING: + case BIT_PROGRAM: + case BIT_OBJECT: + for(e=1; e<a->size; e++) + if(ITEM(a)[e].u.refs != ITEM(a)[0].u.refs) + break; + break; + + case BIT_FUNCTION: + for(e=1; e<a->size; e++) + if(ITEM(a)[e].u.object != ITEM(a)[0].u.object || + ITEM(a)[e].subtype != ITEM(a)[0].subtype) + break; + break; + } + if(e == a->size) + return mkefuncallnode("allocate",mknode(F_ARG_LIST, + mkintnode(a->size), + mksvaluenode(ITEM(a)))); + } + if(check_that_array_is_constant(a)) { s.type=T_ARRAY; diff --git a/src/docode.c b/src/docode.c index 7b276ac050c0f914150ee6aa4d4f27852232a794..6e8c3683e9156185b12963562596c77437de7efc 100644 --- a/src/docode.c +++ b/src/docode.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: docode.c,v 1.49 1999/08/03 00:45:09 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.50 1999/09/16 23:56:09 hubbe Exp $"); #include "las.h" #include "program.h" #include "language.h" @@ -235,6 +235,24 @@ static int do_docode2(node *n,int flags) flags &=~DO_INDIRECT; } + /* Stack check */ + { + long x_= ((char *)&x_) + STACK_DIRECTION * (32768) - stack_top ; + x_*=STACK_DIRECTION; + if(x_>0) + { + yyerror("Too dep recursion in compiler. (please report this)"); + + emit(F_NUMBER,0); + if(flags & DO_LVALUE) + { + emit(F_NUMBER,0); + return 2; + } + return 1; + } + } + switch(n->token) { case F_MAGIC_INDEX: diff --git a/src/las.c b/src/las.c index 6b388920115376e5f1f7caa9d75223e76b4dda0b..40156ef252d0188ecf7a5c881168cbfce3251c0d 100644 --- a/src/las.c +++ b/src/las.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: las.c,v 1.86 1999/09/11 08:15:55 hubbe Exp $"); +RCSID("$Id: las.c,v 1.87 1999/09/16 23:56:10 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -354,9 +354,6 @@ node *mknode(short token,node *a,node *b) if(a) a->parent = res; if(b) b->parent = res; - /* We try to optimize most things, but argument lists are hard... */ - if(token != F_ARG_LIST && (a || b)) - res->node_info |= OPT_TRY_OPTIMIZE; switch(token) { @@ -378,6 +375,7 @@ node *mknode(short token,node *a,node *b) case F_MAGIC_INDEX: case F_MAGIC_SET_INDEX: res->node_info |= OPT_EXTERNAL_DEPEND; + break; case F_UNDEFINED: res->node_info |= OPT_EXTERNAL_DEPEND | OPT_SIDE_EFFECT; @@ -413,6 +411,10 @@ node *mknode(short token,node *a,node *b) break; default: + /* We try to optimize most things, but argument lists are hard... */ + if(token != F_ARG_LIST && (a || b)) + res->node_info |= OPT_TRY_OPTIMIZE; + res->tree_info = res->node_info; if(a) res->tree_info |= a->tree_info; if(b) res->tree_info |= b->tree_info; diff --git a/src/testsuite.in b/src/testsuite.in index f3e2cafef5532d90e5c810cc713698cc62d1b6ea..4ea253d7dd90fad59e5724ccc3261f723d6afa4c 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.195 1999/09/14 22:54:52 noring Exp $"]]) +test_true([["$Id: testsuite.in,v 1.196 1999/09/16 23:56:12 hubbe Exp $"]]) cond([[all_constants()->_verify_internals]], [[ test_do(_verify_internals()) @@ -2585,6 +2585,7 @@ test_eq(all_constants()["all_constants"],all_constants) test_true(arrayp(allocate(0))) test_equal(allocate(2),({0,0})) test_false(allocate(2)==({0,0})) +test_true(allocate(65536,random)) // - backtrace test_true(arrayp(backtrace()))