]> granicus.if.org Git - vim/commitdiff
updated for version 7.2-191 v7.2.191
authorBram Moolenaar <Bram@vim.org>
Tue, 26 May 2009 20:59:55 +0000 (20:59 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 26 May 2009 20:59:55 +0000 (20:59 +0000)
13 files changed:
runtime/doc/if_mzsch.txt
src/Make_ming.mak
src/Make_mvc.mak
src/Makefile
src/auto/configure
src/config.mk.in
src/configure.in
src/eval.c
src/if_mzsch.c
src/if_mzsch.h
src/main.c
src/proto/if_mzsch.pro
src/version.c

index 87298eccf0de4c15bf28176413a7380372c96ad3..d22544419878433ed8deaa1358bb05d65727f789 100644 (file)
@@ -1,4 +1,4 @@
-*if_mzsch.txt*  For Vim version 7.2.  Last change: 2008 Jun 28
+*if_mzsch.txt*  For Vim version 7.2.  Last change: 2009 May 26
 
 
                  VIM REFERENCE MANUAL    by Sergey Khorev
@@ -42,10 +42,6 @@ Note: On FreeBSD you should use the "drscheme" port.
 
                                                        *:mzfile* *:mzf*
 :[range]mzf[ile] {file}        Execute the MzScheme script in {file}.  {not in Vi}
-                       All statements are executed in the namespace of the
-                       buffer that was current during :mzfile start.
-                       If you want to access other namespaces, use
-                       'parameterize'.
 
 All of these commands do essentially the same thing - they execute a piece of
 MzScheme code, with the "current range" set to the given line
@@ -54,8 +50,6 @@ range.
 In the case of :mzscheme, the code to execute is in the command-line.
 In the case of :mzfile, the code to execute is the contents of the given file.
 
-Each buffer has its own MzScheme namespace. Global namespace is bound to
-the "global-namespace" value from the 'vimext' module.
 MzScheme interface defines exception exn:vim, derived from exn.
 It is raised for various Vim errors.
 
@@ -79,40 +73,8 @@ To avoid clashes with MzScheme, consider using prefix when requiring module,
 e.g.: >
        :mzscheme (require (prefix vim- vimext))
 <
-All the examples below assume this naming scheme.  Note that you need to do
-this again for every buffer.
+All the examples below assume this naming scheme. 
 
-The auto-instantiation can be achieved with autocommands, e.g. you can put
-something like this in your .vimrc (EOFs should not have indentation): >
-    function s:MzRequire()
-       if has("mzscheme")
-           :mz << EOF
-           (require (prefix vim- vimext))
-           (let ((buf (vim-get-buff-by-name (vim-eval "expand(\"<afile>\")"))))
-             (when (and buf (not (eq? buf (vim-curr-buff))))
-               (parameterize ((current-namespace (vim-get-buff-namespace buf)))
-                 (namespace-attach-module vim-global-namespace 'vimext)
-                 (namespace-require '(prefix vim vimext)))))
-    EOF
-       endif
-    endfunction
-
-    function s:MzStartup()
-       if has("mzscheme")
-           au BufNew,BufNewFile,BufAdd,BufReadPre * :call s:MzRequire()
-           :mz << EOF
-           (current-library-collection-paths
-               (cons
-                   (build-path (find-system-path 'addon-dir) (version) "collects")
-                   (current-library-collection-paths)))
-    EOF
-       endif
-    endfunction
-
-    call s:MzStartup()
-<
-
-The global namespace just instantiated this module with the prefix "vimext:".
                                                        *mzscheme-sandbox*
 When executed in the |sandbox|, access to some filesystem and Vim interface
 procedures is restricted.
@@ -121,15 +83,20 @@ procedures is restricted.
 2. Examples                                            *mzscheme-examples*
 >
        :mzscheme (display "Hello")
+       :mz (display (string-append "Using MzScheme version " (version)))
+       :mzscheme (require (prefix vim- vimext)) ; for MzScheme < 4.x
+       :mzscheme (require (prefix-in vim- 'vimext)) ; MzScheme 4.x
        :mzscheme (vim-set-buff-line 10 "This is line #10")
 <
 Inline script usage: >
        function! <SID>SetFirstLine()
            :mz << EOF
            (display "!!!")
+           (require (prefix vim- vimext))
+           ; for newer versions (require (prefix-in vim- 'vimext))
            (vim-set-buff-line 1 "This is line #1")
            (vim-beep)
-           EOF
+       EOF
        endfunction
 
        nmap <F9> :call <SID>SetFirstLine() <CR>
@@ -137,17 +104,33 @@ Inline script usage: >
 File execution: >
        :mzfile supascript.scm
 <
-Accessing the current buffer namespace from an MzScheme program running in
-another buffer within |:mzfile|-executed script : >
-       ; Move to the window below
-       (vim-command "wincmd j")
-       ; execute in the context of buffer, to which window belongs
-       ; assume that buffer has 'textstring' defined
-       (parameterize ((current-namespace
-                       (vim-get-buff-namespace (vim-curr-buff))))
-        (eval '(vim-set-buff-line 1 textstring)))
+Vim exception handling: >
+       :mz << EOF
+       (require (prefix vim- vimext))
+       ; for newer versions (require (prefix-in vim- 'vimext))
+       (with-handlers
+         ([exn:vim? (lambda (e) (display (exn-message e)))])
+         (vim-eval "nonsense-string"))
+       EOF
 <
+Auto-instantiation of vimext module (can be placed in your |vimrc|): >
+    function! MzRequire()
+       :redir => l:mzversion
+       :mz (version)
+       :redir END
+       if strpart(l:mzversion, 1, 1) < "4"
+           " MzScheme versions < 4.x:
+           :mz (require (prefix vim- vimext))
+       else
+           " newer versions:
+           :mz (require (prefix-in vim- 'vimext))
+       endif
+    endfunction
 
+    if has("mzscheme")
+       silent call MzRequire()
+    endif
+<
 ==============================================================================
 3. Threads                                             *mzscheme-threads*
 
@@ -168,11 +151,11 @@ interface.
 Common
 ------
     (command {command-string})     Perform the vim ":Ex" style command.
-    (eval {expr-string})           Evaluate the vim expression to a string.
-                                   A |List| is turned into a string by
-                                   joining the items and inserting line
-                                   breaks.
-                                   NOTE clashes with MzScheme eval
+    (eval {expr-string})           Evaluate the vim expression into
+                                   respective MzScheme object: |Lists| are
+                                   represented as Scheme lists,
+                                   |Dictionaries| as hash tables.
+                                   NOTE the name clashes with MzScheme eval
     (range-start)                  Start/End of the range passed with
     (range-end)                            the Scheme command.
     (beep)                         beep
@@ -186,7 +169,6 @@ Common
                                    be set. The symbol 'global can be passed
                                    as {buffer-or-window}. Then |:setglobal|
                                    will be used.
-    global-namespace               The MzScheme main namespace.
 
 Buffers                                                         *mzscheme-buffer*
 -------
@@ -228,7 +210,6 @@ Buffers                                                      *mzscheme-buffer*
                                        if there is no such buffer.
     (get-buff-by-num {buffernum})   Get a buffer by its number (return #f if
                                    there is no buffer with this number).
-    (get-buff-namespace [buffer])   Get buffer namespace.
 
 Windows                                                            *mzscheme-window*
 ------
@@ -250,7 +231,7 @@ Windows                                                         *mzscheme-window*
     (set-cursor (line . col) [window])  Set cursor position.
 
 ==============================================================================
-5. Dynamic loading                                     *mzscheme-dynamic*
+5. Dynamic loading                                 *mzscheme-dynamic* *E812*
 
 On MS-Windows the MzScheme libraries can be loaded dynamically. The |:version|
 output then includes |+mzscheme/dyn|.
index 6d28e466857b5e5cbe61b9f06208f1621dc5cd3b..e0717b62aeb725a0351ebc19efc4963b867d98a2 100644 (file)
@@ -115,8 +115,21 @@ ifndef MZSCHEME_VER
 MZSCHEME_VER=205_000
 endif
 
+ifndef MZSCHEME_PRECISE_GC
+MZSCHEME_PRECISE_GC=no
+endif
+
+# for version 4.x we need to generate byte-code for Scheme base
+ifndef MZSCHEME_GENERATE_BASE
+MZSCHEME_GENERATE_BASE=no
+endif
+
 ifeq (no,$(DYNAMIC_MZSCHEME))
+ifeq (yes,$(MZSCHEME_PRECISE_GC))
+MZSCHEME_LIB=-lmzsch$(MZSCHEME_VER)
+else
 MZSCHEME_LIB = -lmzsch$(MZSCHEME_VER) -lmzgc$(MZSCHEME_VER)
+endif
 # the modern MinGW can dynamically link to dlls directly.
 # point MZSCHEME_DLLS to where you put libmzschXXXXXXX.dll and libgcXXXXXXX.dll
 ifndef MZSCHEME_DLLS
@@ -410,6 +423,13 @@ endif
 ifdef MZSCHEME
 OBJ += $(OUTDIR)/if_mzsch.o
 MZSCHEME_INCL = if_mzsch.h
+ifeq (yes,$(MZSCHEME_GENERATE_BASE))
+CFLAGS += -DINCLUDE_MZSCHEME_BASE
+MZ_EXTRA_DEP += mzscheme_base.c
+endif
+ifeq (yes,$(MZSCHEME_PRECISE_GC))
+CFLAGS += -DMZ_PRECISE_GC
+endif
 endif
 ifdef PYTHON
 OBJ += $(OUTDIR)/if_python.o
@@ -588,6 +608,12 @@ if_perl.c: if_perl.xs typemap
 $(OUTDIR)/netbeans.o:  netbeans.c $(INCL) $(NBDEBUG_INCL) $(NBDEBUG_SRC)
        $(CC) -c $(CFLAGS) netbeans.c -o $(OUTDIR)/netbeans.o
 
+$(OUTDIR)/if_mzsch.o:  if_mzsch.c $(INCL) if_mzsch.h $(MZ_EXTRA_DEP)
+       $(CC) -c $(CFLAGS) if_mzsch.c -o $(OUTDIR)/if_mzsch.o
+
+mzscheme_base.c:
+       $(MZSCHEME)/mzc --c-mods mzscheme_base.c ++lib scheme/base
+
 pathdef.c: $(INCL)
 ifneq (sh.exe, $(SHELL))
        @echo creating pathdef.c
index 545c94d341a9ef9cdd3a92bb501c391e9e2622a7..178258696010709fdd4ab20618fdea7bc0ac34dc 100644 (file)
@@ -34,6 +34,7 @@
 #        MZSCHEME=[Path to MzScheme directory]
 #        DYNAMIC_MZSCHEME=yes (to load the MzScheme DLLs dynamically)
 #        MZSCHEME_VER=[version, 205_000, ...]
+#        MZSCHEME_DEBUG=no
 #
 #      Perl interface:
 #        PERL=[Path to Perl directory]
@@ -621,15 +622,37 @@ PYTHON_LIB = $(PYTHON)\libs\python$(PYTHON_VER).lib
 MZSCHEME_VER = 205_000
 !endif
 CFLAGS = $(CFLAGS) -DFEAT_MZSCHEME -I $(MZSCHEME)\include
+!if EXIST("$(MZSCHEME)\collects\scheme\base.ss")
+# for MzScheme 4.x we need to include byte code for basic Scheme stuff
+MZSCHEME_EXTRA_DEP = mzscheme_base.c
+CFLAGS = $(CFLAGS) -DINCLUDE_MZSCHEME_BASE
+!endif
+!if EXIST("$(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib") \
+       && !EXIST("$(MZSCHEME)\lib\msvc\libmzgc$(MZSCHEME_VER).lib")
+!message Building with Precise GC
+MZSCHEME_PRECISE_GC = yes
+CFLAGS = $(CFLAGS) -DMZ_PRECISE_GC
+!endif
 !if "$(DYNAMIC_MZSCHEME)" == "yes"
+!if "$(MZSCHEME_PRECISE_GC)" == "yes"
+!error MzScheme with Precise GC cannot be loaded dynamically
+!endif
 !message MzScheme DLLs will be loaded dynamically
 CFLAGS = $(CFLAGS) -DDYNAMIC_MZSCHEME \
                -DDYNAMIC_MZSCH_DLL=\"libmzsch$(MZSCHEME_VER).dll\" \
                -DDYNAMIC_MZGC_DLL=\"libmzgc$(MZSCHEME_VER).dll\"
 !else
+!if "$(MZSCHEME_DEBUG)" == "yes"
+CFLAGS = $(CFLAGS) -DMZSCHEME_FORCE_GC
+!endif
+!if "$(MZSCHEME_PRECISE_GC)" == "yes"
+# Precise GC does not use separate dll
+MZSCHEME_LIB = $(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib
+!else
 MZSCHEME_LIB = $(MZSCHEME)\lib\msvc\libmzgc$(MZSCHEME_VER).lib \
                $(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib
 !endif
+!endif
 MZSCHEME_OBJ = $(OUTDIR)\if_mzsch.obj
 !endif
 
@@ -930,9 +953,11 @@ $(OUTDIR)/if_perl.obj: $(OUTDIR) if_perl.c  $(INCL)
 $(OUTDIR)/if_perlsfio.obj: $(OUTDIR) if_perlsfio.c  $(INCL)
        $(CC) $(CFLAGS) $(PERL_INC) if_perlsfio.c
 
-$(OUTDIR)/if_mzsch.obj: $(OUTDIR) if_mzsch.c  $(INCL)
+$(OUTDIR)/if_mzsch.obj: $(OUTDIR) if_mzsch.c  $(INCL) $(MZSCHEME_EXTRA_DEP)
        $(CC) $(CFLAGS) if_mzsch.c \
                -DMZSCHEME_COLLECTS=\"$(MZSCHEME:\=\\)\\collects\"
+mzscheme_base.c:
+       $(MZSCHEME)\mzc --c-mods mzscheme_base.c ++lib scheme/base
 
 $(OUTDIR)/if_python.obj: $(OUTDIR) if_python.c  $(INCL)
        $(CC) $(CFLAGS) $(PYTHON_INC) if_python.c
index e6d26b1641ea705b15ca63d3864053d5215af71a..02b8d6cb823716d7feb7560624a7b09b59bbcc83 100644 (file)
@@ -536,7 +536,7 @@ CClink = $(CC)
 # Use this with GCC to check for mistakes, unused arguments, etc.
 #CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code
 #PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
-#MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code
+#MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
 
 # EFENCE - Electric-Fence malloc debugging: catches memory accesses beyond
 # allocated memory (and makes every malloc()/free() very slow).
@@ -2200,6 +2200,7 @@ clean celan: testclean
        -rm -f $(TOOLS) auto/osdef.h auto/pathdef.c auto/if_perl.c
        -rm -f conftest* *~ auto/link.sed
        -rm -rf $(APPDIR)
+       -rm -rf mzscheme_base.c
        if test -d $(PODIR); then \
                cd $(PODIR); $(MAKE) prefix=$(DESTDIR)$(prefix) clean; \
        fi
@@ -2433,8 +2434,11 @@ objects/if_cscope.o: if_cscope.c
 objects/if_xcmdsrv.o: if_xcmdsrv.c
        $(CCC) -o $@ if_xcmdsrv.c
 
-objects/if_mzsch.o: if_mzsch.c
+objects/if_mzsch.o: if_mzsch.c $(MZSCHEME_EXTRA)
        $(CCC) -o $@ $(MZSCHEME_CFLAGS_EXTRA) if_mzsch.c
+mzscheme_base.c:
+       $(MZSCHEME_MZC) --c-mods mzscheme_base.c ++lib scheme/base
 
 objects/if_perl.o: auto/if_perl.c
        $(CCC) -o $@ auto/if_perl.c
index 596e0349d56998347e30a1a160d403b845470a3d..42f4784ddc7e9beed426b9e00c443ad5b1b67fc0 100755 (executable)
@@ -701,6 +701,8 @@ PERL_SRC
 shrpenv
 vi_cv_perllib
 vi_cv_path_perl
+MZSCHEME_MZC
+MZSCHEME_EXTRA
 MZSCHEME_CFLAGS
 MZSCHEME_LIBS
 MZSCHEME_PRO
@@ -4641,8 +4643,8 @@ $as_echo_n "checking PLTHOME environment var... " >&6; }
 $as_echo "\"$PLTHOME\"" >&6; }
        vi_cv_path_mzscheme_pfx="$PLTHOME"
     else
-       { $as_echo "$as_me:$LINENO: result: \"not set\"" >&5
-$as_echo "\"not set\"" >&6; }
+       { $as_echo "$as_me:$LINENO: result: not set" >&5
+$as_echo "not set" >&6; }
                # Extract the first word of "mzscheme", so it can be a program name with args.
 set dummy mzscheme; ac_word=$2
 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
@@ -4697,16 +4699,16 @@ $as_echo_n "checking MzScheme install prefix... " >&6; }
 if test "${vi_cv_path_mzscheme_pfx+set}" = set; then
   $as_echo_n "(cached) " >&6
 else
-   vi_cv_path_mzscheme_pfx=`
-           ${vi_cv_path_mzscheme} -evm \
-           "(display (simplify-path            \
+                   echo "(display (simplify-path               \
               (build-path (call-with-values    \
                (lambda () (split-path (find-system-path (quote exec-file)))) \
-               (lambda (base name must-be-dir?) base)) (quote up))))"`
+               (lambda (base name must-be-dir?) base)) (quote up))))" > mzdirs.scm
+                    vi_cv_path_mzscheme_pfx=`${vi_cv_path_mzscheme} -r mzdirs.scm | \
+               sed -e 's+/$++'`
 fi
 { $as_echo "$as_me:$LINENO: result: $vi_cv_path_mzscheme_pfx" >&5
 $as_echo "$vi_cv_path_mzscheme_pfx" >&6; }
-                   vi_cv_path_mzscheme_pfx=`echo "$vi_cv_path_mzscheme_pfx" | sed 's+/$++'`
+           rm -f mzdirs.scm
        fi
     fi
   fi
@@ -4716,21 +4718,32 @@ $as_echo "$vi_cv_path_mzscheme_pfx" >&6; }
     { $as_echo "$as_me:$LINENO: checking if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include" >&5
 $as_echo_n "checking if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include... " >&6; }
     if test -f $vi_cv_path_mzscheme_pfx/include/scheme.h; then
-      { $as_echo "$as_me:$LINENO: result: \"yes\"" >&5
-$as_echo "\"yes\"" >&6; }
+      SCHEME_INC=${vi_cv_path_mzscheme_pfx}/include
+      { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
     else
-      { $as_echo "$as_me:$LINENO: result: \"no\"" >&5
-$as_echo "\"no\"" >&6; }
-      { $as_echo "$as_me:$LINENO: checking if scheme.h can be found in $vi_cv_path_mzscheme_pfx/plt/include" >&5
-$as_echo_n "checking if scheme.h can be found in $vi_cv_path_mzscheme_pfx/plt/include... " >&6; }
+      { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+      { $as_echo "$as_me:$LINENO: checking if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include/plt" >&5
+$as_echo_n "checking if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include/plt... " >&6; }
       if test -f $vi_cv_path_mzscheme_pfx/include/plt/scheme.h; then
-       { $as_echo "$as_me:$LINENO: result: \"yes\"" >&5
-$as_echo "\"yes\"" >&6; }
-       SCHEME_INC=/plt
+       { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+       SCHEME_INC=${vi_cv_path_mzscheme_pfx}/include/plt
       else
-       { $as_echo "$as_me:$LINENO: result: \"no\"" >&5
-$as_echo "\"no\"" >&6; }
-       vi_cv_path_mzscheme_pfx=
+       { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+       { $as_echo "$as_me:$LINENO: checking if scheme.h can be found in /usr/include/plt/" >&5
+$as_echo_n "checking if scheme.h can be found in /usr/include/plt/... " >&6; }
+       if test -f /usr/include/plt/scheme.h; then
+         { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+         SCHEME_INC=/usr/include/plt
+       else
+         { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+         vi_cv_path_mzscheme_pfx=
+       fi
       fi
     fi
   fi
@@ -4738,21 +4751,34 @@ $as_echo "\"no\"" >&6; }
   if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
     if test "x$MACOSX" = "xyes"; then
       MZSCHEME_LIBS="-framework PLT_MzScheme"
+    elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"; then
+      MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"
+      MZSCHEME_CFLAGS="-DMZ_PRECISE_GC"
     elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
       MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
     else
-      MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
+            if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.so"; then
+        MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme3m"
+       MZSCHEME_CFLAGS="-DMZ_PRECISE_GC"
+      else
+        MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
+      fi
       if test "$GCC" = yes; then
-                       MZSCHEME_LIBS="$MZSCHEME_LIBS -Wl,-rpath -Wl,${vi_cv_path_mzscheme_pfx}/lib"
+                       MZSCHEME_LIBS="${MZSCHEME_LIBS} -Wl,-rpath -Wl,${vi_cv_path_mzscheme_pfx}/lib"
       elif test "`(uname) 2>/dev/null`" = SunOS &&
                               uname -r | grep '^5' >/dev/null; then
-       MZSCHEME_LIBS="$MZSCHEME_LIBS -R ${vi_cv_path_mzscheme_pfx}/lib"
+       MZSCHEME_LIBS="${MZSCHEME_LIBS} -R ${vi_cv_path_mzscheme_pfx}/lib"
       fi
     fi
     if test -d $vi_cv_path_mzscheme_pfx/lib/plt/collects; then
       SCHEME_COLLECTS=lib/plt/
     fi
-    MZSCHEME_CFLAGS="-I${vi_cv_path_mzscheme_pfx}/include${SCHEME_INC}   \
+    if test -f "${vi_cv_path_mzscheme_pfx}/${SCHEME_COLLECTS}collects/scheme/base.ss" ; then
+            MZSCHEME_EXTRA="mzscheme_base.c"
+      MZSCHEME_CFLAGS="${MZSCHEME_CFLAGS} -DINCLUDE_MZSCHEME_BASE"
+      MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/mzc"
+    fi
+    MZSCHEME_CFLAGS="${MZSCHEME_CFLAGS} -I${SCHEME_INC} \
       -DMZSCHEME_COLLECTS='\"${vi_cv_path_mzscheme_pfx}/${SCHEME_COLLECTS}collects\"'"
     MZSCHEME_SRC="if_mzsch.c"
     MZSCHEME_OBJ="objects/if_mzsch.o"
@@ -4767,6 +4793,8 @@ _ACEOF
 
 
 
+
+
 fi
 
 
index 9590d445a1aee878a9768ce4fc117cb10eac3c96..f36e676c194c9e62ba3f534892244a262e6b0f2d 100644 (file)
@@ -41,6 +41,8 @@ MZSCHEME_SRC  = @MZSCHEME_SRC@
 MZSCHEME_OBJ   = @MZSCHEME_OBJ@
 MZSCHEME_CFLAGS        = @MZSCHEME_CFLAGS@
 MZSCHEME_PRO   = @MZSCHEME_PRO@
+MZSCHEME_EXTRA  = @MZSCHEME_EXTRA@
+MZSCHEME_MZC   = @MZSCHEME_MZC@
 
 PERL           = @vi_cv_path_perl@
 PERLLIB                = @vi_cv_perllib@
index a644d941fcc654b3aa5eea38eb52b5ce90a200f9..eb7db7674727710fe20d0c16831dd0df1dcdf8d4 100644 (file)
@@ -414,7 +414,7 @@ if test "$enable_mzschemeinterp" = "yes"; then
        AC_MSG_RESULT("$PLTHOME")
        vi_cv_path_mzscheme_pfx="$PLTHOME"
     else
-       AC_MSG_RESULT("not set")
+       AC_MSG_RESULT(not set)
        dnl -- try to find MzScheme executable
        AC_PATH_PROG(vi_cv_path_mzscheme, mzscheme)
 
@@ -430,14 +430,16 @@ if test "$enable_mzschemeinterp" = "yes"; then
        if test "X$vi_cv_path_mzscheme" != "X"; then
            dnl -- find where MzScheme thinks it was installed
            AC_CACHE_CHECK(MzScheme install prefix,vi_cv_path_mzscheme_pfx,
-           [ vi_cv_path_mzscheme_pfx=`
-           ${vi_cv_path_mzscheme} -evm \
-           "(display (simplify-path            \
+           dnl different versions of MzScheme differ in command line processing
+           dnl use universal approach
+           echo "(display (simplify-path               \
               (build-path (call-with-values    \
                (lambda () (split-path (find-system-path (quote exec-file)))) \
-               (lambda (base name must-be-dir?) base)) (quote up))))"` ])
-           dnl Remove a trailing slash.
-           vi_cv_path_mzscheme_pfx=`echo "$vi_cv_path_mzscheme_pfx" | sed 's+/$++'`
+               (lambda (base name must-be-dir?) base)) (quote up))))" > mzdirs.scm
+           dnl Remove a trailing slash
+           [ vi_cv_path_mzscheme_pfx=`${vi_cv_path_mzscheme} -r mzdirs.scm | \
+               sed -e 's+/$++'` ])
+           rm -f mzdirs.scm
        fi
     fi
   fi
@@ -446,16 +448,24 @@ if test "$enable_mzschemeinterp" = "yes"; then
   if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
     AC_MSG_CHECKING(if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include)
     if test -f $vi_cv_path_mzscheme_pfx/include/scheme.h; then
-      AC_MSG_RESULT("yes")
+      SCHEME_INC=${vi_cv_path_mzscheme_pfx}/include
+      AC_MSG_RESULT(yes)
     else
-      AC_MSG_RESULT("no")
-      AC_MSG_CHECKING(if scheme.h can be found in $vi_cv_path_mzscheme_pfx/plt/include)
+      AC_MSG_RESULT(no)
+      AC_MSG_CHECKING(if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include/plt)
       if test -f $vi_cv_path_mzscheme_pfx/include/plt/scheme.h; then
-       AC_MSG_RESULT("yes")
-       SCHEME_INC=/plt
+       AC_MSG_RESULT(yes)
+       SCHEME_INC=${vi_cv_path_mzscheme_pfx}/include/plt
       else
-       AC_MSG_RESULT("no")
-       vi_cv_path_mzscheme_pfx=
+       AC_MSG_RESULT(no)
+       AC_MSG_CHECKING(if scheme.h can be found in /usr/include/plt/)
+       if test -f /usr/include/plt/scheme.h; then
+         AC_MSG_RESULT(yes)
+         SCHEME_INC=/usr/include/plt
+       else
+         AC_MSG_RESULT(no)
+         vi_cv_path_mzscheme_pfx=
+       fi
       fi
     fi
   fi
@@ -463,23 +473,38 @@ if test "$enable_mzschemeinterp" = "yes"; then
   if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
     if test "x$MACOSX" = "xyes"; then
       MZSCHEME_LIBS="-framework PLT_MzScheme"
+    elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"; then
+      MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"
+      MZSCHEME_CFLAGS="-DMZ_PRECISE_GC"
     elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
       MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
     else
-      MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
+      dnl Using shared objects
+      if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.so"; then
+        MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme3m"
+       MZSCHEME_CFLAGS="-DMZ_PRECISE_GC"
+      else
+        MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
+      fi
       if test "$GCC" = yes; then
        dnl Make Vim remember the path to the library.  For when it's not in
        dnl $LD_LIBRARY_PATH.
-       MZSCHEME_LIBS="$MZSCHEME_LIBS -Wl,-rpath -Wl,${vi_cv_path_mzscheme_pfx}/lib"
+       MZSCHEME_LIBS="${MZSCHEME_LIBS} -Wl,-rpath -Wl,${vi_cv_path_mzscheme_pfx}/lib"
       elif test "`(uname) 2>/dev/null`" = SunOS &&
                               uname -r | grep '^5' >/dev/null; then
-       MZSCHEME_LIBS="$MZSCHEME_LIBS -R ${vi_cv_path_mzscheme_pfx}/lib"
+       MZSCHEME_LIBS="${MZSCHEME_LIBS} -R ${vi_cv_path_mzscheme_pfx}/lib"
       fi
     fi
     if test -d $vi_cv_path_mzscheme_pfx/lib/plt/collects; then
       SCHEME_COLLECTS=lib/plt/
     fi
-    MZSCHEME_CFLAGS="-I${vi_cv_path_mzscheme_pfx}/include${SCHEME_INC}   \
+    if test -f "${vi_cv_path_mzscheme_pfx}/${SCHEME_COLLECTS}collects/scheme/base.ss" ; then
+      dnl need to generate bytecode for MzScheme base
+      MZSCHEME_EXTRA="mzscheme_base.c"
+      MZSCHEME_CFLAGS="${MZSCHEME_CFLAGS} -DINCLUDE_MZSCHEME_BASE"
+      MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/mzc"
+    fi
+    MZSCHEME_CFLAGS="${MZSCHEME_CFLAGS} -I${SCHEME_INC} \
       -DMZSCHEME_COLLECTS='\"${vi_cv_path_mzscheme_pfx}/${SCHEME_COLLECTS}collects\"'"
     MZSCHEME_SRC="if_mzsch.c"
     MZSCHEME_OBJ="objects/if_mzsch.o"
@@ -491,6 +516,8 @@ if test "$enable_mzschemeinterp" = "yes"; then
   AC_SUBST(MZSCHEME_PRO)
   AC_SUBST(MZSCHEME_LIBS)
   AC_SUBST(MZSCHEME_CFLAGS)
+  AC_SUBST(MZSCHEME_EXTRA)
+  AC_SUBST(MZSCHEME_MZC)
 fi
 
 
index 2e3d9fd7725ea625a980443b93f4a6edcc6dad06..bf0c3030f765f907bb7b24f6265ae36ba5b0f498 100644 (file)
@@ -5866,7 +5866,7 @@ list_equal(l1, l2, ic)
     return item1 == NULL && item2 == NULL;
 }
 
-#if defined(FEAT_PYTHON) || defined(PROTO)
+#if defined(FEAT_PYTHON) || defined(FEAT_MZSCHEME) || defined(PROTO)
 /*
  * Return the dictitem that an entry in a hashtable points to.
  */
index 7f43cab6ed04891e5a17e1a1c02f7fb0f2f8a782..017f8041edafdc5f31dd27636f0902acf78617ba 100644 (file)
@@ -4,6 +4,8 @@
  * Original work by Brent Fulgham <bfulgham@debian.org>
  * (Based on lots of help from Matthew Flatt)
  *
+ * TODO Convert byte-strings to char strings?
+ *
  * This consists of six parts:
  * 1. MzScheme interpreter main program
  * 2. Routines that handle the external interface between MzScheme and
@@ -18,7 +20,7 @@
  *    garbage collector will do it self
  * 2. Requires at least NORMAL features. I can't imagine why one may want
  *    to build with SMALL or TINY features but with MzScheme interface.
- * 3. I don't use K&R-style functions. Anyway, MzScheme headers are ANSI.
+ * 3. I don't use K&R-style functions. Anyways, MzScheme headers are ANSI.
  */
 
 #include "vim.h"
  * depend". */
 #if defined(FEAT_MZSCHEME) || defined(PROTO)
 
+#include <assert.h>
+
 /* Base data structures */
 #define SCHEME_VIMBUFFERP(obj)  SAME_TYPE(SCHEME_TYPE(obj), mz_buffer_type)
 #define SCHEME_VIMWINDOWP(obj)  SAME_TYPE(SCHEME_TYPE(obj), mz_window_type)
 
 typedef struct
 {
-    Scheme_Type            tag;
-    Scheme_Env     *env;
+    Scheme_Object   so;
     buf_T          *buf;
 } vim_mz_buffer;
 
@@ -44,7 +47,7 @@ typedef struct
 
 typedef struct
 {
-    Scheme_Type            tag;
+    Scheme_Object   so;
     win_T          *win;
 } vim_mz_window;
 
@@ -67,19 +70,6 @@ typedef struct
     Scheme_Object   *port;
 } Port_Info;
 
-/* info for closed prim */
-/*
- * data have different means:
- * for do_eval it is char*
- * for do_apply is Apply_Onfo*
- * for do_load is Port_Info*
- */
-typedef struct
-{
-    void       *data;
-    Scheme_Env *env;
-} Cmd_Info;
-
 /* info for do_apply */
 typedef struct
 {
@@ -122,7 +112,6 @@ static Scheme_Object *set_buffer_line_list(void *, int, Scheme_Object **);
 static Scheme_Object *insert_buffer_line_list(void *, int, Scheme_Object **);
 static Scheme_Object *get_range_start(void *, int, Scheme_Object **);
 static Scheme_Object *get_range_end(void *, int, Scheme_Object **);
-static Scheme_Object *get_buffer_namespace(void *, int, Scheme_Object **);
 static vim_mz_buffer *get_vim_curr_buffer(void);
 
 /*  Window-related commands */
@@ -163,8 +152,6 @@ static int vim_error_check(void);
 static int do_mzscheme_command(exarg_T *, void *, Scheme_Closed_Prim *what);
 static void startup_mzscheme(void);
 static char *string_to_line(Scheme_Object *obj);
-static int mzscheme_io_init(void);
-static void mzscheme_interface_init(vim_mz_buffer *self);
 static void do_output(char *mesg, long len);
 static void do_printf(char *format, ...);
 static void do_flush(void);
@@ -174,19 +161,52 @@ static Scheme_Object *extract_exn_message(Scheme_Object *v);
 static Scheme_Object *do_eval(void *, int noargc, Scheme_Object **noargv);
 static Scheme_Object *do_load(void *, int noargc, Scheme_Object **noargv);
 static Scheme_Object *do_apply(void *, int noargc, Scheme_Object **noargv);
-static void register_vim_exn(Scheme_Env *env);
+static void register_vim_exn(void);
 static vim_mz_buffer *get_buffer_arg(const char *fname, int argnum,
        int argc, Scheme_Object **argv);
 static vim_mz_window *get_window_arg(const char *fname, int argnum,
        int argc, Scheme_Object **argv);
-static void add_vim_exn(Scheme_Env *env);
 static int line_in_range(linenr_T, buf_T *);
 static void check_line_range(linenr_T, buf_T *);
 static void mz_fix_cursor(int lo, int hi, int extra);
 
-static int eval_in_namespace(void *, Scheme_Closed_Prim *, Scheme_Env *,
-               Scheme_Object **ret);
-static void make_modules(Scheme_Env *);
+static int eval_with_exn_handling(void *, Scheme_Closed_Prim *,
+           Scheme_Object **ret);
+static void make_modules(void);
+static void init_exn_catching_apply(void);
+static int mzscheme_env_main(Scheme_Env *env, int argc, char **argv);
+static int mzscheme_init(void);
+#ifdef FEAT_EVAL
+static Scheme_Object *vim_to_mzscheme(typval_T *vim_value, int depth,
+       Scheme_Hash_Table *visited);
+#endif
+
+#ifdef MZ_PRECISE_GC
+static int buffer_size_proc(void *obj)
+{
+    return gcBYTES_TO_WORDS(sizeof(vim_mz_buffer));
+}
+static int buffer_mark_proc(void *obj)
+{
+    return buffer_size_proc(obj);
+}
+static int buffer_fixup_proc(void *obj)
+{
+    return buffer_size_proc(obj);
+}
+static int window_size_proc(void *obj)
+{
+    return gcBYTES_TO_WORDS(sizeof(vim_mz_window));
+}
+static int window_mark_proc(void *obj)
+{
+    return window_size_proc(obj);
+}
+static int window_fixup_proc(void *obj)
+{
+    return window_size_proc(obj);
+}
+#endif
 
 #ifdef DYNAMIC_MZSCHEME
 
@@ -260,8 +280,6 @@ static Scheme_Object *(*dll_scheme_make_closed_prim_w_arity)
     (Scheme_Closed_Prim *prim, void *data, const char *name, mzshort mina,
      mzshort maxa);
 static Scheme_Object *(*dll_scheme_make_integer_value)(long i);
-static Scheme_Object *(*dll_scheme_make_namespace)(int argc,
-       Scheme_Object *argv[]);
 static Scheme_Object *(*dll_scheme_make_pair)(Scheme_Object *car,
        Scheme_Object *cdr);
 static Scheme_Object *(*dll_scheme_make_prim_w_arity)(Scheme_Prim *prim,
@@ -311,6 +329,17 @@ static Scheme_Object *(*dll_scheme_char_string_to_byte_string)
 static Scheme_Object *(*dll_scheme_char_string_to_path)
     (Scheme_Object *s);
 # endif
+static Scheme_Hash_Table *(*dll_scheme_make_hash_table)(int type);
+static void (*dll_scheme_hash_set)(Scheme_Hash_Table *table,
+       Scheme_Object *key, Scheme_Object *value);
+static Scheme_Object *(*dll_scheme_hash_get)(Scheme_Hash_Table *table,
+       Scheme_Object *key);
+static Scheme_Object *(*dll_scheme_make_double)(double d);
+# ifdef INCLUDE_MZSCHEME_BASE
+static Scheme_Object *(*dll_scheme_make_sized_byte_string)(char *chars,
+       long len, int copy);
+static Scheme_Object *(*dll_scheme_namespace_require)(Scheme_Object *req);
+# endif
 
 /* arrays are imported directly */
 # define scheme_eof dll_scheme_eof
@@ -368,7 +397,6 @@ static Scheme_Object *(*dll_scheme_char_string_to_path)
 # define scheme_lookup_global dll_scheme_lookup_global
 # define scheme_make_closed_prim_w_arity dll_scheme_make_closed_prim_w_arity
 # define scheme_make_integer_value dll_scheme_make_integer_value
-# define scheme_make_namespace dll_scheme_make_namespace
 # define scheme_make_pair dll_scheme_make_pair
 # define scheme_make_prim_w_arity dll_scheme_make_prim_w_arity
 # if MZSCHEME_VERSION_MAJOR < 299
@@ -403,6 +431,14 @@ static Scheme_Object *(*dll_scheme_char_string_to_path)
 #  define scheme_char_string_to_path \
     dll_scheme_char_string_to_path
 # endif
+# define scheme_make_hash_table dll_scheme_make_hash_table
+# define scheme_hash_set dll_scheme_hash_set
+# define scheme_hash_get dll_scheme_hash_get
+# define scheme_make_double dll_scheme_make_double
+# ifdef INCLUDE_MZSCHEME_BASE
+#  define scheme_make_sized_byte_string dll_scheme_make_sized_byte_string
+#  define scheme_namespace_require dll_scheme_namespace_require
+# endif
 
 typedef struct
 {
@@ -468,7 +504,6 @@ static Thunk_Info mzsch_imports[] = {
     {"scheme_make_closed_prim_w_arity",
        (void **)&dll_scheme_make_closed_prim_w_arity},
     {"scheme_make_integer_value", (void **)&dll_scheme_make_integer_value},
-    {"scheme_make_namespace", (void **)&dll_scheme_make_namespace},
     {"scheme_make_pair", (void **)&dll_scheme_make_pair},
     {"scheme_make_prim_w_arity", (void **)&dll_scheme_make_prim_w_arity},
 # if MZSCHEME_VERSION_MAJOR < 299
@@ -502,9 +537,16 @@ static Thunk_Info mzsch_imports[] = {
     {"scheme_current_config", (void **)&dll_scheme_current_config},
     {"scheme_char_string_to_byte_string",
        (void **)&dll_scheme_char_string_to_byte_string},
-    {"scheme_char_string_to_path",
-       (void **)&dll_scheme_char_string_to_path},
+    {"scheme_char_string_to_path", (void **)&dll_scheme_char_string_to_path},
 # endif
+    {"scheme_make_hash_table", (void **)&dll_scheme_make_hash_table},
+    {"scheme_hash_set", (void **)&dll_scheme_hash_set},
+    {"scheme_hash_get", (void **)&dll_scheme_hash_get},
+    {"scheme_make_double", (void **)&dll_scheme_make_double},
+# ifdef INCLUDE_MZSCHEME_BASE
+    {"scheme_make_sized_byte_string", (void **)&dll_scheme_make_sized_byte_string},
+    {"scheme_namespace_require", (void **)&dll_scheme_namespace_require},
+#endif
     {NULL, NULL}};
 
 static HINSTANCE hMzGC = 0;
@@ -592,6 +634,11 @@ dynamic_mzscheme_end(void)
 }
 #endif /* DYNAMIC_MZSCHEME */
 
+/* need to put it here for dynamic stuff to work */
+#ifdef INCLUDE_MZSCHEME_BASE
+# include "mzscheme_base.c"
+#endif
+
 /*
  *========================================================================
  *  1. MzScheme interpreter startup
@@ -601,21 +648,22 @@ dynamic_mzscheme_end(void)
 static Scheme_Type mz_buffer_type;
 static Scheme_Type mz_window_type;
 
-static int initialized = 0;
+static int initialized = FALSE;
 
 /* global environment */
 static Scheme_Env    *environment = NULL;
 /* output/error handlers */
 static Scheme_Object *curout = NULL;
 static Scheme_Object *curerr = NULL;
-/* vim:exn exception */
+/* exn:vim exception */
 static Scheme_Object *exn_catching_apply = NULL;
 static Scheme_Object *exn_p = NULL;
 static Scheme_Object *exn_message = NULL;
 static Scheme_Object *vim_exn = NULL; /* Vim Error exception */
- /* values for exn:vim - constructor, predicate, accessors etc */
-static Scheme_Object *vim_exn_names = NULL;
-static Scheme_Object *vim_exn_values = NULL;
+
+#if !defined(MZ_PRECISE_GC) || MZSCHEME_VERSION_MAJOR < 400
+static void *stack_base = NULL;
+#endif
 
 static long range_start;
 static long range_end;
@@ -668,10 +716,10 @@ static void remove_timer(void);
 timer_proc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
 # elif defined(FEAT_GUI_GTK)
     static gint
-timer_proc(gpointer data UNUSED)
+timer_proc(gpointer data)
 # elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)
     static void
-timer_proc(XtPointer timed_out UNUSED, XtIntervalId *interval_id UNUSED)
+timer_proc(XtPointer timed_out, XtIntervalId *interval_id)
 # elif defined(FEAT_GUI_MAC)
     pascal void
 timer_proc(EventLoopTimerRef theTimer, void *userData)
@@ -751,12 +799,64 @@ mzscheme_end(void)
 #endif
 }
 
+    void
+mzscheme_main(void)
+{
+#if defined(MZ_PRECISE_GC) && MZSCHEME_VERSION_MAJOR >= 400
+    /* use trampoline for precise GC in MzScheme >= 4.x */
+    scheme_main_setup(TRUE, mzscheme_env_main, 0, NULL);
+#else
+    mzscheme_env_main(NULL, 0, NULL);
+#endif
+}
+
+    static int
+mzscheme_env_main(Scheme_Env *env, int argc, char **argv)
+{
+    /* neither argument nor return values are used */
+#ifdef MZ_PRECISE_GC
+# if MZSCHEME_VERSION_MAJOR < 400
+    /*
+     * Starting from version 4.x, embedding applications must use
+     * scheme_main_setup/scheme_main_stack_setup trampolines
+     * rather than setting stack base directly with scheme_set_stack_base
+     */
+    Scheme_Object   *dummy = NULL;
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, dummy);
+
+    stack_base = &__gc_var_stack__;
+# else
+    /* environment has been created by us by Scheme */
+    environment = env;
+# endif
+    /*
+     * In 4.x, all activities must be performed inside trampoline
+     * so we are forced to initialise GC immediately
+     * This can be postponed in 3.x but I see no point in implementing
+     * a feature which will work in older versions only.
+     * One would better use conservative GC if he needs dynamic MzScheme
+     */
+    mzscheme_init();
+#else
+    int dummy = 0;
+    stack_base = (void *)&dummy;
+#endif
+    main_loop(FALSE, FALSE);
+#if defined(MZ_PRECISE_GC) && MZSCHEME_VERSION_MAJOR < 400
+    /* releasing dummy */
+    MZ_GC_REG();
+    MZ_GC_UNREG();
+#endif
+    return 0;
+}
+
     static void
 startup_mzscheme(void)
 {
-    Scheme_Object *proc_make_security_guard;
-
-    scheme_set_stack_base(NULL, 1);
+#if !defined(MZ_PRECISE_GC) || MZSCHEME_VERSION_MAJOR < 400
+    scheme_set_stack_base(stack_base, 1);
+#endif
 
     MZ_REGISTER_STATIC(environment);
     MZ_REGISTER_STATIC(curout);
@@ -765,10 +865,35 @@ startup_mzscheme(void)
     MZ_REGISTER_STATIC(exn_p);
     MZ_REGISTER_STATIC(exn_message);
     MZ_REGISTER_STATIC(vim_exn);
-    MZ_REGISTER_STATIC(vim_exn_names);
-    MZ_REGISTER_STATIC(vim_exn_values);
 
+#if !defined(MZ_PRECISE_GC) || MZSCHEME_VERSION_MAJOR < 400
+    /* in newer versions of precise GC the initial env has been created */
     environment = scheme_basic_env();
+#endif
+    MZ_GC_CHECK();
+
+#ifdef INCLUDE_MZSCHEME_BASE
+    {
+       /*
+        * versions 4.x do not provide Scheme bindings by defaults
+        * we need to add them explicitly
+        */
+       Scheme_Object *scheme_base_symbol = NULL;
+       MZ_GC_DECL_REG(1);
+       MZ_GC_VAR_IN_REG(0, scheme_base_symbol);
+       MZ_GC_REG();
+       /* invoke function from generated and included base.c */
+       declare_modules(environment);
+       scheme_base_symbol = scheme_intern_symbol("scheme/base");
+       MZ_GC_CHECK();
+       scheme_namespace_require(scheme_base_symbol);
+       MZ_GC_CHECK();
+       MZ_GC_UNREG();
+    }
+#endif
+    register_vim_exn();
+    /* use new environment to initialise exception handling */
+    init_exn_catching_apply();
 
     /* redirect output */
     scheme_console_output = do_output;
@@ -776,48 +901,131 @@ startup_mzscheme(void)
 
 #ifdef MZSCHEME_COLLECTS
     /* setup 'current-library-collection-paths' parameter */
-    scheme_set_param(scheme_config, MZCONFIG_COLLECTION_PATHS,
-           scheme_make_pair(
 # if MZSCHEME_VERSION_MAJOR >= 299
-               scheme_char_string_to_path(
-                   scheme_byte_string_to_char_string(
-                       scheme_make_byte_string(MZSCHEME_COLLECTS))),
+    {
+       Scheme_Object   *coll_byte_string = NULL;
+       Scheme_Object   *coll_char_string = NULL;
+       Scheme_Object   *coll_path = NULL;
+       Scheme_Object   *coll_pair = NULL;
+       Scheme_Config   *config = NULL;
+
+       MZ_GC_DECL_REG(5);
+       MZ_GC_VAR_IN_REG(0, coll_byte_string);
+       MZ_GC_VAR_IN_REG(1, coll_char_string);
+       MZ_GC_VAR_IN_REG(2, coll_path);
+       MZ_GC_VAR_IN_REG(3, coll_pair);
+       MZ_GC_VAR_IN_REG(4, config);
+       MZ_GC_REG();
+       coll_byte_string = scheme_make_byte_string(MZSCHEME_COLLECTS);
+       MZ_GC_CHECK();
+       coll_char_string = scheme_byte_string_to_char_string(coll_byte_string);
+       MZ_GC_CHECK();
+       coll_path = scheme_char_string_to_path(coll_char_string);
+       MZ_GC_CHECK();
+       coll_pair = scheme_make_pair(coll_path, scheme_null);
+       MZ_GC_CHECK();
+       config = scheme_config;
+       MZ_GC_CHECK();
+       scheme_set_param(config, MZCONFIG_COLLECTION_PATHS, coll_pair);
+       MZ_GC_CHECK();
+       MZ_GC_UNREG();
+    }
 # else
-               scheme_make_string(MZSCHEME_COLLECTS),
+    {
+       Scheme_Object   *coll_string = NULL;
+       Scheme_Object   *coll_pair = NULL;
+       Scheme_Config   *config = NULL;
+
+       MZ_GC_DECL_REG(3);
+       MZ_GC_VAR_IN_REG(0, coll_string);
+       MZ_GC_VAR_IN_REG(1, coll_pair);
+       MZ_GC_VAR_IN_REG(2, config);
+       MZ_GC_REG();
+       coll_string = scheme_make_string(MZSCHEME_COLLECTS);
+       MZ_GC_CHECK();
+       coll_pair = scheme_make_pair(coll_string, scheme_null);
+       MZ_GC_CHECK();
+       config = scheme_config;
+       MZ_GC_CHECK();
+       scheme_set_param(config, MZCONFIG_COLLECTION_PATHS, coll_pair);
+       MZ_GC_CHECK();
+       MZ_GC_UNREG();
+    }
 # endif
-               scheme_null));
 #endif
 #ifdef HAVE_SANDBOX
-    /* setup sandbox guards */
-    proc_make_security_guard = scheme_lookup_global(
-           scheme_intern_symbol("make-security-guard"),
-           environment);
-    if (proc_make_security_guard != NULL)
     {
-       Scheme_Object *args[3];
-       Scheme_Object *guard;
-       args[0] = scheme_get_param(scheme_config, MZCONFIG_SECURITY_GUARD);
-       args[1] = scheme_make_prim_w_arity(sandbox_file_guard,
-               "sandbox-file-guard", 3, 3);
-       args[2] = scheme_make_prim_w_arity(sandbox_network_guard,
-               "sandbox-network-guard", 4, 4);
-       guard = scheme_apply(proc_make_security_guard, 3, args);
-       scheme_set_param(scheme_config, MZCONFIG_SECURITY_GUARD, guard);
+       Scheme_Object   *make_security_guard = NULL;
+       MZ_GC_DECL_REG(1);
+       MZ_GC_VAR_IN_REG(0, make_security_guard);
+       MZ_GC_REG();
+
+#if MZSCHEME_VERSION_MAJOR < 400
+       {
+           Scheme_Object       *make_security_guard_symbol = NULL;
+           MZ_GC_DECL_REG(1);
+           MZ_GC_VAR_IN_REG(0, make_security_guard_symbol);
+           MZ_GC_REG();
+           make_security_guard_symbol = scheme_intern_symbol("make-security-guard");
+           MZ_GC_CHECK();
+           make_security_guard = scheme_lookup_global(
+                   make_security_guard_symbol, environment);
+           MZ_GC_UNREG();
+       }
+#else
+       make_security_guard = scheme_builtin_value("make-security-guard");
+       MZ_GC_CHECK();
+#endif
+
+       /* setup sandbox guards */
+       if (make_security_guard != NULL)
+       {
+           Scheme_Object   *args[3] = {NULL, NULL, NULL};
+           Scheme_Object   *guard = NULL;
+           Scheme_Config   *config = NULL;
+           MZ_GC_DECL_REG(5);
+           MZ_GC_ARRAY_VAR_IN_REG(0, args, 3);
+           MZ_GC_VAR_IN_REG(3, guard);
+           MZ_GC_VAR_IN_REG(4, config);
+           MZ_GC_REG();
+           config = scheme_config;
+           MZ_GC_CHECK();
+           args[0] = scheme_get_param(config, MZCONFIG_SECURITY_GUARD);
+           MZ_GC_CHECK();
+           args[1] = scheme_make_prim_w_arity(sandbox_file_guard,
+                   "sandbox-file-guard", 3, 3);
+           args[2] = scheme_make_prim_w_arity(sandbox_network_guard,
+                   "sandbox-network-guard", 4, 4);
+           guard = scheme_apply(make_security_guard, 3, args);
+           MZ_GC_CHECK();
+           scheme_set_param(config, MZCONFIG_SECURITY_GUARD, guard);
+           MZ_GC_CHECK();
+           MZ_GC_UNREG();
+       }
+       MZ_GC_UNREG();
     }
 #endif
     /* Create buffer and window types for use in Scheme code */
     mz_buffer_type = scheme_make_type("<vim-buffer>");
+    MZ_GC_CHECK();
     mz_window_type = scheme_make_type("<vim-window>");
+    MZ_GC_CHECK();
+#ifdef MZ_PRECISE_GC
+    GC_register_traversers(mz_buffer_type,
+           buffer_size_proc, buffer_mark_proc, buffer_fixup_proc,
+           TRUE, TRUE);
+    GC_register_traversers(mz_window_type,
+           window_size_proc, window_mark_proc, window_fixup_proc,
+           TRUE, TRUE);
+#endif
 
-    register_vim_exn(environment);
-    make_modules(environment);
+    make_modules();
 
     /*
      * setup callback to receive notifications
      * whether thread scheduling is (or not) required
      */
     scheme_notify_multithread = notify_multithread;
-    initialized = 1;
 }
 
 /*
@@ -827,73 +1035,40 @@ startup_mzscheme(void)
     static int
 mzscheme_init(void)
 {
-    int do_require = FALSE;
-
     if (!initialized)
     {
-       do_require = TRUE;
 #ifdef DYNAMIC_MZSCHEME
        if (!mzscheme_enabled(TRUE))
        {
-           EMSG(_("???: Sorry, this command is disabled, the MzScheme library could not be loaded."));
+           EMSG(_("E812: Sorry, this command is disabled, the MzScheme libraries could not be loaded."));
            return -1;
        }
 #endif
        startup_mzscheme();
-
-       if (mzscheme_io_init())
-           return -1;
-
+       initialized = TRUE;
     }
-    /* recreate ports each call effectivelly clearing these ones */
-    curout = scheme_make_string_output_port();
-    curerr = scheme_make_string_output_port();
-    scheme_set_param(scheme_config, MZCONFIG_OUTPUT_PORT, curout);
-    scheme_set_param(scheme_config, MZCONFIG_ERROR_PORT, curerr);
-
-    if (do_require)
     {
-       /* auto-instantiate in basic env */
-       eval_in_namespace("(require (prefix vimext: vimext))", do_eval,
-               environment, NULL);
+       Scheme_Config   *config = NULL;
+       MZ_GC_DECL_REG(1);
+       MZ_GC_VAR_IN_REG(0, config);
+       MZ_GC_REG();
+       config = scheme_config;
+       MZ_GC_CHECK();
+       /* recreate ports each call effectivelly clearing these ones */
+       curout = scheme_make_string_output_port();
+       MZ_GC_CHECK();
+       curerr = scheme_make_string_output_port();
+       MZ_GC_CHECK();
+       scheme_set_param(config, MZCONFIG_OUTPUT_PORT, curout);
+       MZ_GC_CHECK();
+       scheme_set_param(config, MZCONFIG_ERROR_PORT, curerr);
+       MZ_GC_CHECK();
+       MZ_GC_UNREG();
     }
 
     return 0;
 }
 
-/*
- * This routine fills the namespace with various important routines that can
- * be used within MzScheme.
- */
-    static void
-mzscheme_interface_init(vim_mz_buffer *mzbuff)
-{
-    Scheme_Object   *attach;
-
-    mzbuff->env = (Scheme_Env *)scheme_make_namespace(0, NULL);
-
-    /*
-     * attach instantiated modules from global namespace
-     * so they can be easily instantiated in the buffer namespace
-     */
-    attach = scheme_lookup_global(
-           scheme_intern_symbol("namespace-attach-module"),
-           environment);
-
-    if (attach != NULL)
-    {
-       Scheme_Object   *ret;
-       Scheme_Object   *args[2];
-
-       args[0] = (Scheme_Object *)environment;
-       args[1] = scheme_intern_symbol("vimext");
-
-       ret = (Scheme_Object *)mzvim_apply(attach, 2, args);
-    }
-
-    add_vim_exn(mzbuff->env);
-}
-
 /*
  *========================================================================
  *  2.  External Interface
@@ -901,28 +1076,25 @@ mzscheme_interface_init(vim_mz_buffer *mzbuff)
  */
 
 /*
- * Evaluate command in namespace with exception handling
+ * Evaluate command with exception handling
  */
     static int
-eval_in_namespace(void *data, Scheme_Closed_Prim *what, Scheme_Env *env,
-               Scheme_Object **ret)
+eval_with_exn_handling(void *data, Scheme_Closed_Prim *what, Scheme_Object **ret)
 {
-    Scheme_Object   *value;
-    Scheme_Object   *exn;
-    Cmd_Info       info;   /* closure info */
+    Scheme_Object   *value = NULL;
+    Scheme_Object   *exn = NULL;
+    Scheme_Object   *prim = NULL;
 
-    info.data = data;
-    info.env = env;
+    MZ_GC_DECL_REG(3);
+    MZ_GC_VAR_IN_REG(0, value);
+    MZ_GC_VAR_IN_REG(1, exn);
+    MZ_GC_VAR_IN_REG(2, prim);
+    MZ_GC_REG();
 
-    scheme_set_param(scheme_config, MZCONFIG_ENV,
-           (Scheme_Object *) env);
-    /*
-     * ensure all evaluations will be in current buffer namespace,
-     * the second argument to scheme_eval_string isn't enough!
-     */
-    value = _apply_thunk_catch_exceptions(
-           scheme_make_closed_prim_w_arity(what, &info, "mzvim", 0, 0),
-           &exn);
+    prim = scheme_make_closed_prim_w_arity(what, data, "mzvim", 0, 0);
+    MZ_GC_CHECK();
+    value = _apply_thunk_catch_exceptions(prim, &exn);
+    MZ_GC_CHECK();
 
     if (!value)
     {
@@ -930,9 +1102,11 @@ eval_in_namespace(void *data, Scheme_Closed_Prim *what, Scheme_Env *env,
        /* Got an exn? */
        if (value)
        {
-           scheme_display(value, curerr);  /*  Send to stderr-vim */
+           scheme_display(value, curerr);   /*  Send to stderr-vim */
+           MZ_GC_CHECK();
            do_flush();
        }
+       MZ_GC_UNREG();
        /* `raise' was called on some arbitrary value */
        return FAIL;
     }
@@ -941,9 +1115,13 @@ eval_in_namespace(void *data, Scheme_Closed_Prim *what, Scheme_Env *env,
        *ret = value;
     /* Print any result, as long as it's not a void */
     else if (!SCHEME_VOIDP(value))
+    {
        scheme_display(value, curout);  /* Send to stdout-vim */
+       MZ_GC_CHECK();
+    }
 
     do_flush();
+    MZ_GC_UNREG();
     return OK;
 }
 
@@ -957,7 +1135,7 @@ do_mzscheme_command(exarg_T *eap, void *data, Scheme_Closed_Prim *what)
     range_start = eap->line1;
     range_end = eap->line2;
 
-    return eval_in_namespace(data, what, get_vim_curr_buffer()->env, NULL);
+    return eval_with_exn_handling(data, what, NULL);
 }
 
 /*
@@ -974,6 +1152,7 @@ mzscheme_buffer_free(buf_T *buf)
        bp->buf = INVALID_BUFFER_VALUE;
        buf->b_mzscheme_ref = NULL;
        scheme_gc_ptr_ok(bp);
+       MZ_GC_CHECK();
     }
 }
 
@@ -990,6 +1169,7 @@ mzscheme_window_free(win_T *win)
        wp->win = INVALID_WINDOW_VALUE;
        win->w_mzscheme_ref = NULL;
        scheme_gc_ptr_ok(wp);
+       MZ_GC_CHECK();
     }
 }
 
@@ -1014,18 +1194,6 @@ ex_mzscheme(exarg_T *eap)
     }
 }
 
-/* eval MzScheme string */
-    void *
-mzvim_eval_string(char_u *str)
-{
-    Scheme_Object *ret = NULL;
-    if (mzscheme_init())
-       return FAIL;
-
-    eval_in_namespace(str, do_eval, get_vim_curr_buffer()->env, &ret);
-    return ret;
-}
-
 /*
  * apply MzScheme procedure with arguments,
  * handling errors
@@ -1033,43 +1201,65 @@ mzvim_eval_string(char_u *str)
     Scheme_Object *
 mzvim_apply(Scheme_Object *proc, int argc, Scheme_Object **argv)
 {
-    Apply_Info data;
-    Scheme_Object *ret = NULL;
-
     if (mzscheme_init())
        return FAIL;
-
-    data.proc = proc;
-    data.argc = argc;
-    data.argv = argv;
-
-    eval_in_namespace(&data, do_apply, get_vim_curr_buffer()->env, &ret);
-    return ret;
+    else
+    {
+       Apply_Info      data = {NULL, 0, NULL};
+       Scheme_Object   *ret = NULL;
+
+       MZ_GC_DECL_REG(5);
+       MZ_GC_VAR_IN_REG(0, ret);
+       MZ_GC_VAR_IN_REG(1, data.proc);
+       MZ_GC_ARRAY_VAR_IN_REG(2, data.argv, argc);
+       MZ_GC_REG();
+
+       data.proc = proc;
+       data.argc = argc;
+       data.argv = argv;
+
+       eval_with_exn_handling(&data, do_apply, &ret);
+       MZ_GC_UNREG();
+       return ret;
+    }
 }
 
     static Scheme_Object *
 do_load(void *data, int noargc, Scheme_Object **noargv)
 {
-    Cmd_Info       *info = (Cmd_Info *)data;
-    Scheme_Object   *result = scheme_void;
-    Scheme_Object   *expr;
-    char_u         *file = scheme_malloc_fail_ok(
-                                         scheme_malloc_atomic, MAXPATHL + 1);
-    Port_Info      *pinfo = (Port_Info *)(info->data);
+    Scheme_Object   *expr = NULL;
+    Scheme_Object   *result = NULL;
+    char           *file = NULL;
+    Port_Info      *pinfo = (Port_Info *)data;
+
+    MZ_GC_DECL_REG(3);
+    MZ_GC_VAR_IN_REG(0, expr);
+    MZ_GC_VAR_IN_REG(1, result);
+    MZ_GC_VAR_IN_REG(2, file);
+    MZ_GC_REG();
+
+    file = (char *)scheme_malloc_fail_ok(scheme_malloc_atomic, MAXPATHL + 1);
+    MZ_GC_CHECK();
 
     /* make Vim expansion */
-    expand_env((char_u *)pinfo->name, file, MAXPATHL);
-    /* scheme_load looks strange working with namespaces and error handling*/
+    expand_env((char_u *)pinfo->name, (char_u *)file, MAXPATHL);
     pinfo->port = scheme_open_input_file(file, "mzfile");
-    scheme_count_lines(pinfo->port); /* to get accurate read error location*/
+    MZ_GC_CHECK();
+    scheme_count_lines(pinfo->port);  /* to get accurate read error location*/
+    MZ_GC_CHECK();
 
     /* Like REPL but print only last result */
     while (!SCHEME_EOFP(expr = scheme_read(pinfo->port)))
-       result = scheme_eval(expr, info->env);
+    {
+       result = scheme_eval(expr, environment);
+       MZ_GC_CHECK();
+    }
 
     /* errors will be caught in do_mzscheme_comamnd and ex_mzfile */
     scheme_close_input_port(pinfo->port);
+    MZ_GC_CHECK();
     pinfo->port = NULL;
+    MZ_GC_UNREG();
     return result;
 }
 
@@ -1077,13 +1267,20 @@ do_load(void *data, int noargc, Scheme_Object **noargv)
     void
 ex_mzfile(exarg_T *eap)
 {
-    Port_Info  pinfo;
+    Port_Info  pinfo = {NULL, NULL};
+
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, pinfo.port);
+    MZ_GC_REG();
 
     pinfo.name = (char *)eap->arg;
-    pinfo.port = NULL;
     if (do_mzscheme_command(eap, &pinfo, do_load) != OK
            && pinfo.port != NULL)      /* looks like port was not closed */
+    {
        scheme_close_input_port(pinfo.port);
+       MZ_GC_CHECK();
+    }
+    MZ_GC_UNREG();
 }
 
 
@@ -1103,14 +1300,12 @@ init_exn_catching_apply(void)
                "(with-handlers ([void (lambda (exn) (cons #f exn))]) "
                "(cons #t (thunk))))";
 
-       /* make sure we have a namespace with the standard syntax: */
-       Scheme_Env *env = (Scheme_Env *)scheme_make_namespace(0, NULL);
-       add_vim_exn(env);
-
-       exn_catching_apply = scheme_eval_string(e, env);
-       exn_p = scheme_lookup_global(scheme_intern_symbol("exn?"), env);
-       exn_message = scheme_lookup_global(
-               scheme_intern_symbol("exn-message"), env);
+       exn_catching_apply = scheme_eval_string(e, environment);
+       MZ_GC_CHECK();
+       exn_p = scheme_builtin_value("exn?");
+       MZ_GC_CHECK();
+       exn_message = scheme_builtin_value("exn-message");
+       MZ_GC_CHECK();
     }
 }
 
@@ -1124,8 +1319,6 @@ _apply_thunk_catch_exceptions(Scheme_Object *f, Scheme_Object **exn)
 {
     Scheme_Object *v;
 
-    init_exn_catching_apply();
-
     v = _scheme_apply(exn_catching_apply, 1, &f);
     /* v is a pair: (cons #t value) or (cons #f exn) */
 
@@ -1141,8 +1334,6 @@ _apply_thunk_catch_exceptions(Scheme_Object *f, Scheme_Object **exn)
     static Scheme_Object *
 extract_exn_message(Scheme_Object *v)
 {
-    init_exn_catching_apply();
-
     if (SCHEME_TRUEP(_scheme_apply(exn_p, 1, &v)))
        return _scheme_apply(exn_message, 1, &v);
     else
@@ -1152,16 +1343,13 @@ extract_exn_message(Scheme_Object *v)
     static Scheme_Object *
 do_eval(void *s, int noargc, Scheme_Object **noargv)
 {
-    Cmd_Info   *info = (Cmd_Info *)s;
-
-    return scheme_eval_string_all((char *)(info->data), info->env, TRUE);
+    return scheme_eval_string_all((char *)s, environment, TRUE);
 }
 
     static Scheme_Object *
 do_apply(void *a, int noargc, Scheme_Object **noargv)
 {
-    Apply_Info *info = (Apply_Info *)(((Cmd_Info *)a)->data);
-
+    Apply_Info *info = (Apply_Info *)a;
     return scheme_apply(info->proc, info->argc, info->argv);
 }
 
@@ -1219,6 +1407,7 @@ do_flush(void)
     long length;
 
     buff = scheme_get_sized_string_output(curerr, &length);
+    MZ_GC_CHECK();
     if (length)
     {
        do_err_output(buff, length);
@@ -1226,17 +1415,11 @@ do_flush(void)
     }
 
     buff = scheme_get_sized_string_output(curout, &length);
+    MZ_GC_CHECK();
     if (length)
        do_output(buff, length);
 }
 
-    static int
-mzscheme_io_init(void)
-{
-    /* Nothing needed so far... */
-    return 0;
-}
-
 /*
  *========================================================================
  *  4. Implementation of the Vim Features for MzScheme
@@ -1263,22 +1446,30 @@ vim_command(void *data, int argc, Scheme_Object **argv)
 vim_eval(void *data, int argc, Scheme_Object **argv)
 {
 #ifdef FEAT_EVAL
-    Vim_Prim       *prim = (Vim_Prim *)data;
-    char           *expr;
-    char           *str;
-    Scheme_Object   *result;
+    Vim_Prim           *prim = (Vim_Prim *)data;
+    char               *expr;
+    Scheme_Object      *result;
+    /* hash table to store visited values to avoid infinite loops */
+    Scheme_Hash_Table  *visited = NULL;
+    typval_T           *vim_result;
 
-    expr = SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0));
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, visited);
+    MZ_GC_REG();
 
-    str = (char *)eval_to_string((char_u *)expr, NULL, TRUE);
+    visited = scheme_make_hash_table(SCHEME_hash_ptr);
+    MZ_GC_CHECK();
 
-    if (str == NULL)
-       raise_vim_exn(_("invalid expression"));
+    expr = SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0));
+    vim_result = eval_expr((char_u *)expr, NULL);
 
-    result = scheme_make_string(str);
+    if (vim_result == NULL)
+       raise_vim_exn(_("invalid expression"));
 
-    vim_free(str);
+    result = vim_to_mzscheme(vim_result, 1, visited);
+    free_tv(vim_result);
 
+    MZ_GC_UNREG();
     return result;
 #else
     raise_vim_exn(_("expressions disabled at compile time"));
@@ -1318,7 +1509,7 @@ get_option(void *data, int argc, Scheme_Object **argv)
     Vim_Prim       *prim = (Vim_Prim *)data;
     char_u         *name;
     long           value;
-    char_u         *strval;
+    char           *strval;
     int                    rc;
     Scheme_Object   *rval;
     int                    opt_flags = 0;
@@ -1333,6 +1524,7 @@ get_option(void *data, int argc, Scheme_Object **argv)
        {
            MZ_REGISTER_STATIC(M_global);
            M_global = scheme_intern_symbol("global");
+           MZ_GC_CHECK();
        }
 
        if (argv[1] == M_global)
@@ -1354,7 +1546,7 @@ get_option(void *data, int argc, Scheme_Object **argv)
            scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
     }
 
-    rc = get_option_value(name, &value, &strval, opt_flags);
+    rc = get_option_value(name, &value, (char_u **)&strval, opt_flags);
     curbuf = save_curb;
     curwin = save_curw;
 
@@ -1364,6 +1556,7 @@ get_option(void *data, int argc, Scheme_Object **argv)
        return scheme_make_integer_value(value);
     case 0:
        rval = scheme_make_string(strval);
+       MZ_GC_CHECK();
        vim_free(strval);
        return rval;
     case -1:
@@ -1393,6 +1586,7 @@ set_option(void *data, int argc, Scheme_Object **argv)
        {
            MZ_REGISTER_STATIC(M_global);
            M_global = scheme_intern_symbol("global");
+           MZ_GC_CHECK();
        }
 
        if (argv[1] == M_global)
@@ -1463,7 +1657,10 @@ get_window_list(void *data, int argc, Scheme_Object **argv)
 
     for (w = firstwin; w != NULL; w = w->w_next)
        if (w->w_buffer == buf->buf)
+       {
            list = scheme_make_pair(window_new(w), list);
+           MZ_GC_CHECK();
+       }
 
     return list;
 }
@@ -1471,7 +1668,11 @@ get_window_list(void *data, int argc, Scheme_Object **argv)
     static Scheme_Object *
 window_new(win_T *win)
 {
-    vim_mz_window *self;
+    vim_mz_window *self = NULL;
+
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, self);
+    MZ_GC_REG();
 
     /* We need to handle deletion of windows underneath us.
      * If we add a "w_mzscheme_ref" field to the win_T structure,
@@ -1485,13 +1686,14 @@ window_new(win_T *win)
        return win->w_mzscheme_ref;
 
     self = scheme_malloc_fail_ok(scheme_malloc, sizeof(vim_mz_window));
-
     vim_memset(self, 0, sizeof(vim_mz_window));
     scheme_dont_gc_ptr(self);  /* because win isn't visible to GC */
+    MZ_GC_CHECK();
     win->w_mzscheme_ref = self;
     self->win = win;
-    self->tag = mz_window_type;
+    self->so.type = mz_window_type;
 
+    MZ_GC_UNREG();
     return (Scheme_Object *)(self);
 }
 
