~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to o/cmpaux.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
 
3
 
 
4
This file is part of GNU Common Lisp, herein referred to as GCL
 
5
 
 
6
GCL is free software; you can redistribute it and/or modify it under
 
7
the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
 
8
the Free Software Foundation; either version 2, or (at your option)
 
9
any later version.
 
10
 
 
11
GCL is distributed in the hope that it will be useful, but WITHOUT
 
12
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
13
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
 
14
License for more details.
 
15
 
 
16
You should have received a copy of the GNU Library General Public License 
 
17
along with GCL; see the file COPYING.  If not, write to the Free Software
 
18
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 
 
20
*/
 
21
 
 
22
/*
 
23
 
 
24
        cmpaux.c
 
25
*/
 
26
 
 
27
#include <string.h>
 
28
#include <signal.h>
 
29
#include <stdlib.h>
 
30
#define NEED_MP_H
 
31
#include "include.h"
 
32
#define dcheck_type(a,b) check_type(a,b)
 
33
 
 
34
DEFUNO_NEW("SPECIALP",object,fSspecialp,SI
 
35
       ,1,1,NONE,OO,OO,OO,OO,void,siLspecialp,(object sym),"")
 
36
{
 
37
        /* 1 args */
 
38
        if (type_of(sym) == t_symbol &&
 
39
            (enum stype)sym->s.s_stype == stp_special)
 
40
                sym = Ct;
 
41
        else
 
42
                sym = Cnil;
 
43
        RETURN1(sym);
 
44
}
 
45
 
 
46
DEF_ORDINARY("DEBUG",sSdebug,SI,"");
 
47
 
 
48
DEFUN_NEW("DEFVAR1",object,fSdefvar1,SI
 
49
       ,2,3,NONE,OO,OO,OO,OO,(object sym,object val,...),"")
 
50
{       int n=VFUN_NARGS;
 
51
        object doc;
 
52
        va_list ap;
 
53
        { va_start(ap,val);
 
54
          if (n>=3) doc=va_arg(ap,object);else goto LDEFAULT3;
 
55
          goto LEND_VARARG;
 
56
        LDEFAULT3: doc = Cnil;
 
57
        LEND_VARARG: va_end(ap);}
 
58
 
 
59
        CHECK_ARG_RANGE(2,3);
 
60
        if(sym->s.s_dbind==0 && n > 1)
 
61
          sym->s.s_dbind= val;
 
62
        sym->s.s_stype=(short)stp_special;
 
63
        if(n > 2)
 
64
          putprop(sym,doc,sSvariable_documentation);
 
65
        RETURN1(sym);
 
66
      }
 
67
 
 
68
 
 
69
DEFUN_NEW("DEBUG",object,fSdebug,SI
 
70
       ,2,2,NONE,OO,OO,OO,OO,(object sym,object val),"")
 
71
{ /* 2 args */
 
72
  putprop(sym,val,sSdebug);
 
73
  RETURN1(sym);
 
74
}
 
75
 
 
76
 
 
77
DEFUN_NEW("SETVV",object,fSsetvv,SI
 
78
       ,2,2,NONE,OO,OO,OO,OO,(object index,object val),"")
 
79
{ /* 2 args */
 
80
  if(type_of(sSPmemory->s.s_dbind)==t_cfdata)
 
81
  sSPmemory->s.s_dbind->cfd.cfd_self[fix(index)]=val;
 
82
  else FEerror("setvv called outside %init",0);
 
83
  RETURN1(index);
 
84
}
 
85
 
 
86
DEF_ORDINARY("%MEMORY",sSPmemory,SI,"");
 
87
DEF_ORDINARY("%INIT",sSPinit,SI,"");
 
88
 
 
89
/* void Lidentity(void); */
 
90
void
 
91
gcl_init_cmpaux(void)
 
92
{
 
93
 
 
94
 
 
95
        /* real one defined in predlib.lsp, need this for bootstrap */
 
96
/*      make_si_function("WARN-VERSION",Lidentity); */
 
97
        
 
98
}
 
99
 
 
100
  
 
101
/* Now inlined directly by optimizer  */
 
102
/* int */
 
103
/* ifloor(int x, int y) */
 
104
/* { */
 
105
/*   if (y == 0) { */
 
106
/*     FEerror("Zero divizor", 0); */
 
107
/*     return 0; */
 
108
/*   } */
 
109
/*   if (y > 0) { */
 
110
/*     if (x >= 0) */
 
111
/*       return(x/y); */
 
112
/*     else */
 
113
      /* FIXME, deal with possible overflow here*/
 
114
/*       return(-((-x-1))/y-1); */
 
115
/*   } */
 
116
/*   if (x >= 0) */
 
117
      /* FIXME, deal with possible overflow here*/
 
118
/*     return(-((x-1)/(-y))-1); */
 
