pike.git / src / interpret.c

version» Context lines:

pike.git/src/interpret.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: interpret.c,v 1.358 2004/10/30 11:38:25 mast Exp $ + || $Id: interpret.c,v 1.359 2004/11/12 13:13:30 grubba Exp $   */      #include "global.h"   #include "interpret.h"   #include "object.h"   #include "program.h"   #include "svalue.h"   #include "array.h"   #include "mapping.h"   #include "pike_error.h"
pike.git/src/interpret.c:988:   #define EVAL_INSTR_RET_CHECK(x) \    if (x == -2) \    Pike_fatal("Return value -2 from eval_instruction is not handled here.\n"\    "Probable cause: F_ESCAPE_CATCH outside catch block.\n")   #else   #define EVAL_INSTR_RET_CHECK(x)   #endif         #ifdef PIKE_USE_MACHINE_CODE -  +    /* Labels to jump to to cause eval_instruction to return */   /* FIXME: Replace these with assembler lables */   void *do_inter_return_label = NULL;   void *do_escape_catch_label;   void *dummy_label = NULL;    - #ifndef DEF_PROG_COUNTER - #define DEF_PROG_COUNTER - #endif /* !DEF_PROG_COUNTER */ -  +    #ifndef CALL_MACHINE_CODE   #define CALL_MACHINE_CODE(pc) \    do { \    /* The test is needed to get the labels to work... */ \    if (pc) { \    /* No extra setup needed! \    */ \    return ((int (*)(void))(pc))(); \    } \    } while(0)
pike.git/src/interpret.c:1062:   }   void simple_debug_instr_prologue_2 (PIKE_INSTR_T instr, INT32 arg1, INT32 arg2)   {    if (d_flag || Pike_interpreter.trace_level > 2) {    low_debug_instr_prologue (instr);    DEBUG_LOG_ARG (arg1);    DEBUG_LOG_ARG2 (arg2);    }   }    - #else /* !PIKE_DEBUG */ - #define DEBUG_PROLOGUE(OPCODE, EXTRA) do {} while (0) +    #endif /* !PIKE_DEBUG */    -  + #endif /* PIKE_USE_MACHINE_CODE */ +  + #ifdef PIKE_SMALL_EVAL_INSTRUCTION + #undef PROG_COUNTER + #define PROG_COUNTER Pike_fp->pc+1 + #endif /* PIKE_SMALL_EVAL_INSTRUCTION */ +  + #if defined(PIKE_USE_MACHINE_CODE) || defined(PIKE_SMALL_EVAL_INSTRUCTION) +  + #ifndef DEF_PROG_COUNTER + #define DEF_PROG_COUNTER + #endif /* !DEF_PROG_COUNTER */ +  + #ifndef DEBUG_PROLOGUE + #define DEBUG_PROLOGUE(OPCODE, EXTRA) do {} while (0) + #endif +    #define OPCODE0(O,N,F,C) \   void PIKE_CONCAT(opcode_,O)(void) { \    DEF_PROG_COUNTER; \    DEBUG_PROLOGUE (O, ;); \   C }      #define OPCODE1(O,N,F,C) \   void PIKE_CONCAT(opcode_,O)(INT32 arg1) {\    DEF_PROG_COUNTER; \    DEBUG_PROLOGUE (O, DEBUG_LOG_ARG (arg1)); \   C }      #define OPCODE2(O,N,F,C) \   void PIKE_CONCAT(opcode_,O)(INT32 arg1,INT32 arg2) { \    DEF_PROG_COUNTER; \    DEBUG_PROLOGUE (O, DEBUG_LOG_ARG (arg1); DEBUG_LOG_ARG2 (arg2)); \   C }    - #ifdef OPCODE_RETURN_JUMPADDR + #if defined(OPCODE_RETURN_JUMPADDR) || defined(PIKE_SMALL_EVAL_INSTRUCTION)      #define OPCODE0_JUMP(O,N,F,C) \    void *PIKE_CONCAT(jump_opcode_,O)(void) { \    void *jumpaddr DO_IF_DEBUG(= NULL); \    DEF_PROG_COUNTER; \    DEBUG_PROLOGUE (O, ;); \    C; \    JUMP_DONE; \    }   
pike.git/src/interpret.c:1125:   #ifdef PIKE_DEBUG   #define JUMP_DONE do { \    if (!jumpaddr) \    Pike_fatal ("Instruction didn't set jump address.\n"); \    return jumpaddr; \    } while (0)   #else   #define JUMP_DONE return jumpaddr   #endif    - #else /* !OPCODE_RETURN_JUMPADDR */ + #else /* !OPCODE_RETURN_JUMPADDR && !PIKE_SMALL_EVAL_INSTRUCTION */   #define OPCODE0_JUMP OPCODE0   #define OPCODE1_JUMP OPCODE1   #define OPCODE2_JUMP OPCODE2   #define JUMP_DONE DONE - #endif /* !OPCODE_RETURN_JUMPADDR */ + #endif /* OPCODE_RETURN_JUMPADDR || PIKE_SMALL_EVAL_INSTRUCTION */    - #ifdef OPCODE_INLINE_BRANCH + #if defined(OPCODE_INLINE_BRANCH) || defined(PIKE_SMALL_EVAL_INSTRUCTION)   #define TEST_OPCODE0(O,N,F,C) \   int PIKE_CONCAT(test_opcode_,O)(void) { \    int branch_taken = 0; \    DEF_PROG_COUNTER; \    DEBUG_PROLOGUE (O, ;); \    C; \    return branch_taken; \    }      #define TEST_OPCODE1(O,N,F,C) \
pike.git/src/interpret.c:1163:   int PIKE_CONCAT(test_opcode_,O)(INT32 arg1, INT32 arg2) { \    int branch_taken = 0; \    DEF_PROG_COUNTER; \    DEBUG_PROLOGUE (O, DEBUG_LOG_ARG (arg1); DEBUG_LOG_ARG2 (arg2)); \    C; \    return branch_taken; \    }      #define DO_BRANCH() (branch_taken = -1)   #define DONT_BRANCH() (branch_taken = 0) - #else /* !OPCODE_INLINE_BRANCH */ + #else /* !OPCODE_INLINE_BRANCH && !PIKE_SMALL_EVAL_INSTRUCTION */   #define TEST_OPCODE0(O,N,F,C) OPCODE0_PTRJUMP(O,N,F,C)   #define TEST_OPCODE1(O,N,F,C) OPCODE1_PTRJUMP(O,N,F,C)   #define TEST_OPCODE2(O,N,F,C) OPCODE2_PTRJUMP(O,N,F,C) - #endif /* OPCODE_INLINE_BRANCH */ + #endif /* OPCODE_INLINE_BRANCH || PIKE_SMALL_EVAL_INSTRUCTION */      #define OPCODE0_TAIL(O,N,F,C) OPCODE0(O,N,F,C)   #define OPCODE1_TAIL(O,N,F,C) OPCODE1(O,N,F,C)   #define OPCODE2_TAIL(O,N,F,C) OPCODE2(O,N,F,C)      #define OPCODE0_PTRJUMP(O,N,F,C) OPCODE0_JUMP(O,N,F,C)   #define OPCODE1_PTRJUMP(O,N,F,C) OPCODE1_JUMP(O,N,F,C)   #define OPCODE2_PTRJUMP(O,N,F,C) OPCODE2_JUMP(O,N,F,C)   #define OPCODE0_TAILPTRJUMP(O,N,F,C) OPCODE0_PTRJUMP(O,N,F,C)   #define OPCODE1_TAILPTRJUMP(O,N,F,C) OPCODE1_PTRJUMP(O,N,F,C)
pike.git/src/interpret.c:1207:   #define OPCODE0_ALIAS(O,N,F,C)   #define OPCODE1_ALIAS(O,N,F,C)   #define OPCODE2_ALIAS(O,N,F,C)      #undef HAVE_COMPUTED_GOTO      #ifdef GLOBAL_DEF_PROG_COUNTER   GLOBAL_DEF_PROG_COUNTER;   #endif    + #ifndef SET_PROG_COUNTER + #define SET_PROG_COUNTER(X) (PROG_COUNTER=(X)) + #endif /* SET_PROG_COUNTER */ +  + #undef DONE + #undef FETCH + #undef INTER_RETURN + #undef INTER_ESCAPE_CATCH +  + #define DONE return + #define FETCH + #define INTER_RETURN {SET_PROG_COUNTER(do_inter_return_label);JUMP_DONE;} + #define INTER_ESCAPE_CATCH {SET_PROG_COUNTER(do_escape_catch_label);JUMP_DONE;} +  + #if defined(PIKE_USE_MACHINE_CODE) && defined(_M_IX86) + /* Disable frame pointer optimization */ + #pragma optimize("y", off) + #endif +  + #include "interpret_functions_fixed.h" +  + #if defined(PIKE_USE_MACHINE_CODE) && defined(_M_IX86) + /* Restore optimization */ + #pragma optimize("", on) + #endif +  + #ifdef PIKE_SMALL_EVAL_INSTRUCTION + #undef SET_PROG_COUNTER + #undef PROG_COUNTER + #define PROG_COUNTER pc + #endif +  + #endif /* PIKE_USE_MACHINE_CODE || PIKE_SMALL_EVAL_INSTRUCTION */ +  + #ifdef PIKE_USE_MACHINE_CODE +    #ifdef PIKE_DEBUG   /* Note: The debug code is extracted, to keep the frame size constant. */   static int eval_instruction_low(PIKE_OPCODE_T *pc);   #endif /* PIKE_DEBUG */      static int eval_instruction(PIKE_OPCODE_T *pc)   #ifdef PIKE_DEBUG   {    if (Pike_interpreter.trace_level > 5 && pc) {    int i;
pike.git/src/interpret.c:1299:    inter_escape_catch_label:    EXIT_MACHINE_CODE();    return -2;    }       inter_return_label:    EXIT_MACHINE_CODE();    return -1;   }    - #ifndef SET_PROG_COUNTER - #define SET_PROG_COUNTER(X) (PROG_COUNTER=(X)) - #endif /* SET_PROG_COUNTER */ -  - #undef DONE - #undef FETCH - #undef INTER_RETURN - #undef INTER_ESCAPE_CATCH -  - #define DONE return - #define FETCH - #define INTER_RETURN {SET_PROG_COUNTER(do_inter_return_label);JUMP_DONE;} - #define INTER_ESCAPE_CATCH {SET_PROG_COUNTER(do_escape_catch_label);JUMP_DONE;} -  - #ifdef _M_IX86 - // Disable frame pointer optimization - #pragma optimize("y", off) - #endif -  - #include "interpret_functions_fixed.h" -  - #ifdef _M_IX86 - // Restore optimization - #pragma optimize("", on) - #endif -  +    #else /* PIKE_USE_MACHINE_CODE */         #ifndef SET_PROG_COUNTER   #define SET_PROG_COUNTER(X) (PROG_COUNTER=(X))   #endif /* SET_PROG_COUNTER */      #ifdef HAVE_COMPUTED_GOTO   int lookup_sort_fun(const void *a, const void *b)   {
pike.git/src/interpret.c:1374:      static INLINE int eval_instruction(unsigned char *pc)   {    if(d_flag || Pike_interpreter.trace_level>2)    return eval_instruction_with_debug(pc);    else    return eval_instruction_without_debug(pc);   }       - #else + #else /* !PIKE_DEBUG || HAVE_COMPUTED_GOTO */   #include "interpreter.h"   #endif         #endif /* PIKE_USE_MACHINE_CODE */      static void do_trace_call(INT32 args, dynamic_buffer *old_buf)   {    struct pike_string *filep = NULL;    char *file, *s;
pike.git/src/interpret.c:1636:    case T_INT:    if (!s->u.integer) {    PIKE_ERROR("0", "Attempt to call the NULL-value\n", Pike_sp, args);    } else {    Pike_error("Attempt to call the value %"PRINTPIKEINT"d\n",    s->u.integer);    }       case T_STRING:    if (s->u.string->len > 20) { -  Pike_error("Attempt to call the string \"%20s\"...\n", s->u.string->str); +  Pike_error("Attempt to call the string \"%20S\"...\n", s->u.string);    } else { -  Pike_error("Attempt to call the string \"%s\"\n", s->u.string->str); +  Pike_error("Attempt to call the string \"%S\"\n", s->u.string);    }    case T_MAPPING:    Pike_error("Attempt to call a mapping\n");    default:    Pike_error("Call to non-function value type:%s.\n",    get_name_of_type(s->type));       case T_FUNCTION:    if(s->subtype == FUNCTION_BUILTIN)    {
pike.git/src/interpret.c:1670:    do_trace_call(args, &save_buf);    }    check_threads_etc();    (*(s->u.efun->function))(args);      #ifdef PIKE_DEBUG    s->u.efun->runs++;    if(Pike_sp != expected_stack + !s->u.efun->may_return_void)    {    if(Pike_sp < expected_stack) -  Pike_fatal("Function popped too many arguments: %s\n", -  s->u.efun->name->str); +  Pike_fatal("Function popped too many arguments: %S\n", +  s->u.efun->name);    if(Pike_sp>expected_stack+1) -  Pike_fatal("Function left droppings on stack: %s\n", -  s->u.efun->name->str); +  Pike_fatal("Function left droppings on stack: %S\n", +  s->u.efun->name);    if(Pike_sp == expected_stack && !s->u.efun->may_return_void) -  Pike_fatal("Non-void function returned without return value on stack: %s %d\n", -  s->u.efun->name->str,s->u.efun->may_return_void); +  Pike_fatal("Non-void function returned without return value on stack: %S %d\n", +  s->u.efun->name, s->u.efun->may_return_void);    if(Pike_sp==expected_stack+1 && s->u.efun->may_return_void) -  Pike_fatal("Void function returned with a value on the stack: %s %d\n", -  s->u.efun->name->str, s->u.efun->may_return_void); +  Pike_fatal("Void function returned with a value on the stack: %S %d\n", +  s->u.efun->name, s->u.efun->may_return_void);    }   #endif       break;    }else{    type=APPLY_SVALUE;    o=s->u.object;    if(o->prog == pike_trampoline_program &&    s->subtype == QUICK_FIND_LFUN(pike_trampoline_program, LFUN_CALL))    {
pike.git/src/interpret.c:2255:   {    int id;   #ifdef PIKE_DEBUG    if(!o->prog) Pike_fatal("Apply safe on destructed object.\n");   #endif    id = find_identifier(fun, o->prog);    if (id >= 0)    safe_apply_low2(o, id, args, 1);    else {    char buf[4096]; +  /* FIXME: Ought to use string_buffer_vsprintf(). */    SNPRINTF(buf, sizeof (buf), "Cannot call unknown function \"%s\".\n", fun);    push_error (buf);    free_svalue (&throw_value);    move_svalue (&throw_value, --Pike_sp);    call_handle_error();    push_int (0);    }   }      /* Returns nonzero if the function was called in some handler. */
pike.git/src/interpret.c:2351:    if (SETJMP_SP(recovery, args)) {    ret = 0;    } else {    if (low_unsafe_apply_handler (fun, handler, compat, args) &&    rettypes && !((1 << Pike_sp[-1].type) & rettypes)) {    if ((rettypes & BIT_ZERO) && SAFE_IS_ZERO (Pike_sp - 1)) {    pop_stack();    push_int(0);    }    else { -  push_constant_text("Invalid return value from %s: %O\n"); -  push_text(fun); -  push_svalue(Pike_sp - 3); -  f_sprintf(3); -  if (!Pike_sp[-1].u.string->size_shift) -  Pike_error("%s", Pike_sp[-1].u.string->str); -  else -  Pike_error("Invalid return value from %s\n", fun); +  Pike_error("Invalid return value from %s: %O\n", +  fun, Pike_sp-1);    }    }       ret = 1;    }       UNSETJMP(recovery);       STACK_LEVEL_DONE(ret);   
pike.git/src/interpret.c:2392:   }      PMOD_EXPORT void apply_shared(struct object *o,    struct pike_string *fun,    int args)   {    int id = find_shared_string_identifier(fun, o->prog);    if (id >= 0)    apply_low(o, id, args);    else -  if (fun->size_shift) -  Pike_error ("Cannot call unknown function.\n"); -  else -  Pike_error ("Cannot call unknown function \"%s\".\n", fun->str); +  Pike_error("Cannot call unknown function \"%S\".\n", fun);   }      PMOD_EXPORT void apply(struct object *o, const char *fun, int args)   {    int id = find_identifier(fun, o->prog);    if (id >= 0)    apply_low(o, id, args);    else    Pike_error ("Cannot call unknown function \"%s\".\n", fun);   }