@@ -1660,7 +1862,6 @@ set_cursor(void *data, int argc, Scheme_Object **argv)
 /*
  *===========================================================================
  *  6. Vim Buffer-related Manipulation Functions
- *     Note that each buffer should have its own private namespace.
  *===========================================================================
  */
 
@@ -1669,14 +1870,14 @@ set_cursor(void *data, int argc, Scheme_Object **argv)
 mzscheme_open_buffer(void *data, int argc, Scheme_Object **argv)
 {
     Vim_Prim       *prim = (Vim_Prim *)data;
-    char           *fname;
+    char_u         *fname;
     int                    num = 0;
     Scheme_Object   *onum;
 
 #ifdef HAVE_SANDBOX
     sandbox_check();
 #endif
-    fname = SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0));
+    fname = (char_u *)SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0));
     /* TODO make open existing file */
     num = buflist_add(fname, BLN_LISTED | BLN_CURBUF);
 
@@ -1712,7 +1913,7 @@ get_buffer_by_name(void *data, int argc, Scheme_Object **argv)
     buf_T      *buf;
     char_u     *fname;
 
-    fname = SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0));
+    fname = (char_u *)SCHEME_STR_VAL(GUARANTEE_STRING(prim->name, 0));
 
     for (buf = firstbuf; buf; buf = buf->b_next)
        if (buf->b_ffname == NULL || buf->b_sfname == NULL)
