Patch title: Release 94 bulk changes
Abstract:
File: /pliant/language/declare/struct.c
Key:
    Removed line
    Added line
// Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation.
// 
// 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
// version 2 along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

/*
abstract
  text "This program defines all the data types and constants used in the C part of the Pliant compiler kernel."
*/

#define pliant_release_number  93
#define pliant_release_number  94
// #if defined(_LINUX_)
//   #define _EXPERIMENTAL_
// #endif
#define _EXPERIMENTAL_
// #define _CHECK_STACK_

#if defined(_LINUX_)
  #define computer_os_kernel          "Linux"
#elif defined(_FreeBSD_)
  #define computer_os_kernel          "FreeBSD"
#elif defined(_OpenBSD_)
  #define computer_os_kernel          "OpenBSD"
#elif defined(_POSIX_)
  #define computer_os_kernel          "UNKNOWN-POSIX"
#elif defined(_OS2_)
  #define computer_os_kernel          "OS/2"
#elif defined(_WIN32_)
  #define computer_os_kernel          "Windows"
#else
  #error Operating system is undefined or unknown!
#endif

#if defined(_LINUX_API_)
  #define computer_os_api             "linux"
#elif defined(_POSIX_API_)
  #define computer_os_api             "posix"
#elif defined(_WIN32_API_)
  #define computer_os_api             "win32"
#elif defined(_OS2_API_)
  #define computer_os_api             "os2"
#else
  #error Kernel API is undefined or unknown!
#endif

#ifdef _i386_
  #define computer_processor_name     "i386"
  #define _32BITS_
#endif
#ifdef _ALPHA_
  #define computer_processor_name     "alpha"
  #define _64BITS_
#endif
#ifdef _BYTECODE_
  #define computer_processor_name     "bytecode"
#endif

#ifdef _STATIC_
  #define computer_os_extra_info "static"
#endif
#ifdef _SO1_
  #define computer_os_extra_info "libc5"
#endif
#ifdef _SO2_
  #define computer_os_extra_info "libc6"
#endif

#ifdef computer_os_extra_info
  #define _OS_EXTRA_INFO_
#else
  #define computer_os_extra_info ""
#endif

#ifdef computer_processor_extra_info
  #define _PROCESSOR_EXTRA_INFO_
#else
  #define computer_processor_extra_info ""
#endif


#ifdef _i386_
  #define Register_EAX  0x00
  #define Register_ECX  0x01
  #define Register_EDX  0x02
  #define Register_EBX  0x03
  #define Register_ESP  0x04
  #define Register_EBP  0x05
  #define Register_ESI  0x06
  #define Register_EDI  0x07
  #define nb_register         8
  #define nb_8_register_sets  4
  // this is to allocate an integer size area rather than a single byte area
  #define memory_page_size    4096
#endif
#ifdef _ALPHA_
  #define nb_register         31
  #define nb_8_register_sets  4
  #define memory_page_size    8192
#endif
#ifdef _BYTECODE_
  #define nb_register         31
  #define nb_8_register_sets  4
  #define memory_page_size    8192
#endif

#ifdef _MSVC_
  #pragma warning( disable : 4146 )
  #pragma warning( disable : 4090 )
  #pragma warning( disable : 4024 )
  #pragma warning( disable : 4101 )
  #pragma warning( disable : 4244 )
  #pragma warning( disable : 4018 )
  #pragma warning( disable : 4113 )
#endif

/*****************************************************************************/

/*
doc
  text "Now the ugly macros of Pliant C style ..."
*/

#define sizeof(x) ((Int)sizeof(x))

#define eif(c) else if(c)
#define orif(c) } else if(c) {
#define other } else {

#ifdef _CHECK_
  #define _check_(x) x
  #define _nocheck_(x)
#else
  #define _check_(x)
  #define _nocheck_(x) x
#endif

#define field_offset(s,f) ((Int)&((s *)null)->f)
#define struct_from_field(type,field,ptr) ((struct type *)address_translate(ptr, -integer_from_address(&((struct type *)address_from_integer(0))->field) ))


#define PROTOTYPE static
#define FUNCTION static
#define ASM_PROTOTYPE external
#define ASM_INLINE

#if defined(_GCC_) && !defined(_CHECK_)
  #define INLINE inline
#else
  #define INLINE static
  #define inline
#endif
#ifdef _GCC_
  #ifdef _WIN32_
    #define __stdcall __attribute__ ((stdcall, regparm(0)))
    #define _EXTERNAL_ __attribute__ ((stdcall, regparm(0)))
  #else
    #define _EXTERNAL_ __attribute__ ((cdecl, regparm(0)))
  #endif
