*** empty log message ***
[bpt/guile.git] / src / objcodes.c
CommitLineData
8f5cfc81
KN
1/* Copyright (C) 2001 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
41
42#include <string.h>
43#include <fcntl.h>
44#include <unistd.h>
45#include <sys/mman.h>
46#include <sys/stat.h>
47#include <sys/types.h>
48
49#include "programs.h"
50#include "objcodes.h"
51
52#define OBJCODE_COOKIE "GOOF-0.5"
53
54\f
55/*
56 * Objcode type
57 */
58
59scm_bits_t scm_tc16_objcode;
60
61static SCM
62make_objcode (size_t size)
63#define FUNC_NAME "make_objcode"
64{
65 struct scm_objcode *p = SCM_MUST_MALLOC (sizeof (struct scm_objcode));
66 p->size = size;
67 p->base = SCM_MUST_MALLOC (size);
68 p->fd = -1;
69 SCM_RETURN_NEWSMOB (scm_tc16_objcode, p);
70}
71#undef FUNC_NAME
72
73static SCM
74make_objcode_by_mmap (int fd)
75#define FUNC_NAME "make_objcode_by_mmap"
76{
77 int ret;
78 char *addr;
79 struct stat st;
80 struct scm_objcode *p;
81
82 ret = fstat (fd, &st);
83 if (ret < 0) SCM_SYSERROR;
84
85 addr = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
86 if (addr == MAP_FAILED) SCM_SYSERROR;
87
88 p = SCM_MUST_MALLOC (sizeof (struct scm_objcode));
89 p->size = st.st_size;
90 p->base = addr;
91 p->fd = fd;
92 SCM_RETURN_NEWSMOB (scm_tc16_objcode, p);
93}
94#undef FUNC_NAME
95
96static scm_sizet
97objcode_free (SCM obj)
98#define FUNC_NAME "objcode_free"
99{
100 size_t size = (sizeof (struct scm_objcode));
101 struct scm_objcode *p = SCM_OBJCODE_DATA (obj);
102
103 if (p->fd >= 0)
104 {
105 int rv;
106 rv = munmap (p->base, p->size);
107 if (rv < 0) SCM_SYSERROR;
108 rv = close (p->fd);
109 if (rv < 0) SCM_SYSERROR;
110 }
111 else
112 {
113 size += p->size;
114 scm_must_free (p->base);
115 }
116
117 scm_must_free (p);
118 return size;
119}
120#undef FUNC_NAME
121
122\f
123/*
124 * Scheme interface
125 */
126
127SCM_DEFINE (scm_objcode_p, "objcode?", 1, 0, 0,
128 (SCM obj),
129 "")
130#define FUNC_NAME s_scm_objcode_p
131{
132 return SCM_BOOL (SCM_OBJCODE_P (obj));
133}
134#undef FUNC_NAME
135
136SCM_DEFINE (scm_bytecode_to_objcode, "bytecode->objcode", 3, 0, 0,
137 (SCM bytecode, SCM nlocs, SCM nexts),
138 "")
139#define FUNC_NAME s_scm_bytecode_to_objcode
140{
141 size_t size;
142 char *base;
143 SCM objcode;
144
145 SCM_VALIDATE_STRING (1, bytecode);
146 SCM_VALIDATE_INUM (2, nlocs);
147 SCM_VALIDATE_INUM (3, nexts);
148
149 size = SCM_STRING_LENGTH (bytecode) + 10;
150 objcode = make_objcode (size);
151 base = SCM_OBJCODE_BASE (objcode);
152
153 memcpy (base, OBJCODE_COOKIE, 8);
154 base[8] = SCM_INUM (nlocs);
155 base[9] = SCM_INUM (nexts);
156 memcpy (base + 10, SCM_STRING_CHARS (bytecode), size - 10);
157 return objcode;
158}
159#undef FUNC_NAME
160
161SCM_DEFINE (scm_load_objcode, "load-objcode", 1, 0, 0,
162 (SCM file),
163 "")
164#define FUNC_NAME s_scm_load_objcode
165{
166 int fd;
167
168 SCM_VALIDATE_STRING (1, file);
169
170 fd = open (SCM_STRING_CHARS (file), O_RDONLY);
171 if (fd < 0) SCM_SYSERROR;
172
173 return make_objcode_by_mmap (fd);
174}
175#undef FUNC_NAME
176
177SCM_DEFINE (scm_objcode_to_string, "objcode->string", 1, 0, 0,
178 (SCM objcode),
179 "")
180#define FUNC_NAME s_scm_objcode_to_string
181{
182 SCM_VALIDATE_OBJCODE (1, objcode);
183 return scm_makfromstr (SCM_OBJCODE_BASE (objcode),
184 SCM_OBJCODE_SIZE (objcode),
185 0);
186}
187#undef FUNC_NAME
188
189SCM_DEFINE (scm_objcode_to_program, "objcode->program", 1, 0, 0,
190 (SCM objcode),
191 "")
192#define FUNC_NAME s_scm_objcode_to_program
193{
194 SCM prog;
195 size_t size;
196 char *base;
ac99cb0c 197 struct scm_program *p;
8f5cfc81
KN
198
199 SCM_VALIDATE_OBJCODE (1, objcode);
200
201 base = SCM_OBJCODE_BASE (objcode);
202 size = SCM_OBJCODE_SIZE (objcode);
203 prog = scm_c_make_program (base + 10, size - 10, objcode);
ac99cb0c
KN
204 p = SCM_PROGRAM_DATA (prog);
205 p->nlocs = base[8];
206 p->nexts = base[9];
8f5cfc81
KN
207 return prog;
208}
209#undef FUNC_NAME
210
211\f
212void
213scm_init_objcodes (void)
214{
215 scm_tc16_objcode = scm_make_smob_type ("objcode", 0);
216 scm_set_smob_free (scm_tc16_objcode, objcode_free);
217
218#ifndef SCM_MAGIC_SNARFER
219#include "objcodes.x"
220#endif
221}
222
223/*
224 Local Variables:
225 c-file-style: "gnu"
226 End:
227*/