@@ -1783,7 +1984,7 @@ get_buffer_name(void *data, int argc, Scheme_Object **argv)
     Vim_Prim       *prim = (Vim_Prim *)data;
     vim_mz_buffer   *buf = get_buffer_arg(prim->name, 0, argc, argv);
 
-    return scheme_make_string(buf->buf->b_ffname);
+    return scheme_make_string((char *)buf->buf->b_ffname);
 }
 
 /* (curr-buff) */
@@ -1796,7 +1997,11 @@ get_curr_buffer(void *data, int argc, Scheme_Object **argv)
     static Scheme_Object *
 buffer_new(buf_T *buf)
 {
-    vim_mz_buffer *self;
+    vim_mz_buffer *self = NULL;
+
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, self);
+    MZ_GC_REG();
 
     /* We need to handle deletion of buffers underneath us.
      * If we add a "b_mzscheme_ref" field to the buf_T structure,
@@ -1806,15 +2011,14 @@ buffer_new(buf_T *buf)
        return buf->b_mzscheme_ref;
 
     self = scheme_malloc_fail_ok(scheme_malloc, sizeof(vim_mz_buffer));
-
     vim_memset(self, 0, sizeof(vim_mz_buffer));
-    scheme_dont_gc_ptr(self);  /* because buf isn't visible to GC */
+    scheme_dont_gc_ptr(self); /* because buf isn't visible to GC */
+    MZ_GC_CHECK();
     buf->b_mzscheme_ref = self;
     self->buf = buf;
