2016-09-28 14:40:37 +00:00
/*
2018-02-07 14:13:13 +00:00
Copyright ( c ) 2016 - 2018 Chung , Hyung - Hwan . All rights reserved .
2016-09-28 14:40:37 +00:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE AUTHOR " AS IS " AND ANY EXPRESS OR
IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2025-09-02 23:58:15 +09:00
# include "hak-prv.h"
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_PROFILE_VM)
2020-12-31 17:48:47 +00:00
# include <sys/time.h>
# include <sys/resource.h> /* getrusage */
# endif
2016-09-28 14:40:37 +00:00
/* ========================================================================= */
2024-03-03 22:17:14 +09:00
/*
* Apex . . . . . . . . . . . . . . . . . . . . . .
* ^ ^ ^ : . . . . . . .
* | | | v v :
* | | + - - - - - - - - - - - - - - - - - - - Class . . . . .
* | | ^ ^
* | + - - - - - - - - NilObject . . . . . . : :
* | ^ . . . . . . . . nil :
* Object . . . . . . . . . . . . . . . . . . . . . . . . . . . :
* ^
* |
*
* The class hierarchy is roughly as follows :
*
* Apex
* Class
* NilObject
* Object
* Collection
* IndexedCollection
* FixedSizedCollection
* Array
* ByteArray
2024-07-27 01:14:51 +09:00
* String
* Symbol
2024-03-03 22:17:14 +09:00
* Set
* Dictionary
* SystemDictionary
* SymbolSet
* Magnitude
* Association
* Character
* Number
* Integer
* SmallInteger
* LargeInteger
* LargePositiveInteger
* LargeNegativeInteger
*
* Apex has no instance variables .
*
*/
2016-09-28 14:40:37 +00:00
2024-03-03 22:17:14 +09:00
struct kernel_class_info_t
2016-09-28 14:40:37 +00:00
{
2025-09-02 23:58:15 +09:00
const hak_bch_t * name ;
2024-07-27 01:14:51 +09:00
int superclass_kci ;
2024-03-08 00:23:52 +09:00
int class_brand ;
2024-07-27 01:14:51 +09:00
int class_flags ; /* class flags for selfspec */
int class_ncvars ; /* number of class variables */
2016-09-28 14:40:37 +00:00
2024-07-27 01:14:51 +09:00
int class_spec_nivars ; /* number of named instance variables */
2024-03-03 22:17:14 +09:00
int class_spec_flags ;
int class_spec_indexed_type ;
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
hak_oow_t offset ; /* offset to the field in hak_t that stored the class pointer */
2024-03-03 22:17:14 +09:00
} ;
typedef struct kernel_class_info_t kernel_class_info_t ;
2016-09-28 14:40:37 +00:00
2024-07-27 01:14:51 +09:00
enum {
KCI_APEX = 0 ,
KCI_CLASS ,
KCI_UNDEFINED_OBJECT ,
KCI_NIL_OBJECT ,
KCI_OBJECT ,
KCI_COLLECTION ,
KCI_INDEXED_COLLECTION ,
KCI_FIXED_SIZED_COLLECTION ,
KCI_STRING ,
2024-09-07 10:15:54 +09:00
KCI_BYTE_STRING ,
2024-07-27 01:14:51 +09:00
KCI_SYMBOL ,
KCI_ARRAY ,
2024-09-15 11:51:11 +09:00
KCI_CHARACTER_ARRAY ,
2024-07-27 01:14:51 +09:00
KCI_BYTE_ARRAY ,
KCI_SYMBOL_TABLE ,
KCI_DICTIONARY ,
KCI_CONS ,
KCI_METHOD_DICTIONARY ,
KCI_FUNCTION ,
2024-09-12 00:26:23 +09:00
KCI_PRIMITIVE ,
2024-07-27 01:14:51 +09:00
KCI_COMPILED_BLOCK ,
KCI_BLOCK_CONTEXT ,
KCI_PROCESS ,
KCI_SEMAPHORE ,
KCI_SEMAPHORE_GROUP ,
KCI_PROCESS_SCHEDULER ,
KCI_ERROR ,
KCI_TRUE ,
KCI_FALSE ,
KCI_MAGNITUDE ,
KCI_CHARACTER ,
KCI_NUMBER ,
KCI_SMALL_INTEGER ,
KCI_LARGE_POSITIVE_INTEGER ,
KCI_LARGE_NEGATIVE_INTEGER ,
KCI_FIXED_POINT_DECIMAL ,
KCI_SMALL_POINTER ,
KCI_LARGE_POINTER ,
KCI_SYSTEM ,
__KCI_MAX__
} ;
2025-09-02 23:58:15 +09:00
# define KCI(x) HAK_AID(x)
2024-07-27 01:14:51 +09:00
static kernel_class_info_t kernel_classes [ __KCI_MAX__ ] =
2024-03-03 22:17:14 +09:00
{
/* --------------------------------------------------------------
2024-07-27 01:14:51 +09:00
* Apex - proto - object with 1 class variable .
* Class
* UndefinedObject - class for the undefined state
* NilObject - class for nil
* Object - top of all ordinary objects .
* String
* Symbol
* Array
* ByteArray
* Character
* SmallIntger
2024-03-03 22:17:14 +09:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2024-07-27 01:14:51 +09:00
KCI ( KCI_APEX ) {
" Apex " ,
- 1 , /* no superclass */
0 , /* brand */
0 , /* selfspec flags */
0 , /* ncvars */
0 , /* nivars */
0 , /* spec flags */
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP , /* indexed type */
HAK_OFFSETOF ( hak_t , c_apex )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_CLASS ) {
" Class " ,
KCI_APEX ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_CLASS ,
HAK_CLASS_SELFSPEC_FLAG_FINAL | HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 , /* ncvars */
2025-09-02 23:58:15 +09:00
HAK_CLASS_NAMED_INSTVARS , /* nivars */
HAK_CLASS_SPEC_FLAG_INDEXED | HAK_CLASS_SPEC_FLAG_UNCOPYABLE ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_class )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_UNDEFINED_OBJECT ) {
" UndefinedObject " ,
KCI_APEX ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_UNDEF ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_undefobj )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_NIL_OBJECT ) {
" NilObject " ,
KCI_APEX ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_NIL ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_nilobj )
2024-07-27 01:14:51 +09:00
} ,
2016-09-28 14:40:37 +00:00
2020-12-31 17:48:47 +00:00
#if 0
2024-03-03 22:17:14 +09:00
{ " Interface " ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-03-03 22:17:14 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_INTERFACE_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_INDEXED | HAK_CLASS_SPEC_FLAG_UNCOPYABLE ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , _interface ) } ,
2020-12-31 17:48:47 +00:00
# endif
2016-09-28 14:40:37 +00:00
2024-07-27 01:14:51 +09:00
KCI ( KCI_OBJECT ) {
" Object " ,
KCI_APEX ,
0 , /* brand */
0 , /* selfspec flags */
0 , /* ncvars */
0 , /* nivars */
0 , /* spec flags */
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_object )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_COLLECTION ) {
" Collection " ,
KCI_OBJECT ,
0 , /* brand */
0 ,
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_collection )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_INDEXED_COLLECTION ) {
" IndexedCollection " ,
KCI_COLLECTION ,
0 , /* brand */
0 ,
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_indexed_collection )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_FIXED_SIZED_COLLECTION ) {
" FixedSizedCollection " ,
KCI_INDEXED_COLLECTION ,
0 , /* brand */
0 ,
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_fixed_sized_collection )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_STRING ) {
" String " ,
KCI_FIXED_SIZED_COLLECTION ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_STRING ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_CHAR ,
HAK_OFFSETOF ( hak_t , c_string )
2024-07-27 01:14:51 +09:00
} ,
2024-09-07 10:15:54 +09:00
KCI ( KCI_BYTE_STRING ) {
2024-09-07 00:39:46 +09:00
" ByteString " ,
KCI_FIXED_SIZED_COLLECTION ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_BYTE_STRING ,
2024-09-07 00:39:46 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_BYTE ,
HAK_OFFSETOF ( hak_t , c_byte_string )
2024-09-07 00:39:46 +09:00
} ,
2024-07-27 01:14:51 +09:00
KCI ( KCI_SYMBOL ) {
" Symbol " ,
KCI_STRING ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_SYMBOL ,
HAK_CLASS_SELFSPEC_FLAG_FINAL | HAK_CLASS_SELFSPEC_FLAG_LIMITED , /* TODO: these flags not implemented yet */
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED | HAK_CLASS_SPEC_FLAG_IMMUTABLE ,
HAK_OBJ_TYPE_CHAR ,
HAK_OFFSETOF ( hak_t , c_symbol )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_ARRAY ) {
" Array " ,
KCI_FIXED_SIZED_COLLECTION ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_ARRAY ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_array )
2024-07-27 01:14:51 +09:00
} ,
2024-09-15 11:51:11 +09:00
KCI ( KCI_CHARACTER_ARRAY ) {
" CharacterArray " ,
KCI_FIXED_SIZED_COLLECTION ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_CHARACTER_ARRAY ,
2024-09-15 11:51:11 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_CHAR ,
HAK_OFFSETOF ( hak_t , c_character_array )
2024-09-15 11:51:11 +09:00
} ,
2024-07-27 01:14:51 +09:00
KCI ( KCI_BYTE_ARRAY ) {
" ByteArray " ,
KCI_FIXED_SIZED_COLLECTION ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_BYTE_ARRAY ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_BYTE ,
HAK_OFFSETOF ( hak_t , c_byte_array )
2024-07-27 01:14:51 +09:00
} ,
2021-06-25 15:19:11 +00:00
2024-03-08 00:23:52 +09:00
/* A special incarnation of a dictionary that allows only a symbol as a value.
* The value in bucket is a symbol while the value in a normal dictionary is a
* pair ( cons ) that contains a key and a value . */
2024-07-27 01:14:51 +09:00
KCI ( KCI_SYMBOL_TABLE ) {
" SymbolTable " ,
KCI_COLLECTION ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_DIC , /* TODO: make this a special child class of Dictionary?? */
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_DIC_NAMED_INSTVARS ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_symtab )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_DICTIONARY ) {
" Dictionary " ,
KCI_COLLECTION ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_DIC ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_DIC_NAMED_INSTVARS ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_dictionary )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_CONS ) {
" Cons " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_CONS ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CONS_NAMED_INSTVARS ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_cons )
2024-07-27 01:14:51 +09:00
} ,
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
#if 0
{ " Namespace " ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-03-03 22:17:14 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_NSDIC_NAMED_INSTVARS ,
2024-03-03 22:17:14 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_namespace ) } ,
2023-11-10 00:03:03 +09:00
2024-03-03 22:17:14 +09:00
{ " PoolDictionary " ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_DIC_NAMED_INSTVARS ,
2024-03-03 22:17:14 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_pool_dictionary ) } ,
2020-12-31 17:48:47 +00:00
# endif
2024-07-27 01:14:51 +09:00
KCI ( KCI_METHOD_DICTIONARY ) {
" MethodDictionary " ,
KCI_DICTIONARY ,
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_DIC_NAMED_INSTVARS ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_method_dictionary )
2024-07-27 01:14:51 +09:00
} ,
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
#if 0
{ " CompiledMethod " ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_METHOD_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_method ) } ,
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
{ " MethodSignature " ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_METHSIG_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_methsig ) } ,
2024-03-03 22:17:14 +09:00
# endif
2020-12-31 17:48:47 +00:00
2024-05-15 22:59:34 +09:00
/* special function created with MAKE_FUNCTION in interactive mode
* for execution of code fed and compiled . */
2024-07-27 01:14:51 +09:00
KCI ( KCI_FUNCTION ) {
" Function " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_FUNCTION ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_FUNCTION_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_function )
2024-07-27 01:14:51 +09:00
} ,
2024-05-15 22:59:34 +09:00
2024-09-12 00:26:23 +09:00
KCI ( KCI_PRIMITIVE ) {
" Primitive " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_PRIM ,
2024-09-12 00:26:23 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_PRIM_NAMED_INSTVARS ,
2024-09-12 00:26:23 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_WORD ,
HAK_OFFSETOF ( hak_t , c_primitive )
2024-09-12 00:26:23 +09:00
} ,
2024-05-15 22:59:34 +09:00
2024-07-27 01:14:51 +09:00
KCI ( KCI_COMPILED_BLOCK ) {
" CompiledBlock " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_BLOCK ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_BLOCK_NAMED_INSTVARS ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_compiled_block )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_BLOCK_CONTEXT ) {
" BlockContext " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_CONTEXT ,
HAK_CLASS_SELFSPEC_FLAG_FINAL | HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_CONTEXT_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_block_context )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_PROCESS ) {
" Process " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_PROCESS ,
HAK_CLASS_SELFSPEC_FLAG_FINAL | HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_PROCESS_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_INDEXED | HAK_CLASS_SPEC_FLAG_UNCOPYABLE ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_process )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_SEMAPHORE ) {
" Semaphore " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_SEMAPHORE ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_SEMAPHORE_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_UNCOPYABLE ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_semaphore )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_SEMAPHORE_GROUP ) {
" SemaphoreGroup " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_SEMAPHORE_GROUP ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_SEMAPHORE_GROUP_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_UNCOPYABLE ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_semaphore_group )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_PROCESS_SCHEDULER ) {
" ProcessScheduler " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_PROCESS_SCHEDULER ,
HAK_CLASS_SELFSPEC_FLAG_FINAL | HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_PROCESS_SCHEDULER_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_UNCOPYABLE ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_process_scheduler )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_ERROR ) {
" Error " ,
KCI_OBJECT ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_error )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_TRUE ) {
" True " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_TRUE ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED | HAK_CLASS_SELFSPEC_FLAG_FINAL ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_true )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_FALSE ) {
" False " ,
KCI_OBJECT ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_FALSE ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED | HAK_CLASS_SELFSPEC_FLAG_FINAL ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_false )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_MAGNITUDE ) {
" Magnitude " ,
KCI_OBJECT ,
0 , /* brand */
0 ,
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_magnitude )
2024-07-27 01:14:51 +09:00
} ,
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
/* TOOD: what is a proper spec for Character and SmallInteger?
* If the fixed part is 0 , its instance must be an object of 0 payload fields .
* Does this make sense ? */
2024-07-27 01:14:51 +09:00
KCI ( KCI_CHARACTER ) {
" Character " ,
KCI_MAGNITUDE ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_CHARACTER ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_character )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_NUMBER ) {
" Number " ,
KCI_MAGNITUDE ,
0 , /* brand */
2025-09-02 23:58:15 +09:00
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_number )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_SMALL_INTEGER ) {
" SmallInteger " ,
KCI_NUMBER ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_SMOOI ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_small_integer )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_LARGE_POSITIVE_INTEGER ) {
" LargePositiveInteger " ,
KCI_NUMBER ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_PBIGINT ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED | HAK_CLASS_SPEC_FLAG_IMMUTABLE ,
HAK_OBJ_TYPE_LIWORD ,
HAK_OFFSETOF ( hak_t , c_large_positive_integer )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_LARGE_NEGATIVE_INTEGER ) {
" LargeNegativeInteger " ,
KCI_NUMBER ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_NBIGINT ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_INDEXED | HAK_CLASS_SPEC_FLAG_IMMUTABLE ,
HAK_OBJ_TYPE_LIWORD ,
HAK_OFFSETOF ( hak_t , c_large_negative_integer )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_FIXED_POINT_DECIMAL ) {
" FixedPointDecimal " ,
KCI_NUMBER ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_FPDEC ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
2025-09-02 23:58:15 +09:00
HAK_FPDEC_NAMED_INSTVARS ,
HAK_CLASS_SPEC_FLAG_IMMUTABLE ,
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_fixed_point_decimal )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_SMALL_POINTER ) {
" SmallPointer " ,
KCI_MAGNITUDE ,
2025-09-02 23:58:15 +09:00
HAK_BRAND_SMPTR ,
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_small_pointer )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_LARGE_POINTER ) {
" LargePointer " ,
KCI_MAGNITUDE ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SELFSPEC_FLAG_LIMITED ,
2024-07-27 01:14:51 +09:00
0 ,
1 , /* #word(1) */
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_FLAG_IMMUTABLE | HAK_CLASS_SPEC_FLAG_INDEXED ,
HAK_OBJ_TYPE_WORD ,
HAK_OFFSETOF ( hak_t , c_large_pointer )
2024-07-27 01:14:51 +09:00
} ,
KCI ( KCI_SYSTEM ) {
" System " ,
2024-10-21 01:19:53 +09:00
KCI_APEX ,
2024-07-27 01:14:51 +09:00
0 ,
0 ,
5 , /* asyncsg, gcfin_sem, gcfin_should_exit, ossig_pid, shr */
0 ,
0 ,
2025-09-02 23:58:15 +09:00
HAK_OBJ_TYPE_OOP ,
HAK_OFFSETOF ( hak_t , c_system )
2024-07-27 01:14:51 +09:00
}
2024-03-03 22:17:14 +09:00
} ;
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
/* ========================================================================= */
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
static void compact_symbol_table ( hak_t * hak , hak_oop_t _nil )
2020-12-31 17:48:47 +00:00
{
2025-09-02 23:58:15 +09:00
hak_oop_char_t symbol ;
hak_oow_t i , x , y , z ;
hak_oow_t bucket_size , index ;
hak_ooi_t tally ;
2020-12-31 17:48:47 +00:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_SUPPORT_GC_DURING_IGNITION)
if ( ! hak - > symtab ) return ; /* symbol table has not been created */
2020-12-31 17:48:47 +00:00
# endif
2025-09-02 23:58:15 +09:00
/* the symbol table doesn't allow more data items than HAK_SMOOI_MAX.
* so hak - > symtab - > tally must always be a small integer */
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , HAK_OOP_IS_SMOOI ( hak - > symtab - > tally ) ) ;
2025-09-02 23:58:15 +09:00
tally = HAK_OOP_TO_SMOOI ( hak - > symtab - > tally ) ;
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , tally > = 0 ) ; /* it must not be less than 0 */
2024-03-03 22:17:14 +09:00
if ( tally < = 0 ) return ;
2020-12-31 17:48:47 +00:00
2025-09-02 23:58:15 +09:00
/* NOTE: in theory, the bucket size can be greater than HAK_SMOOI_MAX
2024-03-03 22:17:14 +09:00
* as it is an internal header field and is of an unsigned type */
2025-09-02 23:58:15 +09:00
bucket_size = HAK_OBJ_GET_SIZE ( hak - > symtab - > bucket ) ;
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
for ( index = 0 ; index < bucket_size ; )
2020-12-31 17:48:47 +00:00
{
2025-09-02 23:58:15 +09:00
if ( HAK_OBJ_GET_FLAGS_MOVED ( hak - > symtab - > bucket - > slot [ index ] ) )
2020-12-31 17:48:47 +00:00
{
2024-03-03 22:17:14 +09:00
index + + ;
continue ;
2020-12-31 17:48:47 +00:00
}
2024-03-03 22:17:14 +09:00
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > symtab - > bucket - > slot [ index ] ! = _nil ) ;
2024-03-03 22:17:14 +09:00
for ( i = 0 , x = index , y = index ; i < bucket_size ; i + + )
2020-12-31 17:48:47 +00:00
{
2024-03-03 22:17:14 +09:00
y = ( y + 1 ) % bucket_size ;
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
/* done if the slot at the current hash index is _nil */
2025-09-02 23:58:15 +09:00
if ( hak - > symtab - > bucket - > slot [ y ] = = _nil ) break ;
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
/* get the natural hash index for the data in the slot
* at the current hash index */
2025-09-02 23:58:15 +09:00
symbol = ( hak_oop_char_t ) hak - > symtab - > bucket - > slot [ y ] ;
2020-12-31 17:48:47 +00:00
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , HAK_IS_SYMBOL ( hak , symbol ) ) ;
2024-03-03 22:17:14 +09:00
2025-09-02 23:58:15 +09:00
z = hak_hash_oochars ( symbol - > slot , HAK_OBJ_GET_SIZE ( symbol ) ) % bucket_size ;
2024-03-03 22:17:14 +09:00
/* move an element if necessary */
if ( ( y > x & & ( z < = x | | z > y ) ) | |
( y < x & & ( z < = x & & z > y ) ) )
2020-12-31 17:48:47 +00:00
{
2025-09-02 23:58:15 +09:00
hak - > symtab - > bucket - > slot [ x ] = hak - > symtab - > bucket - > slot [ y ] ;
2024-03-03 22:17:14 +09:00
x = y ;
2020-12-31 17:48:47 +00:00
}
}
2025-09-02 23:58:15 +09:00
hak - > symtab - > bucket - > slot [ x ] = _nil ;
2024-03-03 22:17:14 +09:00
tally - - ;
}
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , tally > = 0 ) ;
HAK_ASSERT ( hak , tally < = HAK_SMOOI_MAX ) ;
2025-09-02 23:58:15 +09:00
hak - > symtab - > tally = HAK_SMOOI_TO_OOP ( tally ) ;
2024-03-03 22:17:14 +09:00
}
2025-09-02 23:58:15 +09:00
hak_oow_t hak_getobjpayloadbytes ( hak_t * hak , hak_oop_t oop )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oow_t nbytes_aligned ;
2024-03-03 22:17:14 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_OBJ_GET_FLAGS_TRAILER ( oop ) )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oow_t nbytes ;
2024-03-03 22:17:14 +09:00
/* only an OOP object can have the trailer.
*
* | _flags |
* | _size | < - - if it ' s 3
* | _class |
* | X |
* | X |
* | X |
* | Y | < - - it may exist if EXTRA is set in _flags .
* | Z | < - - if TRAILER is set , it is the number of bytes in the trailer
* | | | | |
*/
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , HAK_OBJ_GET_FLAGS_TYPE ( oop ) = = HAK_OBJ_TYPE_OOP ) ;
HAK_ASSERT ( hak , HAK_OBJ_GET_FLAGS_UNIT ( oop ) = = HAK_SIZEOF ( hak_oow_t ) ) ;
HAK_ASSERT ( hak , HAK_OBJ_GET_FLAGS_EXTRA ( oop ) = = 0 ) ; /* no 'extra' for an OOP object */
2024-03-03 22:17:14 +09:00
2025-09-02 23:58:15 +09:00
nbytes = HAK_OBJ_BYTESOF ( oop ) + HAK_SIZEOF ( hak_oow_t ) + HAK_OBJ_GET_TRAILER_SIZE ( oop ) ;
nbytes_aligned = HAK_ALIGN ( nbytes , HAK_SIZEOF ( hak_oop_t ) ) ;
2024-03-03 22:17:14 +09:00
}
else
{
/* calculate the payload size in bytes */
2025-09-02 23:58:15 +09:00
nbytes_aligned = HAK_ALIGN ( HAK_OBJ_BYTESOF ( oop ) , HAK_SIZEOF ( hak_oop_t ) ) ;
2020-12-31 17:48:47 +00:00
}
2024-03-03 22:17:14 +09:00
return nbytes_aligned ;
2020-12-31 17:48:47 +00:00
}
2024-03-03 22:17:14 +09:00
/* ----------------------------------------------------------------------- */
#if 0
2025-09-02 23:58:15 +09:00
static HAK_INLINE void gc_ms_mark ( hak_t * hak , hak_oop_t oop )
2020-12-31 17:48:47 +00:00
{
2025-09-02 23:58:15 +09:00
hak_oow_t i , sz ;
2020-12-31 17:48:47 +00:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_SUPPORT_GC_DURING_IGNITION)
2024-03-03 22:17:14 +09:00
if ( ! oop ) return ;
2020-12-31 17:48:47 +00:00
# endif
2025-09-02 23:58:15 +09:00
if ( ! HAK_OOP_IS_POINTER ( oop ) ) return ;
if ( HAK_OBJ_GET_FLAGS_MOVED ( oop ) ) return ; /* already marked */
2024-03-03 22:17:14 +09:00
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_FLAGS_MOVED ( oop , 1 ) ; /* mark */
2024-03-03 22:17:14 +09:00
2025-09-05 10:52:02 +09:00
/*gc_ms_mark(hak, (hak_oop_t)HAK_OBJ_GET_CLASS(oop));*/ /* TODO: remove recursion */
2024-03-03 22:17:14 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_OBJ_GET_FLAGS_TYPE ( oop ) = = HAK_OBJ_TYPE_OOP )
2020-12-31 17:48:47 +00:00
{
2025-09-02 23:58:15 +09:00
hak_oow_t size , i ;
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
/* is it really better to use a flag bit in the header to
* determine that it is an instance of process ? */
2025-09-02 23:58:15 +09:00
if ( HAK_UNLIKELY ( HAK_OBJ_GET_FLAGS_PROC ( oop ) ) )
2020-12-31 17:48:47 +00:00
{
2024-03-03 22:17:14 +09:00
/* the stack in a process object doesn't need to be
* scanned in full . the slots above the stack pointer
* are garbages . */
2025-09-02 23:58:15 +09:00
size = HAK_PROCESS_NAMED_INSTVARS + HAK_OOP_TO_SMOOI ( ( ( hak_oop_process_t ) oop ) - > sp ) + 1 ;
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , size < = HAK_OBJ_GET_SIZE ( oop ) ) ;
2020-12-31 17:48:47 +00:00
}
else
{
2025-09-02 23:58:15 +09:00
size = HAK_OBJ_GET_SIZE ( oop ) ;
2020-12-31 17:48:47 +00:00
}
2024-03-03 22:17:14 +09:00
for ( i = 0 ; i < size ; i + + )
{
2025-09-02 23:58:15 +09:00
hak_oop_t tmp = HAK_OBJ_GET_OOP_VAL ( oop , i ) ;
2025-09-05 10:52:02 +09:00
if ( HAK_OOP_IS_POINTER ( tmp ) ) gc_ms_mark ( hak , tmp ) ; /* TODO: no resursion */
2024-03-03 22:17:14 +09:00
}
2020-12-31 17:48:47 +00:00
}
2024-03-03 22:17:14 +09:00
}
# else
2025-09-02 23:58:15 +09:00
static HAK_INLINE void gc_ms_mark_object ( hak_t * hak , hak_oop_t oop )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
# if defined(HAK_SUPPORT_GC_DURING_IGNITION)
2024-03-03 22:17:14 +09:00
if ( ! oop ) return ;
2020-12-31 17:48:47 +00:00
# endif
2025-09-02 23:58:15 +09:00
if ( ! HAK_OOP_IS_POINTER ( oop ) | | HAK_OBJ_GET_FLAGS_MOVED ( oop ) ) return ; /* non-pointer or already marked */
2024-03-03 22:17:14 +09:00
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_FLAGS_MOVED ( oop , 1 ) ; /* mark */
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > gci . stack . len < hak - > gci . stack . capa ) ;
2025-09-02 23:58:15 +09:00
hak - > gci . stack . ptr [ hak - > gci . stack . len + + ] = oop ; /* push */
if ( hak - > gci . stack . len > hak - > gci . stack . max ) hak - > gci . stack . max = hak - > gci . stack . len ;
2020-12-31 17:48:47 +00:00
}
2025-09-02 23:58:15 +09:00
static HAK_INLINE void gc_ms_scan_stack ( hak_t * hak )
2020-12-31 17:48:47 +00:00
{
2025-09-02 23:58:15 +09:00
hak_oop_t oop ;
2020-12-31 17:48:47 +00:00
2025-09-02 23:58:15 +09:00
while ( hak - > gci . stack . len > 0 )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
oop = hak - > gci . stack . ptr [ - - hak - > gci . stack . len ] ;
2020-12-31 17:48:47 +00:00
2025-09-05 10:52:02 +09:00
gc_ms_mark_object ( hak , ( hak_oop_t ) HAK_OBJ_GET_CLASS ( oop ) ) ;
2020-12-31 17:48:47 +00:00
2025-09-02 23:58:15 +09:00
if ( HAK_OBJ_GET_FLAGS_TYPE ( oop ) = = HAK_OBJ_TYPE_OOP )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_ooi_t i , ll ;
2020-12-31 17:48:47 +00:00
2024-03-03 22:17:14 +09:00
/* is it really better to use a flag bit in the header to
* determine that it is an instance of process ? */
2025-09-02 23:58:15 +09:00
if ( HAK_UNLIKELY ( HAK_OBJ_GET_FLAGS_PROC ( oop ) ) )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oop_process_t proc ;
2024-03-03 22:17:14 +09:00
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , HAK_IS_PROCESS ( hak , oop ) ) ;
2024-03-03 22:17:14 +09:00
/* the stack in a process object doesn't need to be
* scanned in full . the slots above the stack pointer
* are garbages . */
2025-09-02 23:58:15 +09:00
proc = ( hak_oop_process_t ) oop ;
2024-03-03 22:17:14 +09:00
/* the fixed part */
2025-09-02 23:58:15 +09:00
ll = HAK_PROCESS_NAMED_INSTVARS ;
2025-09-05 10:52:02 +09:00
for ( i = 0 ; i < ll ; i + + ) gc_ms_mark_object ( hak , HAK_OBJ_GET_OOP_VAL ( oop , i ) ) ;
2024-03-03 22:17:14 +09:00
/* stack */
2025-09-02 23:58:15 +09:00
ll = HAK_OOP_TO_SMOOI ( proc - > sp ) ;
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , ll < ( hak_ooi_t ) ( HAK_OBJ_GET_SIZE ( oop ) - HAK_PROCESS_NAMED_INSTVARS ) ) ;
for ( i = 0 ; i < = ll ; i + + ) gc_ms_mark_object ( hak , proc - > slot [ i ] ) ;
2024-09-12 18:06:12 +09:00
2024-03-03 22:17:14 +09:00
/* exception stack */
2025-09-02 23:58:15 +09:00
ll = HAK_OOP_TO_SMOOI ( proc - > exsp ) ;
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , ll < ( hak_ooi_t ) ( HAK_OBJ_GET_SIZE ( oop ) - HAK_PROCESS_NAMED_INSTVARS ) ) ;
for ( i = HAK_OOP_TO_SMOOI ( proc - > st ) + 1 ; i < = ll ; i + + ) gc_ms_mark_object ( hak , proc - > slot [ i ] ) ;
2024-09-12 18:06:12 +09:00
2024-03-03 22:17:14 +09:00
/* class stack */
2025-09-02 23:58:15 +09:00
ll = HAK_OOP_TO_SMOOI ( proc - > clsp ) ;
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , ll < ( hak_ooi_t ) ( HAK_OBJ_GET_SIZE ( oop ) - HAK_PROCESS_NAMED_INSTVARS ) ) ;
for ( i = HAK_OOP_TO_SMOOI ( proc - > exst ) + 1 ; i < = ll ; i + + ) gc_ms_mark_object ( hak , proc - > slot [ i ] ) ;
2024-03-03 22:17:14 +09:00
}
else
{
2025-09-02 23:58:15 +09:00
ll = HAK_OBJ_GET_SIZE ( oop ) ;
2025-09-05 10:52:02 +09:00
for ( i = 0 ; i < ll ; i + + ) gc_ms_mark_object ( hak , HAK_OBJ_GET_OOP_VAL ( oop , i ) ) ;
2024-03-03 22:17:14 +09:00
}
}
}
2020-12-31 17:48:47 +00:00
}
2025-09-02 23:58:15 +09:00
static HAK_INLINE void gc_ms_mark ( hak_t * hak , hak_oop_t oop )
2020-12-31 17:48:47 +00:00
{
2025-09-05 10:52:02 +09:00
gc_ms_mark_object ( hak , oop ) ;
2025-09-02 23:58:15 +09:00
gc_ms_scan_stack ( hak ) ;
2020-12-31 17:48:47 +00:00
}
2024-03-03 22:17:14 +09:00
# endif
2020-12-31 17:48:47 +00:00
2025-09-02 23:58:15 +09:00
static HAK_INLINE void gc_ms_mark_roots ( hak_t * hak )
2016-09-28 14:40:37 +00:00
{
2025-09-02 23:58:15 +09:00
hak_oow_t i ;
2024-03-03 22:17:14 +09:00
# if defined(ENABLE_GCFIN)
2025-09-02 23:58:15 +09:00
hak_oow_t gcfin_count ;
2024-03-03 22:17:14 +09:00
# endif
2025-09-02 23:58:15 +09:00
hak_cb_t * cb ;
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_PROFILE_VM)
2024-03-03 22:17:14 +09:00
struct rusage ru ;
2025-09-02 23:58:15 +09:00
hak_ntime_t rut ;
2024-03-03 22:17:14 +09:00
getrusage ( RUSAGE_SELF , & ru ) ;
2025-09-02 23:58:15 +09:00
HAK_INIT_NTIME ( & rut , ru . ru_utime . tv_sec , HAK_USEC_TO_NSEC ( ru . ru_utime . tv_usec ) ) ;
2024-03-03 22:17:14 +09:00
# endif
2025-09-02 23:58:15 +09:00
if ( hak - > processor & & hak - > processor - > active )
2016-09-28 14:40:37 +00:00
{
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , ( hak_oop_t ) hak - > processor ! = hak - > _nil ) ;
HAK_ASSERT ( hak , ( hak_oop_t ) hak - > processor - > active ! = hak - > _nil ) ;
2024-03-03 22:17:14 +09:00
/* commit the stack pointer to the active process because
* gc needs the correct stack pointer for a process object */
2025-09-02 23:58:15 +09:00
hak - > processor - > active - > sp = HAK_SMOOI_TO_OOP ( hak - > sp ) ;
2016-09-28 14:40:37 +00:00
}
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , hak - > _undef ) ;
gc_ms_mark ( hak , hak - > _nil ) ;
gc_ms_mark ( hak , hak - > _true ) ;
gc_ms_mark ( hak , hak - > _false ) ;
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < HAK_COUNTOF ( kernel_classes ) ; i + + )
2024-03-02 19:29:15 +09:00
{
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , * ( hak_oop_t * ) ( ( hak_uint8_t * ) hak + kernel_classes [ i ] . offset ) ) ;
2024-03-02 19:29:15 +09:00
}
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( hak_oop_t ) hak - > sysdic ) ;
gc_ms_mark ( hak , ( hak_oop_t ) hak - > processor ) ;
gc_ms_mark ( hak , ( hak_oop_t ) hak - > nil_process ) ;
2024-03-03 22:17:14 +09:00
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > code . lit . len ; i + + )
2016-09-28 14:40:37 +00:00
{
2023-11-10 00:03:03 +09:00
/* the literal array ia a NGC object. but the literal objects
2018-02-07 07:35:30 +00:00
* pointed by the elements of this array must be gabage - collected . */
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( ( hak_oop_oop_t ) hak - > code . lit . arr ) - > slot [ i ] ) ;
2016-09-28 14:40:37 +00:00
}
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , hak - > p . e ) ;
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > sem_list_count ; i + + )
2016-09-28 14:40:37 +00:00
{
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( hak_oop_t ) hak - > sem_list [ i ] ) ;
2016-09-28 14:40:37 +00:00
}
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > sem_heap_count ; i + + )
2016-09-28 14:40:37 +00:00
{
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( hak_oop_t ) hak - > sem_heap [ i ] ) ;
2016-09-28 14:40:37 +00:00
}
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > sem_io_tuple_count ; i + + )
2020-10-15 12:57:05 +00:00
{
2025-09-02 23:58:15 +09:00
if ( hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_INPUT ] )
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( hak_oop_t ) hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_INPUT ] ) ;
2025-09-02 23:58:15 +09:00
if ( hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_OUTPUT ] )
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( hak_oop_t ) hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_OUTPUT ] ) ;
2020-10-15 12:57:05 +00:00
}
# if defined(ENABLE_GCFIN)
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( hak_oop_t ) hak - > sem_gcfin ) ;
2020-10-15 12:57:05 +00:00
# endif
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > proc_map_capa ; i + + )
2020-10-15 12:57:05 +00:00
{
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , hak - > proc_map [ i ] ) ;
2020-10-15 12:57:05 +00:00
}
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > volat_count ; i + + )
2016-09-28 14:40:37 +00:00
{
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , * hak - > volat_stack [ i ] ) ;
2016-09-28 14:40:37 +00:00
}
2025-09-05 10:52:02 +09:00
if ( hak - > initial_context ) gc_ms_mark ( hak , ( hak_oop_t ) hak - > initial_context ) ;
if ( hak - > active_context ) gc_ms_mark ( hak , ( hak_oop_t ) hak - > active_context ) ;
if ( hak - > initial_function ) gc_ms_mark ( hak , ( hak_oop_t ) hak - > initial_function ) ;
if ( hak - > active_function ) gc_ms_mark ( hak , ( hak_oop_t ) hak - > active_function ) ;
2024-03-03 22:17:14 +09:00
2025-09-05 10:52:02 +09:00
if ( hak - > last_retv ) gc_ms_mark ( hak , hak - > last_retv ) ;
2018-02-22 07:41:03 +00:00
2025-09-02 23:58:15 +09:00
/*hak_rbt_walk (&hak->modtab, call_module_gc, hak); */
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
for ( cb = hak - > cblist ; cb ; cb = cb - > next )
2016-09-28 14:40:37 +00:00
{
2025-09-02 23:58:15 +09:00
if ( cb - > on_gc ) cb - > on_gc ( hak ) ;
2016-09-28 14:40:37 +00:00
}
2024-03-03 22:17:14 +09:00
# if defined(ENABLE_GCFIN)
2025-09-02 23:58:15 +09:00
gcfin_count = move_finalizable_objects ( hak ) ; /* mark finalizable objects */
2024-03-03 22:17:14 +09:00
# endif
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
if ( hak - > symtab )
2016-09-28 14:40:37 +00:00
{
2025-09-05 10:52:02 +09:00
compact_symbol_table ( hak , hak - > _nil ) ; /* delete symbol table entries that are not marked */
2024-03-03 22:17:14 +09:00
#if 0
2025-09-05 10:52:02 +09:00
gc_ms_mark ( hak , ( hak_oop_t ) hak - > symtab ) ; /* mark the symbol table */
2024-03-03 22:17:14 +09:00
# else
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_FLAGS_MOVED ( hak - > symtab , 1 ) ; /* mark */
HAK_OBJ_SET_FLAGS_MOVED ( hak - > symtab - > bucket , 1 ) ; /* mark */
2024-03-03 22:17:14 +09:00
# endif
2016-09-28 14:40:37 +00:00
}
2016-10-04 17:56:28 +00:00
2024-03-03 22:17:14 +09:00
# if defined(ENABLE_GCFIN)
2025-09-02 23:58:15 +09:00
if ( gcfin_count > 0 ) hak - > sem_gcfin_sigreq = 1 ;
2020-12-31 17:48:47 +00:00
# endif
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
if ( hak - > active_function ) hak - > active_code = HAK_FUNCTION_GET_CODE_BYTE ( hak - > active_function ) ; /* update hak->active_code */
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_PROFILE_VM)
2024-03-03 22:17:14 +09:00
getrusage ( RUSAGE_SELF , & ru ) ;
2025-09-02 23:58:15 +09:00
HAK_SUB_NTIME_SNS ( & rut , & rut , ru . ru_utime . tv_sec , HAK_USEC_TO_NSEC ( ru . ru_utime . tv_usec ) ) ;
HAK_SUB_NTIME ( & hak - > gci . stat . mark , & hak - > gci . stat . mark , & rut ) ; /* do subtraction because rut is negative */
2024-03-03 22:17:14 +09:00
# endif
2016-09-28 14:40:37 +00:00
}
2025-09-02 23:58:15 +09:00
void hak_gc_ms_sweep_lazy ( hak_t * hak , hak_oow_t allocsize )
2016-09-28 14:40:37 +00:00
{
2025-09-02 23:58:15 +09:00
hak_gchdr_t * curr , * next , * prev ;
hak_oop_t obj ;
hak_oow_t freed_size ;
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_PROFILE_VM)
2024-03-03 22:17:14 +09:00
struct rusage ru ;
2025-09-02 23:58:15 +09:00
hak_ntime_t rut ;
2024-03-03 22:17:14 +09:00
getrusage ( RUSAGE_SELF , & ru ) ;
2025-09-02 23:58:15 +09:00
HAK_INIT_NTIME ( & rut , ru . ru_utime . tv_sec , HAK_USEC_TO_NSEC ( ru . ru_utime . tv_usec ) ) ;
2024-03-03 22:17:14 +09:00
# endif
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
if ( ! hak - > gci . ls . curr ) goto done ;
2016-09-28 14:40:37 +00:00
2024-03-03 22:17:14 +09:00
freed_size = 0 ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
prev = hak - > gci . ls . prev ;
curr = hak - > gci . ls . curr ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
while ( curr )
{
next = curr - > next ;
2025-09-02 23:58:15 +09:00
obj = ( hak_oop_t ) ( curr + 1 ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_OBJ_GET_FLAGS_MOVED ( obj ) ) /* if marked */
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_FLAGS_MOVED ( obj , 0 ) ; /* unmark */
2024-03-03 22:17:14 +09:00
prev = curr ;
}
else
{
2025-09-02 23:58:15 +09:00
hak_oow_t objsize ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
if ( prev ) prev - > next = next ;
2025-09-02 23:58:15 +09:00
else hak - > gci . b = next ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
objsize = HAK_SIZEOF ( hak_obj_t ) + hak_getobjpayloadbytes ( hak , obj ) ;
2024-03-03 22:17:14 +09:00
freed_size + = objsize ;
2025-09-02 23:58:15 +09:00
hak - > gci . bsz - = objsize ;
hak_freeheapmem ( hak , hak - > heap , curr ) ; /* destroy */
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/*if (freed_size > allocsize)*/ /* TODO: can it secure large enough space? */
if ( objsize = = allocsize )
{
2025-09-02 23:58:15 +09:00
hak - > gci . ls . prev = prev ;
hak - > gci . ls . curr = next ; /* let the next lazy sweeping begin at this point */
2024-03-03 22:17:14 +09:00
goto done ;
}
}
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
curr = next ;
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
hak - > gci . ls . curr = HAK_NULL ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
done :
2025-09-02 23:58:15 +09:00
# if defined(HAK_PROFILE_VM)
2024-03-03 22:17:14 +09:00
getrusage ( RUSAGE_SELF , & ru ) ;
2025-09-02 23:58:15 +09:00
HAK_SUB_NTIME_SNS ( & rut , & rut , ru . ru_utime . tv_sec , HAK_USEC_TO_NSEC ( ru . ru_utime . tv_usec ) ) ;
HAK_SUB_NTIME ( & hak - > gci . stat . sweep , & hak - > gci . stat . sweep , & rut ) ; /* do subtraction because rut is negative */
2024-03-03 22:17:14 +09:00
# endif
return ;
}
2024-02-26 13:34:09 +09:00
2025-09-02 23:58:15 +09:00
static HAK_INLINE void gc_ms_sweep ( hak_t * hak )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_gchdr_t * curr , * next , * prev ;
hak_oop_t obj ;
2024-03-02 19:29:15 +09:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_PROFILE_VM)
2024-03-03 22:17:14 +09:00
struct rusage ru ;
2025-09-02 23:58:15 +09:00
hak_ntime_t rut ;
2024-03-03 22:17:14 +09:00
getrusage ( RUSAGE_SELF , & ru ) ;
2025-09-02 23:58:15 +09:00
HAK_INIT_NTIME ( & rut , ru . ru_utime . tv_sec , HAK_USEC_TO_NSEC ( ru . ru_utime . tv_usec ) ) ;
2024-03-03 22:17:14 +09:00
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
prev = HAK_NULL ;
curr = hak - > gci . b ;
2024-03-03 22:17:14 +09:00
while ( curr )
{
next = curr - > next ;
2025-09-02 23:58:15 +09:00
obj = ( hak_oop_t ) ( curr + 1 ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_OBJ_GET_FLAGS_MOVED ( obj ) ) /* if marked */
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_FLAGS_MOVED ( obj , 0 ) ; /* unmark */
2024-03-03 22:17:14 +09:00
prev = curr ;
}
else
{
if ( prev ) prev - > next = next ;
2025-09-02 23:58:15 +09:00
else hak - > gci . b = next ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
hak - > gci . bsz - = HAK_SIZEOF ( hak_obj_t ) + hak_getobjpayloadbytes ( hak , obj ) ;
hak_freeheapmem ( hak , hak - > heap , curr ) ; /* destroy */
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
curr = next ;
}
2025-09-02 23:58:15 +09:00
hak - > gci . ls . curr = HAK_NULL ;
2024-03-03 22:17:14 +09:00
2025-09-02 23:58:15 +09:00
# if defined(HAK_PROFILE_VM)
2024-03-03 22:17:14 +09:00
getrusage ( RUSAGE_SELF , & ru ) ;
2025-09-02 23:58:15 +09:00
HAK_SUB_NTIME_SNS ( & rut , & rut , ru . ru_utime . tv_sec , HAK_USEC_TO_NSEC ( ru . ru_utime . tv_usec ) ) ;
HAK_SUB_NTIME ( & hak - > gci . stat . sweep , & hak - > gci . stat . sweep , & rut ) ; /* do subtraction because rut is negative */
2024-03-03 22:17:14 +09:00
# endif
}
2025-09-02 23:58:15 +09:00
void hak_gc ( hak_t * hak , int full )
2024-03-02 14:59:27 +09:00
{
2025-09-05 10:52:02 +09:00
if ( hak - > gci . lazy_sweep ) hak_gc_ms_sweep_lazy ( hak , HAK_TYPE_MAX ( hak_oow_t ) ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
HAK_LOG1 ( hak , HAK_LOG_GC | HAK_LOG_INFO , " Starting GC (mark-sweep) - gci.bsz = %zu \n " , hak - > gci . bsz ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
hak - > gci . stack . len = 0 ;
/*hak->gci.stack.max = 0;*/
gc_ms_mark_roots ( hak ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( ! full & & hak - > gci . lazy_sweep )
2024-03-03 22:17:14 +09:00
{
2024-04-04 21:16:28 +09:00
/* set the lazy sweeping pointer to the head of the allocated blocks.
2025-09-02 23:58:15 +09:00
* hak_allocbytes ( ) updates hak - > gci . ls . prev if it is called while
* hak - > gci . ls . curr stays at hak - > gci . b */
hak - > gci . ls . prev = HAK_NULL ;
hak - > gci . ls . curr = hak - > gci . b ;
2024-03-03 22:17:14 +09:00
}
else
{
2025-09-02 23:58:15 +09:00
gc_ms_sweep ( hak ) ;
2024-03-03 22:17:14 +09:00
}
2025-09-02 23:58:15 +09:00
HAK_LOG2 ( hak , HAK_LOG_GC | HAK_LOG_INFO , " Finished GC (mark-sweep) - gci.bsz = %zu, gci.stack.max %zu \n " , hak - > gci . bsz , hak - > gci . stack . max ) ;
2024-03-03 22:17:14 +09:00
}
2025-09-02 23:58:15 +09:00
hak_oop_t hak_moveoop ( hak_t * hak , hak_oop_t oop )
2024-03-03 22:17:14 +09:00
{
2025-09-05 10:52:02 +09:00
if ( oop ) gc_ms_mark ( hak , oop ) ;
2024-03-03 22:17:14 +09:00
return oop ;
}
2024-03-02 14:59:27 +09:00
2024-03-02 19:29:15 +09:00
#if 0
2025-09-02 23:58:15 +09:00
void hak_gc ( hak_t * hak )
2024-03-03 22:17:14 +09:00
{
/*
* move a referenced object to the new heap .
* inspect the fields of the moved object in the new heap .
* move objects pointed to by the fields to the new heap .
* finally perform some tricky symbol table clean - up .
*/
2025-09-02 23:58:15 +09:00
hak_uint8_t * ptr ;
hak_heap_t * tmp ;
hak_oop_t old_nil ;
hak_oow_t i ;
hak_cb_t * cb ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( hak - > active_context )
2024-03-03 22:17:14 +09:00
{
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , ( hak_oop_t ) hak - > processor ! = hak - > _nil ) ;
HAK_ASSERT ( hak , ( hak_oop_t ) hak - > processor - > active ! = hak - > _nil ) ;
HAK_ASSERT ( hak , HAK_IS_PROCESS ( hak , hak - > processor - > active ) ) ;
2024-03-03 22:17:14 +09:00
/* commit the stack pointer to the active process */
2025-09-02 23:58:15 +09:00
hak - > processor - > active - > sp = HAK_SMOOI_TO_OOP ( hak - > sp ) ;
2024-03-03 22:17:14 +09:00
/* commit the instruction pointer to the active context */
2025-09-02 23:58:15 +09:00
hak - > active_context - > ip = HAK_SMOOI_TO_OOP ( hak - > ip ) ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
HAK_LOG4 ( hak , HAK_LOG_GC | HAK_LOG_INFO ,
2024-03-03 22:17:14 +09:00
" Starting GC curheap base %p ptr %p newheap base %p ptr %p \n " ,
2025-09-02 23:58:15 +09:00
hak - > curheap - > base , hak - > curheap - > ptr , hak - > newheap - > base , hak - > newheap - > ptr ) ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* TODO: allocate common objects like _nil and the root dictionary
* in the permanant heap . minimize moving around */
2025-09-02 23:58:15 +09:00
old_nil = hak - > _nil ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* move _nil and the root object table */
2025-09-02 23:58:15 +09:00
hak - > _undef = hak_moveoop ( hak , hak - > _undef ) ;
hak - > _nil = hak_moveoop ( hak , hak - > _nil ) ;
hak - > _true = hak_moveoop ( hak , hak - > _true ) ;
hak - > _false = hak_moveoop ( hak , hak - > _false ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < HAK_COUNTOF ( kernel_classes ) ; i + + )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oop_t tmp ;
tmp = * ( hak_oop_t * ) ( ( hak_uint8_t * ) hak + kernel_classes [ i ] . offset ) ;
tmp = hak_moveoop ( hak , tmp ) ;
* ( hak_oop_t * ) ( ( hak_uint8_t * ) hak + kernel_classes [ i ] . offset ) = tmp ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
hak - > sysdic = ( hak_oop_dic_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > sysdic ) ;
hak - > processor = ( hak_oop_process_scheduler_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > processor ) ;
hak - > nil_process = ( hak_oop_process_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > nil_process ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > code . lit . len ; i + + )
2024-03-03 22:17:14 +09:00
{
/* the literal array ia a NGC object. but the literal objects
* pointed by the elements of this array must be gabage - collected . */
2025-09-02 23:58:15 +09:00
( ( hak_oop_oop_t ) hak - > code . lit . arr ) - > slot [ i ] =
hak_moveoop ( hak , ( ( hak_oop_oop_t ) hak - > code . lit . arr ) - > slot [ i ] ) ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
hak - > p . e = hak_moveoop ( hak , hak - > p . e ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > sem_list_count ; i + + )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak - > sem_list [ i ] = ( hak_oop_semaphore_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > sem_list [ i ] ) ;
2024-03-03 22:17:14 +09:00
}
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > sem_heap_count ; i + + )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak - > sem_heap [ i ] = ( hak_oop_semaphore_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > sem_heap [ i ] ) ;
2024-03-03 22:17:14 +09:00
}
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > sem_io_tuple_count ; i + + )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
if ( hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_INPUT ] )
hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_INPUT ] = ( hak_oop_semaphore_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_INPUT ] ) ;
if ( hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_OUTPUT ] )
hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_OUTPUT ] = ( hak_oop_semaphore_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > sem_io_tuple [ i ] . sem [ HAK_SEMAPHORE_IO_TYPE_OUTPUT ] ) ;
2024-03-03 22:17:14 +09:00
}
# if defined(ENABLE_GCFIN)
2025-09-02 23:58:15 +09:00
hak - > sem_gcfin = ( hak_oop_semaphore_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > sem_gcfin ) ;
2024-03-02 19:29:15 +09:00
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > proc_map_capa ; i + + )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak - > proc_map [ i ] = hak_moveoop ( hak , hak - > proc_map [ i ] ) ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < hak - > volat_count ; i + + )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
* hak - > volat_stack [ i ] = hak_moveoop ( hak , * hak - > volat_stack [ i ] ) ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( hak - > initial_context )
hak - > initial_context = ( hak_oop_context_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > initial_context ) ;
if ( hak - > active_context )
hak - > active_context = ( hak_oop_context_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > active_context ) ;
if ( hak - > initial_function )
hak - > initial_function = ( hak_oop_function_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > initial_function ) ;
if ( hak - > active_function )
hak - > active_function = ( hak_oop_function_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > active_function ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( hak - > last_retv ) hak - > last_retv = hak_moveoop ( hak , hak - > last_retv ) ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
for ( cb = hak - > cblist ; cb ; cb = cb - > next )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
if ( cb - > gc ) cb - > gc ( hak ) ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* scan the new heap to move referenced objects */
2025-09-02 23:58:15 +09:00
ptr = ( hak_uint8_t * ) HAK_ALIGN ( ( hak_uintptr_t ) hak - > newheap - > base , HAK_SIZEOF ( hak_oop_t ) ) ;
ptr = scan_new_heap ( hak , ptr ) ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* traverse the symbol table for unreferenced symbols.
* if the symbol has not moved to the new heap , the symbol
* is not referenced by any other objects than the symbol
* table itself */
2025-09-05 10:52:02 +09:00
compact_symbol_table ( hak , old_nil ) ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* move the symbol table itself */
2025-09-02 23:58:15 +09:00
hak - > symtab = ( hak_oop_dic_t ) hak_moveoop ( hak , ( hak_oop_t ) hak - > symtab ) ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* scan the new heap again from the end position of
* the previous scan to move referenced objects by
* the symbol table . */
2025-09-02 23:58:15 +09:00
ptr = scan_new_heap ( hak , ptr ) ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* the contents of the current heap is not needed any more.
* reset the upper bound to the base . don ' t forget to align the heap
2025-09-02 23:58:15 +09:00
* pointer to the OOP size . See hak_makeheap ( ) also */
hak - > curheap - > ptr = ( hak_uint8_t * ) HAK_ALIGN ( ( ( hak_uintptr_t ) hak - > curheap - > base ) , HAK_SIZEOF ( hak_oop_t ) ) ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* swap the current heap and old heap */
2025-09-02 23:58:15 +09:00
tmp = hak - > curheap ;
hak - > curheap = hak - > newheap ;
hak - > newheap = tmp ;
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/*
2025-09-02 23:58:15 +09:00
if ( hak - > symtab & & HAK_LOG_ENABLED ( hak , HAK_LOG_GC | HAK_LOG_DEBUG ) )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oow_t index ;
hak_oop_oop_t buc ;
HAK_LOG0 ( hak , HAK_LOG_GC | HAK_LOG_DEBUG , " --------- SURVIVING SYMBOLS IN GC ---------- \n " ) ;
buc = ( hak_oop_oop_t ) hak - > symtab - > bucket ;
for ( index = 0 ; index < HAK_OBJ_GET_SIZE ( buc ) ; index + + )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
if ( ( hak_oop_t ) buc - > slot [ index ] ! = hak - > _nil )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
HAK_LOG1 ( hak , HAK_LOG_GC | HAK_LOG_DEBUG , " \t %O \n " , buc - > slot [ index ] ) ;
2024-03-03 22:17:14 +09:00
}
}
2025-09-02 23:58:15 +09:00
HAK_LOG0 ( hak , HAK_LOG_GC | HAK_LOG_DEBUG , " -------------------------------------------- \n " ) ;
2024-03-03 22:17:14 +09:00
}
*/
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( hak - > active_function ) hak - > active_code = HAK_FUNCTION_GET_CODE_BYTE ( hak - > active_function ) ; /* update hak->active_code */
2024-03-02 14:59:27 +09:00
2024-03-03 22:17:14 +09:00
/* TODO: include some gc statstics like number of live objects, gc performance, etc */
2025-09-02 23:58:15 +09:00
HAK_LOG4 ( hak , HAK_LOG_GC | HAK_LOG_INFO ,
2024-03-03 22:17:14 +09:00
" Finished GC curheap base %p ptr %p newheap base %p ptr %p \n " ,
2025-09-02 23:58:15 +09:00
hak - > curheap - > base , hak - > curheap - > ptr , hak - > newheap - > base , hak - > newheap - > ptr ) ;
2024-03-03 22:17:14 +09:00
}
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
void hak_pushvolat ( hak_t * hak , hak_oop_t * oop_ptr )
2024-03-03 22:17:14 +09:00
{
/* if you have too many temporaries pushed, something must be wrong.
* change your code not to exceede the stack limit */
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > volat_count < HAK_COUNTOF ( hak - > volat_stack ) ) ;
2025-09-02 23:58:15 +09:00
hak - > volat_stack [ hak - > volat_count + + ] = oop_ptr ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
void hak_popvolat ( hak_t * hak )
2024-03-03 22:17:14 +09:00
{
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > volat_count > 0 ) ;
2025-09-02 23:58:15 +09:00
hak - > volat_count - - ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
void hak_popvolats ( hak_t * hak , hak_oow_t count )
2024-03-03 22:17:14 +09:00
{
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > volat_count > = count ) ;
2025-09-02 23:58:15 +09:00
hak - > volat_count - = count ;
2024-03-03 22:17:14 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
hak_oop_t hak_shallowcopy ( hak_t * hak , hak_oop_t oop )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
if ( HAK_OOP_IS_POINTER ( oop ) & & HAK_OBJ_GET_CLASS ( oop ) ! = ( hak_oop_t ) hak - > c_symbol )
2024-03-03 22:17:14 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oop_t z ;
hak_oow_t total_bytes ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
total_bytes = HAK_SIZEOF ( hak_obj_t ) + hak_getobjpayloadbytes ( hak , oop ) ;
2024-03-02 14:59:27 +09:00
2025-09-05 10:52:02 +09:00
hak_pushvolat ( hak , & oop ) ;
2025-09-02 23:58:15 +09:00
z = ( hak_oop_t ) hak_allocbytes ( hak , total_bytes ) ;
hak_popvolat ( hak ) ;
2024-03-02 14:59:27 +09:00
2025-09-05 10:52:02 +09:00
HAK_MEMCPY ( z , oop , total_bytes ) ;
2024-03-03 22:17:14 +09:00
return z ;
}
return oop ;
}
/* ========================================================================= */
2024-03-02 14:59:27 +09:00
/* -----------------------------------------------------------------------
* BOOTSTRAPPER
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2025-09-02 23:58:15 +09:00
static hak_oop_class_t alloc_kernel_class ( hak_t * hak , int class_flags , hak_oow_t num_classvars , hak_oow_t spec , hak_ooi_t nivars_super , int ibrand )
2024-03-02 14:59:27 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oop_class_t c ;
hak_ooi_t cspec ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
c = ( hak_oop_class_t ) hak_allocoopobj ( hak , HAK_CLASS_NAMED_INSTVARS + num_classvars ) ;
if ( HAK_UNLIKELY ( ! c ) ) return HAK_NULL ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_FLAGS_KERNEL ( c , HAK_OBJ_FLAGS_KERNEL_IMMATURE ) ;
2024-03-02 14:59:27 +09:00
cspec = kernel_classes [ KCI_CLASS ] . class_spec_flags ;
2025-09-02 23:58:15 +09:00
if ( HAK_CLASS_SPEC_IS_IMMUTABLE ( cspec ) ) HAK_OBJ_SET_FLAGS_RDONLY ( c , 1 ) ; /* just for completeness of code. will never be true as it's not defined in the kernel class info table */
2024-09-08 15:52:32 +09:00
#if 0 /* TODO extend the flags and uncomment this part */
2025-09-02 23:58:15 +09:00
if ( HAK_CLASS_SPEC_IS_UNCOPYABLE ( cspec ) ) HAK_OBJ_SET_FLAGS_UNCOPYABLE ( c , 1 ) ; /* class itself is uncopyable */
2024-03-06 07:51:29 +09:00
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_CLASS ( c , ( hak_oop_t ) hak - > c_class ) ;
c - > spec = HAK_SMOOI_TO_OOP ( spec ) ;
c - > selfspec = HAK_SMOOI_TO_OOP ( HAK_CLASS_SELFSPEC_MAKE ( num_classvars , 0 , class_flags ) ) ;
c - > nivars_super = HAK_SMOOI_TO_OOP ( nivars_super ) ; /* TODO: encode it into spec? */
c - > ibrand = HAK_SMOOI_TO_OOP ( ibrand ) ;
2024-03-02 14:59:27 +09:00
return c ;
}
2025-09-02 23:58:15 +09:00
static int ignite_1 ( hak_t * hak )
2024-03-02 14:59:27 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oow_t i ;
2024-03-02 14:59:27 +09:00
/*
* Create fundamental class objects with some fields mis - initialized yet .
* Such fields include ' superclass ' , ' subclasses ' , ' name ' , etc .
*/
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > _nil ! = HAK_NULL ) ;
HAK_ASSERT ( hak , HAK_OBJ_GET_CLASS ( hak - > _nil ) = = HAK_NULL ) ;
2024-03-02 14:59:27 +09:00
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > c_class = = HAK_NULL ) ;
2024-03-02 14:59:27 +09:00
/* --------------------------------------------------------------
* Class
* The instance of Class can have indexed instance variables
* which are actually class variables .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > c_class ) )
2024-03-08 00:23:52 +09:00
{
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , kernel_classes [ KCI_CLASS ] . superclass_kci > = 0 ) ;
2025-09-02 23:58:15 +09:00
hak - > c_class = alloc_kernel_class (
hak ,
2024-07-23 23:50:29 +09:00
kernel_classes [ KCI_CLASS ] . class_flags ,
2024-07-27 01:14:51 +09:00
kernel_classes [ KCI_CLASS ] . class_ncvars ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_MAKE ( kernel_classes [ KCI_CLASS ] . class_spec_nivars ,
2024-03-08 00:23:52 +09:00
kernel_classes [ KCI_CLASS ] . class_spec_flags ,
kernel_classes [ KCI_CLASS ] . class_spec_indexed_type ) ,
2024-07-27 16:27:43 +09:00
kernel_classes [ kernel_classes [ KCI_CLASS ] . superclass_kci ] . class_spec_nivars ,
2024-03-08 00:23:52 +09:00
kernel_classes [ KCI_CLASS ] . class_brand ) ;
2025-09-02 23:58:15 +09:00
if ( HAK_UNLIKELY ( ! hak - > c_class ) )
2024-03-08 00:23:52 +09:00
{
2025-09-02 23:58:15 +09:00
const hak_ooch_t * orgmsg = hak_backuperrmsg ( hak ) ;
2025-09-05 10:52:02 +09:00
hak_seterrbfmt ( hak , HAK_ERRNUM ( hak ) , " unable to allocate %hs - %js " , kernel_classes [ KCI_CLASS ] . name , orgmsg ) ;
2024-03-08 00:23:52 +09:00
return - 1 ;
}
2024-03-02 14:59:27 +09:00
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , HAK_OBJ_GET_CLASS ( hak - > c_class ) = = HAK_NULL ) ;
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_CLASS ( hak - > c_class , ( hak_oop_t ) hak - > c_class ) ;
2024-03-08 00:23:52 +09:00
}
2024-03-02 14:59:27 +09:00
2024-07-29 15:36:07 +09:00
/* create class objects except Class */
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < HAK_COUNTOF ( kernel_classes ) ; i + + )
2024-03-02 14:59:27 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oop_class_t tmp ;
hak_ooi_t nivars_super ;
2024-07-27 16:27:43 +09:00
int superclass_kci ;
2024-03-02 14:59:27 +09:00
if ( i = = KCI_CLASS ) continue ; /* skip Class as it's created above */
2024-07-27 16:27:43 +09:00
superclass_kci = kernel_classes [ i ] . superclass_kci ;
nivars_super = superclass_kci < = - 1 ? 0 : kernel_classes [ superclass_kci ] . class_spec_nivars ;
2024-03-02 14:59:27 +09:00
tmp = alloc_kernel_class (
2025-09-02 23:58:15 +09:00
hak ,
2024-07-23 23:50:29 +09:00
kernel_classes [ i ] . class_flags ,
2024-07-27 01:14:51 +09:00
kernel_classes [ i ] . class_ncvars ,
2025-09-02 23:58:15 +09:00
HAK_CLASS_SPEC_MAKE ( kernel_classes [ i ] . class_spec_nivars ,
2024-03-02 14:59:27 +09:00
kernel_classes [ i ] . class_spec_flags ,
2024-03-08 00:23:52 +09:00
kernel_classes [ i ] . class_spec_indexed_type ) ,
2024-07-27 16:27:43 +09:00
nivars_super ,
2024-03-08 00:23:52 +09:00
kernel_classes [ i ] . class_brand ) ;
2025-09-02 23:58:15 +09:00
if ( HAK_UNLIKELY ( ! tmp ) )
2024-03-08 00:23:52 +09:00
{
2025-09-02 23:58:15 +09:00
const hak_ooch_t * orgmsg = hak_backuperrmsg ( hak ) ;
2025-09-05 10:52:02 +09:00
hak_seterrbfmt ( hak , HAK_ERRNUM ( hak ) , " unable to allocate %hs - %js " , kernel_classes [ i ] . name , orgmsg ) ;
2024-03-08 00:23:52 +09:00
return - 1 ;
}
2025-09-02 23:58:15 +09:00
* ( hak_oop_class_t * ) ( ( hak_uint8_t * ) hak + kernel_classes [ i ] . offset ) = tmp ;
2024-03-02 14:59:27 +09:00
}
2024-07-29 15:36:07 +09:00
/* update the superclass field */
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < HAK_COUNTOF ( kernel_classes ) ; i + + )
2024-07-29 15:36:07 +09:00
{
int skci ;
skci = kernel_classes [ i ] . superclass_kci ;
if ( skci > = 0 )
{
2025-09-02 23:58:15 +09:00
hak_oop_class_t * x , * y ;
x = ( hak_oop_class_t * ) ( ( hak_uint8_t * ) hak + kernel_classes [ i ] . offset ) ;
y = ( hak_oop_class_t * ) ( ( hak_uint8_t * ) hak + kernel_classes [ skci ] . offset ) ;
( * x ) - > superclass = ( hak_oop_t ) * y ;
2024-07-29 15:36:07 +09:00
}
}
2024-03-06 07:51:29 +09:00
#if 0
2024-03-02 14:59:27 +09:00
/* an instance of a method class stores byte codes in the trailer space.
* unlike other classes with trailer size set , the size of the trailer
2024-03-08 00:23:52 +09:00
* space is not really determined by the trailer size set in the class .
2024-03-02 14:59:27 +09:00
* the compiler determines the actual size of the trailer space depending
* on the byte codes generated . i should set the following fields to avoid
* confusion at the GC phase . */
2025-09-02 23:58:15 +09:00
hak - > c_method - > trsize = HAK_SMOOI_TO_OOP ( 0 ) ;
hak - > c_method - > trgc = HAK_SMPTR_TO_OOP ( 0 ) ;
2024-03-06 07:51:29 +09:00
# endif
2024-03-02 14:59:27 +09:00
return 0 ;
}
2025-09-02 23:58:15 +09:00
static int ignite_2 ( hak_t * hak )
2024-03-02 14:59:27 +09:00
{
2025-09-02 23:58:15 +09:00
hak_oop_t tmp ;
2024-03-06 07:51:29 +09:00
#if 0
2025-09-02 23:58:15 +09:00
int old_igniting = hak - > igniting ;
2024-03-06 07:51:29 +09:00
# endif
2024-03-02 14:59:27 +09:00
/* Create 'true' and 'false objects */
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > _true ) )
2024-03-08 00:23:52 +09:00
{
2025-09-02 23:58:15 +09:00
hak - > _true = hak_instantiate ( hak , hak - > c_true , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! hak - > _true ) ) goto oops ;
2024-03-08 00:23:52 +09:00
}
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > _false ) )
2024-03-08 00:23:52 +09:00
{
2025-09-02 23:58:15 +09:00
hak - > _false = hak_instantiate ( hak , hak - > c_false , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! hak - > _false ) ) goto oops ;
2024-03-08 00:23:52 +09:00
}
2024-03-02 14:59:27 +09:00
2024-03-06 07:51:29 +09:00
#if 0
2024-04-05 10:00:58 +09:00
/* Prevent the object instantions in the permspace.
2024-03-02 14:59:27 +09:00
*
* 1. The symbol table is big and it may resize after ignition .
* the resizing operation will migrate the obejct out of the
* permspace . The space taken by the symbol table and the
* system dictionary is wasted . I ' d rather allocate these
* in the normal space .
*
2025-09-02 23:58:15 +09:00
* 2. For compact_symbol_table ( ) to work properly , hak_gc ( ) must not
2024-03-02 14:59:27 +09:00
* scan the symbol table before it executes compact_symbol_table ( ) .
2025-09-02 23:58:15 +09:00
* since hak_gc ( ) scans the entire perspace , it naturally gets to
* hak - > symtab , which causes problems in compact_symbol_table ( ) .
2024-03-02 14:59:27 +09:00
* I may reserve a special space for only the symbol table
* to overcome this issue .
*
* For now , let ' s just allocate the symbol table and the system dictionary
* in the normal space */
2025-09-02 23:58:15 +09:00
hak - > igniting = 0 ;
2024-03-06 07:51:29 +09:00
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > symtab ) )
2024-03-08 00:23:52 +09:00
{
/* Create the symbol table - values in the bucket are limited to symbols only */
2025-09-02 23:58:15 +09:00
tmp = hak_instantiate ( hak , hak - > c_symtab , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! tmp ) ) goto oops ;
hak - > symtab = ( hak_oop_dic_t ) tmp ;
hak - > symtab - > tally = HAK_SMOOI_TO_OOP ( 0 ) ;
2024-03-08 00:23:52 +09:00
}
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ( hak_oop_t ) hak - > symtab - > bucket = = hak - > _nil ) )
2024-03-08 00:23:52 +09:00
{
2025-09-02 23:58:15 +09:00
/* It's important to assign the result of hak_instantiate() to a temporary
* variable first and then assign it to hak - > symtab - > bucket .
* The pointer ' hak - > symtab ; can change in hak_instantiate ( ) and the
* target address of assignment may get set before hak_instantiate ( )
2024-03-08 00:23:52 +09:00
* is called . */
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > option . dfl_symtab_size > 0 ) ;
2025-09-02 23:58:15 +09:00
tmp = hak_instantiate ( hak , hak - > c_array , HAK_NULL , hak - > option . dfl_symtab_size ) ;
if ( HAK_UNLIKELY ( ! tmp ) ) goto oops ; /* TODO: delete hak->symtab instad of this separate initialization of the bucket??? */
hak - > symtab - > bucket = ( hak_oop_oop_t ) tmp ;
2024-03-08 00:23:52 +09:00
}
2024-03-02 14:59:27 +09:00
2024-03-06 07:51:29 +09:00
#if 0
2024-03-02 14:59:27 +09:00
/* Create the system dictionary */
2025-09-02 23:58:15 +09:00
tmp = ( hak_oop_t ) hak_makensdic ( hak , hak - > _namespace , hak - > option . dfl_sysdic_size ) ;
2024-03-02 14:59:27 +09:00
if ( ! tmp ) return - 1 ;
2025-09-02 23:58:15 +09:00
hak - > sysdic = ( hak_oop_nsdic_t ) tmp ;
2024-03-08 00:23:52 +09:00
# else
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > sysdic ) )
2024-03-08 00:23:52 +09:00
{
2025-09-02 23:58:15 +09:00
tmp = hak_instantiate ( hak , hak - > c_dictionary , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! tmp ) ) goto oops ;
hak - > sysdic = ( hak_oop_dic_t ) tmp ;
hak - > sysdic - > tally = HAK_SMOOI_TO_OOP ( 0 ) ;
2024-03-08 00:23:52 +09:00
}
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ( hak_oop_t ) hak - > sysdic - > bucket = = hak - > _nil ) )
2024-03-08 00:23:52 +09:00
{
2025-09-02 23:58:15 +09:00
/* It's important to assign the result of hak_instantiate() to a temporary
* variable first and then assign it to hak - > symtab - > bucket .
* The pointer ' hak - > symtab ; can change in hak_instantiate ( ) and the
* target address of assignment may get set before hak_instantiate ( )
2024-03-08 00:23:52 +09:00
* is called . */
2025-09-02 23:58:15 +09:00
tmp = hak_instantiate ( hak , hak - > c_array , HAK_NULL , hak - > option . dfl_sysdic_size ) ;
if ( HAK_UNLIKELY ( ! tmp ) ) goto oops ;
hak - > sysdic - > bucket = ( hak_oop_oop_t ) tmp ;
2024-03-08 00:23:52 +09:00
}
2024-03-06 07:51:29 +09:00
# endif
2024-03-02 14:59:27 +09:00
2024-03-06 07:51:29 +09:00
#if 0
2025-09-02 23:58:15 +09:00
hak - > igniting = old_igniting ; /* back to the permspace */
2024-03-06 07:51:29 +09:00
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > nil_process ) )
2024-03-08 00:23:52 +09:00
{
/* Create a nil process used to simplify nil check in GC.
* only accessible by VM . not exported via the global dictionary . */
2025-09-02 23:58:15 +09:00
tmp = ( hak_oop_t ) hak_instantiate ( hak , hak - > c_process , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! tmp ) ) goto oops ;
hak - > nil_process = ( hak_oop_process_t ) tmp ;
hak - > nil_process - > id = HAK_SMOOI_TO_OOP ( - 1 ) ;
hak - > nil_process - > state = HAK_SMOOI_TO_OOP ( HAK_PROCESS_STATE_TERMINATED ) ;
2024-03-08 00:23:52 +09:00
#if 0
2025-09-02 23:58:15 +09:00
hak - > nil_process - > perr = HAK_ERROR_TO_OOP ( HAK_ENOERR ) ;
hak - > nil_process - > perrmsg = hak - > _nil ;
2024-03-08 00:23:52 +09:00
# endif
/* unusable stack */
2025-09-02 23:58:15 +09:00
hak - > nil_process - > sp = HAK_SMOOI_TO_OOP ( - 1 ) ;
hak - > nil_process - > st = HAK_SMOOI_TO_OOP ( - 1 ) ;
2024-03-08 00:23:52 +09:00
/* unusable exception stack */
2025-09-02 23:58:15 +09:00
hak - > nil_process - > exsp = HAK_SMOOI_TO_OOP ( - 1 ) ;
hak - > nil_process - > exst = HAK_SMOOI_TO_OOP ( - 1 ) ;
2024-03-08 00:23:52 +09:00
/* unusable class stack */
2025-09-02 23:58:15 +09:00
hak - > nil_process - > clsp = HAK_SMOOI_TO_OOP ( - 1 ) ;
hak - > nil_process - > clst = HAK_SMOOI_TO_OOP ( - 1 ) ;
2024-03-08 00:23:52 +09:00
}
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > processor ) )
2024-03-08 00:23:52 +09:00
{
/* Create a process scheduler */
2025-09-02 23:58:15 +09:00
tmp = ( hak_oop_t ) hak_instantiate ( hak , hak - > c_process_scheduler , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! tmp ) ) goto oops ;
hak - > processor = ( hak_oop_process_scheduler_t ) tmp ;
hak - > processor - > active = hak - > nil_process ;
hak - > processor - > total_count = HAK_SMOOI_TO_OOP ( 0 ) ;
hak - > processor - > runnable . count = HAK_SMOOI_TO_OOP ( 0 ) ;
hak - > processor - > suspended . count = HAK_SMOOI_TO_OOP ( 0 ) ;
2024-03-08 00:23:52 +09:00
}
2024-03-02 14:59:27 +09:00
return 0 ;
2024-03-08 00:23:52 +09:00
oops :
return - 1 ;
2024-03-02 14:59:27 +09:00
}
2025-09-02 23:58:15 +09:00
static int ignite_3 ( hak_t * hak )
2024-03-02 14:59:27 +09:00
{
/* Register kernel classes manually created so far to the system dictionary */
2024-04-04 21:16:28 +09:00
#if 0
2025-09-02 23:58:15 +09:00
static hak_ooch_t str_processor [ ] = { ' P ' , ' r ' , ' o ' , ' c ' , ' e ' , ' s ' , ' s ' , ' o ' , ' r ' } ;
static hak_ooch_t str_dicnew [ ] = { ' n ' , ' e ' , ' w ' , ' : ' } ;
static hak_ooch_t str_dicputassoc [ ] = { ' _ ' , ' _ ' , ' p ' , ' u ' , ' t ' , ' _ ' , ' a ' , ' s ' , ' s ' , ' o ' , ' c ' , ' : ' } ;
static hak_ooch_t str_does_not_understand [ ] = { ' d ' , ' o ' , ' e ' , ' s ' , ' N ' , ' o ' , ' t ' , ' U ' , ' n ' , ' d ' , ' e ' , ' r ' , ' s ' , ' t ' , ' a ' , ' n ' , ' d ' , ' : ' } ;
static hak_ooch_t str_primitive_failed [ ] = { ' p ' , ' r ' , ' i ' , ' m ' , ' i ' , ' t ' , ' i ' , ' v ' , ' e ' , ' F ' , ' a ' , ' i ' , ' l ' , ' e ' , ' d ' } ;
static hak_ooch_t str_unwindto_return [ ] = { ' u ' , ' n ' , ' w ' , ' i ' , ' n ' , ' d ' , ' T ' , ' o ' , ' : ' , ' r ' , ' e ' , ' t ' , ' u ' , ' r ' , ' n ' , ' : ' } ;
2024-04-04 21:16:28 +09:00
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
hak_oow_t i ;
hak_oop_t sym ;
hak_oop_class_t _class ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
for ( i = 0 ; i < HAK_COUNTOF ( kernel_classes ) ; i + + )
2024-03-02 14:59:27 +09:00
{
2025-09-02 23:58:15 +09:00
sym = hak_makesymbolwithbcstr ( hak , kernel_classes [ i ] . name ) ;
if ( HAK_UNLIKELY ( ! sym ) ) return - 1 ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
_class = * ( hak_oop_class_t * ) ( ( hak_uint8_t * ) hak + kernel_classes [ i ] . offset ) ;
2025-09-05 10:52:02 +09:00
HAK_STORE_OOP ( hak , ( hak_oop_t * ) & _class - > name , sym ) ;
2024-07-06 00:47:47 +09:00
#if 0
2025-09-05 10:52:02 +09:00
HAK_STORE_OOP ( hak , ( hak_oop_t * ) & _class - > nsup , ( hak_oop_t ) hak - > sysdic ) ;
2024-04-04 21:16:28 +09:00
# endif
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( ! hak_putatsysdic ( hak , sym , ( hak_oop_t ) _class ) ) return - 1 ;
2024-03-02 14:59:27 +09:00
}
2024-04-04 21:16:28 +09:00
#if 0
2024-03-02 14:59:27 +09:00
/* Attach the system dictionary to the nsdic field of the System class */
2025-09-05 10:52:02 +09:00
HAK_STORE_OOP ( hak , ( hak_oop_t * ) & hak - > _system - > nsdic , ( hak_oop_t ) hak - > sysdic ) ;
2024-03-02 14:59:27 +09:00
/* Set the name field of the system dictionary */
2025-09-05 10:52:02 +09:00
HAK_STORE_OOP ( hak , ( hak_oop_t * ) & hak - > sysdic - > name , ( hak_oop_t ) hak - > _system - > name ) ;
2024-03-02 14:59:27 +09:00
/* Set the owning class field of the system dictionary, it's circular here */
2025-09-05 10:52:02 +09:00
HAK_STORE_OOP ( hak , ( hak_oop_t * ) & hak - > sysdic - > nsup , ( hak_oop_t ) hak - > _system ) ;
2024-03-02 14:59:27 +09:00
/* Make the process scheduler avaialble as the global name 'Processor' */
2025-09-02 23:58:15 +09:00
sym = hak_makesymbol ( hak , str_processor , HAK_COUNTOF ( str_processor ) ) ;
2024-03-02 14:59:27 +09:00
if ( ! sym ) return - 1 ;
2025-09-02 23:58:15 +09:00
if ( ! hak_putatsysdic ( hak , sym , ( hak_oop_t ) hak - > processor ) ) return - 1 ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
sym = hak_makesymbol ( hak , str_dicnew , HAK_COUNTOF ( str_dicnew ) ) ;
2024-03-02 14:59:27 +09:00
if ( ! sym ) return - 1 ;
2025-09-02 23:58:15 +09:00
hak - > dicnewsym = ( hak_oop_char_t ) sym ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
sym = hak_makesymbol ( hak , str_dicputassoc , HAK_COUNTOF ( str_dicputassoc ) ) ;
2024-03-02 14:59:27 +09:00
if ( ! sym ) return - 1 ;
2025-09-02 23:58:15 +09:00
hak - > dicputassocsym = ( hak_oop_char_t ) sym ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
sym = hak_makesymbol ( hak , str_does_not_understand , HAK_COUNTOF ( str_does_not_understand ) ) ;
2024-03-02 14:59:27 +09:00
if ( ! sym ) return - 1 ;
2025-09-02 23:58:15 +09:00
hak - > does_not_understand_sym = ( hak_oop_char_t ) sym ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
sym = hak_makesymbol ( hak , str_primitive_failed , HAK_COUNTOF ( str_primitive_failed ) ) ;
2024-03-02 14:59:27 +09:00
if ( ! sym ) return - 1 ;
2025-09-02 23:58:15 +09:00
hak - > primitive_failed_sym = ( hak_oop_char_t ) sym ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
sym = hak_makesymbol ( hak , str_unwindto_return , HAK_COUNTOF ( str_unwindto_return ) ) ;
2024-03-02 14:59:27 +09:00
if ( ! sym ) return - 1 ;
2025-09-02 23:58:15 +09:00
hak - > unwindto_return_sym = ( hak_oop_char_t ) sym ;
2024-04-04 21:16:28 +09:00
# endif
2024-03-02 14:59:27 +09:00
return 0 ;
}
2025-09-02 23:58:15 +09:00
static int make_kernel_objs ( hak_t * hak )
2024-02-26 13:34:09 +09:00
{
2024-03-08 00:23:52 +09:00
/* make_kernel_objs() creates a chain of classes as well as some key objects
* for initial bootstrapping . when the objects are loaded from an image file ,
* this function is skipped */
2024-03-06 07:51:29 +09:00
2024-02-26 13:34:09 +09:00
#if 0
2025-09-02 23:58:15 +09:00
hak - > igniting = 1 ;
2024-03-08 00:23:52 +09:00
# endif
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > _undef ) )
2024-03-08 00:23:52 +09:00
{ /* TODO: create it as nogc */
2025-09-02 23:58:15 +09:00
hak - > _undef = hak_hatchundef ( hak ) ;
if ( HAK_UNLIKELY ( ! hak - > _undef ) ) goto oops ;
2024-03-08 00:23:52 +09:00
}
2024-02-26 13:34:09 +09:00
2025-09-02 23:58:15 +09:00
if ( HAK_LIKELY ( ! hak - > _nil ) )
2024-03-08 00:23:52 +09:00
{ /* TODO: create it as nogc? */
2025-09-02 23:58:15 +09:00
hak - > _nil = hak_hatchnil ( hak ) ;
if ( HAK_UNLIKELY ( ! hak - > _nil ) ) goto oops ;
2024-03-08 00:23:52 +09:00
}
2024-02-26 13:34:09 +09:00
2025-09-02 23:58:15 +09:00
if ( ignite_1 ( hak ) < = - 1 ) goto oops ;
2024-02-26 13:34:09 +09:00
2024-03-08 00:23:52 +09:00
/* ready to set the class of object created prior to class creation in ignite_1() */
2025-09-02 23:58:15 +09:00
HAK_OBJ_SET_CLASS ( hak - > _nil , ( hak_oop_t ) hak - > c_undefobj ) ;
HAK_OBJ_SET_CLASS ( hak - > _undef , ( hak_oop_t ) hak - > c_undefobj ) ;
2024-03-08 00:23:52 +09:00
2025-09-02 23:58:15 +09:00
if ( ignite_2 ( hak ) < = - 1 ) goto oops ;
2024-03-02 14:59:27 +09:00
2025-09-02 23:58:15 +09:00
if ( ignite_3 ( hak ) < = - 1 ) goto oops ;
2024-03-08 00:23:52 +09:00
2024-04-05 10:00:58 +09:00
/* TODO: scan the heap. and fix the class of objects using brand if the class is NULL */
2024-04-04 21:16:28 +09:00
#if 0
2025-09-02 23:58:15 +09:00
hak - > igniting = 0 ;
2024-02-26 13:34:09 +09:00
# endif
return 0 ;
2024-03-06 07:51:29 +09:00
oops :
#if 0
2025-09-02 23:58:15 +09:00
hak > igniting = 0 ;
2024-03-06 07:51:29 +09:00
# endif
return - 1 ;
2024-02-26 13:34:09 +09:00
}
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
int hak_ignite ( hak_t * hak , hak_oow_t heapsize )
2016-09-28 14:40:37 +00:00
{
2025-09-02 23:58:15 +09:00
if ( ! hak - > heap )
2021-02-09 14:54:54 +00:00
{
2025-09-02 23:58:15 +09:00
hak - > heap = hak_makeheap ( hak , heapsize ) ;
if ( HAK_UNLIKELY ( ! hak - > heap ) ) return - 1 ;
2021-02-09 14:54:54 +00:00
}
2025-09-02 23:58:15 +09:00
if ( make_kernel_objs ( hak ) < = - 1 ) return - 1 ;
2018-02-05 10:43:25 +00:00
2025-09-05 10:52:02 +09:00
HAK_ASSERT ( hak , hak - > _true ! = HAK_NULL ) ;
HAK_ASSERT ( hak , hak - > _false ! = HAK_NULL ) ;
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
if ( ! hak - > symtab )
2016-09-28 14:40:37 +00:00
{
2025-09-02 23:58:15 +09:00
hak - > symtab = ( hak_oop_dic_t ) hak_makedic ( hak , hak - > option . dfl_symtab_size ) ;
if ( HAK_UNLIKELY ( ! hak - > symtab ) ) goto oops ;
2016-09-28 14:40:37 +00:00
}
2025-09-02 23:58:15 +09:00
if ( ! hak - > sysdic )
2016-09-28 14:40:37 +00:00
{
2025-09-02 23:58:15 +09:00
hak - > sysdic = ( hak_oop_dic_t ) hak_makedic ( hak , hak - > option . dfl_sysdic_size ) ;
if ( HAK_UNLIKELY ( ! hak - > sysdic ) ) goto oops ;
2016-09-28 14:40:37 +00:00
}
2025-09-02 23:58:15 +09:00
if ( ! hak - > nil_process )
2016-10-04 17:56:28 +00:00
{
/* Create a nil process used to simplify nil check in GC.
* only accessible by VM . not exported via the global dictionary . */
2025-09-02 23:58:15 +09:00
/*hak->nil_process = (hak_oop_process_t)hak_allocoopobj(hak, HAK_BRAND_PROCESS, HAK_PROCESS_NAMED_INSTVARS);*/
hak - > nil_process = ( hak_oop_process_t ) hak_instantiate ( hak , hak - > c_process , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! hak - > nil_process ) )
2024-09-12 18:06:12 +09:00
{
2025-09-02 23:58:15 +09:00
const hak_ooch_t * orgmsg = hak_backuperrmsg ( hak ) ;
2025-09-05 10:52:02 +09:00
hak_seterrbfmt ( hak , HAK_ERRNUM ( hak ) ,
2025-09-02 23:58:15 +09:00
" unable to instantiate %O to be nil process - %js " , hak - > c_process - > name , orgmsg ) ;
2024-09-12 18:06:12 +09:00
goto oops ;
}
2021-06-25 16:07:29 +00:00
/* unusable stack */
2025-09-02 23:58:15 +09:00
hak - > nil_process - > sp = HAK_SMOOI_TO_OOP ( - 1 ) ;
hak - > nil_process - > st = HAK_SMOOI_TO_OOP ( - 1 ) ;
2021-06-25 16:07:29 +00:00
/* unusable exception stack */
2025-09-02 23:58:15 +09:00
hak - > nil_process - > exsp = HAK_SMOOI_TO_OOP ( - 1 ) ;
hak - > nil_process - > exst = HAK_SMOOI_TO_OOP ( - 1 ) ;
2021-06-25 16:07:29 +00:00
/* unusable class stack */
2025-09-02 23:58:15 +09:00
hak - > nil_process - > clsp = HAK_SMOOI_TO_OOP ( - 1 ) ;
hak - > nil_process - > clst = HAK_SMOOI_TO_OOP ( - 1 ) ;
2016-10-04 17:56:28 +00:00
}
2025-09-02 23:58:15 +09:00
if ( ! hak - > processor )
2016-10-04 17:56:28 +00:00
{
2025-09-02 23:58:15 +09:00
/*hak->processor = (hak_oop_process_scheduler_t)hak_allocoopobj(hak, HAK_BRAND_PROCESS_SCHEDULER, HAK_PROCESS_SCHEDULER_NAMED_INSTVARS);*/
hak - > processor = ( hak_oop_process_scheduler_t ) hak_instantiate ( hak , hak - > c_process_scheduler , HAK_NULL , 0 ) ;
if ( HAK_UNLIKELY ( ! hak - > processor ) )
2024-09-12 18:06:12 +09:00
{
2025-09-02 23:58:15 +09:00
const hak_ooch_t * orgmsg = hak_backuperrmsg ( hak ) ;
2025-09-05 10:52:02 +09:00
hak_seterrbfmt ( hak , HAK_ERRNUM ( hak ) ,
2025-09-02 23:58:15 +09:00
" unable to instantiate %O - %js " , hak - > c_process_scheduler - > name , orgmsg ) ;
2024-09-12 18:06:12 +09:00
goto oops ;
}
2025-09-02 23:58:15 +09:00
hak - > processor - > active = hak - > nil_process ;
hak - > processor - > total_count = HAK_SMOOI_TO_OOP ( 0 ) ;
hak - > processor - > runnable . count = HAK_SMOOI_TO_OOP ( 0 ) ;
hak - > processor - > suspended . count = HAK_SMOOI_TO_OOP ( 0 ) ;
2020-12-31 17:48:47 +00:00
2025-09-02 23:58:15 +09:00
/* commit the sp field of the initial active context to hak->sp */
hak - > sp = HAK_OOP_TO_SMOOI ( hak - > processor - > active - > sp ) ;
2016-10-04 17:56:28 +00:00
}
2025-09-02 23:58:15 +09:00
/* TODO: move this initialization to hak_init? */
if ( hak_brewcode ( hak , & hak - > code ) < = - 1 ) goto oops ;
2016-09-28 14:40:37 +00:00
2025-09-02 23:58:15 +09:00
hak - > p . e = hak - > _nil ;
2016-09-28 14:40:37 +00:00
return 0 ;
2024-03-08 00:23:52 +09:00
oops :
return - 1 ;
2016-09-28 14:40:37 +00:00
}
2021-01-17 17:45:39 +00:00