#else
  #ifdef _WIN32_
    #include <windef.h>
    #define _EXTERNAL_ WINAPI
  #else
    #ifdef _OS2_
      #define _EXTERNAL_ _System
    #else
      #define _EXTERNAL_
    #endif
  #endif
#endif

#define compare_inferior  0x01
#define compare_equal     0x02
#define compare_superior  0x04
#define compare_different 0x08
#define compare_unknown   0x10



/*****************************************************************************/

/*
doc
  text "Now types and constants"
*/

typedef void Void;
typedef int Bool;
typedef int Err;
typedef unsigned char Byte;

#define false 0
#define true 1


#define phase_startup -3
#define phase_restore -2
#define phase_wakeup -1
#define phase_run 0
#define phase_shutdown 1
#define phase_backup 2 
#define phase_exit 3
#define phase_free 4
#define phase_free_objects 4
#define phase_free_types 5
#define phase_free_report 6


/*****************************************************************************/


typedef unsigned char uInt8;
typedef unsigned short uInt16;
typedef unsigned int uInt32;
typedef unsigned long uInt;

typedef signed char Int8;
typedef signed short Int16;
typedef signed int Int32;
typedef signed long Int;

typedef unsigned long Any;


/*****************************************************************************/


typedef Void * Address;

#define null ((Address)0)
#define END  ((Address)-1)


/*****************************************************************************/


typedef unsigned char Char;

struct Str {
  Char *chars;
  Int len2; };

#ifdef _32BITS_
  #define Str_allocated             0x80000000
#endif
#ifdef _64BITS_
  #define Str_allocated             0x8000000000000000
#endif

typedef Void * Arrow;

typedef Int Access;

#define Access_read                 0x0001
#define Access_write                0x0002
#define Access_constant             0x0004

#define Access_byvalue              0x0010
#define Access_mapped               0x0020
#define Access_object               0x0040

#define Access_result_read          0x0100
#define Access_result_write         0x0200
#define Access_result_consistent    0x1000

#define Definition_weak             0x00010000
#define Definition_strong           0x00020000
#define Definition_always           0x00040000

#define Access_was_byvalue          0x00100000
#define Access_auto                 0x00200000
#define Access_force_byaddress      0x00400000

#define Access_nocompile            0x80000000


#define Ar Access_read
#define Aw Access_write
#define Arw (Access_read|Access_write)
#define Arv (Access_read|Access_byvalue)
#define Awv (Access_write|Access_byvalue)
#define Arwv (Access_read|Access_write|Access_byvalue)
#define AwR (Access_write|Access_result_read)
#define AwRW (Access_write|Access_result_read|Access_result_write)
#define AwC (Access_write|Access_result_consistent)
#define AwvR (Access_write|Access_byvalue|Access_result_read)
#define AwvRW (Access_write|Access_byvalue|Access_result_read|Access_result_write)
#define AwvC (Access_write|Access_byvalue|Access_result_consistent)
#define AwmR (Access_write|Access_mapped|Access_result_read)
#define AwmRW (Access_write|Access_mapped|Access_result_read|Access_result_write)
#define AwmC (Access_write|Access_mapped|Access_result_consistent)


struct EntryHeader {
  #ifdef _CHECK_
    struct EntryHeader *next,*previous;
    Int signature;
    Int index;
  #endif
  Int counter;
  struct Type *type; };

#define entry_signature  0xBE31C972


/*****************************************************************************/


#define align_size               8
#define sort_threshold           512
#define first_reserve_step       16*1024*1024
#define reserve_step             256*1024*1024
#define commit_step              64*1024
#define nb_bins                  128
#define nb_8_bins_packets        16

#define _MEMORY_DECOMMIT_
#define _MARK_OBJECTS_

#define previous_chunk_is_inuse    1
#define chunk_is_decomitted        2
#ifdef _MARK_OBJECTS_
  #define chunk_is_object          2
#endif


struct MemoryChunk {
  Int prev_size;
  Int size;
  struct MemoryChunk *next;
  struct MemoryChunk *previous; };

struct MemoryChunk2 {
  struct MemoryChunk chunk;
  Address decomitted_address;
  Int decomitted_size; };

struct MemoryChunkBin {
  struct MemoryChunkBin *first;
  struct MemoryChunkBin *last; };

struct MemoryArea {
  Address address;
  Int size;
  Int consumed; };

