src/wam/constants.lisp @ b36cb61805d4

THE CONCATENING

This patch does something I've been dreading since I started: it concatenates
the registers, stack, and heap into one single big-ass array called the store.
This is how the original WAM was laid out (actually the original WAM has
EVERYTHING in one giant block of memory, but let's not get carried away here).

I was hoping I wouldn't have to do this, because the code reads a lot nicer when
these things are separate, but after reading ahead in the book I think I'm
pretty sure it had to be done.

The upside here is that now dereferencing things can be done without caring
where they live -- it's all just pointers into this giant array.  For example:
a register could refer to a stack cell, or a heap cell could point at a stack
cell.  The downside is that the stack is no longer adjustable (and things are
a bit less safe).
author Steve Losh <steve@stevelosh.com>
date Sun, 08 May 2016 21:25:08 +0000
parents 4d33f11b074f
children 4050f38d9715
(in-package #:bones.wam)

(define-constant +cell-width+ 16
  :documentation "Number of bits in each heap cell.")

(define-constant +cell-tag-width+ 2
  :documentation "Number of bits reserved for cell type tags.")

(define-constant +cell-value-width+ (- +cell-width+ +cell-tag-width+)
  :documentation "Number of bits reserved for cell values.")

(define-constant +cell-tag-bitmask+ #b11
  :documentation "Bitmask for masking the cell type tags.")


(define-constant +code-word-size+ 16
  :documentation "Size (in bits) of each word in the code store.")

(define-constant +code-limit+ (expt 2 +code-word-size+)
  :documentation "Maximum size of the WAM code store.")

(define-constant +code-sentinal+ (1- +code-limit+)
  :documentation "Sentinal value used in the PC and CP.")


(define-constant +tag-null+      #b00
  :documentation "An empty cell.")

(define-constant +tag-structure+ #b01
  :documentation "A structure cell.")

(define-constant +tag-reference+ #b10
  :documentation "A pointer to a cell.")

(define-constant +tag-functor+   #b11
  :documentation "A functor.")


(define-constant +register-count+ 2048
  :documentation "The number of registers the WAM has available.")


(define-constant +maximum-arity+ 1024
  :documentation "The maximum allowed arity of functors.")

(define-constant +maximum-query-size+ 1024
  :documentation
  "The maximum size (in bytes of bytecode) a query may compile to.")


(define-constant +stack-limit+ 2048
  :documentation "Maximum size of the WAM stack.")

(define-constant +stack-frame-size-limit+ (+ 7 +register-count+)
  :documentation "The maximum size, in stack frame words, that a stack frame could be.")


(define-constant +stack-start+ +register-count+
  :documentation "The address in the store of the first cell of the stack.")

(define-constant +stack-end+ (+ +stack-start+ +stack-limit+)
  :documentation "The address in the store one past the last cell in the stack.")

(define-constant +heap-start+ +stack-end+
  :documentation "The address in the store of the first cell of the heap.")

(define-constant +trail-limit+ (expt 2 +cell-width+)
  ;; The trail's fill pointer is stored inside choice frames on the stack, so it
  ;; needs to be able to fit inside a stack word.  We don't tag it, though, so
  ;; we can technically use all of the cell bits if we want.
  :documentation "The maximum number of variables that may exist in the trail.")


(define-constant +store-limit+ (expt 2 16)
  :documentation "Maximum size of the WAM store.")

(define-constant +heap-limit+ (- +store-limit+ +register-count+ +stack-limit+)
  ;; The heap gets whatever's left over after the registers and stack have taken
  ;; their chunk of memory.
  :documentation "Maximum size of the WAM heap.")


(define-constant +functor-limit+ (expt 2 +cell-value-width+)
  ;; Functors are referred to by their index into the functor array.  This index
  ;; is stored in the value part of functor cells.
  :documentation "The maximum number of functors the WAM can keep track of.")


;;;; Opcodes
;;; Program
(define-constant +opcode-noop+ 0)
(define-constant +opcode-get-structure-local+ 1)
(define-constant +opcode-unify-variable-local+ 2)
(define-constant +opcode-unify-variable-stack+ 3)
(define-constant +opcode-unify-value-local+ 4)
(define-constant +opcode-unify-value-stack+ 5)
(define-constant +opcode-get-variable-local+ 6)
(define-constant +opcode-get-variable-stack+ 7)
(define-constant +opcode-get-value-local+ 8)
(define-constant +opcode-get-value-stack+ 9)


;;; Query
(define-constant +opcode-put-structure-local+ 10)
(define-constant +opcode-set-variable-local+ 11)
(define-constant +opcode-set-variable-stack+ 12)
(define-constant +opcode-set-value-local+ 13)
(define-constant +opcode-set-value-stack+ 14)
(define-constant +opcode-put-variable-local+ 15)
(define-constant +opcode-put-variable-stack+ 16)
(define-constant +opcode-put-value-local+ 17)
(define-constant +opcode-put-value-stack+ 18)


;;; Control
(define-constant +opcode-call+ 19)
(define-constant +opcode-proceed+ 20)
(define-constant +opcode-allocate+ 21)
(define-constant +opcode-deallocate+ 22)
(define-constant +opcode-done+ 23)
(define-constant +opcode-try+ 24)
(define-constant +opcode-retry+ 25)
(define-constant +opcode-trust+ 26)


;;;; Debug Config
(defparameter *off-by-one* nil)