File: init.c

package info (click to toggle)
rscheme 0.7.2-1.1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 10,672 kB
  • ctags: 12,430
  • sloc: lisp: 37,104; ansic: 29,763; cpp: 2,630; sh: 1,677; makefile: 568; yacc: 202; lex: 175; perl: 33
file content (238 lines) | stat: -rw-r--r-- 5,270 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*-----------------------------------------------------------------*-C-*---
 * File:    handc/runtime/init.c
 *
 *          Copyright (C)1997 Donovan Kolbly <d.kolbly@rscheme.org>
 *          as part of the RScheme project, licensed for free use.
 *          See <http://www.rscheme.org/> for the latest information.
 *
 * File version:     1.17
 * File mod date:    1997.11.29 23:10:48
 * System build:     v0.7.2, 97.12.21
 *
 * Purpose:          RScheme initialization code
 *------------------------------------------------------------------------*/

#include <stdio.h>
#include <signal.h>
#include <string.h>

#include <rscheme.h>
#include <rscheme/regs.h>
#include <rscheme/scheme.h>
#include <rscheme/osglue.h>
#include <rscheme/heapi.h>
#include <rscheme/rlseconf.h>
#include <rscheme/api.h>
#include "intrs.h"

#ifdef TIMEPOINT
void timepoint( int id );
#else
#define timepoint( id ) (void)0
#endif

char *rs_install_dir = NULL;

/* #define DEBUG_0 */

#ifdef STEP_DUMP
extern int do_step_dump;
extern FILE *step_dump_file;
extern const char *step_dump_filename;

void init_step_dump( void )
{
    if (!step_dump_filename)
	step_dump_filename = "stepdump.tra";
    step_dump_file = NULL;
}
#endif

      
static void load_rscheme_globals( obj init_globals )
{
  UINT_32 i, n;
  obj *dest;

  n = SIZEOF_PTR( init_globals );
  if (n > SLOT(NUM_RSCHEME_GLOBALS))
    {
      fprintf( stderr, "warning: %u initial globals supplied (max %u)\n",
	       n / SLOT(1), NUM_RSCHEME_GLOBALS );
      n = SLOT(NUM_RSCHEME_GLOBALS);
    }

  /* note that we skip copying SLOT(0) & SLOT(1).  
     This is because rscheme_global[0] is "boot_image", which is to be
     a pointer to the actual image that was loaded, 
     and rscheme_global[1] is "boot_args", which will
     be initialized to the argv passed to init_scheme()
  */
  dest = rscheme_global+2;
  for (i=SLOT(2); i<n; i+=SLOT(1))
    {
      *dest++ = gvec_read( init_globals, i );
    }
}

static obj prepend_pre_args( obj rest, obj src )
{
  if (PAIR_P(src))
    {
      timepoint( 308 );
      return cons( pair_car( src ), 
		   prepend_pre_args( rest, pair_cdr(src) ) );
    }
  else
    {
      return rest;
    }
}

#ifdef SPEW_LOADED_IMAGE_AS_TEXT

/* steals the GC's word just before the object to record information;
   works at least with the IRC; no other guarantees!
*/

#define FBIT 0x40000000
#define SHOVE(x) (((UINT_32 *)PTR_TO_HDRPTR(x))[-1])
#define SHOVED(x) (SHOVE(x) >= FBIT)

void dump_image_as_text( obj root )
{
  obj *i, *queue_p, *queue;

  FILE *f = fopen( "/tmp/image.txt", "w" );
  if (!f)
    {
      perror( "/tmp/image.txt" );
      exit(1);
    }
  queue = malloc( 200000 * 4 );
  queue_p = queue;

  *queue_p++ = root;
  SHOVE(root) = 0 + FBIT;

  for (i=queue; i<queue_p; i++)
    {
      obj item = *i;

      fprintf( f, "-- %#x <%d> --\n ==> ", item, i-queue );
      fprinto( f, item );
      fprintf( f, "class %#x =? %#x\n", CLASSOF_PTR(item), vector_class );
      fprintf( f, "\n" );
      if (GVEC_P(item))
	{
	  int k;

	  for (k=-SLOT(1); k<SIZEOF_PTR(item); k+=SLOT(1))
	    {
	      obj t = gvec_ref( item, k );

	      if (k < 0)
		fprintf( f, " class = " );
	      else
		fprintf( f, "   [%d] = ", k/SLOT(1) );

	      if (OBJ_ISA_PTR(t))
		{
		  UINT_32 tx;
		  if (SHOVED(t))
		    {
		      tx = SHOVE(t) - FBIT;
		    }
		  else
		    {
		      tx = queue_p - queue;
		      SHOVE(t) = tx + FBIT;
		      *queue_p++ = t;
		    }
		  fprintf( f, "%#x <%d> = ", t, tx );
		}
	      fprinto( f, t );
	      fputc( '\n', f );
	    }
	  fputc( '\n', f );
	}
    }
  fclose(f);
  exit(0);
}
#endif /* SPEW_LOADED_IMAGE_AS_TEXT */

obj init_scheme( int argc, const char **argv,
		 const char *boot_image_path,
		 rs_bool verbose, 
		 struct module_descr **module_tab )
{
  obj start;
  obj args, pre_args;

  timepoint( 300 );
  switch_hw_regs_into_scheme();
  init_regs();
  timepoint( 301 );
  init_linkage( module_tab );
  timepoint( 302 );
  init_runtim( );
  timepoint( 303 );
  
#ifdef STEP_DUMP
  init_step_dump();
#endif /* STEP_DUMP */
  

  /*
   * this initializes the GC as well as loading the initial
   * image (two functions glommed together because somethimes
   * they ARE the same operation)
   */

  pre_args = NIL_OBJ;
  timepoint( 304 );
  boot_image = load_initial_heap( boot_image_path, 
				  &pre_args, 
				  verbose );
  timepoint( 305 );
  
  if (EQ(boot_image,FALSE_OBJ))
    return FALSE_OBJ;
  
  /* so far, we don't actually have any type information; the
     well-known classes have been loaded, but we need to store
     them in the rscheme_globals[] array
     */
  
  load_rscheme_globals( gvec_read( boot_image, SLOT(0) ) );
  timepoint( 306 );
  
  /* now, we have type information... */
#ifdef SPEW_LOADED_IMAGE_AS_TEXT
  dump_image_as_text( boot_image );
#endif /* SPEW_LOADED_IMAGE_AS_TEXT */

  init_os();
  init_math();

  init_interrupts();
  timepoint( 307 );
  
  args = NIL_OBJ;
  while (argc > 0)
    args = cons( make_string( argv[--argc] ), args );
  boot_args = args;

  install_dir = make_string( rs_install_dir ? rs_install_dir : "install" );
  rs_init_c_signals();

  timepoint( 309 );
  
  start = gvec_read( boot_image, SLOT(2) );

  switch_hw_regs_back_to_os();
  timepoint( 310 );
  
  return start;
}