119
/*   else */
 
120
/*     return((-x)/(-y)); */
 
121
/* } */
 
122
 
 
123
/* int */
 
124
/* imod(int x, int y) */
 
125
/* { */
 
126
/*   return(x - ifloor(x, y)*y); */
 
127
/* } */
 
128
 
 
129
/* static void */
 
130
/* set_VV(object *, int, object); */
 
131
 
 
132
/* static void */
 
133
/* set_VV_data(object *VV, int n, object data, char *start, int size) */
 
134
/* {set_VV(VV,n,data); */
 
135
/*  data->cfd.cfd_start=start; */
 
136
/*  data->cfd.cfd_size = size; */
 
137
/* } */
 
138
 
 
139
/* static void */
 
140
/* set_VV(object *VV, int n, object data) */
 
141
/* { */
 
142
/*      object *p, *q; */
 
143
 
 
144
/*      p = VV; */
 
145
/*      q = data->v.v_self; */
 
146
/*      while (n-- > 0) */
 
147
/*              *p++ = *q++; */
 
148
/*      data->cfd.cfd_self = VV; */
 
149
/* } */
 
150
 
 
151
/*
 
152
        Conversions to C
 
153
*/
 
154
 
 
155
char
 
156
object_to_char(object x)
 
157
{
 
158
        int c=0;
 
159
        switch (type_of(x)) {
 
160
        case t_fixnum:
 
161
                c = fix(x);  break;
 
162
        case t_bignum:
 
163
          {object *to = vs_top;
 
164
          vs_push(x);
 
165
          vs_push(small_fixnum(0xff));
 
166
          Llogand();
 
167
          x = vs_base[0];
 
168
          vs_top = to;
 
169
          c = (char) fix(x);
 
170
          break;
 
171
          }
 
172
        case t_character:
 
173
                c = char_code(x);  break;
 
174
        default:
 
175
                FEerror("~S cannot be coerce to a C char.", 1, x);
 
176
        }
 
177
        return(c);
 
178
}
 
179
 
 
180
int
 
181
object_to_int(object x)
 
182
{
 
183
        int i=0;
 
184
 
 
185
        switch (type_of(x)) {
 
186
        case t_character:
 
187
                i = char_code(x);  break;
 
188
        case t_fixnum:
 
189
                i = fix(x);  break;
 
190
        case t_bignum:
 
191
          i = number_to_double(x);
 
192
          break;
 
193
        case t_ratio:
 
194
                i = number_to_double(x);  break;
 
195
        case t_shortfloat:
 
196
                i = sf(x);  break;
 
197
        case t_longfloat:
 
198
                i = lf(x);  break;
 
199
        default:
 
200
                FEerror("~S cannot be coerce to a C int.", 1, x);
 
201
        }
 
202
        return(i);
 
203
}
 
204
 
 
205
float 
 
206
object_to_float(object x) 
 
207
 
208
        float f=0.0; 
 
209
 
 
210
        switch (type_of(x)) { 
 
211
        case t_character: 
 
212
                f = char_code(x);  break; 
 
213
        case t_fixnum: 
 
214
                f = fix(x);  break; 
 
215
        case t_bignum: 
 
216
        case t_ratio: 
 
217
                f = number_to_double(x);  break; 
 
218
        case t_shortfloat: 
 
219
                f = sf(x);  break; 
 
220
        case t_longfloat: 
 
221
                f = lf(x);  break; 
 
222
        default: 
 
223
                FEerror("~S cannot be coerce to a C float.", 1, x); 
 
224
        } 
 
225
        return(f); 
 
226
 
227
 
 
228
double 
 
229
object_to_double(object x) 
 
230
 
231
        double d=0.0; 
 
232
 
 
233
        switch (type_of(x)) { 
 
234
        case t_character: 
 
235
                d = char_code(x);  break; 
 
236
        case t_fixnum: 
 
237
                d = fix(x);  break; 
 
238
        case t_bignum: 
 
239
        case t_ratio: 
 
240
                d = number_to_double(x);  break; 
 
241
        case t_shortfloat: 
 
242
                d = sf(x);  break; 
 
243
        case t_longfloat: 
 
244
                d = lf(x);  break; 
 
245
        default: 
 
246
                FEerror("~S cannot be coerce to a C double.", 1, x); 
 
247
        } 
 
248
        return(d); 
 
249
 
250
 
 
251
/* this may allocate storage.  The user can prevent this
 
252
   by providing a string will fillpointer < length and
 
253
   have a null character in the fillpointer position. */
 
254
 
 
255
char *
 
256
object_to_string(object x)
 
