Skip to content

Commit

Permalink
Moving error handler into exceptions.asm
Browse files Browse the repository at this point in the history
Needed by core routines, so will need to add
to earlier steps.
  • Loading branch information
bendudson committed Dec 26, 2017
1 parent e8915ef commit e64592a
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 135 deletions.
138 changes: 138 additions & 0 deletions nasm/exceptions.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
;; ----------------------------------------------
;;
;; Error handling
;;
;; A handler consists of:
;; - A stack pointer address to reset to
;; - An address to jump to
;; - An optional data structure to pass
;;
;; When jumped to, an error handler will be given:
;; - the object thrown in RSI
;; - the optional data structure in RDI
;;

section .bss
;; Error handler list
error_handler: resq 1
section .text
;; Add an error handler to the front of the list
;;
;; Input: RSI - Stack pointer
;; RDI - Address to jump to
;; RCX - Data structure. Set to zero for none.
;; If not zero, reference count incremented
;;
;; Modifies registers:
;; RAX
;; RBX
error_handler_push:
call alloc_cons
; car will point to a list (stack, addr, data)
; cdr will point to the previous handler
mov [rax], BYTE (block_cons + container_list + content_pointer)
mov rbx, [error_handler]
cmp rbx, 0 ; Check if previous handler was zero
je .create_handler ; Zero, so leave null
; Not zero, so create pointer to it
mov [rax + Cons.typecdr], BYTE content_pointer
mov [rax + Cons.cdr], rbx

; note: not incrementing reference count, since
; we're replacing one reference with another
.create_handler:
mov [error_handler], rax ; new error handler
mov rdx, rax
call alloc_cons
mov [rdx + Cons.car], rax
; Store stack pointer
mov [rax], BYTE (block_cons + container_list + content_function)
mov [rax + Cons.car], rsi ; stack pointer
mov rdx, rax
call alloc_cons
mov [rdx + Cons.typecdr], BYTE content_pointer
mov [rdx + Cons.cdr], rax
; Store function pointer to jump to
; Note: This can't use content_pointer or release
; will try to release this memory address
mov [rax], BYTE (block_cons + container_list + content_function)
mov [rax + Cons.car], rdi

; Check if there is an object to pass to handler
cmp rcx, 0
je .done

; Set the final CDR to point to the object
mov [rax + Cons.typecdr], BYTE content_pointer
mov [rax + Cons.cdr], rcx

mov rsi, rcx
call incref_object
.done:
ret
;; Removes an error handler from the list
;;
;; Modifies registers:
;; RSI
;; RAX
;; RCX
error_handler_pop:
; get the address
mov rsi, [error_handler]
cmp rsi, 0
je .done ; Nothing to remove
push rsi
mov rsi, [rsi + Cons.cdr] ; next handler
mov [error_handler], rsi
;call incref_object ; needed because releasing soon
pop rsi ; handler being removed
mov [rsi + Cons.typecdr], BYTE 0
call release_cons
.done:
ret
;; Throw an error
;; Object to pass to handler should be in RSI
error_throw:
; Get the next error handler
mov rax, [error_handler]
cmp rax, 0
je .no_handler
; Got a handler
mov rax, [rax + Cons.car] ; handler
mov rbx, [rax + Cons.car] ; stack pointer
mov rax, [rax + Cons.cdr]
mov rcx, [rax + Cons.car] ; function
mov rdi, [rax + Cons.cdr] ; data structure

; Reset stack
mov rsp, rbx

; Jump to the handler
jmp rcx
.no_handler:
; Print the object in RSI then quit
cmp rsi, 0
je .done ; nothing to print
mov rdi, 1 ; print_readably
call pr_str
mov rsi, rax
call print_string
.done:
jmp quit_error
160 changes: 25 additions & 135 deletions nasm/stepA_mal.asm
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ global _start
%include "reader.asm" ; String -> Data structures
%include "core.asm" ; Core functions
%include "printer.asm" ; Data structures -> String
%include "exceptions.asm" ; Error handling
section .bss
;; Top-level (REPL) environment
repl_env:resq 1

;; Error handler list
error_handler: resq 1
section .data

;; ------------------------------------------
Expand Down Expand Up @@ -87,139 +85,9 @@ section .data