-    self->tag = mz_buffer_type;
-
-    mzscheme_interface_init(self);     /* Set up namespace */
+    self->so.type = mz_buffer_type;
 
+    MZ_GC_UNREG();
     return (Scheme_Object *)(self);
 }
 
@@ -1845,14 +2049,14 @@ get_buffer_line(void *data, int argc, Scheme_Object **argv)
     Vim_Prim       *prim = (Vim_Prim *)data;
     vim_mz_buffer   *buf;
     int                    linenr;
-    char           *line;
+    char_u         *line;
 
     buf = get_buffer_arg(prim->name, 1, argc, argv);
     linenr = SCHEME_INT_VAL(GUARANTEE_INTEGER(prim->name, 0));
     line = ml_get_buf(buf->buf, (linenr_T)linenr, FALSE);
 
     raise_if_error();
-    return scheme_make_string(line);
+    return scheme_make_string((char *)line);
 }
 
 
@@ -1869,7 +2073,11 @@ get_buffer_line_list(void *data, int argc, Scheme_Object **argv)
     Vim_Prim       *prim = (Vim_Prim *)data;
     vim_mz_buffer   *buf;
     int                    i, hi, lo, n;
-    Scheme_Object   *list;
+    Scheme_Object   *list = NULL;
+
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, list);
+    MZ_GC_REG();
 
     buf = get_buffer_arg(prim->name, 2, argc, argv);
     list = scheme_null;