257
{ unsigned int leng;
 
258
  if (type_of(x)!=t_string) FEwrong_type_argument(sLstring,x);
 
259
  leng= x->st.st_fillp;
 
260
  /* user has thoughtfully provided a null terminated string ! */
 
261
    if (leng > 0 && leng < x->st.st_dim && x->st.st_self[leng]==0)
 
262
    return x->st.st_self;
 
263
  if (x->st.st_dim == leng
 
264
      && ( leng % sizeof(object))
 
265
     )
 
266
    { x->st.st_self[leng] = 0;
 
267
      return x->st.st_self;
 
268
    }
 
269
  else
 
270
    {char *res=malloc(leng+1);
 
271
     bcopy(x->st.st_self,res,leng);
 
272
     res[leng]=0;
 
273
     return res;
 
274
   }}
 
275
 
 
276
 
 
277
/*  typedef int (*FUNC)(); */
 
278
 
 
279
/* perform the actual invocation of the init function durint a fasload
 
280
   init_address is the offset from the place in memory where the code is loaded
 
281
   in.  In most systems this will be 0.
 
282
   The new style fasl vector MUST end with an entry (si::%init f1 f2 .....)
 
283
   where f1 f2 are forms to be evaled.
 
284
*/
 
285
 
 
286
/* #ifdef CLEAR_CACHE */
 
287
/* static int */
 
288
/* sigh(int sig,long code,void *scp, char *addr) { */
 
289
 
 
290
/*     fprintf(stderr,"Received SIGILL at %p\n",((siginfo_t *)code)->si_addr); */
 
291
/*     exit(1); */
 
292
/* } */
 
293
/* #endif */
 
294
 
 
295
void
 
296
call_init(int init_address, object memory, object fasl_vec, FUNC fptr)
 
297
{object form;
 
298
 FUNC at;
 
299
/* #ifdef CLEAR_CACHE */
 
300
/*  static int n; */
 
301
/*  static sigset_t ss; */
 
302
 
 
303
/*  if (!n) { */
 
304
/*      struct sigaction sa={{(void *)sigh},{{0}},SA_RESTART|SA_SIGINFO,NULL}; */
 
305
 
 
306
/*      sigaction(SIGILL,&sa,NULL); */
 
307
/*      sigemptyset(&ss); */
 
308
/*      sigaddset(&ss,SIGILL); */
 
309
/*      sigprocmask(SIG_BLOCK,&ss,NULL); */
 
310
/*      n=1; */
 
311
/*  } */
 
312
/* #endif */
 
313
 
 
314
 
 
315
  check_type(fasl_vec,t_vector);
 
316
  form=(fasl_vec->v.v_self[fasl_vec->v.v_fillp -1]);
 
317
 
 
318
 if (fptr) at = fptr;
 
319
  else 
 
320
 at=(FUNC)(memory->cfd.cfd_start+ init_address );
 
321
 
 
322
#ifdef VERIFY_INIT
 
323
 VERIFY_INIT
 
324
#endif
 
325
   
 
326
 if (type_of(form)==t_cons &&
 
327
     form->c.c_car == sSPinit)
 
328
   {bds_bind(sSPinit,fasl_vec);
 
329
    bds_bind(sSPmemory,memory);
 
330
/* #ifdef CLEAR_CACHE */
 
331
/*     sigprocmask(SIG_UNBLOCK,&ss,NULL); */
 
332
/* #endif */
 
333
    (*at)();
 
334
/* #ifdef CLEAR_CACHE */
 
335
/*     sigprocmask(SIG_BLOCK,&ss,NULL); */
 
336
/* #endif */
 
337
    bds_unwind1;
 
338
    bds_unwind1;
 
339
  }
 
340
 else
 
341
   /* old style three arg init, with all init being done by C code. */
 
342
   {memory->cfd.cfd_self = fasl_vec->v.v_self;
 
343
    memory->cfd.cfd_fillp = fasl_vec->v.v_fillp;
 
344
/* #ifdef CLEAR_CACHE */
 
345
/*     sigprocmask(SIG_UNBLOCK,&ss,NULL); */
 
346
/* #endif */
 
347
    (*at)(memory->cfd.cfd_start, memory->cfd.cfd_size, memory);
 
348
/* #ifdef CLEAR_CACHE */
 
349
/*     sigprocmask(SIG_BLOCK,&ss,NULL); */
 
350
/* #endif */
 
351
}}
 
352
 
 
353
/* statVV is the address of some static storage, which is used by the
 
354
   cfunctions to refer to global variables,..
 
355
   Initially it holds a number of addresses.   We also have sSPmemory->s.s_dbind
 
356
   which points to a vector  of lisp constants.   We switch the
 
357
   fn addresses and lisp constants.   We follow this convoluted path,
 
358
   since we don't wish to have a separate block of data space allocated
 
359
   in the object module simply to temporarily have access to the
 
360
   actual function addresses during load. 
 
361
 
 
362
   */
 
363
 
 
364
void
 
365
do_init(object *statVV)
 
