mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 12:26:29 +00:00
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.
252 lines
8.1 KiB
C
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 */
|