@@ -1897,8 +2105,9 @@ get_buffer_line_list(void *data, int argc, Scheme_Object **argv)
 
        /* Set the list item */
        list = scheme_make_pair(str, list);
+       MZ_GC_CHECK();
     }
-
+    MZ_GC_UNREG();
     return list;
 }
 
@@ -1925,11 +2134,14 @@ set_buffer_line(void *data, int argc, Scheme_Object **argv)
      */
     Vim_Prim       *prim = (Vim_Prim *)data;
     vim_mz_buffer   *buf;
-    Scheme_Object   *line;
+    Scheme_Object   *line = NULL;
     char           *save;
-    buf_T          *savebuf;
     int                    n;
 
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, line);
+    MZ_GC_REG();
+
 #ifdef HAVE_SANDBOX
     sandbox_check();
 #endif
@@ -1943,7 +2155,8 @@ set_buffer_line(void *data, int argc, Scheme_Object **argv)
 
     if (SCHEME_FALSEP(line))
     {
-       savebuf = curbuf;
+       buf_T       *savebuf = curbuf;
+
        curbuf = buf->buf;
 
        if (u_savedel((linenr_T)n, 1L) == FAIL)
@@ -1962,33 +2175,56 @@ set_buffer_line(void *data, int argc, Scheme_Object **argv)
 
        curbuf = savebuf;
 
+       MZ_GC_UNREG();
        raise_if_error();
        return scheme_void;
     }