struct MemoryPool {
  struct MemoryChunkBin bins[nb_bins];
  Byte noempty_bins[nb_8_bins_packets];
  struct MemoryArea areas[16];
  Int nb_area;
  struct MemoryPool *next;
  Int semaphore; };


/*****************************************************************************/


struct List {
  struct ListNode *first;
  struct ListNode *last; };

struct ListNode {
  struct ListNode *next;
  struct ListNode *previous;
  Arrow reference; };


struct Array {
  Arrow *references;
  Int nb; };


struct Dictionary {
  struct DictNode **table;
  uInt32 hashsize;
  Int count; };

struct DictNode {
  struct DictNode *next;
  struct Str label;
  Arrow object; };

struct DictNode2 {
  struct DictNode *next;
  struct Str label;
  Arrow object;
  struct Module *module; }; // P

#ifdef _32BITS_
  #define Dict_frozen 0x80000000
#endif
#ifdef _64BITS_
  #define Dict_frozen 0x8000000000000000
#endif


struct Relation {
  struct RelationNode **table;
  uInt32 hashsize;
  Int count; 
  Int flags; };

struct RelationNode {
  struct RelationNode *next;
  Address address1,address2;
  Arrow reference; };


/*****************************************************************************/


struct Module {
  Int flags;
  //
  struct Relation visibles;
  struct List submodules;
  struct Module *external;
  struct ModuleNode *first_rewindable_node;
  //
  struct Str *name;
  struct Dictionary properties;
  struct Module *parent;
  struct List scope; };

struct ModuleNode {
  struct ModuleNode *next_rewindable_node;
  uInt32 key;
  Arrow object; };

struct ListingPosition {
  struct Str *module;
  unsigned short line,column; };
 
struct ListingPositions {
  Int ptr;
  Int nb; };
 


#define Module_flag_absolutepath 0x01
#define Module_flag_external     0x02
#define Module_flag_submodule    0x04
#define Module_flag_public       0x08
#define Module_flag_blackhole    0x10
#define Module_flag_ring         0x20


/*****************************************************************************/


struct Argument {
  struct Type *type;  // R
  Int where;
  union {
    Arrow constant;
    Int cpu_register;
    struct {
      struct Argument *pointer;
      Int offset; } indirect;
    Int possible_registers; } u;
  struct Str name;
  struct Dictionary properties;
  struct List requires;
  /* optimizing fields */
  struct Instruction *first_instruction,*last_instruction;
  Address user_field; };

// logical definition
#define Argument_undefined  0
#define Argument_constant   1
#define Argument_register   2
#define Argument_indirect   3
#define Argument_local      4
#define Argument_a_register 5


struct Argument2 {
  struct Argument *argument;
  Int access; };


/*****************************************************************************/


struct Instruction {
  struct Instruction *next_instruction; // R
  struct Instruction *previous_instruction; // P
  struct Function *function; // R
  struct Array arguments; // of Argument
  struct Instruction *jump;
  struct Instruction *nested_with;
  struct ListingPositions position;
  struct Dictionary properties;
  /* optimizing fields */
  Int section,order,stackdelta;
  struct List backward_jumps;
  Address user_field; };

#define Section_header      0
#define Section_build      1
#define Section_initialize  2
#define Section_body        3
#define Section_terminate   4
#define Section_destroy     5
#define Section_tail        6
#define Section_outside     7
#define Section_nb          8

struct GeneratorContext {
  struct Instruction *first_instruction; // R
  struct Instruction *last_instruction; // P
  struct List arguments;
  struct Dictionary locals;
  struct Argument *registers[nb_register]; // R
  struct Instruction *sections[Section_nb];
  struct Function *function;
  struct Module *module; };

typedef Void (*GeneratorContextBeginPrototype)(struct GeneratorContext *gc,struct Str *section,struct Function *function);
typedef Void (*GeneratorContextEndPrototype)(struct GeneratorContext *gc,struct Str *section,struct Function *function);


/*****************************************************************************/


// typedef Void (*FunctionMacroPrototype)(struct Expression *expression);
typedef Void (*FunctionAssemblyPrototype)(struct Instruction *instruction,struct GeneratorContext *gc);
typedef Void (*FunctionBinaryPrototype)(struct Instruction *instruction,struct Function *function);
// return used temporary registers


struct Function {
  Address exe;
  Int exe_size;
  Int flags;
  Int definition;

  struct FunctionPrototype *arguments; // of Argument
  Int nb_arg,nb_argres;
  Byte modify_registers[nb_8_register_sets]; Int stack_grow;
  Int generic_index;
  struct Str name;
  struct ListingPosition position;
  struct Dictionary properties;

