Files
mercury/bytecode/mb_interface.h
Levi Cameron 0921310ca5 More work on the bytecode interpreter.
With these changes, it now passes all tests/general/* test cases
  except those with floats.

  Changes to the compiler:
  - Added extra argument to test instruction (string comparisons were
    being treated as integer comparisons; properly deals with different
    atomic type unifications now)
  - Changed bytecode stub functions

  Changes to the bytecode interpreter:
  - Cleaned up comments
  - Forked part of mb_machine to mb_exec
  - Added support for submodules
  - Added support for nondet procedures
  - Added support for cc_xxx procedures
  - Finished higher order calls
  - Added (very basic) debug interface
  - Added support for type information
  - Added memory corruption checking
  - Changed machine state dump formatting
  - Fixed bug in nested switches
  - Resolved builtin__unify and builtin_compare failures
  - Modified bytecode tags generation so .c & .m tag files are separate
  - Header usage rationalised

  Changes to test suite:
  - Added test cases for the bytecode interpreter.
  - More work on the bytecode interpreter.

bytecode/Mmakefile:
        Modified bytecode tags generation so .c & .m tag files are separate.
        mb_machine split into mb_exec.
        test file renamed to simple.m (copy over tests/simple??.m to test).

bytecode/TODO:
        Updated.

bytecode/mb_basetypes.h:
        Removed redundant MB_WORD_BITS (use MR_WORDBITS instead).

bytecode/mb_bytecode.h:
bytecode/mpb_bytecode.c:
        Formatting changes
        Third test instruction argument added.

bytecode/mb_disasm.h:
bytecode/mb_disasm.c:
        Formatting changes.
        Third test instruction argument added.
        Added MB_FMT_INTWIDE.

bytecode/mb_exec.h:
bytecode/mb_exec.c:
bytecode/mb_machine.h:
bytecode/mb_machine.c:
        mb_machine* split into mb_exec* and mb_machine*.
        Almost all instructions now work (see important changes above).

bytecode/mb_interface.h:
bytecode/mb_interface.c:
        Added nondet stub functions.
        Added functions to lookup builtin compiler procedures:
                do_redo, do_fail, __unify, __compare.
        Removed old debugging code.
        Stack layout changed to support nondet procedures.

bytecode/mb_interface_stub.c:
bytecode/mb_interface_stub.h:
        Split off bare minimum of includes for bytecode stubs.
        Added nondet stubs.

bytecode/mb_machine_show.c:
        Made code cleaner (added subfunctions for MB_show_state).
        Added variable names to machine state dump.

bytecode/mb_mem.h:
bytecode/mb_mem.c:
        Added limited memory corruption checking.

bytecode/mb_module.h:
bytecode/mb_module.c:
        Swapped order of temps & vars on stack.
        Fixed nested switches causing random crashes.
        Added nested module support.

bytecode/test/simple??.m:
        Various test files - just to check that it doesn't crash.
        (Most do not output anything & must be verified by stepping through
        manually).

compiler/bytecode.m:
compiler/bytecode_gen.m:
        Added extra argument to test instruction (otherwise
        string comparisons would be treated as integer comparisons).

compiler/code_gen.m:
        Changed call structure name in bytecode stub to resolve
        issues with illegal characters in C structure names.
        Changed bytecode stub header file name.
2001-02-19 02:05:59 +00:00

252 lines
8.1 KiB
C

/*
** Copyright (C) 2000-2001 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
**
** Native-bytecode interface
**
*/
#ifndef MB_INTERFACE_H
#define MB_INTERFACE_H
#include "mb_interface_stub.h"
#include "mb_util.h"
/* Returns pointer to the stub that calls corresponding function */
MB_Native_Addr MB_native_get_return_det(void);
MB_Native_Addr MB_native_get_return_temp_det(void);
MB_Native_Addr MB_native_get_return_temp_nondet(void);
MB_Native_Addr MB_native_get_return_nondet(void);
MB_Native_Addr MB_native_get_do_redo(void);
MB_Native_Addr MB_native_get_do_fail(void);
MB_Native_Addr MB_native_get_unify_2(void);
MB_Native_Addr MB_native_get_compare_3(void);
/* Find the native code entry point for a procedure */
MB_Native_Addr MB_code_find_proc_native(MB_CString_Const module_name,
MB_CString_Const pred_name,
MB_Word mode_num, MB_Word arity,
MB_Bool is_func);
MB_Native_Addr MB_code_find_proc_native(MB_CString_Const module_name,
MB_CString_Const pred_name,
MB_Word mode_num, MB_Word arity,
MB_Bool is_func);
/* Get type info. Will abort program if it cannot find it */
MR_TypeCtorInfo MB_type_find_ctor_info_guaranteed(
MB_CString_Const module_name,
MB_CString_Const type_name,
MB_Word type_arity);
/**************************************************************/
/*
** det stack
**
** Each normal det stack frame looks like the following:
** sp-1: [succip]
** sp-2: [temp 0]
** sp-3: [temp 1]
** ...
** sp-n: [var 0]
** sp-n-1: [var 1]
** ...
**
** If model semidet, then temp 0 is the semidet success indicator
** This is why putting the temps straight after the fixed stack
** slots allows SEMIDET_SUCCESS to be in a fixed location
**
*/
/* saved succip */
#define MB_DETFRAME_SUCCIP (1)
/* fixed size of deterministic stack frame */
#define MB_DETFRAME_SIZE (1)
/* semidet success indicator (loaded into r0 at endof_proc) */
#define MB_DETFRAME_SEMIDET_SUCCESS (2)
/*
** An interface det stack frame is pushed when bytecode wishes
** to jump to native code and later return to bytecode. Succip
** will have been set to a stub that reads the interface stack
** frame and directs control appropriately (MB_bytecode_return_det_stub)
** sp-1: [succip in bytecode to return to]
** sp-2: [saved machine state initial frame]
*/
/* bytecode return address for stub */
#define MB_DETFRAME_INTERFACE_BCRETIP (1)
#define MB_DETFRAME_INTERFACE_BCINITFR (2)
/* Size of a deterministic interface frame */
#define MB_DETFRAME_INTERFACE_SIZE (2)
/*
** Nondet stack
**
** An ordinary stack frame looks like so:
** curfr[ 0] prevfr (frame below this one)
** curfr[-1] redoip (ip to use at redo) = do_fail
** curfr[-2] redofr (curfr to use at redo)
** curfr[-3] succip (ip to use at success [caller return] )
** curfr[-4] succfr (frame to use at success [calling frame])
** curfr[-5] bcretip (stack slot with next bytecode IP to return
** to following a call to native code)
** curfr[-6] initfr (saved initfr)
** then follows var[0] to var[n]
** then follows temp[0] to temp[n]
**
** A temp stack frame from nondet code looks like so:
** curfr[ 0] prevfr (frame below this one)
** curfr[-1] redoip (ip to use at redo) = MB_bytecode_return_temp_nondet
** curfr[-2] redofr (curfr to use at redo)
** curfr[-3] bcredoip (bytecode ip to return to when redoing this frame)
**
** A temp stack frame from det code looks like so:
** curfr[ 0] prevfr (frame below this one)
** curfr[-1] redoip (ip to use at redo) = MB_bytecode_return_temp_det
** curfr[-2] redofr (curfr to use at redo)
** curfr[-3] detfr (deterministic stack frame (used by accurate GC))
** curfr[-4] bcredoip (bytecode ip to return to when redoing this frame)
** curfr[-5] initfr (saved initfr)
**
** When entering nondet code:
** If initfr is not already set, set it to maxfr
** Push normal nondet stack frame
**
** When calling native code from nondet code:
** bcretip = next bytecode instruction after the call
** MB_succip = MB_bytecode_return_nondet_stub which calls
** MB_bytecode_return_nondet which reads bcretip and jumps
** to the correct bytecode instruction
**
** When returning from nondet code:
** Check if curfr->prevfr = initfr then this procedure was the one that
** set initfr.
** If it was, we should return to native code address succip.
** If it wasn't, we should return to bytecode address succip.
*/
/* Present in all stack frames on the nondet stack */
#define MB_FRAME_PREVFR (0)
#define MB_FRAME_REDOIP (1)
#define MB_FRAME_REDOFR (2)
/* Present in temporary nondet stack frames on the nondet stack */
#define MB_FRAME_TEMP_NONDET_BCREDOIP (3)
/* Present in temporary det stack frames on the nondet stack */
#define MB_FRAME_DETFR (3)
#define MB_FRAME_TEMP_DET_BCREDOIP (4)
#define MB_FRAME_TEMP_DET_BCINITFR (5)
/* Present in all normal nondet stack frames */
#define MB_FRAME_SUCCIP (3)
#define MB_FRAME_SUCCFR (4)
#define MB_FRAME_BCRETIP (5)
#define MB_FRAME_BCINITFR (6)
/*
** Note that the 3-4-5 size of the original native stack frames no longer
** applies; bytecode stack frames can have sizes of 4-6-7.
** The redoip of a bytecode stack frame will always be one of:
** MR_do_fail
** MB_bytecode_return_temp_det_stub
** MB_bytecode_return_temp_nondet_stub
**
*/
/* size of normal nondet stack frame */
#define MB_FRAME_NORMAL_SIZE 7
/* size of temp nondet stack frame created by model det/semidet code */
#define MB_FRAME_TEMP_DET_SIZE 6
/* size of temp nondet stack frame created by model nondet code */
#define MB_FRAME_TEMP_NONDET_SIZE 4
/* Invalid frame address */
#define MB_FRAME_INVALID ((MB_Word) (-1))
/*
** semidet success flags: stored in a temp slot until the procedure
** returns, when it is returned in a register
*/
#define MB_SEMIDET_SUCCESS TRUE
#define MB_SEMIDET_FAILURE FALSE
#define MB_SEMIDET_SUCCESS_REG 1
/**************************************************************/
/* register definitions */
#define MB_reg(n) MR_virtual_reg(n)
#define MB_succip MR_virtual_succip
#define MB_sp MR_virtual_sp
#define MB_curfr MR_virtual_curfr
#define MB_maxfr MR_virtual_maxfr
/* Det stack: slot 1 is the top (used - slot 0 is unused) */
#define MB_stackvar(x) ((MB_sp)[-((x) + MB_DETFRAME_SIZE + 1)])
#define MB_stackitem(x) ((MB_sp)[-(x)])
#define MB_incr_sp(x) ( \
MB_sp += (x), \
(void)0 \
)
#define MB_decr_sp(x) MB_incr_sp(-(x))
/* Nondet stack - same as with det statck */
#define MB_frameitem(frame_ptr, x) ((frame_ptr)[-(x)])
#define MB_framevar(x) (MB_frameitem(MB_curfr, MB_FRAME_NORMAL_SIZE))
#define MB_fr_prevfr(frame_ptr) \
((MB_Word *) MB_frameitem(frame_ptr, MB_FRAME_PREVFR))
#define MB_fr_redoip(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_REDOIP)
#define MB_fr_redofr(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_REDOFR)
#define MB_fr_temp_nondet_bcredoip(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_TEMP_NONDET_BCREDOIP)
#define MB_fr_detfr(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_DETFR)
#define MB_fr_temp_det_bcredoip(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_TEMP_DET_BCREDOIP)
#define MB_fr_temp_det_bcinitfr(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_TEMP_DET_BCINITFR)
#define MB_fr_succip(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_SUCCIP)
#define MB_fr_succfr(frame_ptr) \
((MB_Word *) MB_frameitem(frame_ptr, MB_FRAME_SUCCFR))
#define MB_fr_bcretip(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_BCRETIP)
#define MB_fr_bcinitfr(frame_ptr) \
MB_frameitem(frame_ptr, MB_FRAME_BCINITFR)
#define MB_frame_size(frame_ptr) \
(frame_ptr - (MB_Word *) MB_fr_prevfr(frame_ptr))
/**************************************************************/
/* tags */
#include "mercury_tags.h"
#define MB_mktag(t) MR_mktag(t)
#define MB_mkbody(p) MR_mkbody(p)
#define MB_tag(w) MR_tag(w)
#define MB_body(w,t) MR_body(w,t)
#define MB_mkword(t,p) MR_mkword(t,p)
#define MB_strip_tag(w) MR_strip_tag(w)
#define MB_field(t, w, i) MR_field(t,w,i)
#endif /* MB_INTERFACE_H */