2009-02-17 15:02:16 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
2009-02-16 09:23:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
#ifndef _SCI_SEG_MANAGER_H
|
|
|
|
#define _SCI_SEG_MANAGER_H
|
|
|
|
|
|
|
|
#include "sci/engine/int_hashmap.h"
|
|
|
|
#include "sci/include/sys_strings.h"
|
|
|
|
#include "sci/include/vm.h"
|
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
namespace Sci {
|
|
|
|
|
2009-02-16 09:23:58 +00:00
|
|
|
#define DEFAULT_SCRIPTS 32
|
2009-02-20 22:29:49 +00:00
|
|
|
#define DEFAULT_OBJECTS 8 // default # of objects per script
|
|
|
|
#define DEFAULT_OBJECTS_INCREMENT 4 // Number of additional objects to instantiate if we're running out of them
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-20 22:29:49 +00:00
|
|
|
// SCRIPT_ID must be 0
|
2009-02-16 09:23:58 +00:00
|
|
|
typedef enum {
|
2009-02-20 22:29:49 +00:00
|
|
|
SCRIPT_ID,
|
|
|
|
SEG_ID
|
2009-02-16 09:23:58 +00:00
|
|
|
} id_flag;
|
|
|
|
|
2009-02-20 22:29:49 +00:00
|
|
|
//void dbg_print( const char* msg, void *i ); // for debug only
|
|
|
|
|
|
|
|
// verify the the given condition is true, output the message if condition is false, and exit
|
|
|
|
// Parameters:
|
|
|
|
// cond - condition to be verified
|
|
|
|
// msg - the message to be printed if condition fails
|
|
|
|
// return:
|
|
|
|
// none, terminate the program if fails
|
|
|
|
#define VERIFY( cond, msg ) if (!(cond)) {\
|
|
|
|
sciprintf("%s, line, %d, %s\n", __FILE__, __LINE__, msg); \
|
|
|
|
BREAKPOINT(); \
|
2009-02-16 09:23:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define MEM_OBJ_INVALID 0
|
|
|
|
#define MEM_OBJ_SCRIPT 1
|
|
|
|
#define MEM_OBJ_CLONES 2
|
|
|
|
#define MEM_OBJ_LOCALS 3
|
|
|
|
#define MEM_OBJ_STACK 4
|
|
|
|
#define MEM_OBJ_SYS_STRINGS 5
|
|
|
|
#define MEM_OBJ_LISTS 6
|
|
|
|
#define MEM_OBJ_NODES 7
|
|
|
|
#define MEM_OBJ_HUNK 8
|
|
|
|
#define MEM_OBJ_DYNMEM 9
|
|
|
|
#define MEM_OBJ_RESERVED 10
|
2009-02-20 22:29:49 +00:00
|
|
|
#define MEM_OBJ_MAX MEM_OBJ_RESERVED // For sanity checking
|
|
|
|
|
2009-02-16 09:23:58 +00:00
|
|
|
typedef int mem_obj_enum;
|
|
|
|
|
2009-02-20 22:29:49 +00:00
|
|
|
#define GET_SEGMENT(mgr, index, rtype) ((index) > 0 && (mgr).heap_size > index) ? \
|
|
|
|
(((mgr).heap[index] && (mgr).heap[index]->type == rtype)? (mgr).heap[index] : NULL) : NULL
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-20 22:29:49 +00:00
|
|
|
#define GET_SEGMENT_ANY(mgr, index) ((index) > 0 && (mgr).heap_size > index) ? \
|
|
|
|
(((mgr).heap[index])? (mgr).heap[index] : NULL) : NULL
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-20 22:29:49 +00:00
|
|
|
#define GET_OBJECT_SEGMENT(mgr, index) ((index) > 0 && (mgr).heap_size > index) ? \
|
|
|
|
(((mgr).heap[index] && ((mgr).heap[index]->type == MEM_OBJ_SCRIPT || (mgr).heap[index]->type == MEM_OBJ_CLONES))? (mgr).heap[index] \
|
|
|
|
: NULL): NULL
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
struct SegManager {
|
2009-02-20 22:29:49 +00:00
|
|
|
int_hash_map_t *id_seg_map; // id - script id; seg - index of heap
|
2009-02-21 19:01:32 +00:00
|
|
|
mem_obj_t **heap;
|
2009-02-20 22:29:49 +00:00
|
|
|
int heap_size; // size of the heap
|
|
|
|
int reserved_id;
|
|
|
|
int exports_wide;
|
|
|
|
int sci1_1;
|
|
|
|
|
|
|
|
int gc_mark_bits;
|
|
|
|
// For standard Mark&Sweep:
|
|
|
|
// 1 or 0, depending on what unreachable/freshly allocated
|
|
|
|
// memory is tagged as
|
|
|
|
size_t mem_allocated; // Total amount of memory allocated
|
|
|
|
|
|
|
|
seg_id_t clones_seg_id; // ID of the (a) clones segment
|
|
|
|
seg_id_t lists_seg_id; // ID of the (a) list segment
|
|
|
|
seg_id_t nodes_seg_id; // ID of the (a) node segment
|
|
|
|
seg_id_t hunks_seg_id; // ID of the (a) hunk segment
|
2009-02-21 11:04:47 +00:00
|
|
|
};
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-20 22:29:49 +00:00
|
|
|
// Toplevel functionality
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_init(SegManager *self, int sci1_1);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Initialize the segment manager
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_destroy(SegManager *self);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Deallocate all memory associated with the segment manager
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_gc(SegManager *self, EngineState *s);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Perform garbage collection
|
|
|
|
// Parameters: (state_t *) s: The state to operate on
|
|
|
|
// Effects : Unreachable objects in 's' are deallocated
|
|
|
|
|
|
|
|
// 1. Scripts
|
|
|
|
|
|
|
|
void sm_free_script(mem_obj_t* mem);
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
mem_obj_t *sm_allocate_script(SegManager* self, EngineState *s, int script_nr, int* seg_id);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocate a script into the segment manager
|
|
|
|
// Parameters: (int) script_nr: number of the script to load
|
|
|
|
// (state_t *) s: The state containing resource manager handlers to load the
|
|
|
|
// script data
|
|
|
|
// Returns : (int) 0 on failure, 1 on success
|
|
|
|
// (int) *seg_id: The segment ID of the newly allocated segment, on success
|
|
|
|
|
|
|
|
// The script must then be initialised; see section (1b.), below.
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
int sm_deallocate_script(SegManager* self, int script_nr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Forcefully deallocate a previously allocated script
|
|
|
|
// Parameters: (int) script_nr: number of the script to deallocate
|
|
|
|
// Returns : (int) 1 on success, 0 on failure
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
int sm_script_is_loaded(SegManager* self, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Determines whether a script has been loaded yet
|
|
|
|
// Parameters: (int) id: number of the script or ID of the script segment to check for
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
|
2009-02-21 21:16:41 +00:00
|
|
|
uint16 sm_validate_export_func(SegManager* self, int pubfunct, int seg);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Validate whether the specified public function is exported by the script in the specified segment
|
|
|
|
// Parameters: (int) pubfunct: Index of the function to validate
|
|
|
|
// (int) seg: Segment ID of the script the check is to be performed for
|
2009-02-21 21:16:41 +00:00
|
|
|
// Returns : (uint16) 0 if the public function is invalid, its offset into the script's segment
|
2009-02-20 22:29:49 +00:00
|
|
|
// otherwise
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
int sm_seg_get(SegManager* self, int script_nr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Get the segment ID associated with a script number
|
|
|
|
// Parameters: (int) script_nr: Number of the script to look up
|
|
|
|
// Returns : (int) The associated segment ID, or -1 if no matching segment exists
|
|
|
|
// This function is "pure" (i.e, it doesn't modify anything).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// script lock operations
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_increment_lockers(SegManager *self, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Increments the number of lockers of the script in question by one
|
|
|
|
// Parameters: (int) id: ID of the script or script segment to modify
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_decrement_lockers(SegManager *self, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Decrements the number of lockers of the script in question by one
|
|
|
|
// Parameters: (int) id: ID of the script or script segment to modify
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
int sm_get_lockers(SegManager *self, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Retrieves the number of locks held on this script
|
|
|
|
// Parameters: (int) id: ID of the script or script segment to read from
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
// Returns : (int) The number of locks held on the previously identified script
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_set_lockers(SegManager *self, int lockers, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Sets the number of locks held on the specified script
|
|
|
|
// Parameters: (int) id: ID of the script or script segment to modify
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
byte *sm_get_synonyms(SegManager *self, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Retrieves a pointer to the synonyms associated with the specified script
|
|
|
|
// Parameters: (int) id: ID of the script or script segment to read from
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
// Returns : (byte *) Pointer to the synonyms, in non-parsed format.
|
|
|
|
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
int sm_get_synonyms_nr(SegManager *self, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Retrieves the number of synonyms associated with the specified script
|
|
|
|
// Parameters: (int) id: ID of the script or script segment to read from
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
// Returns : (int) The number of synonyms associated with the specified script
|
|
|
|
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1b. Script Initialisation
|
|
|
|
|
|
|
|
// The set of functions below are intended
|
|
|
|
// to be used during script instantiation,
|
|
|
|
// i.e. loading and linking.
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_script_initialise_locals_zero(SegManager *self, seg_id_t seg, int nr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Initializes a script's local variable block
|
|
|
|
// Parameters: (seg_id_t) seg: Segment containing the script to initialize
|
|
|
|
// (int) nr: Number of local variables to allocate
|
|
|
|
// All variables are initialized to zero.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_script_initialise_locals(SegManager *self, reg_t location);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Initializes a script's local variable block according to a prototype
|
|
|
|
// Parameters: (reg_t) location: Location to initialize from
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
object_t *sm_script_obj_init(SegManager *self, EngineState *s, reg_t obj_pos);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Initializes an object within the segment manager
|
|
|
|
// Parameters: (reg_t) obj_pos: Location (segment, offset) of the object
|
|
|
|
// Returns : (object_t *) A newly created object_t describing the object
|
|
|
|
// obj_pos must point to the beginning of the script/class block (as opposed
|
|
|
|
// to what the VM considers to be the object location)
|
|
|
|
// The corresponding object_t is stored within the relevant script.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_script_add_code_block(SegManager *self, reg_t location);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Informs the segment manager that a code block must be relocated
|
|
|
|
// Parameters: (reg_t) location: Start of block to relocate
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_set_export_width(SegManager *self, int flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Tells the segment manager whether exports are wide (32-bit) or not.
|
|
|
|
// Parameters: (int) flag: 1 if exports are wide, 0 otherwise
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_script_relocate(SegManager *self, reg_t block);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Processes a relocation block witin a script
|
|
|
|
// Parameters: (reg_t) obj_pos: Location (segment, offset) of the block
|
|
|
|
// Returns : (object_t *) Location of the relocation block
|
|
|
|
// This function is idempotent, but it must only be called after all
|
|
|
|
// objects have been instantiated, or a run-time error will occur.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_script_free_unused_objects(SegManager *self, seg_id_t segid);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Deallocates all unused but allocated entries for objects
|
|
|
|
// Parameters: (seg_id_t) segid: segment of the script to prune in this way
|
|
|
|
// These entries are created during script instantiation; deallocating them
|
|
|
|
// frees up some additional memory.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_set_export_table_offset(SegManager *self, int offset, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Sets the script-relative offset of the exports table
|
|
|
|
// Parameters: (int) offset: The script-relative exports table offset
|
|
|
|
// (int) id: ID of the script or script segment to write to
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_set_synonyms_offset(SegManager *self, int offset, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Sets the script-relative offset of the synonyms associated with the specified script
|
|
|
|
// Parameters: (int) offset: The script-relative offset of the synonyms block
|
|
|
|
// (int) id: ID of the script or script segment to write to
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_set_synonyms_nr(SegManager *self, int nr, int id, id_flag flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Sets the number of synonyms associated with the specified script
|
|
|
|
// Parameters: (int) nr: The number of synonyms, as to be stored within the script
|
|
|
|
// (int) id: ID of the script or script segment to write to
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_mark_script_deleted(SegManager *self, int script_nr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Marks the script identified by its script number as deleted
|
|
|
|
// Parameters: (int) script_nr: Script number to mark as deleted
|
|
|
|
// This will not actually delete the script. If references remain present on the
|
|
|
|
// heap or the stack, the script will stay in memory in a quasi-deleted state until
|
|
|
|
// either unreachable (resulting in its eventual deletion) or reloaded (resulting
|
|
|
|
// in its data being updated).
|
|
|
|
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_unmark_script_deleted(SegManager *self, int script_nr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Marks the script identified by its script number as not deleted
|
|
|
|
// Parameters: (int) script_nr: Script number to mark as not deleted
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-20 22:29:49 +00:00
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
int sm_script_is_marked_as_deleted(SegManager *self, seg_id_t seg);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Determines whether the script referenced by the indicated segment is marked as being deleted.
|
|
|
|
// Parameters: (seg_id_t) Segment ID of the script to investigate
|
|
|
|
// Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise
|
|
|
|
// Will return 0 when applied to an invalid or non-script seg.
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Clones
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
clone_t *sm_alloc_clone(SegManager *self, reg_t *addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocate a fresh clone
|
|
|
|
// Returns : (clone_t*): Reference to the memory allocated for the clone
|
|
|
|
// (reg_t) *addr: The offset of the freshly allocated clone
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_free_clone(SegManager *self, reg_t addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Deallocates a clone
|
|
|
|
// Parameters: (reg_t) addr: Offset of the clone scheduled for termination
|
|
|
|
|
|
|
|
|
|
|
|
// Objects (static, from Scripts, and dynmic, from Clones)
|
|
|
|
|
|
|
|
// Not all of these functions are fully operational for clones ATM
|
|
|
|
|
2009-02-21 21:16:41 +00:00
|
|
|
int16 sm_get_heap(SegManager* self, reg_t reg);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Retrieves a 16 bit value from within a script's heap representation
|
|
|
|
// Parameters: (reg_t) reg: The address to read from
|
2009-02-21 21:16:41 +00:00
|
|
|
// Returns : (int16) The value read from the specified location
|
2009-02-20 22:29:49 +00:00
|
|
|
|
|
|
|
|
2009-02-21 21:16:41 +00:00
|
|
|
void sm_put_heap(SegManager *self, reg_t reg, int16 value);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Writes a 16 bit value into a script's heap representation
|
|
|
|
// Parameters: (reg_t) reg: The address to write to
|
2009-02-21 21:16:41 +00:00
|
|
|
// (int16) value: The value to write
|
2009-02-20 22:29:49 +00:00
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_mcpy_in_out(SegManager* self, int dst, const void *src, size_t n, int id, int flag);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Copies a byte string into a script's heap representation
|
|
|
|
// Parameters: (int) dst: The script-relative offset of the destination area
|
|
|
|
// (const void *) src: Pointer to the data source location
|
|
|
|
// (size_t) n: Number of bytes to copy
|
|
|
|
// (int) id: ID of the script or script segment to write to
|
|
|
|
// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
|
|
|
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
|
|
|
// but less convenient.
|
|
|
|
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
|
|
|
|
|
|
|
|
|
|
|
// 4. Stack
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
dstack_t *sm_allocate_stack(SegManager *self, int size, seg_id_t *segid);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocates a data stack
|
|
|
|
// Parameters: (int) size: Number of stack entries to reserve
|
|
|
|
// Returns : (dstack_t *): The physical stack
|
|
|
|
// (seg_id_t) segid: Segment ID of the stack
|
|
|
|
|
|
|
|
|
|
|
|
// 5. System Strings
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
sys_strings_t *sm_allocate_sys_strings(SegManager *self, seg_id_t *segid);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocates a system string table
|
|
|
|
// Returns : (dstack_t *): The physical stack
|
|
|
|
// (seg_id_t) segid: Segment ID of the stack
|
|
|
|
// See also sys_string_acquire();
|
|
|
|
|
|
|
|
|
|
|
|
// 6, 7. Lists and Nodes
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
list_t *sm_alloc_list(SegManager *self, reg_t *addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocate a fresh list
|
|
|
|
// Returns : (listY_t*): Reference to the memory allocated for the list
|
|
|
|
// (reg_t) *addr: The offset of the freshly allocated list
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_free_list(SegManager *self, reg_t addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Deallocates a list
|
|
|
|
// Parameters: (reg_t) addr: Offset of the list scheduled for termination
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
node_t *sm_alloc_node(SegManager *self, reg_t *addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocate a fresh node
|
|
|
|
// Returns : (node_t*): Reference to the memory allocated for the node
|
|
|
|
// (reg_t) *addr: The offset of the freshly allocated node
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_free_node(SegManager *self, reg_t addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Deallocates a list node
|
|
|
|
// Parameters: (reg_t) addr: Offset of the node scheduled for termination
|
|
|
|
|
|
|
|
|
|
|
|
// 8. Hunk Memory
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
hunk_t *sm_alloc_hunk_entry(SegManager *self, const char *hunk_type, int size, reg_t *addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocate a fresh chunk of the hunk
|
|
|
|
// Parameters: (int) size: Number of bytes to allocate for the hunk entry
|
|
|
|
// (const char *) hunk_type: A descriptive string for the hunk entry,
|
|
|
|
// for debugging purposes
|
|
|
|
// Returns : (hunk_t*): Reference to the memory allocated for the hunk piece
|
|
|
|
// (reg_t) *addr: The offset of the freshly allocated hunk entry
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
void sm_free_hunk_entry(SegManager *self, reg_t addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Deallocates a hunk eentry
|
|
|
|
// Parameters: (reg_t) addr: Offset of the hunk entry to delete
|
|
|
|
|
|
|
|
|
|
|
|
// 9. Dynamic Memory
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
unsigned char *sm_alloc_dynmem(SegManager *self, int size, const char *description, reg_t *addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Allocate some dynamic memory
|
|
|
|
// Parameters: (int) size: Number of bytes to allocate
|
|
|
|
// (const char_ *) description: A descriptive string,
|
|
|
|
// for debugging purposes
|
|
|
|
// Returns : (unsigned char*): Raw pointer into the allocated dynamic memory
|
|
|
|
// (reg_t) *addr: The offset of the freshly allocated X
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
int sm_free_dynmem(SegManager *self, reg_t addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Deallocates a piece of dynamic memory
|
|
|
|
// Parameters: (reg_t) addr: Offset of the dynmem chunk to free
|
|
|
|
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
const char *sm_get_description(SegManager *self, reg_t addr);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Gets the description of a dynmem segment
|
|
|
|
// Parameters: (reg_t) addr: Segment to describe
|
|
|
|
// Returns : (const char *): Pointer to the descriptive string set in
|
|
|
|
// sm_alloc_dynmem
|
|
|
|
|
|
|
|
|
|
|
|
// 10. Reserved segments
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
seg_id_t sm_allocate_reserved_segment(SegManager *self, char *name);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Reserves a special-purpose segment
|
|
|
|
// Parameters: (char *) name: A string name identifying the segment (the string is cloned and retained)
|
|
|
|
// Returns : A fresh segment ID for the segment in question
|
|
|
|
// Reserved segments are never used by the segment manager. They can be used to tag special-purpose addresses.
|
|
|
|
// Segment 0 is implicitly reserved for numbers.
|
|
|
|
|
|
|
|
|
|
|
|
// Generic Operations on Segments and Addresses
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
byte *sm_dereference(SegManager *self, reg_t reg, int *size);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Dereferences a raw memory pointer
|
|
|
|
// Parameters: (reg_t) reg: The reference to dereference
|
|
|
|
// Returns : (byte *) The data block referenced
|
|
|
|
// (int) size: (optionally) the theoretical maximum size of it
|
|
|
|
|
|
|
|
// 11. Segment interface, primarily for GC
|
2009-02-16 09:23:58 +00:00
|
|
|
|
|
|
|
typedef struct _seg_interface {
|
2009-02-21 11:04:47 +00:00
|
|
|
SegManager *segmgr;
|
2009-02-16 09:23:58 +00:00
|
|
|
mem_obj_t *mobj;
|
|
|
|
seg_id_t seg_id;
|
2009-02-20 22:29:49 +00:00
|
|
|
mem_obj_enum type_id; // Segment type
|
|
|
|
const char *type; // String description of the segment type
|
|
|
|
|
|
|
|
reg_t (*find_canonic_address)(struct _seg_interface *self, reg_t sub_addr);
|
|
|
|
// Finds the canonic address associated with sub_reg
|
|
|
|
// Parameters: (reg_t) sub_addr: The base address whose canonic address is to be found
|
|
|
|
// For each valid address a, there exists a canonic address c(a) such that c(a) = c(c(a)).
|
|
|
|
// This address "governs" a in the sense that deallocating c(a) will deallocate a.
|
|
|
|
|
|
|
|
void (*free_at_address)(struct _seg_interface *self, reg_t sub_addr);
|
|
|
|
// Deallocates all memory associated with the specified address
|
|
|
|
// Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
|
|
|
|
|
|
|
|
void (*list_all_deallocatable)(struct _seg_interface *self, void *param, void (*note)(void *param, reg_t addr));
|
|
|
|
// Iterates over and reports all addresses within the current segment
|
|
|
|
// Parameters: note : (voidptr * addr) -> (): Invoked for each address on which free_at_address()
|
|
|
|
// makes sense
|
|
|
|
// (void *) param: Parameter passed to 'note'
|
|
|
|
|
2009-02-21 10:47:56 +00:00
|
|
|
void (*list_all_outgoing_references)(struct _seg_interface *self, EngineState *s, reg_t object, void *param, void (*note)(void *param, reg_t addr));
|
2009-02-20 22:29:49 +00:00
|
|
|
// Iterates over all references reachable from the specified object
|
|
|
|
// Parameters: (reg_t) object: The object (within the current segment) to analyse
|
|
|
|
// (void *) param: Parameter passed to 'note'
|
|
|
|
// note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
|
|
|
|
// Note: This function may also choose to report numbers (segment 0) as adresses
|
|
|
|
|
|
|
|
void (*deallocate_self)(struct _seg_interface *self);
|
|
|
|
// Deallocates the segment interface
|
2009-02-16 09:23:58 +00:00
|
|
|
} seg_interface_t;
|
|
|
|
|
2009-02-21 11:04:47 +00:00
|
|
|
seg_interface_t *get_seg_interface(SegManager *self, seg_id_t segid);
|
2009-02-20 22:29:49 +00:00
|
|
|
// Retrieves the segment interface to the specified segment
|
|
|
|
// Parameters: (seg_id_t) segid: ID of the segment to look up
|
|
|
|
// Returns : (seg_interface_t *): An interface to the specified segment ID, or NULL on error
|
|
|
|
// The returned interface 'si' must be freed after use by calling 'si->dealloc_self(si)';
|
2009-02-16 09:23:58 +00:00
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
} // End of namespace Sci
|
|
|
|
|
2009-02-16 09:23:58 +00:00
|
|
|
#endif
|