+    else
+    {
+       /* Otherwise it's a line */
+       buf_T       *savebuf = curbuf;
 
-    /* Otherwise it's a line */
-    save = string_to_line(line);
-    savebuf = curbuf;
+       save = string_to_line(line);
 
-    curbuf = buf->buf;
+       curbuf = buf->buf;
+
+       if (u_savesub((linenr_T)n) == FAIL)
+       {
+           curbuf = savebuf;
+           vim_free(save);
+           raise_vim_exn(_("cannot save undo information"));
+       }
+       else if (ml_replace((linenr_T)n, (char_u *)save, TRUE) == FAIL)
+       {
+           curbuf = savebuf;
+           vim_free(save);
+           raise_vim_exn(_("cannot replace line"));
+       }
+       else
+       {
+           vim_free(save);
+           changed_bytes((linenr_T)n, 0);
+       }
 
-    if (u_savesub((linenr_T)n) == FAIL)
-    {
-       curbuf = savebuf;
-       raise_vim_exn(_("cannot save undo information"));
-    }
-    else if (ml_replace((linenr_T)n, (char_u *)save, TRUE) == FAIL)
-    {
        curbuf = savebuf;
-       raise_vim_exn(_("cannot replace line"));
-    }
-    else
-       changed_bytes((linenr_T)n, 0);
 
-    curbuf = savebuf;
+       /* Check that the cursor is not beyond the end of the line now. */
+       if (buf->buf == curwin->w_buffer)
+           check_cursor_col();
 
-    raise_if_error();
-    return scheme_void;
+       MZ_GC_UNREG();
+       raise_if_error();
+       return scheme_void;
+    }
+}
+
+    static void
+free_array(char **array)
+{
+    char **curr = array;
+    while (*curr != NULL)
+       vim_free(*curr++);
+    vim_free(array);
 }
 
 /*
@@ -2013,15 +2249,15 @@ set_buffer_line_list(void *data, int argc, Scheme_Object **argv)
      *   3. Anything else - this is an error.
      */
     Vim_Prim       *prim = (Vim_Prim *)data;
-    vim_mz_buffer   *buf;
-    Scheme_Object   *line_list;
-    Scheme_Object   *line;
-    Scheme_Object   *rest;
-    char           **array;
-    buf_T          *savebuf;
+    vim_mz_buffer   *buf = NULL;
+    Scheme_Object   *line_list = NULL;
     int                    i, old_len, new_len, hi, lo;
     long           extra;
 
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, line_list);
+    MZ_GC_REG();
+
 #ifdef HAVE_SANDBOX
     sandbox_check();
 #endif
@@ -2047,7 +2283,7 @@ set_buffer_line_list(void *data, int argc, Scheme_Object **argv)
 
     if (SCHEME_FALSEP(line_list) || SCHEME_NULLP(line_list))
     {
-       savebuf = curbuf;
+       buf_T   *savebuf = curbuf;
        curbuf = buf->buf;
 
        if (u_savedel((linenr_T)lo, (long)old_len) == FAIL)
@@ -2070,98 +2306,121 @@ set_buffer_line_list(void *data, int argc, Scheme_Object **argv)
 
        curbuf = savebuf;
 
+       MZ_GC_UNREG();
        raise_if_error();
        return scheme_void;
     }
