Allow for bind-optionals without alloc-frame
This reduces subr trampoline instruction count for subrs with optional
args.
* libguile/gsubr.c (get_subr_stub_code): Insert bind-optionals
instructions.
(primitive_call_ip): Handle bind-optionals.
* libguile/programs.c (try_parse_arity): Handle bind-optionals.
* libguile/jit.c (struct scm_jit_state)
(compile_call, compile_call_label, compile_tail_call)
(compile_tail_call_label, compile_receive), compile_receive_values)
(compile_shuffle_down, compile_return_values, compile_subr_call)
(compile_foreign_call, compile_continuation_call)
(compile_compose_continuation, compile_abort, compile_assert_nargs_ee)
(compile_assert_nargs_ge, compile_assert_nargs_le)
(compile_alloc_frame, compile_reset_frame, compile_push)
(compile_pop, compile_drop, compile_expand_apply_argument)
(compile_bind_kwargs, compile_bind_rest, compile_bind_optionals)
(compile, compute_mcode): Separately track min and max frame sizes.
2019-06-06 17:26:59 +02:00
|
|
|
|
/* Copyright 1995-2001,2006,2008-2011,2013,2015,2018-2019
|
2018-06-20 20:01:49 +02:00
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
This file is part of Guile.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is free software: you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU Lesser General Public License as published
|
|
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
|
|
Guile 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 Lesser General Public
|
|
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with Guile. If not, see
|
|
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
|
2008-09-13 15:35:27 +02:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
#include <flexmember.h>
|
1996-07-25 22:56:11 +00:00
|
|
|
|
#include <stdio.h>
|
2009-03-08 16:36:14 +01:00
|
|
|
|
#include <stdarg.h>
|
2018-07-29 15:36:07 +02:00
|
|
|
|
#include <string.h>
|
2009-03-08 16:36:14 +01:00
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "foreign.h"
|
|
|
|
|
|
#include "frames.h"
|
|
|
|
|
|
#include "instructions.h"
|
2018-07-29 15:36:07 +02:00
|
|
|
|
#include "jit.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "modules.h"
|
|
|
|
|
|
#include "numbers.h"
|
|
|
|
|
|
#include "private-options.h"
|
|
|
|
|
|
#include "programs.h"
|
|
|
|
|
|
#include "srfi-4.h"
|
|
|
|
|
|
#include "symbols.h"
|
2018-07-29 15:36:07 +02:00
|
|
|
|
#include "threads.h"
|
* backtrace.c, debug.c, debug.h, deprecation.c, eq.c, eval.c
eval.h, gsubr.c, init.c, macros.c, print.c, print.h, read.c,
read.h, stacks.c, symbols.c, throw.c: use private-options.h
* private-options.h: new file: contain hardcoded option
definitions.
2007-01-22 15:14:40 +00:00
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "gsubr.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* gsubr.c
|
|
|
|
|
|
* Provide `gsubrs' -- subrs taking a prescribed number of required, optional,
|
|
|
|
|
|
* and rest arguments.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
/* In July 2018 there were 1140 subrs defined in stock Guile. */
|
|
|
|
|
|
static const size_t expected_subr_count = 1500;
|
|
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
static scm_i_pthread_mutex_t admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
|
|
|
|
|
|
|
static void **subrs = NULL;
|
|
|
|
|
|
static uint32_t next_subr_idx = 0;
|
|
|
|
|
|
static uint32_t subrs_array_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
static uint32_t
|
|
|
|
|
|
alloc_subr_idx (void *subr)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t idx;
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&admin_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
idx = next_subr_idx++;
|
|
|
|
|
|
|
|
|
|
|
|
if (idx > 0xffffff) abort ();
|
|
|
|
|
|
|
|
|
|
|
|
if (idx >= subrs_array_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
void **new_subrs;
|
|
|
|
|
|
|
|
|
|
|
|
if (subrs_array_size)
|
|
|
|
|
|
subrs_array_size *= 2;
|
|
|
|
|
|
else
|
2018-08-06 13:30:50 +02:00
|
|
|
|
subrs_array_size = expected_subr_count;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
|
|
|
|
|
/* Leak this allocation, as code lives as long as the program
|
|
|
|
|
|
does. In the likely case, we only make one malloc for the
|
|
|
|
|
|
program; in the general case it's still O(n) in number of subrs
|
|
|
|
|
|
because of the geometric factor. Use malloc instead of GC
|
|
|
|
|
|
allocations because it's not traceable and not collectable. */
|
|
|
|
|
|
new_subrs = malloc (subrs_array_size * sizeof (void*));
|
|
|
|
|
|
memcpy (new_subrs, subrs, idx * sizeof (void*));
|
|
|
|
|
|
subrs = new_subrs;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
subrs[idx] = subr;
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&admin_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
return idx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
static SCM *names = NULL;
|
|
|
|
|
|
static uint32_t names_array_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
record_subr_name (uint32_t idx, SCM name)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&admin_mutex);
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
if (idx >= names_array_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM *new_names;
|
|
|
|
|
|
uint32_t new_size;
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
if (names_array_size)
|
|
|
|
|
|
new_size = names_array_size * 2;
|
|
|
|
|
|
else
|
2018-08-06 13:30:50 +02:00
|
|
|
|
new_size = expected_subr_count;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
|
|
|
|
|
new_names = SCM_GC_MALLOC (new_size * sizeof (SCM));
|
|
|
|
|
|
memcpy (new_names, names, names_array_size * sizeof (SCM));
|
|
|
|
|
|
while (names_array_size < new_size)
|
|
|
|
|
|
new_names[names_array_size++] = SCM_BOOL_F;
|
|
|
|
|
|
names = new_names;
|
|
|
|
|
|
names_array_size = new_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
names[idx] = name;
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&admin_mutex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
struct code_arena {
|
|
|
|
|
|
struct code_arena *next;
|
|
|
|
|
|
size_t size;
|
|
|
|
|
|
size_t used;
|
|
|
|
|
|
char data[FLEXIBLE_ARRAY_MEMBER];
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static struct code_arena *code_arena = NULL;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
|
|
|
|
|
static size_t
|
|
|
|
|
|
round_up_power_of_two (size_t n, size_t m)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (n + (m-1)) & ~(m-1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
static struct code_arena *
|
|
|
|
|
|
alloc_chunk (size_t size, struct code_arena *next)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Leak the allocation, as we currently don't allow code to be
|
|
|
|
|
|
collected. */
|
|
|
|
|
|
struct code_arena *ret = malloc (FLEXSIZEOF (struct code_arena, data, size));
|
|
|
|
|
|
if (!ret) abort ();
|
|
|
|
|
|
ret->next = next;
|
|
|
|
|
|
ret->size = size;
|
|
|
|
|
|
ret->used = 0;
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
static char *
|
|
|
|
|
|
alloc (size_t byte_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
char *ret;
|
|
|
|
|
|
|
|
|
|
|
|
byte_size = round_up_power_of_two (byte_size, sizeof (void *));
|
|
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&admin_mutex);
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
if (code_arena == NULL || code_arena->size - code_arena->used < byte_size)
|
2018-07-29 15:36:07 +02:00
|
|
|
|
{
|
2018-08-06 13:30:50 +02:00
|
|
|
|
size_t chunk_size;
|
|
|
|
|
|
size_t avg_code_size = 6 * sizeof(uint32_t);
|
|
|
|
|
|
avg_code_size += sizeof (struct scm_jit_function_data);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
chunk_size = expected_subr_count * avg_code_size;
|
|
|
|
|
|
if (chunk_size < byte_size)
|
|
|
|
|
|
chunk_size = byte_size;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
code_arena = alloc_chunk (chunk_size, code_arena);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
ret = &code_arena->data[code_arena->used];
|
|
|
|
|
|
code_arena->used += byte_size;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&admin_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
memset (ret, 0, byte_size);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
uint32_t *
|
|
|
|
|
|
scm_i_alloc_primitive_code_with_instrumentation (size_t uint32_count,
|
|
|
|
|
|
uint32_t **write_ptr)
|
2018-07-29 15:36:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
char *ptr;
|
|
|
|
|
|
uint32_t *ret;
|
|
|
|
|
|
struct scm_jit_function_data *data;
|
|
|
|
|
|
size_t byte_size, padded_byte_size;
|
|
|
|
|
|
|
|
|
|
|
|
/* Reserve space for instrument-entry. */
|
|
|
|
|
|
byte_size = (2 + uint32_count) * sizeof (uint32_t);
|
|
|
|
|
|
padded_byte_size = round_up_power_of_two (byte_size, sizeof (void *));
|
|
|
|
|
|
/* Reserve space for jit data. */
|
|
|
|
|
|
ptr = alloc (padded_byte_size + sizeof (struct scm_jit_function_data));
|
|
|
|
|
|
ret = (uint32_t *) ptr;
|
2018-08-06 13:30:50 +02:00
|
|
|
|
data = (struct scm_jit_function_data*) (ptr + padded_byte_size);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
|
|
|
|
|
ret[0] = SCM_PACK_OP_24 (instrument_entry, 0);
|
|
|
|
|
|
ret[1] = padded_byte_size / 4;
|
|
|
|
|
|
|
|
|
|
|
|
*write_ptr = ret + 2;
|
|
|
|
|
|
|
|
|
|
|
|
data->mcode = NULL;
|
|
|
|
|
|
data->counter = 0;
|
|
|
|
|
|
data->start = -padded_byte_size;
|
|
|
|
|
|
data->end = -(padded_byte_size - byte_size);
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
return ret;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
is_primitive_code (const void *ptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
const char *cptr = ptr;
|
2018-08-06 13:30:50 +02:00
|
|
|
|
int ret = 0;
|
|
|
|
|
|
struct code_arena *arena;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&admin_mutex);
|
2018-08-06 13:30:50 +02:00
|
|
|
|
for (arena = code_arena; arena; arena = arena->next)
|
|
|
|
|
|
if (&arena->data[0] <= cptr && cptr < &arena->data[arena->used])
|
|
|
|
|
|
{
|
|
|
|
|
|
ret = 1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-07-29 15:36:07 +02:00
|
|
|
|
scm_i_pthread_mutex_unlock (&admin_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint32_t *
|
|
|
|
|
|
alloc_subr_code (uint32_t subr_idx, uint32_t code[], size_t code_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t post[3] = { SCM_PACK_OP_24 (subr_call, subr_idx),
|
|
|
|
|
|
SCM_PACK_OP_24 (handle_interrupts, 0),
|
|
|
|
|
|
SCM_PACK_OP_24 (return_values, 0) };
|
|
|
|
|
|
uint32_t *ret, *write;
|
|
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
ret = scm_i_alloc_primitive_code_with_instrumentation (code_size + 3, &write);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
|
|
|
|
|
|
memcpy (write, code, code_size * sizeof (uint32_t));
|
|
|
|
|
|
write += code_size;
|
|
|
|
|
|
memcpy (write, post, 3 * sizeof (uint32_t));
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enum arity_kind {
|
|
|
|
|
|
NULLARY = 0,
|
|
|
|
|
|
REQ = 1,
|
|
|
|
|
|
OPT = 2,
|
|
|
|
|
|
REST = 4,
|
|
|
|
|
|
REQ_OPT = REQ + OPT,
|
|
|
|
|
|
REQ_REST = REQ + REST,
|
|
|
|
|
|
OPT_REST = OPT + REST,
|
|
|
|
|
|
REQ_OPT_REST = REQ + OPT + REST
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
static uint32_t*
|
|
|
|
|
|
get_subr_stub_code (uint32_t subr_idx,
|
|
|
|
|
|
unsigned int nreq, unsigned int nopt, unsigned int rest)
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
{
|
2018-07-29 15:36:07 +02:00
|
|
|
|
enum arity_kind kind = NULLARY;
|
|
|
|
|
|
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
if (SCM_UNLIKELY (rest > 1 || nreq + nopt + rest > 10))
|
|
|
|
|
|
scm_out_of_range ("make-subr", scm_from_uint (nreq + nopt + rest));
|
|
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
if (nreq) kind += REQ;
|
|
|
|
|
|
if (nopt) kind += OPT;
|
|
|
|
|
|
if (rest) kind += REST;
|
|
|
|
|
|
|
|
|
|
|
|
switch (kind)
|
|
|
|
|
|
{
|
|
|
|
|
|
case NULLARY:
|
|
|
|
|
|
case REQ:
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t code[1] = { SCM_PACK_OP_24 (assert_nargs_ee, nreq + 1) };
|
|
|
|
|
|
return alloc_subr_code (subr_idx, code, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
case OPT:
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t code[2] = { SCM_PACK_OP_24 (assert_nargs_le, nopt + 1),
|
Allow for bind-optionals without alloc-frame
This reduces subr trampoline instruction count for subrs with optional
args.
* libguile/gsubr.c (get_subr_stub_code): Insert bind-optionals
instructions.
(primitive_call_ip): Handle bind-optionals.
* libguile/programs.c (try_parse_arity): Handle bind-optionals.
* libguile/jit.c (struct scm_jit_state)
(compile_call, compile_call_label, compile_tail_call)
(compile_tail_call_label, compile_receive), compile_receive_values)
(compile_shuffle_down, compile_return_values, compile_subr_call)
(compile_foreign_call, compile_continuation_call)
(compile_compose_continuation, compile_abort, compile_assert_nargs_ee)
(compile_assert_nargs_ge, compile_assert_nargs_le)
(compile_alloc_frame, compile_reset_frame, compile_push)
(compile_pop, compile_drop, compile_expand_apply_argument)
(compile_bind_kwargs, compile_bind_rest, compile_bind_optionals)
(compile, compute_mcode): Separately track min and max frame sizes.
2019-06-06 17:26:59 +02:00
|
|
|
|
SCM_PACK_OP_24 (bind_optionals, nopt + 1) };
|
2018-07-29 15:36:07 +02:00
|
|
|
|
return alloc_subr_code (subr_idx, code, 2);
|
|
|
|
|
|
}
|
|
|
|
|
|
case REST:
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t code[1] = { SCM_PACK_OP_24 (bind_rest, 1) };
|
|
|
|
|
|
return alloc_subr_code (subr_idx, code, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
case REQ_OPT:
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t code[3] = { SCM_PACK_OP_24 (assert_nargs_ge, nreq + 1),
|
|
|
|
|
|
SCM_PACK_OP_24 (assert_nargs_le, nreq + nopt + 1),
|
Allow for bind-optionals without alloc-frame
This reduces subr trampoline instruction count for subrs with optional
args.
* libguile/gsubr.c (get_subr_stub_code): Insert bind-optionals
instructions.
(primitive_call_ip): Handle bind-optionals.
* libguile/programs.c (try_parse_arity): Handle bind-optionals.
* libguile/jit.c (struct scm_jit_state)
(compile_call, compile_call_label, compile_tail_call)
(compile_tail_call_label, compile_receive), compile_receive_values)
(compile_shuffle_down, compile_return_values, compile_subr_call)
(compile_foreign_call, compile_continuation_call)
(compile_compose_continuation, compile_abort, compile_assert_nargs_ee)
(compile_assert_nargs_ge, compile_assert_nargs_le)
(compile_alloc_frame, compile_reset_frame, compile_push)
(compile_pop, compile_drop, compile_expand_apply_argument)
(compile_bind_kwargs, compile_bind_rest, compile_bind_optionals)
(compile, compute_mcode): Separately track min and max frame sizes.
2019-06-06 17:26:59 +02:00
|
|
|
|
SCM_PACK_OP_24 (bind_optionals, nreq + nopt + 1) };
|
2018-07-29 15:36:07 +02:00
|
|
|
|
return alloc_subr_code (subr_idx, code, 3);
|
|
|
|
|
|
}
|
|
|
|
|
|
case REQ_REST:
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t code[2] = { SCM_PACK_OP_24 (assert_nargs_ge, nreq + 1),
|
|
|
|
|
|
SCM_PACK_OP_24 (bind_rest, nreq + 1) };
|
|
|
|
|
|
return alloc_subr_code (subr_idx, code, 2);
|
|
|
|
|
|
}
|
|
|
|
|
|
case OPT_REST:
|
|
|
|
|
|
{
|
Allow for bind-optionals without alloc-frame
This reduces subr trampoline instruction count for subrs with optional
args.
* libguile/gsubr.c (get_subr_stub_code): Insert bind-optionals
instructions.
(primitive_call_ip): Handle bind-optionals.
* libguile/programs.c (try_parse_arity): Handle bind-optionals.
* libguile/jit.c (struct scm_jit_state)
(compile_call, compile_call_label, compile_tail_call)
(compile_tail_call_label, compile_receive), compile_receive_values)
(compile_shuffle_down, compile_return_values, compile_subr_call)
(compile_foreign_call, compile_continuation_call)
(compile_compose_continuation, compile_abort, compile_assert_nargs_ee)
(compile_assert_nargs_ge, compile_assert_nargs_le)
(compile_alloc_frame, compile_reset_frame, compile_push)
(compile_pop, compile_drop, compile_expand_apply_argument)
(compile_bind_kwargs, compile_bind_rest, compile_bind_optionals)
(compile, compute_mcode): Separately track min and max frame sizes.
2019-06-06 17:26:59 +02:00
|
|
|
|
uint32_t code[2] = { SCM_PACK_OP_24 (bind_optionals, nopt + 1),
|
|
|
|
|
|
SCM_PACK_OP_24 (bind_rest, nopt + 1) };
|
|
|
|
|
|
return alloc_subr_code (subr_idx, code, 2);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
case REQ_OPT_REST:
|
|
|
|
|
|
{
|
Allow for bind-optionals without alloc-frame
This reduces subr trampoline instruction count for subrs with optional
args.
* libguile/gsubr.c (get_subr_stub_code): Insert bind-optionals
instructions.
(primitive_call_ip): Handle bind-optionals.
* libguile/programs.c (try_parse_arity): Handle bind-optionals.
* libguile/jit.c (struct scm_jit_state)
(compile_call, compile_call_label, compile_tail_call)
(compile_tail_call_label, compile_receive), compile_receive_values)
(compile_shuffle_down, compile_return_values, compile_subr_call)
(compile_foreign_call, compile_continuation_call)
(compile_compose_continuation, compile_abort, compile_assert_nargs_ee)
(compile_assert_nargs_ge, compile_assert_nargs_le)
(compile_alloc_frame, compile_reset_frame, compile_push)
(compile_pop, compile_drop, compile_expand_apply_argument)
(compile_bind_kwargs, compile_bind_rest, compile_bind_optionals)
(compile, compute_mcode): Separately track min and max frame sizes.
2019-06-06 17:26:59 +02:00
|
|
|
|
uint32_t code[3] = { SCM_PACK_OP_24 (assert_nargs_ge, nreq + 1),
|
|
|
|
|
|
SCM_PACK_OP_24 (bind_optionals, nreq + nopt + 1),
|
2018-07-29 15:36:07 +02:00
|
|
|
|
SCM_PACK_OP_24 (bind_rest, nreq + nopt + 1) };
|
Allow for bind-optionals without alloc-frame
This reduces subr trampoline instruction count for subrs with optional
args.
* libguile/gsubr.c (get_subr_stub_code): Insert bind-optionals
instructions.
(primitive_call_ip): Handle bind-optionals.
* libguile/programs.c (try_parse_arity): Handle bind-optionals.
* libguile/jit.c (struct scm_jit_state)
(compile_call, compile_call_label, compile_tail_call)
(compile_tail_call_label, compile_receive), compile_receive_values)
(compile_shuffle_down, compile_return_values, compile_subr_call)
(compile_foreign_call, compile_continuation_call)
(compile_compose_continuation, compile_abort, compile_assert_nargs_ee)
(compile_assert_nargs_ge, compile_assert_nargs_le)
(compile_alloc_frame, compile_reset_frame, compile_push)
(compile_pop, compile_drop, compile_expand_apply_argument)
(compile_bind_kwargs, compile_bind_rest, compile_bind_optionals)
(compile, compute_mcode): Separately track min and max frame sizes.
2019-06-06 17:26:59 +02:00
|
|
|
|
return alloc_subr_code (subr_idx, code, 3);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
}
|
2000-12-11 14:48:23 +00:00
|
|
|
|
|
2001-05-20 00:34:10 +00:00
|
|
|
|
static SCM
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
create_subr (int define, const char *name,
|
|
|
|
|
|
unsigned int nreq, unsigned int nopt, unsigned int rest,
|
2018-07-29 15:36:07 +02:00
|
|
|
|
void *fcn, SCM *generic_loc)
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
SCM ret, sname;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
uint32_t idx;
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
scm_t_bits flags;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
scm_t_bits nfree = generic_loc ? 1 : 0;
|
2001-05-20 00:34:10 +00:00
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
idx = alloc_subr_idx (fcn);
|
2011-10-25 17:45:29 +02:00
|
|
|
|
sname = scm_from_utf8_symbol (name);
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
|
2010-01-06 22:16:57 +01:00
|
|
|
|
flags = SCM_F_PROGRAM_IS_PRIMITIVE;
|
|
|
|
|
|
flags |= generic_loc ? SCM_F_PROGRAM_IS_PRIMITIVE_GENERIC : 0;
|
2013-10-18 17:41:33 +02:00
|
|
|
|
|
2013-11-19 18:24:22 +01:00
|
|
|
|
ret = scm_words (scm_tc7_program | (nfree << 16) | flags, nfree + 2);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
SCM_SET_CELL_WORD_1 (ret, get_subr_stub_code (idx, nreq, nopt, rest));
|
|
|
|
|
|
record_subr_name (idx, sname);
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
if (generic_loc)
|
2018-07-29 15:36:07 +02:00
|
|
|
|
SCM_PROGRAM_FREE_VARIABLE_SET (ret, 0,
|
|
|
|
|
|
scm_from_pointer (generic_loc, NULL));
|
Remove "compiled closures" ("cclos") in favor of a simpler mechanism.
The idea is to introduce `gsubrs' whose arity is encoded in their type
(more precisely in the sizeof (void *) - 8 MSBs). This removes the
indirection introduced by cclos and simplifies the code.
* libguile/__scm.h (CCLO): Remove.
* libguile/debug.c (scm_procedure_source, scm_procedure_environment):
Remove references to `scm_tc7_cclo'.
* libguile/eval.c (scm_trampoline_0, scm_trampoline_1,
scm_trampoline_2): Replace `scm_tc7_cclo' with `scm_tc7_gsubr'.
* libguile/eval.i.c (CEVAL): Likewise. No longer make PROC the first
argument. Directly invoke `scm_gsubr_apply ()' instead of jump to the
`evap(N+1)' label or call to `SCM_APPLY ()'.
* libguile/evalext.c (scm_self_evaluating_p): Remove reference to
`scm_tc7_cclo'.
* libguile/gc-card.c (scm_i_sweep_card, scm_i_tag_name): Likewise.
* libguile/gc-mark.c (scm_gc_mark_dependencies): Likewise.
* libguile/goops.c (scm_class_of): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/gsubr.c (create_gsubr): Use `unsigned int's for REQ, OPT and
RST. Use `scm_tc7_gsubr' instead of `scm_makcclo ()' in the default
case.
(scm_gsubr_apply): Remove calls to `SCM_GSUBR_PROC ()'.
(scm_f_gsubr_apply): Remove.
* libguile/gsubr.h (SCM_GSUBR_TYPE): New definition.
(SCM_GSUBR_MAX): Changed to 33.
(SCM_SET_GSUBR_TYPE, SCM_GSUBR_PROC, SCM_SET_GSUBR_PROC,
scm_f_gsubr_apply): Remove.
* libguile/procprop.c (scm_i_procedure_arity): Remove reference to
`scm_tc7_cclo'; add proper handling of `scm_tc7_gsubr'.
* libguile/procs.c (scm_makcclo, scm_make_cclo): Remove.
(scm_procedure_p): Remove reference to `scm_tc7_cclo'.
(scm_thunk_p): Likewise, plus add proper `scm_tc7_gsubr' handling.
* libguile/procs.h (SCM_CCLO_LENGTH, SCM_MAKE_CCLO_TAG,
SCM_SET_CCLO_LENGTH, SCM_CCLO_BASE, SCM_SET_CCLO_BASE, SCM_CCLO_REF,
SCM_CCLO_SET, SCM_CCLO_SUBR, SCM_SET_CCLO_SUBR, scm_makcclo,
scm_make_cclo): Remove.
* libguile/stacks.c (read_frames): Remove reference to `scm_f_gsubr_apply'.
* libguile/tags.h (scm_tc7_cclo): Remove.
(scm_tc7_gsubr): New.
(scm_tcs_subrs): Add `scm_tc7_gsubr'.
2009-02-16 00:24:00 +01:00
|
|
|
|
|
|
|
|
|
|
if (define)
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
scm_define (sname, ret);
|
Remove "compiled closures" ("cclos") in favor of a simpler mechanism.
The idea is to introduce `gsubrs' whose arity is encoded in their type
(more precisely in the sizeof (void *) - 8 MSBs). This removes the
indirection introduced by cclos and simplifies the code.
* libguile/__scm.h (CCLO): Remove.
* libguile/debug.c (scm_procedure_source, scm_procedure_environment):
Remove references to `scm_tc7_cclo'.
* libguile/eval.c (scm_trampoline_0, scm_trampoline_1,
scm_trampoline_2): Replace `scm_tc7_cclo' with `scm_tc7_gsubr'.
* libguile/eval.i.c (CEVAL): Likewise. No longer make PROC the first
argument. Directly invoke `scm_gsubr_apply ()' instead of jump to the
`evap(N+1)' label or call to `SCM_APPLY ()'.
* libguile/evalext.c (scm_self_evaluating_p): Remove reference to
`scm_tc7_cclo'.
* libguile/gc-card.c (scm_i_sweep_card, scm_i_tag_name): Likewise.
* libguile/gc-mark.c (scm_gc_mark_dependencies): Likewise.
* libguile/goops.c (scm_class_of): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/gsubr.c (create_gsubr): Use `unsigned int's for REQ, OPT and
RST. Use `scm_tc7_gsubr' instead of `scm_makcclo ()' in the default
case.
(scm_gsubr_apply): Remove calls to `SCM_GSUBR_PROC ()'.
(scm_f_gsubr_apply): Remove.
* libguile/gsubr.h (SCM_GSUBR_TYPE): New definition.
(SCM_GSUBR_MAX): Changed to 33.
(SCM_SET_GSUBR_TYPE, SCM_GSUBR_PROC, SCM_SET_GSUBR_PROC,
scm_f_gsubr_apply): Remove.
* libguile/procprop.c (scm_i_procedure_arity): Remove reference to
`scm_tc7_cclo'; add proper handling of `scm_tc7_gsubr'.
* libguile/procs.c (scm_makcclo, scm_make_cclo): Remove.
(scm_procedure_p): Remove reference to `scm_tc7_cclo'.
(scm_thunk_p): Likewise, plus add proper `scm_tc7_gsubr' handling.
* libguile/procs.h (SCM_CCLO_LENGTH, SCM_MAKE_CCLO_TAG,
SCM_SET_CCLO_LENGTH, SCM_CCLO_BASE, SCM_SET_CCLO_BASE, SCM_CCLO_REF,
SCM_CCLO_SET, SCM_CCLO_SUBR, SCM_SET_CCLO_SUBR, scm_makcclo,
scm_make_cclo): Remove.
* libguile/stacks.c (read_frames): Remove reference to `scm_f_gsubr_apply'.
* libguile/tags.h (scm_tc7_cclo): Remove.
(scm_tc7_gsubr): New.
(scm_tcs_subrs): Add `scm_tc7_gsubr'.
2009-02-16 00:24:00 +01:00
|
|
|
|
|
subrs are now VM trampoline procedures
* libguile/_scm.h: Add foreign.h and programs.h to the private include
list, as snarfing subrs with static allocation now needs access to
some of their enums and macros.
* libguile/gsubr.c (create_gsubr): Instead of creating a tc7_gsubr
object, create a VM program with the call-subr opcode, so that the
representation of subrs is now gsubrs. CPP and elisp, together at
last.
(scm_subr_objcode_trampoline): New function, used by the SCM_DEFINE
snarf macro.
* libguile/gsubr.h (SCM_SUBR_META_INFO, SCM_SUBR_PROPS)
(SCM_SET_SUBR_GENERIC_LOC, SCM_SUBR_ARITY_TO_TYPE): Remove these
macros. They were never deprecated, but hopefully people aren't using
them.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC, SCM_SET_SUBR_GENERIC):
Update to work on the new subr representation.
* libguile/objcodes.h (SCM_F_OBJCODE_IS_STATIC): New flag, indicates
that the "backing store" of the objcode is statically allocated.
* libguile/procprop.c (scm_sym_name): Define here instead of in gsubr.c.
* libguile/snarf.h (SCM_DEFINE): If we are doing static allocation,
statically allocate the foreign object, the object table, and the
program, and use some SCM_SNARF_INITtery to fix things up.
Unfortunately I have not been able to make this immutable. It might be
possible, though.
(SCM_IMMUTABLE_CELL, SCM_STATIC_DOUBLE_CELL, SCM_IMMUTABLE_FOREIGN):
(SCM_STATIC_SUBR_OBJVECT, SCM_STATIC_PROGRAM): New helper macros.
2010-01-06 20:11:33 +01:00
|
|
|
|
return ret;
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-11-27 11:44:11 +01:00
|
|
|
|
int
|
2018-06-21 08:39:03 +02:00
|
|
|
|
scm_i_primitive_code_p (const uint32_t *code)
|
2015-11-27 11:44:11 +01:00
|
|
|
|
{
|
2018-07-29 15:36:07 +02:00
|
|
|
|
return is_primitive_code (code);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uintptr_t
|
|
|
|
|
|
primitive_call_ip (const uint32_t *code)
|
|
|
|
|
|
{
|
|
|
|
|
|
int direction = 0;
|
|
|
|
|
|
while (1)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (code[0] & 0xff)
|
|
|
|
|
|
{
|
|
|
|
|
|
case scm_op_instrument_entry:
|
|
|
|
|
|
if (direction < 0) abort ();
|
|
|
|
|
|
direction = 1;
|
|
|
|
|
|
code += 2;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case scm_op_assert_nargs_ee:
|
|
|
|
|
|
case scm_op_assert_nargs_le:
|
|
|
|
|
|
case scm_op_assert_nargs_ge:
|
Allow for bind-optionals without alloc-frame
This reduces subr trampoline instruction count for subrs with optional
args.
* libguile/gsubr.c (get_subr_stub_code): Insert bind-optionals
instructions.
(primitive_call_ip): Handle bind-optionals.
* libguile/programs.c (try_parse_arity): Handle bind-optionals.
* libguile/jit.c (struct scm_jit_state)
(compile_call, compile_call_label, compile_tail_call)
(compile_tail_call_label, compile_receive), compile_receive_values)
(compile_shuffle_down, compile_return_values, compile_subr_call)
(compile_foreign_call, compile_continuation_call)
(compile_compose_continuation, compile_abort, compile_assert_nargs_ee)
(compile_assert_nargs_ge, compile_assert_nargs_le)
(compile_alloc_frame, compile_reset_frame, compile_push)
(compile_pop, compile_drop, compile_expand_apply_argument)
(compile_bind_kwargs, compile_bind_rest, compile_bind_optionals)
(compile, compute_mcode): Separately track min and max frame sizes.
2019-06-06 17:26:59 +02:00
|
|
|
|
case scm_op_bind_optionals:
|
2018-07-29 15:36:07 +02:00
|
|
|
|
case scm_op_bind_rest:
|
|
|
|
|
|
case scm_op_alloc_frame:
|
|
|
|
|
|
if (direction < 0) abort ();
|
|
|
|
|
|
direction = 1;
|
|
|
|
|
|
code += 1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case scm_op_subr_call:
|
2018-08-06 13:30:50 +02:00
|
|
|
|
case scm_op_foreign_call:
|
2018-07-29 15:36:07 +02:00
|
|
|
|
return (uintptr_t) code;
|
|
|
|
|
|
case scm_op_return_values:
|
|
|
|
|
|
case scm_op_handle_interrupts:
|
|
|
|
|
|
/* Going back isn't possible for instruction streams where we
|
|
|
|
|
|
don't know the length of the preceding instruction, but for
|
|
|
|
|
|
the code we emit, these particular opcodes are only ever
|
|
|
|
|
|
preceded by 4-byte instructions. */
|
|
|
|
|
|
if (direction > 0) abort ();
|
|
|
|
|
|
direction = -1;
|
|
|
|
|
|
code -= 1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2018-08-17 08:15:04 +02:00
|
|
|
|
return 0;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2015-11-27 11:44:11 +01:00
|
|
|
|
|
2018-08-06 13:30:50 +02:00
|
|
|
|
static const uint32_t NOT_A_SUBR_CALL = 0xffffffff;
|
|
|
|
|
|
|
2018-07-29 15:36:07 +02:00
|
|
|
|
static uint32_t
|
|
|
|
|
|
primitive_subr_idx (const uint32_t *code)
|
|
|
|
|
|
{
|
2018-08-17 08:15:04 +02:00
|
|
|
|
uint32_t word;
|
2018-07-29 15:36:07 +02:00
|
|
|
|
uintptr_t call_ip = primitive_call_ip (code);
|
2018-08-17 08:15:04 +02:00
|
|
|
|
if (call_ip == 0)
|
|
|
|
|
|
return NOT_A_SUBR_CALL;
|
|
|
|
|
|
word = ((uint32_t *) call_ip)[0];
|
2018-08-06 13:30:50 +02:00
|
|
|
|
if ((word & 0xff) == scm_op_subr_call)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t idx = word >> 8;
|
|
|
|
|
|
if (idx >= next_subr_idx) abort();
|
|
|
|
|
|
return idx;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
return NOT_A_SUBR_CALL;
|
2015-11-27 11:44:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
uintptr_t
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
scm_i_primitive_call_ip (SCM subr)
|
|
|
|
|
|
{
|
2018-07-29 15:36:07 +02:00
|
|
|
|
return primitive_call_ip (SCM_PROGRAM_CODE (subr));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_i_primitive_name (const uint32_t *code)
|
|
|
|
|
|
{
|
2018-08-06 13:30:50 +02:00
|
|
|
|
uint32_t idx = primitive_subr_idx (code);
|
|
|
|
|
|
if (idx == NOT_A_SUBR_CALL)
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
return names[idx];
|
2018-07-29 15:36:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
scm_t_subr
|
2018-08-19 17:38:11 +02:00
|
|
|
|
scm_subr_function_by_index (uint32_t idx)
|
2018-07-29 15:36:07 +02:00
|
|
|
|
{
|
2018-08-06 13:30:50 +02:00
|
|
|
|
if (idx == NOT_A_SUBR_CALL)
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
return subrs[idx];
|
2018-08-19 17:38:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
scm_t_subr
|
|
|
|
|
|
scm_subr_function (SCM subr)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t idx = primitive_subr_idx (SCM_PROGRAM_CODE (subr));
|
|
|
|
|
|
return scm_subr_function_by_index (idx);
|
2018-07-29 15:36:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_subr_name (SCM subr)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_i_primitive_name (SCM_PROGRAM_CODE (subr));
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-10-22 12:13:37 +00:00
|
|
|
|
SCM
|
2018-07-29 15:36:07 +02:00
|
|
|
|
scm_apply_subr (union scm_vm_stack_element *sp, uint32_t idx, ptrdiff_t nslots)
|
2015-10-22 12:13:37 +00:00
|
|
|
|
{
|
2018-07-29 15:36:07 +02:00
|
|
|
|
SCM (*subr)() = subrs[idx];
|
2015-10-22 12:13:37 +00:00
|
|
|
|
|
|
|
|
|
|
#define ARG(i) (sp[i].as_scm)
|
|
|
|
|
|
switch (nslots - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
return subr ();
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
return subr (ARG (0));
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
return subr (ARG (1), ARG (0));
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
return subr (ARG (2), ARG (1), ARG (0));
|
|
|
|
|
|
case 4:
|
|
|
|
|
|
return subr (ARG (3), ARG (2), ARG (1), ARG (0));
|
|
|
|
|
|
case 5:
|
|
|
|
|
|
return subr (ARG (4), ARG (3), ARG (2), ARG (1), ARG (0));
|
|
|
|
|
|
case 6:
|
|
|
|
|
|
return subr (ARG (5), ARG (4), ARG (3), ARG (2), ARG (1),
|
|
|
|
|
|
ARG (0));
|
|
|
|
|
|
case 7:
|
|
|
|
|
|
return subr (ARG (6), ARG (5), ARG (4), ARG (3), ARG (2),
|
|
|
|
|
|
ARG (1), ARG (0));
|
|
|
|
|
|
case 8:
|
|
|
|
|
|
return subr (ARG (7), ARG (6), ARG (5), ARG (4), ARG (3),
|
|
|
|
|
|
ARG (2), ARG (1), ARG (0));
|
|
|
|
|
|
case 9:
|
|
|
|
|
|
return subr (ARG (8), ARG (7), ARG (6), ARG (5), ARG (4),
|
|
|
|
|
|
ARG (3), ARG (2), ARG (1), ARG (0));
|
|
|
|
|
|
case 10:
|
|
|
|
|
|
return subr (ARG (9), ARG (8), ARG (7), ARG (6), ARG (5),
|
|
|
|
|
|
ARG (4), ARG (3), ARG (2), ARG (1), ARG (0));
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef ARG
|
|
|
|
|
|
}
|
|
|
|
|
|
|
* procs.c, procs.h (scm_subr_entry): New type: Stores data
associated with subrs.
(SCM_SUBRNUM, SCM_SUBR_ENTRY, SCM_SUBR_GENERIC, SCM_SUBR_PROPS,
SCM_SUBR_DOC): New macros.
(scm_subr_table): New variable.
(scm_mark_subr_table): New function.
* init.c (scm_boot_guile_1): Call scm_init_subr_table.
* gc.c (scm_gc_mark): Don't mark subr names here.
(scm_igc): Call scm_mark_subr_table.
* snarf.h (SCM_GPROC, SCM_GPROC1): New macros.
* procs.c, procs.h (scm_subr_p): New function (used internally).
* gsubr.c, gsubr.h (scm_make_gsubr_with_generic): New function.
* objects.c, objects.h (scm_primitive_generic): New class.
* objects.h (SCM_CMETHOD_CODE, SCM_CMETHOD_ENV): New macros.
* print.c (scm_iprin1): Print primitive-generics.
* __scm.h (SCM_WTA_DISPATCH_1, SCM_GASSERT1,
SCM_WTA_DISPATCH_2, SCM_GASSERT2): New macros.
* eval.c (SCM_CEVAL, SCM_APPLY): Replace scm_wta -->
SCM_WTA_DISPATCH_1 for scm_cxr's (unary floating point
primitives). NOTE: This means that it is now *required* to use
SCM_GPROC1 when creating float scm_cxr's (float scm_cxr's is an
obscured representation that will be removed in the future anyway,
so backward compatibility is no problem here).
* numbers.c: Converted most numeric primitives (all but bit
comparison operations and bit operations) to dispatch on generic
if args don't match.
* eval.c, eval.h (scm_eval_body): New function.
* objects.c (scm_call_generic_0, scm_call_generic_1,
scm_call_generic_2, scm_call_generic_3, scm_apply_generic): New
functions.
* eval.c (SCM_CEVAL): Apply the cmethod directly after having
called scm_memoize_method instead of doing a second lookup.
* objects.h (scm_memoize_method): Now returns the memoized cmethod.
* procs.c (scm_make_subr_opt): Use scm_sysintern0 instead of
scm_sysintern so that the binding connected with the subr name
isn't cleared when we give set = 0.
1999-08-26 04:24:42 +00:00
|
|
|
|
SCM
|
2001-05-20 00:34:10 +00:00
|
|
|
|
scm_c_make_gsubr (const char *name, int req, int opt, int rst, SCM (*fcn)())
|
* procs.c, procs.h (scm_subr_entry): New type: Stores data
associated with subrs.
(SCM_SUBRNUM, SCM_SUBR_ENTRY, SCM_SUBR_GENERIC, SCM_SUBR_PROPS,
SCM_SUBR_DOC): New macros.
(scm_subr_table): New variable.
(scm_mark_subr_table): New function.
* init.c (scm_boot_guile_1): Call scm_init_subr_table.
* gc.c (scm_gc_mark): Don't mark subr names here.
(scm_igc): Call scm_mark_subr_table.
* snarf.h (SCM_GPROC, SCM_GPROC1): New macros.
* procs.c, procs.h (scm_subr_p): New function (used internally).
* gsubr.c, gsubr.h (scm_make_gsubr_with_generic): New function.
* objects.c, objects.h (scm_primitive_generic): New class.
* objects.h (SCM_CMETHOD_CODE, SCM_CMETHOD_ENV): New macros.
* print.c (scm_iprin1): Print primitive-generics.
* __scm.h (SCM_WTA_DISPATCH_1, SCM_GASSERT1,
SCM_WTA_DISPATCH_2, SCM_GASSERT2): New macros.
* eval.c (SCM_CEVAL, SCM_APPLY): Replace scm_wta -->
SCM_WTA_DISPATCH_1 for scm_cxr's (unary floating point
primitives). NOTE: This means that it is now *required* to use
SCM_GPROC1 when creating float scm_cxr's (float scm_cxr's is an
obscured representation that will be removed in the future anyway,
so backward compatibility is no problem here).
* numbers.c: Converted most numeric primitives (all but bit
comparison operations and bit operations) to dispatch on generic
if args don't match.
* eval.c, eval.h (scm_eval_body): New function.
* objects.c (scm_call_generic_0, scm_call_generic_1,
scm_call_generic_2, scm_call_generic_3, scm_apply_generic): New
functions.
* eval.c (SCM_CEVAL): Apply the cmethod directly after having
called scm_memoize_method instead of doing a second lookup.
* objects.h (scm_memoize_method): Now returns the memoized cmethod.
* procs.c (scm_make_subr_opt): Use scm_sysintern0 instead of
scm_sysintern so that the binding connected with the subr name
isn't cleared when we give set = 0.
1999-08-26 04:24:42 +00:00
|
|
|
|
{
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
return create_subr (0, name, req, opt, rst, fcn, NULL);
|
2001-05-20 00:34:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_define_gsubr (const char *name, int req, int opt, int rst, SCM (*fcn)())
|
|
|
|
|
|
{
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
return create_subr (1, name, req, opt, rst, fcn, NULL);
|
* procs.c, procs.h (scm_subr_entry): New type: Stores data
associated with subrs.
(SCM_SUBRNUM, SCM_SUBR_ENTRY, SCM_SUBR_GENERIC, SCM_SUBR_PROPS,
SCM_SUBR_DOC): New macros.
(scm_subr_table): New variable.
(scm_mark_subr_table): New function.
* init.c (scm_boot_guile_1): Call scm_init_subr_table.
* gc.c (scm_gc_mark): Don't mark subr names here.
(scm_igc): Call scm_mark_subr_table.
* snarf.h (SCM_GPROC, SCM_GPROC1): New macros.
* procs.c, procs.h (scm_subr_p): New function (used internally).
* gsubr.c, gsubr.h (scm_make_gsubr_with_generic): New function.
* objects.c, objects.h (scm_primitive_generic): New class.
* objects.h (SCM_CMETHOD_CODE, SCM_CMETHOD_ENV): New macros.
* print.c (scm_iprin1): Print primitive-generics.
* __scm.h (SCM_WTA_DISPATCH_1, SCM_GASSERT1,
SCM_WTA_DISPATCH_2, SCM_GASSERT2): New macros.
* eval.c (SCM_CEVAL, SCM_APPLY): Replace scm_wta -->
SCM_WTA_DISPATCH_1 for scm_cxr's (unary floating point
primitives). NOTE: This means that it is now *required* to use
SCM_GPROC1 when creating float scm_cxr's (float scm_cxr's is an
obscured representation that will be removed in the future anyway,
so backward compatibility is no problem here).
* numbers.c: Converted most numeric primitives (all but bit
comparison operations and bit operations) to dispatch on generic
if args don't match.
* eval.c, eval.h (scm_eval_body): New function.
* objects.c (scm_call_generic_0, scm_call_generic_1,
scm_call_generic_2, scm_call_generic_3, scm_apply_generic): New
functions.
* eval.c (SCM_CEVAL): Apply the cmethod directly after having
called scm_memoize_method instead of doing a second lookup.
* objects.h (scm_memoize_method): Now returns the memoized cmethod.
* procs.c (scm_make_subr_opt): Use scm_sysintern0 instead of
scm_sysintern so that the binding connected with the subr name
isn't cleared when we give set = 0.
1999-08-26 04:24:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2001-05-20 00:34:10 +00:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_make_gsubr_with_generic (const char *name,
|
|
|
|
|
|
int req,
|
|
|
|
|
|
int opt,
|
|
|
|
|
|
int rst,
|
|
|
|
|
|
SCM (*fcn)(),
|
|
|
|
|
|
SCM *gf)
|
|
|
|
|
|
{
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
return create_subr (0, name, req, opt, rst, fcn, gf);
|
2001-05-20 00:34:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_define_gsubr_with_generic (const char *name,
|
|
|
|
|
|
int req,
|
|
|
|
|
|
int opt,
|
|
|
|
|
|
int rst,
|
|
|
|
|
|
SCM (*fcn)(),
|
|
|
|
|
|
SCM *gf)
|
|
|
|
|
|
{
|
Subrs are RTL programs
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
2013-10-18 10:03:26 +02:00
|
|
|
|
return create_subr (1, name, req, opt, rst, fcn, gf);
|
2001-05-20 00:34:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
void
|
|
|
|
|
|
scm_init_gsubr()
|
|
|
|
|
|
{
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "gsubr.x"
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|