366
{object fasl_vec=sSPinit->s.s_dbind;
 
367
 object data = sSPmemory->s.s_dbind;
 
368
 {object *p,*q,y;
 
369
  int n=fasl_vec->v.v_fillp -1;
 
370
  int i;
 
371
  object form;
 
372
  check_type(fasl_vec,t_vector);
 
373
  form = fasl_vec->v.v_self[n];
 
374
  dcheck_type(form,t_cons);  
 
375
 
 
376
 
 
377
  /* switch SPinit to point to a vector of function addresses */
 
378
     
 
379
  fasl_vec->v.v_elttype = aet_fix;
 
380
  fasl_vec->v.v_dim *= (sizeof(object)/sizeof(fixnum));
 
381
  fasl_vec->v.v_fillp *= (sizeof(object)/sizeof(fixnum));
 
382
  
 
383
  /* swap the entries */
 
384
  p = fasl_vec->v.v_self;
 
385
 
 
386
  q = statVV;
 
387
  for (i=0; i<=n ; i++)
 
388
    {  y = *p;
 
389
     *p++ = *q;
 
390
     *q++ = y;
 
391
     }
 
392
  
 
393
  data->cfd.cfd_self = statVV;
 
394
  data->cfd.cfd_fillp= n+1;
 
395
  statVV[n] = data;
 
396
  
 
397
 
 
398
  /* So now the fasl_vec is a fixnum array, containing random addresses of c
 
399
     functions and other stuff from the compiled code.
 
400
     data is what it wants to be for the init
 
401
  */
 
402
  /* Now we can run the forms f1 f2 in form= (%init f1 f2 ...) */
 
403
 
 
404
  form=form->c.c_cdr;
 
405
  {object *top=vs_top;
 
406
   
 
407
   for(i=0 ; i< form->v.v_fillp; i++)
 
408
     { 
 
409
       eval(form->v.v_self[i]);
 
410
       vs_top=top;
 
411
     }
 
412
 }
 
413
}}
 
414
 
 
415
#ifdef DOS
 
416
#define PATH_LIM 8
 
417
#define TYPE_LIM 3
 
418
char *
 
419
fix_path_string_dos(s)
 
420
char *s;
 
421
{char buf[200];
 
422
 char *p=s,*q=buf;
 
423
 int i=PATH_LIM;        
 
424
 while(*p)
 
425
  {
 
426
   if (IS_DIR_SEPARATOR(*p)) i=PATH_LIM;
 
427
    else if (*p == '.') i = TYPE_LIM;
 
428
    else i--;
 
429
   if (i>=0) *q++ = *p;
 
430
   p++;}
 
431
 *q = 0;
 
432
 strcpy(s,buf);
 
433
 return s;
 
434
}
 
435
        
 
436
#endif
 
437
 
 
438
void
 
439
gcl_init_or_load1(void (*fn)(void),char *file)
 
440
{int n=strlen(file);
 
441
 if (file[n-1]=='o')
 
442
   { object memory;
 
443
     object fasl_data;
 
444
     file=FIX_PATH_STRING(file);
 
445
 
 
446
     memory=alloc_object(t_cfdata);
 
447
     memory->cfd.cfd_self=0;
 
448
     memory->cfd.cfd_fillp=0;
 
449
     memory->cfd.cfd_size = 0;
 
450
     printf("Initializing %s\n",file); fflush(stdout);
 
451
     fasl_data = read_fasl_data(file);
 
452
     memory->cfd.cfd_start= (char *)fn;
 
453
     call_init(0,memory,fasl_data,0);
 
454
  }
 
455
 else
 
456
  {printf("loading %s\n",file); fflush(stdout);  load(file);}
 
457
}
 
458
 
 
459
DEFUN_NEW("INIT-CMP-ANON", object, fSinit_cmp_anon, SI, 0, 0,
 
460
       NONE, OO, OO, OO,OO,(void),
 
461
      "Initialize previously compiled and linked anonymous function from the \
 
462
.text section of the running executable.  This function is inherently \
 
463
dangerous, and is meant as a work-around to facilitate the production \
 
464
of an ansi GCL image on systems which must currently link using \
 
465
dlopen.  On such systems, it is imposible to compile and load \
 
466
anonymous functions as part of the initialization sequence of the lisp \
 
467
image, as is done in pcl, and preserve that function across a \
 
468
save-system call.  The approach here is to provide a flag to GCL's \
 
469
compile function which will direct the algorithm to forgo \
 
470
recompilation and loading in favor of initialization via this \
 
471
function.")
 
472
{
 
473
 
 
474
  int i;
 
475
 
 
476
  i=gcl_init_cmp_anon();
 
477
  if (i<0) 
 
478
    FEerror("No such anonymous function",0);
 
479
 
 
480
  return i ? Cnil : Ct;
 
481
 
 
482
}