+    else
+    {
+       buf_T   *savebuf = curbuf;
+
+       /* List */
+       new_len = scheme_proper_list_length(line_list);
+       MZ_GC_CHECK();
+       if (new_len < 0)        /* improper or cyclic list */
+           scheme_wrong_type(prim->name, "proper list",
+                   2, argc, argv);
+       else
+       {
+           char                **array = NULL;
+           Scheme_Object   *line = NULL;
+           Scheme_Object   *rest = NULL;
 
-    /* List */
-    new_len = scheme_proper_list_length(line_list);
-    if (new_len < 0)   /* improper or cyclic list */
-       scheme_wrong_type(prim->name, "proper list",
-               2, argc, argv);
+           MZ_GC_DECL_REG(2);
+           MZ_GC_VAR_IN_REG(0, line);
+           MZ_GC_VAR_IN_REG(1, rest);
+           MZ_GC_REG();
 
-    /* Using MzScheme allocator, so we don't need to free this and
-     * can safely keep pointers to GC collected strings
-     */
-    array = (char **)scheme_malloc_fail_ok(scheme_malloc,
-               (unsigned)(new_len * sizeof(char *)));
+           array = (char **)alloc(new_len * sizeof(char *));
+           vim_memset(array, 0, new_len * sizeof(char *));
 
-    rest = line_list;
-    for (i = 0; i < new_len; ++i)
-    {
-       line = SCHEME_CAR(rest);
-       rest = SCHEME_CDR(rest);
-       if (!SCHEME_STRINGP(line))
-           scheme_wrong_type(prim->name, "string-list", 2, argc, argv);
-       array[i] = string_to_line(line);
-    }
+           rest = line_list;
+           for (i = 0; i < new_len; ++i)
+           {
+               line = SCHEME_CAR(rest);
+               rest = SCHEME_CDR(rest);
+               if (!SCHEME_STRINGP(line))
+               {
+                   free_array(array);
+                   scheme_wrong_type(prim->name, "string-list", 2, argc, argv);
+               }
+               array[i] = string_to_line(line);
+           }
 
-    savebuf = curbuf;
-    curbuf = buf->buf;
+           curbuf = buf->buf;
 
-    if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
-    {
-       curbuf = savebuf;
-       raise_vim_exn(_("cannot save undo information"));
-    }
+           if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
+           {
+               curbuf = savebuf;
+               free_array(array);
+               raise_vim_exn(_("cannot save undo information"));
+           }
 
-    /*
-     * If the size of the range is reducing (ie, new_len < old_len) we
-     * need to delete some old_len. We do this at the start, by
-     * repeatedly deleting line "lo".
-     */
-    for (i = 0; i < old_len - new_len; ++i)
-    {
-       if (ml_delete((linenr_T)lo, FALSE) == FAIL)
-       {
-           curbuf = savebuf;
-           raise_vim_exn(_("cannot delete line"));
-       }
-       extra--;
-    }
+           /*
+            * If the size of the range is reducing (ie, new_len < old_len) we
+            * need to delete some old_len. We do this at the start, by
+            * repeatedly deleting line "lo".
+            */
+           for (i = 0; i < old_len - new_len; ++i)
+           {
+               if (ml_delete((linenr_T)lo, FALSE) == FAIL)
+               {
+                   curbuf = savebuf;
+                   free_array(array);
+                   raise_vim_exn(_("cannot delete line"));
+               }
+               extra--;
+           }
 
-    /*
-     * For as long as possible, replace the existing old_len with the
-     * new old_len. This is a more efficient operation, as it requires
-     * less memory allocation and freeing.
-     */
-    for (i = 0; i < old_len && i < new_len; i++)
-       if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], TRUE) == FAIL)
-       {
-           curbuf = savebuf;
-           raise_vim_exn(_("cannot replace line"));
-       }
+           /*
+            * For as long as possible, replace the existing old_len with the
+            * new old_len. This is a more efficient operation, as it requires
+            * less memory allocation and freeing.
+            */
+           for (i = 0; i < old_len && i < new_len; i++)
+               if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], TRUE) == FAIL)
+               {
+                   curbuf = savebuf;
+                   free_array(array);
+                   raise_vim_exn(_("cannot replace line"));
+               }
 
-    /*
-     * Now we may need to insert the remaining new_len.  We don't need to
-     * free the string passed back because MzScheme has control of that
-     * memory.
-     */
-    while (i < new_len)
-    {
-       if (ml_append((linenr_T)(lo + i - 1),
-               (char_u *)array[i], 0, FALSE) == FAIL)
-       {
-           curbuf = savebuf;
-           raise_vim_exn(_("cannot insert line"));
+           /*
+            * Now we may need to insert the remaining new_len.  We don't need to
+            * free the string passed back because MzScheme has control of that
+            * memory.
+            */
+           while (i < new_len)
+           {
+               if (ml_append((linenr_T)(lo + i - 1),
+                           (char_u *)array[i], 0, FALSE) == FAIL)
+               {
+                   curbuf = savebuf;
+                   free_array(array);
+                   raise_vim_exn(_("cannot insert line"));
+               }
+               ++i;
+               ++extra;
+           }
+           MZ_GC_UNREG();
+           free_array(array);
        }
-       ++i;
-       ++extra;
-    }
 
-    /*
-     * Adjust marks. Invalidate any which lie in the
-     * changed range, and move any in the remainder of the buffer.
-     */
-    mark_adjust((linenr_T)lo, (linenr_T)(hi - 1), (long)MAXLNUM, (long)extra);
-    changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
+       /*
+        * Adjust marks. Invalidate any which lie in the
+        * changed range, and move any in the remainder of the buffer.
+        */
+       mark_adjust((linenr_T)lo, (linenr_T)(hi - 1), (long)MAXLNUM, (long)extra);
+       changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
 
-    if (buf->buf == curwin->w_buffer)
-       mz_fix_cursor(lo, hi, extra);
-    curbuf = savebuf;
+       if (buf->buf == curwin->w_buffer)
+           mz_fix_cursor(lo, hi, extra);
+       curbuf = savebuf;
 
-    raise_if_error();
-    return scheme_void;
+       MZ_GC_UNREG();
+       raise_if_error();
+       return scheme_void;
+    }
 }
 
 /*
@@ -2179,15 +2438,15 @@ set_buffer_line_list(void *data, int argc, Scheme_Object **argv)
 insert_buffer_line_list(void *data, int argc, Scheme_Object **argv)
 {
     Vim_Prim       *prim = (Vim_Prim *)data;
-    vim_mz_buffer   *buf;
-    Scheme_Object   *list;
-    Scheme_Object   *line;
-    Scheme_Object   *rest;
-    char           **array;
-    char           *str;
-    buf_T          *savebuf;
+    vim_mz_buffer   *buf = NULL;
+    Scheme_Object   *list = NULL;
+    char           *str = NULL;
     int                    i, n, size;
 
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, list);
+    MZ_GC_REG();
+
 #ifdef HAVE_SANDBOX
     sandbox_check();
 #endif
@@ -2206,89 +2465,99 @@ insert_buffer_line_list(void *data, int argc, Scheme_Object **argv)
        check_line_range(n, buf->buf);
     if (SCHEME_STRINGP(list))
     {
-       str = string_to_line(list);
+       buf_T       *savebuf = curbuf;
 
-       savebuf = curbuf;
+       str = string_to_line(list);
        curbuf = buf->buf;
 
        if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
        {
            curbuf = savebuf;
+           vim_free(str);
            raise_vim_exn(_("cannot save undo information"));
        }
        else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
        {
            curbuf = savebuf;
+           vim_free(str);
            raise_vim_exn(_("cannot insert line"));
        }
        else
+       {
+           vim_free(str);
            appended_lines_mark((linenr_T)n, 1L);
+       }
 
        curbuf = savebuf;
        update_screen(VALID);
 
+       MZ_GC_UNREG();
        raise_if_error();
        return scheme_void;
     }
 
     /* List */
     size = scheme_proper_list_length(list);
+    MZ_GC_CHECK();
     if (size < 0)      /* improper or cyclic list */
        scheme_wrong_type(prim->name, "proper list",
                2, argc, argv);
-
-    /* Using MzScheme allocator, so we don't need to free this and
-     * can safely keep pointers to GC collected strings
-     */
-    array = (char **)scheme_malloc_fail_ok(
-           scheme_malloc, (unsigned)(size * sizeof(char *)));
-
-    rest = list;
-    for (i = 0; i < size; ++i)
+    else
     {
-       line = SCHEME_CAR(rest);
-       rest = SCHEME_CDR(rest);
-       array[i] = string_to_line(line);
-    }
+       Scheme_Object   *line = NULL;
+       Scheme_Object   *rest = NULL;
+       char            **array;
+       buf_T           *savebuf = curbuf;
 
-    savebuf = curbuf;
-    curbuf = buf->buf;
+       MZ_GC_DECL_REG(2);
+       MZ_GC_VAR_IN_REG(0, line);
+       MZ_GC_VAR_IN_REG(1, rest);
+       MZ_GC_REG();
 
-    if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
-    {
-       curbuf = savebuf;
-       raise_vim_exn(_("cannot save undo information"));
-    }
-    else
-    {
+       array = (char **)alloc(size * sizeof(char *));
+       vim_memset(array, 0, size * sizeof(char *));
+
+       rest = list;
        for (i = 0; i < size; ++i)
-           if (ml_append((linenr_T)(n + i), (char_u *)array[i],
-                       0, FALSE) == FAIL)
-           {
-               curbuf = savebuf;
-               raise_vim_exn(_("cannot insert line"));
-           }
+       {
+           line = SCHEME_CAR(rest);
+           rest = SCHEME_CDR(rest);
+           array[i] = string_to_line(line);
+       }
 
-       if (i > 0)
-           appended_lines_mark((linenr_T)n, (long)i);
-    }
+       curbuf = buf->buf;
 
-    curbuf = savebuf;
-    update_screen(VALID);
+       if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
+       {
+           curbuf = savebuf;
+           free_array(array);
+           raise_vim_exn(_("cannot save undo information"));
+       }
+       else
+       {
+           for (i = 0; i < size; ++i)
+               if (ml_append((linenr_T)(n + i), (char_u *)array[i],
+                           0, FALSE) == FAIL)
+               {
+                   curbuf = savebuf;
+                   free_array(array);
+                   raise_vim_exn(_("cannot insert line"));
+               }
 
+           if (i > 0)
+               appended_lines_mark((linenr_T)n, (long)i);
+       }
+       free_array(array);
+       MZ_GC_UNREG();
+       curbuf = savebuf;
+       update_screen(VALID);
+    }
+
+    MZ_GC_UNREG();
     raise_if_error();
     return scheme_void;
 }
 
-/* (get-buff-namespace [buffer]) */
-    static Scheme_Object *
-get_buffer_namespace(void *data, int argc, Scheme_Object **argv)
-{
-    Vim_Prim   *prim = (Vim_Prim *)data;
-
-    return (Scheme_Object *)get_buffer_arg(prim->name, 0, argc, argv)->env;
-}
-
 /*
  * Predicates
  */
