Fix documentation typos, start working on compiled stack traces
parent
74ddfad32c
commit
c0038a28f9
4
Makefile
4
Makefile
|
@ -3,13 +3,13 @@ CC = gcc
|
||||||
BINARY = f
|
BINARY = f
|
||||||
IMAGE = factor.image
|
IMAGE = factor.image
|
||||||
BUNDLE = Factor.app
|
BUNDLE = Factor.app
|
||||||
VERSION = 0.86
|
VERSION = 0.87
|
||||||
DISK_IMAGE_DIR = Factor-$(VERSION)
|
DISK_IMAGE_DIR = Factor-$(VERSION)
|
||||||
DISK_IMAGE = Factor-$(VERSION).dmg
|
DISK_IMAGE = Factor-$(VERSION).dmg
|
||||||
LIBPATH = -L/usr/X11R6/lib
|
LIBPATH = -L/usr/X11R6/lib
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CFLAGS = -pg -O1
|
CFLAGS = -g
|
||||||
STRIP = touch
|
STRIP = touch
|
||||||
else
|
else
|
||||||
CFLAGS = -Wall -O3 -ffast-math -fomit-frame-pointer $(SITE_CFLAGS)
|
CFLAGS = -Wall -O3 -ffast-math -fomit-frame-pointer $(SITE_CFLAGS)
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
+ 0.87:
|
+ 0.87:
|
||||||
|
|
||||||
|
- amd64 structs-by-value bug
|
||||||
|
- intrinsic fixnum>float float>fixnum
|
||||||
|
- compiled call traces
|
||||||
|
|
||||||
- fix search unit test
|
- fix search unit test
|
||||||
- these things are "Too Slow":
|
- these things are "Too Slow":
|
||||||
- all-words
|
- all-words
|
||||||
|
@ -18,10 +22,7 @@
|
||||||
- graphical crossref tool
|
- graphical crossref tool
|
||||||
- ui browser: show currently selected vocab & words
|
- ui browser: show currently selected vocab & words
|
||||||
- auto-update browser and help when sources reload
|
- auto-update browser and help when sources reload
|
||||||
- amd64 structs-by-value bug
|
|
||||||
- intrinsic fixnum>float float>fixnum
|
|
||||||
- mac intel: struct returns from objc methods
|
- mac intel: struct returns from objc methods
|
||||||
- compiled call traces
|
|
||||||
- new windows don't always have focus, eg focus follows mouse
|
- new windows don't always have focus, eg focus follows mouse
|
||||||
- listener commands from a menu should not include 'hide-glass' etc
|
- listener commands from a menu should not include 'hide-glass' etc
|
||||||
- bogus compile errors?
|
- bogus compile errors?
|
||||||
|
@ -32,7 +33,6 @@
|
||||||
- ui docs
|
- ui docs
|
||||||
- some kind of declarative wiring framework for ui
|
- some kind of declarative wiring framework for ui
|
||||||
- overhaul models, set-model* is crap
|
- overhaul models, set-model* is crap
|
||||||
- allow rebinding styles
|
|
||||||
- fix windows gcc issue
|
- fix windows gcc issue
|
||||||
- robustify stepper -- see if step back past a throw works
|
- robustify stepper -- see if step back past a throw works
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: alien
|
IN: alien
|
||||||
USING: compiler errors generic hashtables inference
|
USING: compiler errors generic hashtables inference
|
||||||
kernel namespaces sequences strings words parser prettyprint ;
|
kernel namespaces sequences strings words parser prettyprint
|
||||||
|
kernel-internals ;
|
||||||
|
|
||||||
! Callbacks are registered in a global hashtable. If you clear
|
! Callbacks are registered in a global hashtable. If you clear
|
||||||
! this hashtable, they will all be blown away by code GC, beware
|
! this hashtable, they will all be blown away by code GC, beware
|
||||||
|
|
|
@ -13,6 +13,16 @@ memory namespaces sequences words ;
|
||||||
! r14 data stack
|
! r14 data stack
|
||||||
! r15 call stack
|
! r15 call stack
|
||||||
|
|
||||||
|
! Stack layout:
|
||||||
|
|
||||||
|
! Mach-O -vs- Linux/PPC
|
||||||
|
: stack@ macosx? 24 8 ? + ;
|
||||||
|
: lr@ macosx? 8 4 ? + ;
|
||||||
|
|
||||||
|
! Frames are 16-byte aligned, minimum size is 32 bytes
|
||||||
|
! Grows down
|
||||||
|
! - lr@: return address
|
||||||
|
|
||||||
M: int-regs return-reg drop 3 ;
|
M: int-regs return-reg drop 3 ;
|
||||||
M: int-regs fastcall-regs drop { 3 4 5 6 7 8 9 10 } ;
|
M: int-regs fastcall-regs drop { 3 4 5 6 7 8 9 10 } ;
|
||||||
M: int-regs vregs drop { 3 4 5 6 7 8 9 10 } ;
|
M: int-regs vregs drop { 3 4 5 6 7 8 9 10 } ;
|
||||||
|
@ -21,9 +31,6 @@ M: float-regs return-reg drop 1 ;
|
||||||
M: float-regs fastcall-regs drop { 1 2 3 4 5 6 7 8 } ;
|
M: float-regs fastcall-regs drop { 1 2 3 4 5 6 7 8 } ;
|
||||||
M: float-regs vregs drop { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
|
M: float-regs vregs drop { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
|
||||||
|
|
||||||
! Mach-O -vs- Linux/PPC
|
|
||||||
: stack@ macosx? 24 8 ? + ;
|
|
||||||
: lr@ macosx? 8 4 ? + ;
|
|
||||||
|
|
||||||
GENERIC: loc>operand ( loc -- reg n )
|
GENERIC: loc>operand ( loc -- reg n )
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2004, 2006 Slava Pestov.
|
! Copyright (C) 2004, 2006 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: kernel-internals
|
IN: kernel-internals
|
||||||
USING: arrays generic namespaces sequences ;
|
USING: arrays generic namespaces sequences math ;
|
||||||
|
|
||||||
: >c ( continuation -- ) catchstack* push ;
|
: >c ( continuation -- ) catchstack* push ;
|
||||||
: c> ( -- continuation ) catchstack* pop ;
|
: c> ( -- continuation ) catchstack* pop ;
|
||||||
|
@ -11,6 +11,8 @@ USING: kernel ;
|
||||||
|
|
||||||
SYMBOL: error
|
SYMBOL: error
|
||||||
SYMBOL: error-continuation
|
SYMBOL: error-continuation
|
||||||
|
SYMBOL: error-stack-trace
|
||||||
|
SYMBOL: restarts
|
||||||
|
|
||||||
: catch ( try -- error/f )
|
: catch ( try -- error/f )
|
||||||
[ >c call f c> drop f ] callcc1 nip ; inline
|
[ >c call f c> drop f ] callcc1 nip ; inline
|
||||||
|
@ -49,4 +51,7 @@ M: condition compute-restarts
|
||||||
[ condition-cc ] keep
|
[ condition-cc ] keep
|
||||||
condition-restarts [ swap add ] map-with append ;
|
condition-restarts [ swap add ] map-with append ;
|
||||||
|
|
||||||
|
PREDICATE: array kernel-error ( obj -- ? )
|
||||||
|
dup first \ kernel-error eq? swap second 0 18 between? and ;
|
||||||
|
|
||||||
DEFER: try
|
DEFER: try
|
||||||
|
|
|
@ -9,6 +9,10 @@ HELP: error-continuation
|
||||||
{ $description "Global variable holding current continuation of most recently thrown error." }
|
{ $description "Global variable holding current continuation of most recently thrown error." }
|
||||||
{ $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ;
|
{ $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ;
|
||||||
|
|
||||||
|
HELP: restarts
|
||||||
|
{ $var-description "Global variable holding the set of possible restarts for the most recently thrown error." }
|
||||||
|
{ $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ;
|
||||||
|
|
||||||
HELP: >c
|
HELP: >c
|
||||||
{ $values { "continuation" "a continuation" } }
|
{ $values { "continuation" "a continuation" } }
|
||||||
{ $description "Pushes an exception handler continuation on the catch stack. The continuation must have been reified by " { $link callcc1 } "." } ;
|
{ $description "Pushes an exception handler continuation on the catch stack. The continuation must have been reified by " { $link callcc1 } "." } ;
|
||||||
|
|
|
@ -17,8 +17,8 @@ HELP: <file-writer>
|
||||||
|
|
||||||
HELP: <client>
|
HELP: <client>
|
||||||
{ $values { "host" "a string" } { "port" "an integer between 0 and 65535" } { "stream" "a bidirectional stream" } }
|
{ $values { "host" "a string" } { "port" "an integer between 0 and 65535" } { "stream" "a bidirectional stream" } }
|
||||||
{ $description "Connects to TCP/IP port number " { $code "port" } " on the host named by " { $code "host" } ", and outputs a bidirectional stream." }
|
{ $description "Connects to TCP/IP port number " { $snippet "port" } " on the host named by " { $snippet "host" } ", and outputs a bidirectional stream." }
|
||||||
{ $errors "Throws an error if domain name lookup fails, or if there is a connection cannot be established." } ;
|
{ $errors "Throws an error if domain name lookup fails, or if the connection cannot be established." } ;
|
||||||
|
|
||||||
HELP: <server>
|
HELP: <server>
|
||||||
{ $values { "port" "an integer between 0 and 65535" } { "server" "a handle" } }
|
{ $values { "port" "an integer between 0 and 65535" } { "server" "a handle" } }
|
||||||
|
@ -32,10 +32,10 @@ HELP: <server>
|
||||||
{ $errors "Throws an error if the port is already in use, or if the OS forbits access." } ;
|
{ $errors "Throws an error if the port is already in use, or if the OS forbits access." } ;
|
||||||
|
|
||||||
HELP: accept
|
HELP: accept
|
||||||
{ $values { "server" "a handle" } { "stream" "a bidirectional stream" } }
|
{ $values { "server" "a handle" } { "client" "a bidirectional stream" } }
|
||||||
{ $description "Waits for a connection to a server socket created by " { $link <server> } ", and outputs a bidirectional stream when the connection has been established."
|
{ $description "Waits for a connection to a server socket created by " { $link <server> } ", and outputs a bidirectional stream when the connection has been established."
|
||||||
$terpri
|
$terpri
|
||||||
"The client socket supports two accessor words to get the host name and port number of the incoming connection:"
|
"The new stream supports two accessor words to get the host name and port number of the incoming connection:"
|
||||||
{ $list { $link client-stream-host } { $link client-stream-port } } }
|
{ $list { $link client-stream-host } { $link client-stream-port } } }
|
||||||
{ $errors "Throws an error if the server socket is closed or otherwise is unavailable." } ;
|
{ $errors "Throws an error if the server socket is closed or otherwise is unavailable." } ;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ HELP: font
|
||||||
{ $description "Character style. Font family named by a string." }
|
{ $description "Character style. Font family named by a string." }
|
||||||
{ $examples
|
{ $examples
|
||||||
"This example outputs some different font sizes:"
|
"This example outputs some different font sizes:"
|
||||||
{ $code "{ \"Monospaced\" \"Serif\" \"Sans Serif\" }\n[ dup font associate format terpri ] each" }
|
{ $code "{ \"monospace\" \"serif\" \"sans-serif\" }\n[ dup font associate format terpri ] each" }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
HELP: font-size
|
HELP: font-size
|
||||||
|
@ -90,7 +90,7 @@ HELP: outline
|
||||||
{ $see-also write-outliner } ;
|
{ $see-also write-outliner } ;
|
||||||
|
|
||||||
HELP: table-gap
|
HELP: table-gap
|
||||||
{ $description "Table style. Pixels between table cells." }
|
{ $description "Table style. Horizontal and vertical gap between table cells, denoted by a pair of integers." }
|
||||||
{ $see-also with-stream-table tabular-output } ;
|
{ $see-also with-stream-table tabular-output } ;
|
||||||
|
|
||||||
HELP: table-border
|
HELP: table-border
|
||||||
|
|
|
@ -1,12 +1,43 @@
|
||||||
! Copyright (C) 2004, 2006 Slava Pestov.
|
! Copyright (C) 2004, 2006 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: arrays definitions generic hashtables help tools io
|
USING: arrays definitions generic hashtables help tools io
|
||||||
kernel kernel-internals math namespaces parser prettyprint
|
kernel math namespaces parser prettyprint sequences
|
||||||
sequences sequences-internals strings styles vectors words ;
|
sequences-internals strings styles vectors words errors ;
|
||||||
IN: errors
|
IN: kernel-internals
|
||||||
|
|
||||||
PREDICATE: array kernel-error ( obj -- ? )
|
: save-error ( error trace continuation -- )
|
||||||
dup first \ kernel-error eq? swap second 0 18 between? and ;
|
error-continuation set-global
|
||||||
|
error-stack-trace set-global
|
||||||
|
dup error set-global
|
||||||
|
compute-restarts restarts set-global ;
|
||||||
|
|
||||||
|
: error-handler ( error trace -- )
|
||||||
|
dupd continuation save-error rethrow ;
|
||||||
|
|
||||||
|
: init-error-handler ( -- )
|
||||||
|
V{ } clone set-catchstack
|
||||||
|
! kernel calls on error
|
||||||
|
[ error-handler ] 5 setenv
|
||||||
|
\ kernel-error 12 setenv ;
|
||||||
|
|
||||||
|
: code-heap-start 17 getenv ;
|
||||||
|
: code-heap-end 18 getenv ;
|
||||||
|
|
||||||
|
: <xt-map> ( -- xtmap )
|
||||||
|
[
|
||||||
|
f code-heap-start 2array ,
|
||||||
|
all-words [ compiled? ] subset
|
||||||
|
[ dup word-xt 2array , ] each
|
||||||
|
f code-heap-end 2array ,
|
||||||
|
] { } make [ [ second ] 2apply - ] sort ;
|
||||||
|
|
||||||
|
: find-xt ( xt xtmap -- word )
|
||||||
|
[ second - ] binsearch* first ;
|
||||||
|
|
||||||
|
: symbolic-stack-trace ( seq -- seq )
|
||||||
|
<xt-map> swap [ dup pick find-xt 2array ] map nip ;
|
||||||
|
|
||||||
|
IN: errors
|
||||||
|
|
||||||
GENERIC: error. ( error -- )
|
GENERIC: error. ( error -- )
|
||||||
GENERIC: error-help ( error -- topic )
|
GENERIC: error-help ( error -- topic )
|
||||||
|
@ -19,16 +50,29 @@ M: tuple error-help class ;
|
||||||
|
|
||||||
M: string error. print ;
|
M: string error. print ;
|
||||||
|
|
||||||
SYMBOL: restarts
|
|
||||||
|
|
||||||
: :s ( -- )
|
: :s ( -- )
|
||||||
error-continuation get continuation-data stack. ;
|
error-continuation get continuation-data stack. ;
|
||||||
|
|
||||||
: :r ( -- )
|
: :r ( -- )
|
||||||
error-continuation get continuation-retain stack. ;
|
error-continuation get continuation-retain stack. ;
|
||||||
|
|
||||||
|
: xt. ( xt -- )
|
||||||
|
>hex cell 2 * CHAR: 0 pad-left write ;
|
||||||
|
|
||||||
|
: word-xt. ( xt word -- )
|
||||||
|
"Compiled: " write dup pprint bl
|
||||||
|
"(offset " write word-xt - >hex write ")" write ;
|
||||||
|
|
||||||
|
: bare-xt. ( xt -- )
|
||||||
|
"C code: " write xt. ;
|
||||||
|
|
||||||
|
: :trace
|
||||||
|
error-stack-trace get symbolic-stack-trace <reversed> [
|
||||||
|
first2 [ word-xt. ] [ bare-xt. ] if* terpri
|
||||||
|
] each ;
|
||||||
|
|
||||||
: :c ( -- )
|
: :c ( -- )
|
||||||
error-continuation get continuation-call callstack. ;
|
error-continuation get continuation-call callstack. :trace ;
|
||||||
|
|
||||||
: :get ( variable -- value )
|
: :get ( variable -- value )
|
||||||
error-continuation get continuation-name hash-stack ;
|
error-continuation get continuation-name hash-stack ;
|
||||||
|
@ -99,17 +143,3 @@ SYMBOL: restarts
|
||||||
] recover drop ;
|
] recover drop ;
|
||||||
|
|
||||||
: try ( quot -- ) [ print-error ] recover ;
|
: try ( quot -- ) [ print-error ] recover ;
|
||||||
|
|
||||||
: save-error ( error continuation -- )
|
|
||||||
error-continuation set-global
|
|
||||||
dup error set-global
|
|
||||||
compute-restarts restarts set-global ;
|
|
||||||
|
|
||||||
: error-handler ( error -- )
|
|
||||||
dup continuation save-error rethrow ;
|
|
||||||
|
|
||||||
: init-error-handler ( -- )
|
|
||||||
V{ } clone set-catchstack
|
|
||||||
! kernel calls on error
|
|
||||||
[ error-handler ] 5 setenv
|
|
||||||
\ kernel-error 12 setenv ;
|
|
||||||
|
|
|
@ -2,10 +2,6 @@ IN: errors
|
||||||
USING: alien arrays generic help kernel math memory
|
USING: alien arrays generic help kernel math memory
|
||||||
strings vectors ;
|
strings vectors ;
|
||||||
|
|
||||||
HELP: restarts
|
|
||||||
{ $var-description "Global variable holding the set of possible restarts for the most recently thrown error." }
|
|
||||||
{ $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ;
|
|
||||||
|
|
||||||
HELP: :s
|
HELP: :s
|
||||||
{ $description "Prints the data stack at the time of the most recent error. Used for interactive debugging." } ;
|
{ $description "Prints the data stack at the time of the most recent error. Used for interactive debugging." } ;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ M: hashtable sheet hash>alist ;
|
||||||
|
|
||||||
: describe ( object -- ) dup summary print sheet sheet. ;
|
: describe ( object -- ) dup summary print sheet sheet. ;
|
||||||
|
|
||||||
: stack. ( seq -- ) <reversed> >array sheet sheet. ;
|
: stack. ( seq -- ) >array sheet sheet. ;
|
||||||
|
|
||||||
: .s ( -- ) datastack stack. ;
|
: .s ( -- ) datastack stack. ;
|
||||||
: .r ( -- ) retainstack stack. ;
|
: .r ( -- ) retainstack stack. ;
|
||||||
|
@ -58,6 +58,6 @@ M: hashtable sheet hash>alist ;
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
||||||
: callstack. ( seq -- )
|
: callstack. ( seq -- )
|
||||||
3 group <reversed> [ first2 1- callframe. ] each ;
|
3 group [ first2 1- callframe. ] each ;
|
||||||
|
|
||||||
: .c ( -- ) callstack callstack. ;
|
: .c ( -- ) callstack callstack. ;
|
||||||
|
|
19
vm/cpu-ppc.S
19
vm/cpu-ppc.S
|
@ -1,3 +1,9 @@
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define MANGLE(sym) _##sym
|
||||||
|
#else
|
||||||
|
#define MANGLE(sym) sym
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Thanks to Joshua Grams for this code.
|
/* Thanks to Joshua Grams for this code.
|
||||||
|
|
||||||
On PowerPC processors, we must flush the instruction cache manually
|
On PowerPC processors, we must flush the instruction cache manually
|
||||||
|
@ -6,12 +12,6 @@ after writing to the code heap.
|
||||||
Callable from C as
|
Callable from C as
|
||||||
void flush_icache(void *start, int len) */
|
void flush_icache(void *start, int len) */
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#define MANGLE(sym) _##sym
|
|
||||||
#else
|
|
||||||
#define MANGLE(sym) sym
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.globl MANGLE(flush_icache)
|
.globl MANGLE(flush_icache)
|
||||||
MANGLE(flush_icache):
|
MANGLE(flush_icache):
|
||||||
/* compute number of cache lines to flush */
|
/* compute number of cache lines to flush */
|
||||||
|
@ -30,3 +30,10 @@ MANGLE(flush_icache):
|
||||||
sync /* finish up */
|
sync /* finish up */
|
||||||
isync
|
isync
|
||||||
blr
|
blr
|
||||||
|
|
||||||
|
/* Callable from C as
|
||||||
|
void *native_stack_pointer(void) */
|
||||||
|
.globl MANGLE(native_stack_pointer)
|
||||||
|
MANGLE(native_stack_pointer):
|
||||||
|
mr r3,r1 /* native stack pointer is in r1 */
|
||||||
|
blr
|
||||||
|
|
|
@ -5,3 +5,5 @@ register CELL rs asm("r15");
|
||||||
register CELL cards_offset asm("r16");
|
register CELL cards_offset asm("r16");
|
||||||
|
|
||||||
void flush_icache(CELL start, CELL len);
|
void flush_icache(CELL start, CELL len);
|
||||||
|
|
||||||
|
void *native_stack_pointer(void);
|
||||||
|
|
12
vm/cpu-x86.h
12
vm/cpu-x86.h
|
@ -5,3 +5,15 @@ register CELL rs asm("edi");
|
||||||
CELL cards_offset;
|
CELL cards_offset;
|
||||||
|
|
||||||
INLINE void flush_icache(CELL start, CELL len) {}
|
INLINE void flush_icache(CELL start, CELL len) {}
|
||||||
|
|
||||||
|
INLINE void *native_stack_pointer(void)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
asm("mov %%ebp, %0" : "=r" (ptr));
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _F_STACK_FRAME {
|
||||||
|
struct _F_STACK_FRAME *previous;
|
||||||
|
CELL *return_address;
|
||||||
|
} F_STACK_FRAME;
|
||||||
|
|
|
@ -25,6 +25,8 @@ void init_factor(const char* image,
|
||||||
userenv[GEN_ENV] = tag_fixnum(gen_count);
|
userenv[GEN_ENV] = tag_fixnum(gen_count);
|
||||||
userenv[IMAGE_ENV] = tag_object(from_char_string(image));
|
userenv[IMAGE_ENV] = tag_object(from_char_string(image));
|
||||||
userenv[CELL_SIZE_ENV] = tag_fixnum(sizeof(CELL));
|
userenv[CELL_SIZE_ENV] = tag_fixnum(sizeof(CELL));
|
||||||
|
userenv[CODE_HEAP_START_ENV] = allot_cell(compiling.base);
|
||||||
|
userenv[CODE_HEAP_END_ENV] = allot_cell(compiling.limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE bool factor_arg(const char* str, const char* arg, CELL* value)
|
INLINE bool factor_arg(const char* str, const char* arg, CELL* value)
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
typedef struct _F_STACK_FRAME {
|
||||||
|
struct _F_STACK_FRAME *previous;
|
||||||
|
CELL padding;
|
||||||
|
CELL *return_address;
|
||||||
|
} F_STACK_FRAME;
|
||||||
|
|
||||||
#define SIGSEGV_EXC_STATE_TYPE ppc_exception_state_t
|
#define SIGSEGV_EXC_STATE_TYPE ppc_exception_state_t
|
||||||
#define SIGSEGV_EXC_STATE_FLAVOR PPC_EXCEPTION_STATE
|
#define SIGSEGV_EXC_STATE_FLAVOR PPC_EXCEPTION_STATE
|
||||||
#define SIGSEGV_EXC_STATE_COUNT PPC_EXCEPTION_STATE_COUNT
|
#define SIGSEGV_EXC_STATE_COUNT PPC_EXCEPTION_STATE_COUNT
|
||||||
|
|
15
vm/os-unix.c
15
vm/os-unix.c
|
@ -85,8 +85,7 @@ void primitive_stat(void)
|
||||||
void primitive_read_dir(void)
|
void primitive_read_dir(void)
|
||||||
{
|
{
|
||||||
DIR* dir = opendir(unbox_char_string());
|
DIR* dir = opendir(unbox_char_string());
|
||||||
CELL result_count = 0;
|
GROWABLE_ARRAY(result);
|
||||||
F_ARRAY *result = allot_array(ARRAY_TYPE,100,F);
|
|
||||||
|
|
||||||
if(dir != NULL)
|
if(dir != NULL)
|
||||||
{
|
{
|
||||||
|
@ -94,24 +93,16 @@ void primitive_read_dir(void)
|
||||||
|
|
||||||
while((file = readdir(dir)) != NULL)
|
while((file = readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
if(result_count == array_capacity(result))
|
|
||||||
{
|
|
||||||
result = reallot_array(result,
|
|
||||||
result_count * 2,F);
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_ARRAY(result);
|
REGISTER_ARRAY(result);
|
||||||
CELL name = tag_object(from_char_string(file->d_name));
|
CELL name = tag_object(from_char_string(file->d_name));
|
||||||
UNREGISTER_ARRAY(result);
|
UNREGISTER_ARRAY(result);
|
||||||
|
GROWABLE_ADD(result,name);
|
||||||
set_array_nth(result,result_count,name);
|
|
||||||
result_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = reallot_array(result,result_count,F);
|
GROWABLE_TRIM(result);
|
||||||
|
|
||||||
dpush(tag_object(result));
|
dpush(tag_object(result));
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,31 +115,23 @@ void primitive_read_dir(void)
|
||||||
|
|
||||||
sprintf(path, "%s\\*", unbox_char_string());
|
sprintf(path, "%s\\*", unbox_char_string());
|
||||||
|
|
||||||
F_ARRAY *result = allot_array(ARRAY_TYPE,100,F);
|
GROWABLE_ARRAY(result);
|
||||||
|
|
||||||
if(INVALID_HANDLE_VALUE != (dir = FindFirstFile(path, &find_data)))
|
if(INVALID_HANDLE_VALUE != (dir = FindFirstFile(path, &find_data)))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if(result_count == array_capacity(result))
|
|
||||||
{
|
|
||||||
result = reallot_array(result,
|
|
||||||
result_count * 2,F);
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_ARRAY(result);
|
REGISTER_ARRAY(result);
|
||||||
CELL name = tag_object(from_char_string(
|
CELL name = tag_object(from_char_string(
|
||||||
find_data.cFileName));
|
find_data.cFileName));
|
||||||
UNREGISTER_ARRAY(result);
|
UNREGISTER_ARRAY(result);
|
||||||
|
GROWABLE_ADD(result,name);
|
||||||
set_array_nth(result,result_count,name);
|
|
||||||
result_count++;
|
|
||||||
}
|
}
|
||||||
while (FindNextFile(dir, &find_data));
|
while (FindNextFile(dir, &find_data));
|
||||||
CloseHandle(dir);
|
CloseHandle(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = reallot_array(result,result_count,F);
|
GROWABLE_TRIM(result);
|
||||||
|
|
||||||
dpush(tag_object(result));
|
dpush(tag_object(result));
|
||||||
}
|
}
|
||||||
|
|
25
vm/run.c
25
vm/run.c
|
@ -53,6 +53,7 @@ void handle_error(void)
|
||||||
fix_stacks();
|
fix_stacks();
|
||||||
|
|
||||||
dpush(thrown_error);
|
dpush(thrown_error);
|
||||||
|
dpush(thrown_native_stack_trace);
|
||||||
/* Notify any 'catch' blocks */
|
/* Notify any 'catch' blocks */
|
||||||
push_callframe();
|
push_callframe();
|
||||||
set_callframe(userenv[BREAK_ENV]);
|
set_callframe(userenv[BREAK_ENV]);
|
||||||
|
@ -103,6 +104,7 @@ void interpreter_loop(void)
|
||||||
|
|
||||||
void interpreter(void)
|
void interpreter(void)
|
||||||
{
|
{
|
||||||
|
stack_chain->native_stack_pointer = native_stack_pointer();
|
||||||
SETJMP(stack_chain->toplevel);
|
SETJMP(stack_chain->toplevel);
|
||||||
handle_error();
|
handle_error();
|
||||||
interpreter_loop();
|
interpreter_loop();
|
||||||
|
@ -254,6 +256,28 @@ void early_error(CELL error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CELL native_stack_trace(void)
|
||||||
|
{
|
||||||
|
F_STACK_FRAME *frame = native_stack_pointer();
|
||||||
|
GROWABLE_ARRAY(array);
|
||||||
|
|
||||||
|
while((CELL)frame < (CELL)stack_chain->native_stack_pointer)
|
||||||
|
{
|
||||||
|
fflush(stdout);
|
||||||
|
REGISTER_ARRAY(array);
|
||||||
|
CELL cell = allot_cell((CELL)frame->return_address);
|
||||||
|
UNREGISTER_ARRAY(array);
|
||||||
|
GROWABLE_ADD(array,cell);
|
||||||
|
if((CELL)frame->previous <= (CELL)frame)
|
||||||
|
critical_error("C stack is busted",(CELL)frame);
|
||||||
|
frame = frame->previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
GROWABLE_TRIM(array);
|
||||||
|
|
||||||
|
return tag_object(array);
|
||||||
|
}
|
||||||
|
|
||||||
void throw_error(CELL error, bool keep_stacks)
|
void throw_error(CELL error, bool keep_stacks)
|
||||||
{
|
{
|
||||||
early_error(error);
|
early_error(error);
|
||||||
|
@ -263,6 +287,7 @@ void throw_error(CELL error, bool keep_stacks)
|
||||||
thrown_keep_stacks = keep_stacks;
|
thrown_keep_stacks = keep_stacks;
|
||||||
thrown_ds = ds;
|
thrown_ds = ds;
|
||||||
thrown_rs = rs;
|
thrown_rs = rs;
|
||||||
|
thrown_native_stack_trace = native_stack_trace();
|
||||||
|
|
||||||
/* Return to interpreter() function */
|
/* Return to interpreter() function */
|
||||||
LONGJMP(stack_chain->toplevel,1);
|
LONGJMP(stack_chain->toplevel,1);
|
||||||
|
|
3
vm/run.h
3
vm/run.h
|
@ -28,6 +28,8 @@ CELL callframe_end;
|
||||||
#define OUT_ENV 14
|
#define OUT_ENV 14
|
||||||
#define GEN_ENV 15 /* set to gen_count */
|
#define GEN_ENV 15 /* set to gen_count */
|
||||||
#define IMAGE_ENV 16 /* image name */
|
#define IMAGE_ENV 16 /* image name */
|
||||||
|
#define CODE_HEAP_START_ENV 17 /* start of code heap, used by :trace */
|
||||||
|
#define CODE_HEAP_END_ENV 18 /* end of code heap, used by :trace */
|
||||||
|
|
||||||
/* TAGGED user environment data; see getenv/setenv prims */
|
/* TAGGED user environment data; see getenv/setenv prims */
|
||||||
DLLEXPORT CELL userenv[USER_ENV];
|
DLLEXPORT CELL userenv[USER_ENV];
|
||||||
|
@ -176,6 +178,7 @@ volatile bool throwing;
|
||||||
/* When throw_error throws an error, it sets this global and
|
/* When throw_error throws an error, it sets this global and
|
||||||
longjmps back to the top-level. */
|
longjmps back to the top-level. */
|
||||||
CELL thrown_error;
|
CELL thrown_error;
|
||||||
|
CELL thrown_native_stack_trace;
|
||||||
CELL thrown_keep_stacks;
|
CELL thrown_keep_stacks;
|
||||||
/* Since longjmp restores registers, we must save all these values. */
|
/* Since longjmp restores registers, we must save all these values. */
|
||||||
CELL thrown_ds;
|
CELL thrown_ds;
|
||||||
|
|
|
@ -34,6 +34,9 @@ typedef struct _F_STACKS {
|
||||||
/* saved extra_roots pointer on entry to callback */
|
/* saved extra_roots pointer on entry to callback */
|
||||||
CELL extra_roots;
|
CELL extra_roots;
|
||||||
|
|
||||||
|
/* C stack pointer on entry */
|
||||||
|
void *native_stack_pointer;
|
||||||
|
|
||||||
/* error handler longjmp buffer */
|
/* error handler longjmp buffer */
|
||||||
JMP_BUF toplevel;
|
JMP_BUF toplevel;
|
||||||
|
|
||||||
|
|
26
vm/types.h
26
vm/types.h
|
@ -50,6 +50,32 @@ INLINE CELL array_capacity(F_ARRAY* array)
|
||||||
return array->capacity >> TAG_BITS;
|
return array->capacity >> TAG_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GROWABLE_ARRAY(result) \
|
||||||
|
CELL result##_count = 0; \
|
||||||
|
F_ARRAY *result = allot_array(ARRAY_TYPE,100,F)
|
||||||
|
|
||||||
|
INLINE F_ARRAY *growable_add(F_ARRAY *result, CELL elt, CELL *result_count)
|
||||||
|
{
|
||||||
|
REGISTER_ROOT(elt);
|
||||||
|
|
||||||
|
if(*result_count == array_capacity(result))
|
||||||
|
{
|
||||||
|
result = reallot_array(result,
|
||||||
|
*result_count * 2,F);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNREGISTER_ROOT(elt);
|
||||||
|
set_array_nth(result,*result_count,elt);
|
||||||
|
*result_count = *result_count + 1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GROWABLE_ADD(result,elt) \
|
||||||
|
result = growable_add(result,elt,&result##_count)
|
||||||
|
|
||||||
|
#define GROWABLE_TRIM(result) result = reallot_array(result,result##_count,F)
|
||||||
|
|
||||||
INLINE F_VECTOR* untag_vector(CELL tagged)
|
INLINE F_VECTOR* untag_vector(CELL tagged)
|
||||||
{
|
{
|
||||||
type_check(VECTOR_TYPE,tagged);
|
type_check(VECTOR_TYPE,tagged);
|
||||||
|
|
Loading…
Reference in New Issue