New VM.
[bpt/guile.git] / src / programs.c
CommitLineData
17e90c5e
KN
1/* Copyright (C) 2000 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 "instructions.h"
44#include "programs.h"
45#include "vm.h"
46
47\f
48scm_bits_t scm_tc16_program;
49
50static SCM zero_vector;
51
52SCM
53scm_c_make_program (void *addr, size_t size, SCM holder)
54#define FUNC_NAME "scm_c_make_program"
55{
56 struct scm_program *p = SCM_MUST_MALLOC (sizeof (struct scm_program));
57 p->size = size;
58 p->nargs = 0;
59 p->nrest = 0;
60 p->nlocs = 0;
61 p->meta = SCM_EOL;
62 p->objs = zero_vector;
63 p->external = SCM_EOL;
64 p->holder = holder;
65
66 /* If nobody holds bytecode's address, then allocate a new memory */
67 if (SCM_FALSEP (p->holder))
68 p->base = SCM_MUST_MALLOC (size);
69 else
70 p->base = addr;
71
72 SCM_RETURN_NEWSMOB (scm_tc16_program, p);
73}
74#undef FUNC_NAME
75
76SCM
77scm_c_make_vclosure (SCM program, SCM external)
78{
79 struct scm_program *p;
80 struct scm_program *q = SCM_PROGRAM_DATA (program);
81 SCM prog = scm_c_make_program (q->base, q->size, program);
82 p = SCM_PROGRAM_DATA (prog);
83 p->nargs = q->nargs;
84 p->nrest = q->nrest;
85 p->nlocs = q->nlocs;
86 p->meta = q->meta;
87 p->objs = q->objs;
88 p->external = external;
89 return prog;
90}
91
92static SCM
93program_mark (SCM obj)
94{
95 struct scm_program *p = SCM_PROGRAM_DATA (obj);
96 scm_gc_mark (p->meta);
97 scm_gc_mark (p->objs);
98 scm_gc_mark (p->external);
99 return p->holder;
100}
101
102static scm_sizet
103program_free (SCM obj)
104{
105 struct scm_program *p = SCM_PROGRAM_DATA (obj);
106 scm_sizet size = (sizeof (struct scm_program));
107 if (SCM_FALSEP (p->holder))
108 {
109 size += p->size;
110 scm_must_free (p->base);
111 }
112 scm_must_free (p);
113 return size;
114}
115
116static int
117program_print (SCM obj, SCM port, scm_print_state *pstate)
118{
119 scm_puts ("#<program 0x", port);
120 scm_intprint ((long) SCM_PROGRAM_BASE (obj), 16, port);
121 scm_putc ('>', port);
122 return 1;
123}
124
125static SCM
126program_apply (SCM program, SCM args)
127{
128 return scm_vm_apply (scm_make_vm (), program, args);
129}
130
131\f
132/*
133 * Scheme interface
134 */
135
136SCM_DEFINE (scm_program_p, "program?", 1, 0, 0,
137 (SCM obj),
138 "")
139#define FUNC_NAME s_scm_program_p
140{
141 return SCM_BOOL (SCM_PROGRAM_P (obj));
142}
143#undef FUNC_NAME
144
145SCM_DEFINE (scm_program_arity, "program-arity", 1, 0, 0,
146 (SCM program),
147 "")
148#define FUNC_NAME s_scm_program_arity
149{
150 SCM_VALIDATE_PROGRAM (1, program);
151 return SCM_LIST3 (SCM_MAKINUM (SCM_PROGRAM_NARGS (program)),
152 SCM_MAKINUM (SCM_PROGRAM_NREST (program)),
153 SCM_MAKINUM (SCM_PROGRAM_NLOCS (program)));
154}
155#undef FUNC_NAME
156
157SCM_DEFINE (scm_program_objects, "program-objects", 1, 0, 0,
158 (SCM program),
159 "")
160#define FUNC_NAME s_scm_program_objects
161{
162 SCM_VALIDATE_PROGRAM (1, program);
163 return SCM_PROGRAM_OBJS (program);
164}
165#undef FUNC_NAME
166
167SCM_DEFINE (scm_program_external, "program-external", 1, 0, 0,
168 (SCM program),
169 "")
170#define FUNC_NAME s_scm_program_external
171{
172 SCM_VALIDATE_PROGRAM (1, program);
173 return SCM_PROGRAM_EXTERNAL (program);
174}
175#undef FUNC_NAME
176
177SCM_DEFINE (scm_program_bytecode, "program-bytecode", 1, 0, 0,
178 (SCM program),
179 "")
180#define FUNC_NAME s_scm_program_bytecode
181{
182 SCM_VALIDATE_PROGRAM (1, program);
183 return scm_makfromstr (SCM_PROGRAM_BASE (program),
184 SCM_PROGRAM_SIZE (program), 0);
185}
186#undef FUNC_NAME
187
188\f
189void
190scm_init_programs (void)
191{
192 zero_vector = scm_permanent_object (scm_c_make_vector (0, SCM_BOOL_F));
193
194 scm_tc16_program = scm_make_smob_type ("program", 0);
195 scm_set_smob_mark (scm_tc16_program, program_mark);
196 scm_set_smob_free (scm_tc16_program, program_free);
197 scm_set_smob_print (scm_tc16_program, program_print);
198 scm_set_smob_apply (scm_tc16_program, program_apply, 0, 0, 1);
199
200#ifndef SCM_MAGIC_SNARFER
201#include "programs.x"
202#endif
203}
204
205/*
206 Local Variables:
207 c-file-style: "gnu"
208 End:
209*/