1999-01-31
1999-01-31 09:03:50 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>
-
4218011a67a6637bd37c7d3f303110a3880cd696
(219 lines)
(+157/-62)
[
Show
| Annotate
]
Branch: 7.9
lexical closures implemented...
Rev: src/ChangeLog:1.160
Rev: src/alloca.c:1.3
Rev: src/block_alloc.h:1.5
Rev: src/block_alloc_h.h:1.1
Rev: src/builtin_functions.c:1.146
Rev: src/callback.c:1.16
Rev: src/dmalloc.h:1.9
Rev: src/docode.c:1.43
Rev: src/error.c:1.23
Rev: src/error.h:1.27
Rev: src/interpret.c:1.113
Rev: src/interpret.h:1.26
Rev: src/language.yacc:1.109
Rev: src/las.c:1.73
Rev: src/las.h:1.18
Rev: src/lex.c:1.61
Rev: src/main.c:1.62
Rev: src/modules/call_out/call_out.c:1.24
Rev: src/object.c:1.55
Rev: src/peep.in:1.24
Rev: src/pike_memory.c:1.29
Rev: src/pike_memory.h:1.8
Rev: src/program.c:1.107
Rev: src/program.h:1.48
Rev: src/testsuite.in:1.142
Rev: src/threads.h:1.61
4:
||| See the files COPYING and DISCLAIMER for more information.
\*/
#include "global.h"
- RCSID("$Id: interpret.c,v 1.112 1999/01/21 09:15:01 hubbe Exp $");
+ RCSID("$Id: interpret.c,v 1.113 1999/01/31 09:01:47 hubbe Exp $");
#include "interpret.h"
#include "object.h"
#include "program.h"
29:
#include "callback.h"
#include "fd_control.h"
#include "security.h"
+ #include "block_alloc.h"
#include <fcntl.h>
#include <errno.h>
91:
return sp - *--mark_sp;
}
- struct frame *fp; /* frame pointer */
+ struct pike_frame *fp; /* pike_frame pointer */
#ifdef PIKE_DEBUG
static void gc_check_stack_callback(struct callback *foo, void *bar, void *gazonk)
{
- struct frame *f;
+ struct pike_frame *f;
debug_gc_xmark_svalues(evaluator_stack,sp-evaluator_stack-1,"interpreter stack");
- for(f=fp;f;f=f->parent_frame)
+ for(f=fp;f;f=f->next)
{
if(f->context.parent)
gc_external_mark(f->context.parent);
196:
}
-
+
static int eval_instruction(unsigned char *pc);
662:
print_return_value();
break;
+ CASE(F_TRAMPOLINE);
+ {
+ struct object *o=low_clone(pike_trampoline_program);
+ add_ref( ((struct pike_trampoline *)(o->storage))->frame=fp );
+ ((struct pike_trampoline *)(o->storage))->func=GET_ARG()+fp->context.identifier_level;
+ push_object(o);
+ print_return_value();
+ break;
+ }
+
+
/* The not so basic 'push value' instructions */
CASE(F_GLOBAL);
low_object_index_no_free(sp,
837:
sp+=2;
break;
+ CASE(F_LEXICAL_LOCAL);
+ {
+ struct pike_frame *f=fp;
+ while(accumulator--)
+ {
+ f=f->scope;
+ if(!f) error("Lexical scope error.\n");
+ }
+ push_svalue(f->locals + GET_ARG());
+ print_return_value();
+ break;
+ }
+
+ CASE(F_LEXICAL_LOCAL_LVALUE);
+ {
+ struct pike_frame *f=fp;
+ while(accumulator--)
+ {
+ f=f->scope;
+ if(!f) error("Lexical scope error.\n");
+ }
+ sp[0].type=T_LVALUE;
+ sp[0].u.lval=f->locals+GET_ARG();
+ sp[1].type=T_VOID;
+ sp+=2;
+ break;
+ }
+
CASE(F_ARRAY_LVALUE);
f_aggregate(GET_ARG()*2);
sp[-1].u.array->flags |= ARRAY_LVALUE;
1536:
CASE(F_ADD_NEG_INT); push_int(-GET_ARG()); f_add(2); break;
CASE(F_PUSH_ARRAY);
- if(sp[-1].type!=T_ARRAY)
+ switch(sp[-1].type)
+ {
+ default:
PIKE_ERROR("@", "Bad argument.\n", sp, 1);
-
+
+ case T_OBJECT:
+ if(!sp[-1].u.object->prog || FIND_LFUN(sp[-1].u.object->prog,LFUN__VALUES) == -1)
+ PIKE_ERROR("@", "Bad argument.\n", sp, 1);
+
+ apply_lfun(sp[-1].u.object, LFUN__VALUES, 0);
+ if(sp[-1].type != T_ARRAY)
+ error("Bad return type from o->_values() in @\n");
+ free_svalue(sp-2);
+ sp[-2]=sp[-1];
sp--;
-
+ break;
+
+ case T_ARRAY: break;
+ }
+ sp--;
push_array_items(sp->u.array);
break;
1796:
free(s);
}
+
+ #undef INIT_BLOCK
+ #define INIT_BLOCK(X) do { X->refs=1; X->malloced_locals=0; X->scope=0; }while(0)
+
+ #undef EXIT_BLOCK
+ #define EXIT_BLOCK(X) do { \
+ free_object(X->current_object); \
+ if(X->context.prog) free_program(X->context.prog); \
+ if(X->context.parent) free_object(X->context.parent); \
+ if(X->scope) free_pike_frame(X->scope); \
+ if(X->malloced_locals) \
+ { \
+ free_svalues(X->locals,X->num_locals,BIT_MIXED); \
+ free((char *)(X->locals)); \
+ } \
+ }while(0)
+
+ BLOCK_ALLOC(pike_frame,128)
+
+
+
#ifdef PIKE_SECURITY
static void restore_creds(struct object *creds)
{
1810:
#define mega_apply2 mega_apply
#endif
+
void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2)
{
struct object *o;
-
+ struct pike_frame *scope=0;
int fun, tailrecurse=-1;
struct svalue *save_sp=sp-args;
1919:
case T_OBJECT:
o=s->u.object;
+ if(o->prog == pike_trampoline_program)
+ {
+ fun=((struct pike_trampoline *)(o->storage))->func;
+ scope=((struct pike_trampoline *)(o->storage))->frame;
+ o=scope->current_object;
+ goto apply_low_with_scope;
+ }
fun=LFUN_CALL;
goto call_lfun;
}
1941:
fun=(long)arg2;
apply_low:
+ scope=0;
+ apply_low_with_scope:
{
struct program *p;
struct reference *ref;
- struct frame new_frame;
+ struct pike_frame *new_frame=alloc_pike_frame();
struct identifier *function;
if(fun<0)
1984:
fatal("Inherit offset out of range in program.\n");
#endif
- /* init a new evaluation frame */
- new_frame.parent_frame = fp;
- new_frame.current_object = o;
- new_frame.context = p->inherits[ ref->inherit_offset ];
+ /* init a new evaluation pike_frame */
+ new_frame->next = fp;
+ new_frame->current_object = o;
+ new_frame->context = p->inherits[ ref->inherit_offset ];
- function = new_frame.context.prog->identifiers + ref->identifier_offset;
+ function = new_frame->context.prog->identifiers + ref->identifier_offset;
#ifdef PIKE_SECURITY
CHECK_DATA_SECURITY_OR_ERROR(o, SECURITY_BIT_CALL, ("Function call permission denied.\n"));
2003:
function->num_calls++;
#endif
- new_frame.locals = sp - args;
- new_frame.expendible = new_frame.locals;
- new_frame.args = args;
- new_frame.fun = fun;
- new_frame.current_storage = o->storage+new_frame.context.storage_offset;
- new_frame.pc = 0;
+ new_frame->locals = sp - args;
+ new_frame->expendible = new_frame->locals;
+ new_frame->args = args;
+ new_frame->fun = fun;
+ new_frame->current_storage = o->storage+new_frame->context.storage_offset;
+ new_frame->pc = 0;
+ new_frame->scope=scope;
- add_ref(new_frame.current_object);
- add_ref(new_frame.context.prog);
- if(new_frame.context.parent) add_ref(new_frame.context.parent);
+ add_ref(new_frame->current_object);
+ add_ref(new_frame->context.prog);
+ if(new_frame->context.parent) add_ref(new_frame->context.parent);
+ if(new_frame->scope) add_ref(new_frame->scope);
if(t_flag)
{
2024:
do_trace_call(args);
}
- fp = &new_frame;
+ fp = new_frame;
if(function->func.offset == -1)
PIKE_ERROR(function->name->str, "Calling undefined function.\n", sp, args);
2041:
{
case IDENTIFIER_C_FUNCTION:
fp->num_args=args;
- new_frame.num_locals=args;
+ new_frame->num_locals=args;
check_threads_etc();
(*function->func.c_fun)(args);
break;
2082:
int num_args;
int num_locals;
unsigned char *pc;
- pc=new_frame.context.prog->program + function->func.offset;
+ pc=new_frame->context.prog->program + function->func.offset;
num_locals=EXTRACT_UCHAR(pc++);
num_args=EXTRACT_UCHAR(pc++);
-
+ /* FIXME: this is only needed if this function contains
+ * trampolines
+ */
+ new_frame->expendible+=num_locals;
+
/* adjust arguments on stack */
if(args < num_args) /* push zeros */
{
2114: Inside #if defined(PIKE_DEBUG)
if(num_locals < num_args)
fatal("Wrong number of arguments or locals in function def.\n");
#endif
- new_frame.num_locals=num_locals;
- new_frame.num_args=num_args;
+ new_frame->num_locals=num_locals;
+ new_frame->num_args=num_args;
check_threads_etc();
2163:
#endif
#if 0
- if(sp - new_frame.locals > 1)
+ if(sp - new_frame->locals > 1)
{
- pop_n_elems(sp - new_frame.locals -1);
- }else if(sp - new_frame.locals < 1){
+ pop_n_elems(sp - new_frame->locals -1);
+ }else if(sp - new_frame->locals < 1){
#ifdef PIKE_DEBUG
- if(sp - new_frame.locals<0) fatal("Frame underflow.\n");
+ if(sp - new_frame->locals<0) fatal("Frame underflow.\n");
#endif
sp->u.integer = 0;
sp->subtype=NUMBER_NUMBER;
2177:
}
#endif
- if(new_frame.context.parent) free_object(new_frame.context.parent);
- free_object(new_frame.current_object);
- free_program(new_frame.context.prog);
+ #ifdef PIKE_DEBUG
+ if(fp!=new_frame)
+ fatal("Frame stack out of whack!\n");
+ #endif
- fp = new_frame.parent_frame;
+ POP_PIKE_FRAME();
if(tailrecurse>=0)
{
2256:
int apply_low_safe_and_stupid(struct object *o, INT32 offset)
{
JMP_BUF tmp;
- struct frame new_frame;
+ struct pike_frame *new_frame=alloc_pike_frame();
int ret;
- new_frame.parent_frame = fp;
- new_frame.current_object = o;
- new_frame.context=o->prog->inherits[0];
- new_frame.locals = evaluator_stack;
- new_frame.expendible=new_frame.locals;
- new_frame.args = 0;
- new_frame.num_args=0;
- new_frame.num_locals=0;
- new_frame.fun = -1;
- new_frame.pc = 0;
- new_frame.current_storage=o->storage;
- new_frame.context.parent=0;
- fp = & new_frame;
+ new_frame->next = fp;
+ new_frame->current_object = o;
+ new_frame->context=o->prog->inherits[0];
+ new_frame->locals = evaluator_stack;
+ new_frame->expendible=new_frame->locals;
+ new_frame->args = 0;
+ new_frame->num_args=0;
+ new_frame->num_locals=0;
+ new_frame->fun = -1;
+ new_frame->pc = 0;
+ new_frame->current_storage=o->storage;
+ new_frame->context.parent=0;
+ fp = new_frame;
- add_ref(new_frame.current_object);
- add_ref(new_frame.context.prog);
+ add_ref(new_frame->current_object);
+ add_ref(new_frame->context.prog);
if(SETJMP(tmp))
{
2291:
}
UNSETJMP(tmp);
- free_object(new_frame.current_object);
- free_program(new_frame.context.prog);
+ POP_PIKE_FRAME();
- fp=new_frame.parent_frame;
+
return ret;
}
2401: Inside #if defined(PIKE_DEBUG)
void slow_check_stack(void)
{
struct svalue *s,**m;
- struct frame *f;
+ struct pike_frame *f;
debug_check_stack();
2428: Inside #if defined(PIKE_DEBUG)
if(s > &(evaluator_stack[stack_size]))
fatal("Mark stack exceeds svalue stack\n");
- for(f=fp;f;f=f->parent_frame)
+ for(f=fp;f;f=f->next)
{
if(f->locals)
{
2437: Inside #if defined(PIKE_DEBUG)
fatal("Local variable pointer points to Finspång.\n");
if(f->args < 0 || f->args > stack_size)
- fatal("FEL FEL FEL! HELP!! (corrupted frame)\n");
+ fatal("FEL FEL FEL! HELP!! (corrupted pike_frame)\n");
}
}
}
2451:
while(fp)
{
- free_object(fp->current_object);
- free_program(fp->context.prog);
-
- fp = fp->parent_frame;
+ struct pike_frame *tmp=fp;
+ fp=tmp->next;
+ tmp->next=0;
+ free_pike_frame(tmp);
}
#ifdef PIKE_DEBUG