mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Add bind-optionals instruction
* doc/ref/vm.texi (Function Prologue Instructions): Document new instruction. * libguile/jit.c (compile_bind_optionals): New compiler. * libguile/vm-engine.c (VM_NAME): New interpreter. * module/system/vm/assembler.scm (opt-prelude): Emit bind-optionals as appropriate. * module/system/vm/disassembler.scm (define-stack-effect-parser) (code-annotation): Handle bind-optionals.
This commit is contained in:
parent
12d6e43176
commit
9fd978ed7e
5 changed files with 73 additions and 9 deletions
|
@ -807,6 +807,12 @@ will signal an error if an unknown key is found.
|
||||||
A macro-mega-instruction.
|
A macro-mega-instruction.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn Instruction {} bind-optionals f24:@var{nlocals}
|
||||||
|
Expand the current frame to have at least @var{nlocals} locals, filling
|
||||||
|
in any fresh values with @code{SCM_UNDEFINED}. If the frame has more
|
||||||
|
than @var{nlocals} locals, it is left as it is.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} bind-rest f24:@var{dst}
|
@deftypefn Instruction {} bind-rest f24:@var{dst}
|
||||||
Collect any arguments at or above @var{dst} into a list, and store that
|
Collect any arguments at or above @var{dst} into a list, and store that
|
||||||
list at @var{dst}.
|
list at @var{dst}.
|
||||||
|
@ -814,8 +820,7 @@ list at @var{dst}.
|
||||||
|
|
||||||
@deftypefn Instruction {} alloc-frame c24:@var{nlocals}
|
@deftypefn Instruction {} alloc-frame c24:@var{nlocals}
|
||||||
Ensure that there is space on the stack for @var{nlocals} local
|
Ensure that there is space on the stack for @var{nlocals} local
|
||||||
variables, setting them all to @code{SCM_UNDEFINED}, except those values
|
variables. The value of any new local is undefined.
|
||||||
that are already on the stack.
|
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn Instruction {} reset-frame c24:@var{nlocals}
|
@deftypefn Instruction {} reset-frame c24:@var{nlocals}
|
||||||
|
|
|
@ -2005,6 +2005,37 @@ compile_bind_rest (scm_jit_state *j, uint32_t dst)
|
||||||
jit_patch_here (j->jit, k);
|
jit_patch_here (j->jit, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compile_bind_optionals (scm_jit_state *j, uint32_t dst)
|
||||||
|
{
|
||||||
|
ASSERT_HAS_REGISTER_STATE (FP_IN_REGISTER | SP_IN_REGISTER);
|
||||||
|
ASSERT(j->frame_size == -1);
|
||||||
|
|
||||||
|
jit_gpr_t saved_frame_size = T1_PRESERVED;
|
||||||
|
jit_subr (j->jit, saved_frame_size, FP, SP);
|
||||||
|
|
||||||
|
jit_reloc_t no_optionals = jit_bgei
|
||||||
|
(j->jit, saved_frame_size, dst * sizeof (union scm_vm_stack_element));
|
||||||
|
|
||||||
|
emit_alloc_frame (j, T0, dst);
|
||||||
|
|
||||||
|
jit_gpr_t walk = saved_frame_size;
|
||||||
|
jit_subr (j->jit, walk, FP, saved_frame_size);
|
||||||
|
|
||||||
|
jit_reloc_t done = jit_bler (j->jit, walk, SP);
|
||||||
|
jit_movi (j->jit, T0, SCM_UNPACK (SCM_UNDEFINED));
|
||||||
|
|
||||||
|
void *head = jit_address (j->jit);
|
||||||
|
jit_subi (j->jit, walk, walk, sizeof (union scm_vm_stack_element));
|
||||||
|
jit_str (j->jit, walk, T0);
|
||||||
|
jit_patch_there (j->jit, jit_bner (j->jit, walk, SP), head);
|
||||||
|
|
||||||
|
jit_patch_here (j->jit, done);
|
||||||
|
jit_patch_here (j->jit, no_optionals);
|
||||||
|
|
||||||
|
ASSERT(j->frame_size == -1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
compile_allocate_words (scm_jit_state *j, uint16_t dst, uint16_t nwords)
|
compile_allocate_words (scm_jit_state *j, uint16_t dst, uint16_t nwords)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3231,7 +3231,28 @@ VM_NAME (scm_thread *thread)
|
||||||
VM_DEFINE_OP (153, f64_set, "f64-set!", OP1 (X8_S8_S8_S8))
|
VM_DEFINE_OP (153, f64_set, "f64-set!", OP1 (X8_S8_S8_S8))
|
||||||
PTR_SET (double, F64);
|
PTR_SET (double, F64);
|
||||||
|
|
||||||
VM_DEFINE_OP (154, unused_154, NULL, NOP)
|
/* bind-optionals nargs:24
|
||||||
|
*
|
||||||
|
* Expand the current frame to have NARGS locals, filling in any fresh
|
||||||
|
* values with SCM_UNDEFINED.
|
||||||
|
*/
|
||||||
|
VM_DEFINE_OP (154, bind_optionals, "bind-optionals", DOP1 (X8_F24))
|
||||||
|
{
|
||||||
|
uint32_t nlocals, nargs;
|
||||||
|
|
||||||
|
UNPACK_24 (op, nlocals);
|
||||||
|
nargs = FRAME_LOCALS_COUNT ();
|
||||||
|
|
||||||
|
if (nargs < nlocals)
|
||||||
|
{
|
||||||
|
ALLOC_FRAME (nlocals);
|
||||||
|
while (nargs < nlocals)
|
||||||
|
FP_SET (nargs++, SCM_UNDEFINED);
|
||||||
|
}
|
||||||
|
|
||||||
|
NEXT (1);
|
||||||
|
}
|
||||||
|
|
||||||
VM_DEFINE_OP (155, unused_155, NULL, NOP)
|
VM_DEFINE_OP (155, unused_155, NULL, NOP)
|
||||||
VM_DEFINE_OP (156, unused_156, NULL, NOP)
|
VM_DEFINE_OP (156, unused_156, NULL, NOP)
|
||||||
VM_DEFINE_OP (157, unused_157, NULL, NOP)
|
VM_DEFINE_OP (157, unused_157, NULL, NOP)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Guile bytecode assembler
|
;;; Guile bytecode assembler
|
||||||
|
|
||||||
;;; Copyright (C) 2001, 2009, 2010, 2012, 2013, 2014, 2015, 2017, 2018 Free Software Foundation, Inc.
|
;;; Copyright (C) 2001, 2009-2019 Free Software Foundation, Inc.
|
||||||
;;;
|
;;;
|
||||||
;;; This library is free software; you can redistribute it and/or
|
;;; This library is free software; you can redistribute it and/or
|
||||||
;;; modify it under the terms of the GNU Lesser General Public
|
;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -246,7 +246,6 @@
|
||||||
emit-assert-nargs-ee
|
emit-assert-nargs-ee
|
||||||
emit-assert-nargs-ge
|
emit-assert-nargs-ge
|
||||||
emit-assert-nargs-le
|
emit-assert-nargs-le
|
||||||
emit-alloc-frame
|
|
||||||
emit-reset-frame
|
emit-reset-frame
|
||||||
emit-assert-nargs-ee/locals
|
emit-assert-nargs-ee/locals
|
||||||
emit-bind-kwargs
|
emit-bind-kwargs
|
||||||
|
@ -1478,6 +1477,8 @@ returned instead."
|
||||||
(emit-assert-nargs-ge asm nreq))
|
(emit-assert-nargs-ge asm nreq))
|
||||||
(cond
|
(cond
|
||||||
(rest?
|
(rest?
|
||||||
|
(unless (zero? nopt)
|
||||||
|
(emit-bind-optionals asm (+ nreq nopt)))
|
||||||
(emit-bind-rest asm (+ nreq nopt)))
|
(emit-bind-rest asm (+ nreq nopt)))
|
||||||
(alternate
|
(alternate
|
||||||
(emit-arguments<=? asm (+ nreq nopt))
|
(emit-arguments<=? asm (+ nreq nopt))
|
||||||
|
@ -1485,9 +1486,13 @@ returned instead."
|
||||||
;; whereas for <, NONE usually indicates greater-than-or-equal,
|
;; whereas for <, NONE usually indicates greater-than-or-equal,
|
||||||
;; hence the name jge. Perhaps we just need to rename jge to
|
;; hence the name jge. Perhaps we just need to rename jge to
|
||||||
;; br-if-none.
|
;; br-if-none.
|
||||||
(emit-jge asm alternate))
|
(emit-jge asm alternate)
|
||||||
|
(unless (zero? nopt)
|
||||||
|
(emit-bind-optionals asm (+ nreq nopt))))
|
||||||
(else
|
(else
|
||||||
(emit-assert-nargs-le asm (+ nreq nopt))))
|
(emit-assert-nargs-le asm (+ nreq nopt))
|
||||||
|
(unless (zero? nopt)
|
||||||
|
(emit-bind-optionals asm (+ nreq nopt)))))
|
||||||
(emit-alloc-frame asm nlocals))
|
(emit-alloc-frame asm nlocals))
|
||||||
|
|
||||||
(define-macro-assembler (kw-prelude asm nreq nopt rest? kw-indices
|
(define-macro-assembler (kw-prelude asm nreq nopt rest? kw-indices
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Guile bytecode disassembler
|
;;; Guile bytecode disassembler
|
||||||
|
|
||||||
;;; Copyright (C) 2001, 2009-2010, 2012-2015, 2017-2018 Free Software Foundation, Inc.
|
;;; Copyright (C) 2001, 2009-2010, 2012-2015, 2017-2019 Free Software Foundation, Inc.
|
||||||
;;;
|
;;;
|
||||||
;;; This library is free software; you can redistribute it and/or
|
;;; This library is free software; you can redistribute it and/or
|
||||||
;;; modify it under the terms of the GNU Lesser General Public
|
;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -231,6 +231,8 @@ address of that offset."
|
||||||
(('assert-nargs-ee/locals nargs locals)
|
(('assert-nargs-ee/locals nargs locals)
|
||||||
;; The nargs includes the procedure.
|
;; The nargs includes the procedure.
|
||||||
(list "~a slot~:p (~a arg~:p)" (+ locals nargs) (1- nargs)))
|
(list "~a slot~:p (~a arg~:p)" (+ locals nargs) (1- nargs)))
|
||||||
|
(('bind-optionals nargs)
|
||||||
|
(list "~a args~:p" (1- nargs)))
|
||||||
(('alloc-frame nlocals)
|
(('alloc-frame nlocals)
|
||||||
(list "~a slot~:p" nlocals))
|
(list "~a slot~:p" nlocals))
|
||||||
(('reset-frame nlocals)
|
(('reset-frame nlocals)
|
||||||
|
@ -546,7 +548,7 @@ address of that offset."
|
||||||
#'(lambda (code pos size)
|
#'(lambda (code pos size)
|
||||||
(let ((count (ash (bytevector-u32-native-ref code pos) -8)))
|
(let ((count (ash (bytevector-u32-native-ref code pos) -8)))
|
||||||
(and size (- size count)))))
|
(and size (- size count)))))
|
||||||
((alloc-frame reset-frame)
|
((alloc-frame reset-frame bind-optionals)
|
||||||
#'(lambda (code pos size)
|
#'(lambda (code pos size)
|
||||||
(let ((nlocals (ash (bytevector-u32-native-ref code pos) -8)))
|
(let ((nlocals (ash (bytevector-u32-native-ref code pos) -8)))
|
||||||
nlocals)))
|
nlocals)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue