- (codegen-expr (cadr e) si env)
- (let ([index (cadr tor)]
- [products 2]
- [to-traverse (list-head products index)]
- [offset (fold-left
- (lambda (acc t) (+ acc (type-size t)))
- wordsize ; skip tag in first word
- to-traverse)])
- 3
- ))
-
- (let ([tor (data-tor env e)]
- [constructor (eqv? 'constructor (cadr tor))])
+ (let* ([res (codegen-expr (cadr e) si env)]
+ [info (cadr tor)]
+ [type (car info)]
+ [sum (cadr info)]
+ [index (caddr info)]
+ [product-type (cadddr info)]
+ [product-type-size (type-size dls product-type)]
+
+ [safe-space-offset (- si (type-size dls type))]
+
+ [inner-offset (- si (data-product-offset dls type sum index))])
+
+ (when (not (on-stack? (cadr e)))
+ (error #f "trying to destruct something that isn't a stack expression"))
+ (emit "# deconstructing")
+
+ (if (stack-type? (env-data-layouts env) product-type)
+ ; if copying from the stack, need to first copy
+ ; to a safe space above to avoid overwriting
+ ; the original result on the stack
+ ; this is bad. please remove this in the rewrite.
+ (begin
+ (emit-stack-copy inner-offset safe-space-offset product-type-size)
+ (emit-stack-copy safe-space-offset si product-type-size))
+ (emit "movq ~a(%rbp), %rax" inner-offset))))
+
+ (define (codegen-constructor tor)
+ (let* ([info (cadr tor)]
+ [type (car info)]
+ [sum (cadr info)]
+ [constructor (car e)]
+
+ [args (cdr e)]
+
+ [tag (data-sum-tag (env-data-layouts env)
+ type
+ sum)]
+
+ [inner-si (- si (type-size dls type))]
+
+ [product-types (cdr (assoc sum (cdr (assoc type dls))))]
+
+ [insert-product
+ (lambda (expr i product-type)
+ (let ([dest-offset
+ (- si (data-product-offset dls type sum i))]
+ [product-size (type-size dls product-type)])
+ (codegen-expr expr inner-si env)
+ (if (on-stack? expr)
+ (emit-stack-copy inner-si dest-offset product-size)
+ (emit "movq %rax, ~a(%rbp)" dest-offset))))])
+
+ ; emit the tag
+ (emit "movq $~a, ~a(%rbp)" tag si)
+ ; generate products
+ (for-each insert-product args (range 0 (length args)) product-types)))
+
+ (let* ([tor (data-tor env e)]
+ [constructor (eqv? 'constructor (caddr (cadr tor)))])