;; Command to run at start of REPL
static mal_startup_header, db "(println (str ",34,"Mal [",34," *host-language* ",34,"]",34,"))"
section .text

;; ----------------------------------------------
;;
;; Error handling
;;
;; A handler consists of:
;; - A stack pointer address to reset to
;; - An address to jump to
;; - An optional data structure to pass
;;
;; When jumped to, an error handler will be given:
;; - the object thrown in RSI
;; - the optional data structure in RDI
;;

;; Add an error handler to the front of the list
;;
;; Input: RSI - Stack pointer
;; RDI - Address to jump to
;; RCX - Data structure. Set to zero for none.
;; If not zero, reference count incremented
;;
;; Modifies registers:
;; RAX
;; RBX
error_handler_push:
call alloc_cons
; car will point to a list (stack, addr, data)
; cdr will point to the previous handler
mov [rax], BYTE (block_cons + container_list + content_pointer)
mov rbx, [error_handler]
cmp rbx, 0 ; Check if previous handler was zero
je .create_handler ; Zero, so leave null
; Not zero, so create pointer to it
mov [rax + Cons.typecdr], BYTE content_pointer
mov [rax + Cons.cdr], rbx

; note: not incrementing reference count, since
; we're replacing one reference with another
.create_handler:
mov [error_handler], rax ; new error handler
mov rdx, rax
call alloc_cons
mov [rdx + Cons.car], rax
; Store stack pointer
mov [rax], BYTE (block_cons + container_list + content_function)
mov [rax + Cons.car], rsi ; stack pointer
mov rdx, rax
call alloc_cons
mov [rdx + Cons.typecdr], BYTE content_pointer
mov [rdx + Cons.cdr], rax
; Store function pointer to jump to
; Note: This can't use content_pointer or release
; will try to release this memory address
mov [rax], BYTE (block_cons + container_list + content_function)
mov [rax + Cons.car], rdi

; Check if there is an object to pass to handler
cmp rcx, 0
je .done

; Set the final CDR to point to the object
mov [rax + Cons.typecdr], BYTE content_pointer
mov [rax + Cons.cdr], rcx

mov rsi, rcx
call incref_object
.done:
ret
;; Removes an error handler from the list
;;
;; Modifies registers:
;; RSI
;; RAX
;; RCX
error_handler_pop:
; get the address
mov rsi, [error_handler]
cmp rsi, 0
je .done ; Nothing to remove
push rsi
mov rsi, [rsi + Cons.cdr] ; next handler
mov [error_handler], rsi
;call incref_object ; needed because releasing soon
pop rsi ; handler being removed
mov [rsi + Cons.typecdr], BYTE 0
call release_cons
.done:
ret
;; Throw an error
;; Object to pass to handler should be in RSI
error_throw:
; Get the next error handler
mov rax, [error_handler]
cmp rax, 0
je .no_handler
; Got a handler
mov rax, [rax + Cons.car] ; handler
mov rbx, [rax + Cons.car] ; stack pointer
mov rax, [rax + Cons.cdr]
mov rcx, [rax + Cons.car] ; function
mov rdi, [rax + Cons.cdr] ; data structure

; Reset stack
mov rsp, rbx

; Jump to the handler
jmp rcx
.no_handler:
; Print the object in RSI then quit
cmp rsi, 0
je .done ; nothing to print
mov rdi, 1 ; print_readably
call pr_str
mov rsi, rax
call print_string
.done:
jmp quit_error
section .text
;; ----------------------------------------------
;; Evaluates a form
;;
Expand Down Expand Up @@ -1946,6 +1814,28 @@ apply_fn:
mov rax, [rax + Cons.cdr]
mov rax, [rax + Cons.car] ; Body
pop rcx ; Exprs

;;;
; push rax
; push rcx
; push rsi
; push rdi
; push rdx
; push r15
; push r13

; mov rsi, rcx
; call core_println
; pop r13
; pop r15
; pop rdx
; pop rdi
; pop rsi
; pop rcx
; pop rax

;;;
; Check the type of the body
mov bl, BYTE [rax]
Expand Down

0 comments on commit e64592a

Please sign in to comment.