@@ -2343,40 +2612,172 @@ vim_window_validp(void *data, int argc, Scheme_Object **argv)
 /*
  * Convert an MzScheme string into a Vim line.
  *
- * The result is in allocated memory. All internal nulls are replaced by
- * newline characters. It is an error for the string to contain newline
- * characters.
+ * All internal nulls are replaced by newline characters.
+ * It is an error for the string to contain newline characters.
  *
+ * Returns pointer to Vim allocated memory
  */
     static char *
 string_to_line(Scheme_Object *obj)
 {
-    char       *str;
+    char       *scheme_str = NULL;
+    char       *vim_str = NULL;
     long       len;
     int                i;
 
-    str = scheme_display_to_string(obj, &len);
+    scheme_str = scheme_display_to_string(obj, &len);
 
     /* Error checking: String must not contain newlines, as we
      * are replacing a single line, and we must replace it with
      * a single line.
      */
-    if (memchr(str, '\n', len))
+    if (memchr(scheme_str, '\n', len))
        scheme_signal_error(_("string cannot contain newlines"));
 
+    vim_str = (char *)alloc(len + 1);
+
     /* Create a copy of the string, with internal nulls replaced by
      * newline characters, as is the vim convention.
      */
     for (i = 0; i < len; ++i)
     {
-       if (str[i] == '\0')
-           str[i] = '\n';
+       if (scheme_str[i] == '\0')
+           vim_str[i] = '\n';
+       else
+           vim_str[i] = scheme_str[i];
+    }
+
+    vim_str[i] = '\0';
+
+    MZ_GC_CHECK();
+    return vim_str;
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Convert Vim value into MzScheme, adopted from if_python.c
+ */
+    static Scheme_Object *
+vim_to_mzscheme(typval_T *vim_value, int depth, Scheme_Hash_Table *visited)
+{
+    Scheme_Object   *result = NULL;
+    int                    new_value = TRUE;
+
+    MZ_GC_DECL_REG(1);
+    MZ_GC_VAR_IN_REG(0, result);
+    MZ_GC_REG();
+
+    /* Avoid infinite recursion */
+    if (depth > 100)
+    {
+       MZ_GC_UNREG();
+       return scheme_void;
+    }
+
+    /* Check if we run into a recursive loop.  The item must be in visited
+     * then and we can use it again.
+     */
+    result = scheme_hash_get(visited, (Scheme_Object *)vim_value);
+    MZ_GC_CHECK();
+    if (result != NULL) /* found, do nothing */
+       new_value = FALSE;
+    else if (vim_value->v_type == VAR_STRING)
+    {
+       result = scheme_make_string((char *)vim_value->vval.v_string);
+       MZ_GC_CHECK();
+    }
+    else if (vim_value->v_type == VAR_NUMBER)
+    {
+       result = scheme_make_integer((long)vim_value->vval.v_number);
+       MZ_GC_CHECK();
+    }
+# ifdef FEAT_FLOAT
+    else if (vim_value->v_type == VAR_FLOAT)
+    {
+       result = scheme_make_double((double)vim_value->vval.v_float);
+       MZ_GC_CHECK();
+    }
+# endif
+    else if (vim_value->v_type == VAR_LIST)
+    {
+       list_T          *list = vim_value->vval.v_list;
+       listitem_T      *curr;
+
+       if (list == NULL || list->lv_first == NULL)
+           result = scheme_null;
+       else
+       {
+           Scheme_Object   *obj = NULL;
+
+           MZ_GC_DECL_REG(1);
+           MZ_GC_VAR_IN_REG(0, obj);
+           MZ_GC_REG();
+
+           curr = list->lv_last;
+           obj = vim_to_mzscheme(&curr->li_tv, depth + 1, visited);
+           result = scheme_make_pair(obj, scheme_null);
+           MZ_GC_CHECK();
+
+           while (curr != list->lv_first)
+           {
+               curr = curr->li_prev;
+               obj = vim_to_mzscheme(&curr->li_tv, depth + 1, visited);
+               result = scheme_make_pair(obj, result);
+               MZ_GC_CHECK();
+           }
+       }
+       MZ_GC_UNREG();
     }
+    else if (vim_value->v_type == VAR_DICT)
+    {
+       Scheme_Object     *key = NULL;
+       Scheme_Object     *obj = NULL;
 
-    str[i] = '\0';
+       MZ_GC_DECL_REG(2);
+       MZ_GC_VAR_IN_REG(0, key);
+       MZ_GC_VAR_IN_REG(1, obj);
+       MZ_GC_REG();
 
-    return str;
+       result = (Scheme_Object *)scheme_make_hash_table(SCHEME_hash_ptr);
+       MZ_GC_CHECK();
+       if (vim_value->vval.v_dict != NULL)
+       {
+           hashtab_T   *ht = &vim_value->vval.v_dict->dv_hashtab;
+           long_u      todo = ht->ht_used;
+           hashitem_T  *hi;
+           dictitem_T  *di;
+
+           for (hi = ht->ht_array; todo > 0; ++hi)
+           {
+               if (!HASHITEM_EMPTY(hi))
+               {
+                   --todo;
+
+                   di = dict_lookup(hi);
+                   obj = vim_to_mzscheme(&di->di_tv, depth + 1, visited);
+                   key = scheme_make_string((char *)hi->hi_key);
+                   MZ_GC_CHECK();
+                   scheme_hash_set((Scheme_Hash_Table *)result, key, obj);
+                   MZ_GC_CHECK();
+               }
+           }
+       }
+       MZ_GC_UNREG();
+    }
+    else
+    {
+       result = scheme_void;
+       new_value = FALSE;
+    }
+    if (new_value)
+    {
+       scheme_hash_set(visited, (Scheme_Object *)vim_value, result);
+       MZ_GC_CHECK();
+    }
+    MZ_GC_UNREG();
+    return result;
 }
+#endif
 
 /*
  * Check to see whether a Vim error has been reported, or a keyboard
@@ -2392,50 +2793,59 @@ vim_error_check(void)
  * register Scheme exn:vim
  */
     static void
-register_vim_exn(Scheme_Env *env)
+register_vim_exn(void)
 {
-    Scheme_Object   *exn_name = scheme_intern_symbol("exn:vim");
+    int        nc = 0;
+    int i;
+    Scheme_Object   *struct_exn = NULL;
+    Scheme_Object   *exn_name = NULL;
+
+    MZ_GC_DECL_REG(2);
+    MZ_GC_VAR_IN_REG(0, struct_exn);
+    MZ_GC_VAR_IN_REG(1, exn_name);
+    MZ_GC_REG();
+
+    exn_name = scheme_intern_symbol("exn:vim");
+    MZ_GC_CHECK();
+    struct_exn = scheme_builtin_value("struct:exn");
+    MZ_GC_CHECK();
 
     if (vim_exn == NULL)
        vim_exn = scheme_make_struct_type(exn_name,
-               scheme_builtin_value("struct:exn"), NULL, 0, 0, NULL, NULL
+               struct_exn, NULL, 0, 0, NULL, NULL
 #if MZSCHEME_VERSION_MAJOR >= 299
                , NULL
 #endif
                );
 
-    if (vim_exn_values == NULL)
+
     {
-       int     nc = 0;
-
-       Scheme_Object   **exn_names = scheme_make_struct_names(
-               exn_name, scheme_null, 0, &nc);
-       Scheme_Object   **exn_values = scheme_make_struct_values(
-               vim_exn, exn_names, nc, 0);
-
-       vim_exn_names = scheme_make_vector(nc, scheme_false);
-       vim_exn_values = scheme_make_vector(nc, scheme_false);
-       /* remember names and values */
-       mch_memmove(SCHEME_VEC_ELS(vim_exn_names), exn_names,
-               nc * sizeof(Scheme_Object *));
-       mch_memmove(SCHEME_VEC_ELS(vim_exn_values), exn_values,
-               nc * sizeof(Scheme_Object *));
+       Scheme_Object   **tmp = NULL;
+       Scheme_Object   *exn_names[5] = {NULL, NULL, NULL, NULL, NULL};
+       Scheme_Object   *exn_values[5] = {NULL, NULL, NULL, NULL, NULL};
+       MZ_GC_DECL_REG(6);
+       MZ_GC_ARRAY_VAR_IN_REG(0, exn_names, 5);
+       MZ_GC_ARRAY_VAR_IN_REG(3, exn_values, 5);
+       MZ_GC_REG();
+
+       tmp = scheme_make_struct_names(exn_name, scheme_null, 0, &nc);
+       assert(nc <= 5);
+       mch_memmove(exn_names, tmp, nc * sizeof(Scheme_Object *));
+       MZ_GC_CHECK();
+
+       tmp = scheme_make_struct_values(vim_exn, exn_names, nc, 0);
+       mch_memmove(exn_values, tmp, nc * sizeof(Scheme_Object *));
+       MZ_GC_CHECK();
+
+       for (i = 0; i < nc; i++)
+       {
+           scheme_add_global_symbol(exn_names[i],
+                   exn_values[i], environment);
+           MZ_GC_CHECK();
+       }
+       MZ_GC_UNREG();
     }
-
-    add_vim_exn(env);
-}
-
-/*
- * Add stuff of exn:vim to env
- */
-    static void
-add_vim_exn(Scheme_Env *env)
-{
-    int i;
-
-    for (i = 0; i < SCHEME_VEC_SIZE(vim_exn_values); i++)
-       scheme_add_global_symbol(SCHEME_VEC_ELS(vim_exn_names)[i],
-               SCHEME_VEC_ELS(vim_exn_values)[i], env);
+    MZ_GC_UNREG();
 }
 
 /*
@@ -2444,26 +2854,54 @@ add_vim_exn(Scheme_Env *env)
     void
 raise_vim_exn(const char *add_info)
 {
-    Scheme_Object   *argv[2];
-    char_u         *fmt = _("Vim error: ~a");
+    char           *fmt = _("Vim error: ~a");
+    Scheme_Object   *argv[2] = {NULL, NULL};
+    Scheme_Object   *exn = NULL;
+
+    MZ_GC_DECL_REG(4);
+    MZ_GC_ARRAY_VAR_IN_REG(0, argv, 2);
+    MZ_GC_VAR_IN_REG(3, exn);
+    MZ_GC_REG();
 
     if (add_info != NULL)
     {
-       Scheme_Object   *info = scheme_make_string(add_info);
-       argv[0] = scheme_byte_string_to_char_string(scheme_make_string(
-               scheme_format(fmt, strlen(fmt), 1, &info, NULL)));
+       char            *c_string = NULL;
+       Scheme_Object   *byte_string = NULL;
+       Scheme_Object   *info = NULL;
+
+       MZ_GC_DECL_REG(3);
+       MZ_GC_VAR_IN_REG(0, c_string);
+       MZ_GC_VAR_IN_REG(1, byte_string);
+       MZ_GC_VAR_IN_REG(2, info);
+       MZ_GC_REG();
+
+       info = scheme_make_string(add_info);
+       MZ_GC_CHECK();
+       c_string = scheme_format(fmt, STRLEN(fmt), 1, &info, NULL);
+       MZ_GC_CHECK();
+       byte_string = scheme_make_string(c_string);
+       MZ_GC_CHECK();
+       argv[0] = scheme_byte_string_to_char_string(byte_string);
+       MZ_GC_CHECK();
        SCHEME_SET_IMMUTABLE(argv[0]);
+       MZ_GC_UNREG();
     }
     else
        argv[0] = scheme_make_string(_("Vim error"));
+    MZ_GC_CHECK();
 
 #if MZSCHEME_VERSION_MAJOR < 360
     argv[1] = scheme_current_continuation_marks();
+    MZ_GC_CHECK();
 #else
     argv[1] = scheme_current_continuation_marks(NULL);
+    MZ_GC_CHECK();
 #endif
 
-    scheme_raise(scheme_make_struct_instance(vim_exn, 2, argv));
+    exn = scheme_make_struct_instance(vim_exn, 2, argv);
+    MZ_GC_CHECK();
+    scheme_raise(exn);
+    MZ_GC_UNREG();
 }
 
     void
@@ -2570,6 +3008,8 @@ mz_fix_cursor(int lo, int hi, int extra)
            curwin->w_cursor.lnum = lo;
            check_cursor();
        }
+       else
+           check_cursor_col();
        changed_cline_bef_curs();
     }
     invalidate_botline();
@@ -2595,7 +3035,6 @@ static Vim_Prim prims[]=
     {mzscheme_open_buffer, "open-buff", 1, 1},
     {get_buffer_by_name, "get-buff-by-name", 1, 1},
     {get_buffer_by_num, "get-buff-by-num", 1, 1},
-    {get_buffer_namespace, "get-buff-namespace", 0, 1},
     /*
      * Window-related commands
      */
@@ -2653,23 +3092,35 @@ get_vim_curr_window(void)
 }
 
     static void
-make_modules(Scheme_Env *env)
-{
-    int                i;
-    Scheme_Env *mod;
-
-    mod = scheme_primitive_module(scheme_intern_symbol("vimext"), env);
+make_modules()
+{
+    int                    i;
+    Scheme_Env     *mod = NULL;
+    Scheme_Object   *vimext_symbol = NULL;
+    Scheme_Object   *closed_prim = NULL;
+
+    MZ_GC_DECL_REG(3);
+    MZ_GC_VAR_IN_REG(0, mod);
+    MZ_GC_VAR_IN_REG(1, vimext_symbol);
+    MZ_GC_VAR_IN_REG(2, closed_prim);
+    MZ_GC_REG();
+
+    vimext_symbol = scheme_intern_symbol("vimext");
+    MZ_GC_CHECK();
+    mod = scheme_primitive_module(vimext_symbol, environment);
+    MZ_GC_CHECK();
     /* all prims made closed so they can access their own names */
-    for (i = 0; i < sizeof(prims)/sizeof(prims[0]); i++)
+    for (i = 0; i < (int)(sizeof(prims)/sizeof(prims[0])); i++)
     {
        Vim_Prim *prim = prims + i;
-       scheme_add_global(prim->name,
-               scheme_make_closed_prim_w_arity(prim->prim, prim, prim->name,
-                   prim->mina, prim->maxa),
-               mod);
+       closed_prim = scheme_make_closed_prim_w_arity(prim->prim, prim, prim->name,
+                           prim->mina, prim->maxa);
+       scheme_add_global(prim->name, closed_prim, mod);
+       MZ_GC_CHECK();
     }
-    scheme_add_global("global-namespace", (Scheme_Object *)environment, mod);
     scheme_finish_primitive_module(mod);
+    MZ_GC_CHECK();
+    MZ_GC_UNREG();
 }
 
 #ifdef HAVE_SANDBOX
@@ -2697,21 +3148,25 @@ sandbox_file_guard(int argc, Scheme_Object **argv)
        {
            MZ_REGISTER_STATIC(M_write);
            M_write = scheme_intern_symbol("write");
+           MZ_GC_CHECK();
        }
        if (M_read == NULL)
        {
            MZ_REGISTER_STATIC(M_read);
            M_read = scheme_intern_symbol("read");
+           MZ_GC_CHECK();
        }
        if (M_execute == NULL)
        {
            MZ_REGISTER_STATIC(M_execute);
            M_execute = scheme_intern_symbol("execute");
+           MZ_GC_CHECK();
        }
        if (M_delete == NULL)
        {
            MZ_REGISTER_STATIC(M_delete);
            M_delete = scheme_intern_symbol("delete");
+           MZ_GC_CHECK();
        }
 
        while (!SCHEME_NULLP(requested_access))
index b745cce9eec5f56451ed2d4c6ab2b804627459ea..45888919b522ce37f98e7140ae37371f5932df06 100644 (file)
@@ -11,6 +11,7 @@
 
 /* #ifdef needed for "make depend" */
 #ifdef FEAT_MZSCHEME
+# include <schvers.h>
 # include <scheme.h>
 #endif
 
 # define scheme_byte_string_to_char_string(obj) (obj)
 #endif
 
+/* Precise GC macros */
+#ifndef MZ_GC_DECL_REG
+# define MZ_GC_DECL_REG(size)            /* empty */
+#endif
+#ifndef MZ_GC_VAR_IN_REG
+# define MZ_GC_VAR_IN_REG(x, v)          /* empty */
+#endif
+#ifndef MZ_GC_ARRAY_VAR_IN_REG
+# define MZ_GC_ARRAY_VAR_IN_REG(x, v, l) /* empty */
+#endif
+#ifndef MZ_GC_REG
+# define MZ_GC_REG()                     /* empty */
+#endif
+#ifndef MZ_GC_UNREG
+# define MZ_GC_UNREG()                   /* empty */
+#endif
+
+#ifdef MZSCHEME_FORCE_GC
+/*
+ * force garbage collection to check all references are registered
+ * seg faults will indicate not registered refs
+ */
+# define MZ_GC_CHECK() scheme_collect_garbage();
+#else
+# define MZ_GC_CHECK()                 /* empty */
+#endif
+
 #endif /* _IF_MZSCH_H_ */
index c0dd121425474f168a5c16e5f38bd0ee6e2c6607..84aa146e76d2510f51c21faf43a2261120cc214c 100644 (file)
@@ -935,8 +935,14 @@ main
 
     /*
      * Call the main command loop.  This never returns.
+     * For embedded MzScheme the main_loop will be called by Scheme
+     * for proper stack tracking
      */
+#ifndef FEAT_MZSCHEME
     main_loop(FALSE, FALSE);
+#else
+    mzscheme_main();
+#endif
 
     return 0;
 }
index 522ac94237737b38e6e34403cc47209b23ab3d9f..f61a087d6277b8e46bece217d631862e133d26f1 100644 (file)
@@ -15,10 +15,6 @@ void mzvim_reset_timer __ARGS((void));
 void *mzvim_eval_string __ARGS((char_u *str));
 struct Scheme_Object *mzvim_apply __ARGS((struct Scheme_Object *, int argc,
     struct Scheme_Object **));
-int mzthreads_allowed (void);
-#ifdef FEAT_GUI_KDE
-void timer_proc (void);
-void mzscheme_kde_start_timer (void);
-void mzscheme_kde_stop_timer (void);
-#endif
+int mzthreads_allowed __ARGS((void));
+void mzscheme_main __ARGS((void));
 /* vim: set ft=c : */
index 7282b6b574927ad9014d8b8466c6fbc2e4c598ed..52e08a9c7f76fca18a9ddc2d56aa10373d7ff2a6 100644 (file)
@@ -676,6 +676,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    191,
 /**/
     190,
 /**/