  struct Module *extra_module;
  struct List inline_instructions;
  struct Function *generate_assembly; // R
  struct Function *generate_binary;   // R
  Arrow externals;

  struct Function *next_function;
  struct Function *previous_function;
  Int profiler_counter; };

#define Function_flag_allocated_exe          0x0001
#define Function_flag_prototype_terminated   0x0002
#define Function_flag_under_construction     0x0004
#define Function_flag_later                  0x0008

#define Function_flag_varargs                0x0010
#define Function_flag_external               0x0020
#define Function_flag_kernel                 0x0040
#define Function_flag_generic                0x0080
#define Function_flag_indirect               0x0100
#define Function_flag_pliant_code_generator  0x0200

#define Function_flag_inline_instructions    0x0400
#define Function_flag_inline_binary          0x0800

#define Function_flag_explicit               0x0000
#define Function_flag_implicit               0x1000
#define Function_flag_extension              0x2000
#define Function_flag_reduction              0x4000
#define Function_flag_hidden                 0x8000

#define Function_flag_copy                   0x00010000
#define Function_flag_allow_shared_result    0x00020000
#define Function_flag_may_generate_error     0x00040000
#define Function_flag_has_side_effects       0x00080000
#define Function_flag_has_no_side_effect     0x00100000

#define Function_flag_push_reversed          0x00200000
#define Function_flag_modify_call_registers  0x00400000
#define Function_flag_not_popped             0x00800000

#define Function_flag_ro_byvalue             0x01000000
#define Function_flag_wo_byvalue             0x02000000
#define Function_flag_rw_byvalue             0x04000000
#define Function_flag_result_byvalue         0x08000000
#define Function_flag_byvalue_result_first   0x10000000
#define Function_flag_byaddress_result_first 0x20000000
#define Function_flag_mapped_result_first    0x40000000

#define Function_flag_simulate               0x80000000


struct FunctionPrototype {
  struct Type *type;
  Access access;
  Int cpu_register; // -1 = first_pushed, -2 = second pushed
  Int maps;
  Arrow default_value;
  struct Str name;
  struct Dictionary properties;
  struct Argument *inline_argument; }; // R


struct FunctionExternal {
  Int code_offset;
  Arrow to; };

struct FunctionUse {
  Arrow in;
  Int code_offset; };

struct FunctionName {
  struct Str dll_name;
  struct Str function_name; };


struct CompilingRules {
  Int flags;
  Int *call_registers;
  Int nb_call_registers;
  Int *can_modify_registers;
  Int nb_can_modify_registers;
  Int *might_modify_registers;
  Int nb_might_modify_registers;
  Int *return_registers;
  Int nb_return_registers; };

#define Compile_test   1
#define Compile_method 2


struct LocalVariable {
  struct Str name;
  struct Function *function;
  struct Argument *body; // R
  Int access; };


struct GlobalVariable {
  struct Str name;
  struct ListingPosition position;
  Arrow variable;
  Access access; };


/*****************************************************************************/


struct DelayedAction {
  struct Function *function;
  Arrow parameter; };

typedef Void (*WakeupActionPrototype)(Address parameter);
typedef Void (*ShutdownActionPrototype)(Address parameter);
typedef Void (*BackupActionPrototype)(Address parameter,Any file_handle);
typedef Void (*RestoreActionPrototype)(Address parameter,Any file_handle);
typedef Void (*ExitActionPrototype)(Address parameter);


struct BacktrackingAction {
  struct Function *function;
  Arrow parameter; };

struct BacktrackingDefinition {
  struct Str name;
  Arrow object; };


/*****************************************************************************/


struct GenericIndex {
  Int level;
  struct List types; };


struct TypeGenericalMethod {
  Address exe;
  struct Function *function; }; // R


struct Type {
  _check_( Int signature; )
  Int flags;
  Int size;

  struct TypeField *fields;
  Int nb_field;

  struct Str name;
  struct ListingPosition position;
  struct Dictionary properties;

  Int generic_level;
  struct List maybe;

  _check_( Int objects_counter; )

  struct TypeGenericalMethod generic_methods[1]; };


typedef Void (*TypeCreatePrototype)(Address object);
typedef Void (*TypeDestroyPrototype)(Address object);
typedef Void (*TypeCopyPrototype)(Address src,Address dest);
// non recursive copy
// typedef Void (*TypeCompilePrototype)(Address object,struct Expression *expression,Int access);
typedef Void (*TypeCreateHookPrototype)(struct Type *type);
typedef Void (*TypeDestroyHookPrototype)(struct Type *type);


struct TypeField {
  struct Type *type;  // R
  Int offset;
  Arrow initial_value;
  struct Str name; 
  struct Dictionary properties; };

#define Type_flag_atomic         0x0001      // can be stored in a register
#define Type_flag_scalar         0x0002      // does not need to be initialized or destroyed
#define Type_flag_later          0x0004
#define Type_flag_packed         0x0008
#define Type_flag_do_not_copy    0x0010      // never copy instances, always use references
#define Type_flag_mapper         0x0020      // used to map objects
#define Type_flag_non_universal  0x0040
#define Type_flag_grow           0x0080      // 'maybe' method will grow the type
#define Type_flag_direct_build   0x0100      // do not use fields to build destroy ...
#define Type_flag_direct_destroy 0x0200      // do not use fields to build destroy ...
#define Type_flag_direct_copy    0x0400      // do not use fields to build destroy ...
#define Type_flag_count          0x0800

#define Type_signature       0xF3C287F1


/*****************************************************************************/


struct Expression {
  Arrow value;
  struct Array arguments; // of R Expression
  struct Module *module;  // R
  struct ListingPosition position;
  struct Dictionary properties;
  /**/
  struct List instructions;
  struct Argument *result; Int access; // R Argument
  struct List backtracking;
  /**/
  struct Instruction *last_uncasted_instruction; // R
  struct Argument *uncasted_result; Int uncasted_access; // R
  Int cast_level,cast_flags;
  /**/
  struct ParserOperator *op; // R used to fold at parsing time
  struct Str *closeop; // R used to check openop / closeop consistency at parsing time
  /**/
  struct Str error_message; };

typedef Void (*FunctionMacroPrototype)(struct Expression *expression);
typedef Void (*TypeCompilePrototype)(Address object,Int access,struct Expression *expression);
typedef Void (*FunctionOptimizePrototype)(struct GeneratorContext *gc);

typedef Void (*ExecutionBeginPrototype)(struct Function *function);
typedef Void (*ExecutionEndPrototype)(struct Function *function);


/*****************************************************************************/


struct ParserContext {
  struct List *text; // R  text to be parsed
  struct Module *module;
  struct Str filename; Int delta_y,delta_x; 
  Int y,x; Arrow *current_line; // parser cursor
  struct Expression *current_expr; // pointer to the expression whose arguments are currently beein parsed
  struct Expression *root;
  struct List levels;
  Bool possible_side_effect;
  struct Dictionary locals; };


struct ParserFilter {
  struct Function *function;
  Arrow parameter; };

typedef Void (*ParserFilterPrototype)(struct ParserContext *context,struct Str *line,Address parameter);


struct ParserPending {
  Int y,x;
  struct Function *function; // R
  Arrow parameter; };

typedef Void (*ParserPendingPrototype)(struct ParserContext *context,Address parameter);


struct ParserOperator {
  struct Function *function;
  Arrow parameter;
  Int priority; };

typedef Void (*ParserOperatorPrototype)(struct Array *arguments,Int index,Address parameter);


struct ParserFilterOperatorT1 {
  struct Str name;
  Bool unary;
  struct Str ident;
  Int priority;
  Int nb_before; Arrow before_value;
  Int nb_after; Arrow after_value; };

struct ParserFilterOperatorT2 {
  struct Str openop;
  struct Str closeop;
  struct Str ident; };


typedef Void (*PrecompileRewritePrototype)(struct Expression *expression);
typedef Void (*PostcompileRewritePrototype)(struct Expression *expression);
typedef Void (*FailedtocompileRewritePrototype)(struct Expression *expression);


/*****************************************************************************/


struct ActionRecord {
  struct Str action;
  struct ActionRecord *next; };

struct ErrorRecord {
  Int id;
  Arrow context; 
  struct Str message; 
  Int filter;
  struct ErrorRecord *next; };


#define error_filter_all           (-1)
#define error_filter_none          0

#define error_id_noerror           0
#define error_id_restore           1
#define error_id_parse             2
#define error_id_compile           3
#define error_id_missing           4
#define error_id_multiple          5
#define error_id_mismatch          6
#define error_id_unexpected        7
#define error_id_starvation        8
#define error_id_corrupted         9
#define error_id_memory_violation  10
#define error_id_check             11
#define error_id_os                12
#define error_id_memory_starvation 13
#define error_id_io                14
#define error_id_arithmetic        15
#define error_id_unknown           16

#define error_id_user              17