|
177 | 177 |
|
178 | 178 | (define/override (primitives)
|
179 | 179 | (set-union (super primitives)
|
180 |
| - (set 'eq? 'and 'or 'not))) |
| 180 | + (set 'eq? 'and 'not '< '<= '> '>=))) |
181 | 181 |
|
182 | 182 | (define/override (interp-op op)
|
183 | 183 | (match op
|
184 | 184 | ['eq? (lambda (v1 v2)
|
185 | 185 | (cond [(and (fixnum? v1) (fixnum? v2)) (eq? v1 v2)]
|
186 | 186 | [(and (boolean? v1) (boolean? v2)) (eq? v1 v2)]))]
|
| 187 | + ['and (lambda (v1 v2) |
| 188 | + (cond [(and (boolean? v1) (boolean? v2)) |
| 189 | + (and v1 v2)]))] |
| 190 | + ['not (lambda (v) (match v [#t #f] [#f #t]))] |
187 | 191 | ['< (lambda (v1 v2)
|
188 | 192 | (cond [(and (fixnum? v1) (fixnum? v2)) (< v1 v2)]))]
|
189 | 193 | ['<= (lambda (v1 v2)
|
|
192 | 196 | (cond [(and (fixnum? v1) (fixnum? v2)) (> v1 v2)]))]
|
193 | 197 | ['>= (lambda (v1 v2)
|
194 | 198 | (cond [(and (fixnum? v1) (fixnum? v2)) (>= v1 v2)]))]
|
195 |
| - ['not (lambda (v) (match v [#t #f] [#f #t]))] |
196 |
| - ['and (lambda (v1 v2) |
197 |
| - (cond [(and (boolean? v1) (boolean? v2)) |
198 |
| - (and v1 v2)]))] |
199 | 199 | [else (super interp-op op)]))
|
200 | 200 |
|
201 | 201 | (define/override (interp-scheme env)
|
|
311 | 311 | (define sign (bitwise-and eflags #b000010000000))
|
312 | 312 | (if (= overflow sign) 1 0)]
|
313 | 313 | ['le
|
314 |
| - (or (eflags-status env 'e) (eflags-status env 'l))] |
| 314 | + (if (or (eq? 1 (eflags-status env 'e)) |
| 315 | + (eq? 1 (eflags-status env 'l))) |
| 316 | + 1 0)] |
315 | 317 | ['g
|
316 |
| - (not (eflags-status env 'le))] |
| 318 | + (if (not (eq? 1 (eflags-status env 'le))) |
| 319 | + 1 0)] |
317 | 320 | ['ge
|
318 |
| - (not (eflags-status env 'l))])) |
| 321 | + (if (not (eq? 1 (eflags-status env 'l))) |
| 322 | + 1 0)])) |
319 | 323 |
|
320 | 324 | (define/override (interp-x86 env)
|
321 | 325 | (lambda (ast)
|
|
325 | 329 | [`((set ,cc ,d) . ,ss)
|
326 | 330 | (define name (get-name d))
|
327 | 331 | (define val (eflags-status env cc))
|
| 332 | + (verbose "set" cc val) |
328 | 333 | ((interp-x86 (cons (cons name val) env)) ss)]
|
329 | 334 | ;; if's are present before patch-instructions
|
330 | 335 | [(or `((if ,cnd ,thn ,els) . ,ss)
|
|
335 | 340 |
|
336 | 341 | [`((label ,l) . ,ss)
|
337 | 342 | ((interp-x86 env) ss)]
|
338 |
| - [`((cmpq ,s1 ,s2) . ,ss) |
| 343 | + |
| 344 | + ;; cmpq performs a subq operation and examimines the state |
| 345 | + ;; of the result, this is done without overwriting the second |
| 346 | + ;; register. -andre |
| 347 | + ;; Notice that the syntax is very confusing |
| 348 | + ;; (cmpq ,s2 ,s1) (jl then) (jmp else) ... |
| 349 | + ;; (if (< s1 s2) then else) |
| 350 | + [`((cmpq ,s2 ,s1) . ,ss) |
339 | 351 | (let* ([v1 ((interp-x86-exp env) s1)]
|
340 |
| - [v2 ((interp-x86-exp env) s2)] |
341 |
| - [zero (arithmetic-shift (b2i (eq? v1 v2)) 6)] |
342 |
| - [eflags (bitwise-ior zero)]) |
| 352 | + [v2 ((interp-x86-exp env) s2)] |
| 353 | + [v3 (- v2 v1)] |
| 354 | + [zero (arithmetic-shift (b2i (eq? v3 0)) 6)] |
| 355 | + [sign (arithmetic-shift (b2i (< v3 0)) 7)] |
| 356 | + ;; Our numbers do not overflow so this bit is always 0 |
| 357 | + [overflow (arithmetic-shift 0 11)] |
| 358 | + [eflags (bitwise-ior overflow sign zero)]) |
343 | 359 | ((interp-x86 (cons (cons '__flag eflags) env)) ss))]
|
344 | 360 | [`((movzbq ,s ,d) . ,ss)
|
345 | 361 | (define x (get-name d))
|
|
390 | 406 | tys (range (length tys))))]
|
391 | 407 | [else (super display-by-type ty val)]))
|
392 | 408 |
|
| 409 | + ;; Andre, please write a paragraph or so explaining this |
| 410 | + ;; design for representing the heap. -Jeremy |
393 | 411 |
|
394 | 412 | ;; The simulated global state of the program
|
395 | 413 | ;; define produces private fields
|
|
428 | 446 |
|
429 | 447 | (define/public (collect!)
|
430 | 448 | (lambda (rootset bytes-requested)
|
| 449 | + (verbose "collect!" bytes-requested) |
431 | 450 | ;; after a call to collect we must guarantee there is enough
|
432 | 451 | ;; memory to allocate the requested block of memory
|
433 | 452 | (let double-heap ([hs heap-size])
|
434 | 453 | (if (< hs bytes-requested)
|
435 | 454 | (double-heap (* 2 hs))
|
436 |
| - (let ((h-begin (allocate! 'fromspace hs))) |
| 455 | + (let ((h-begin (allocate-page! 'fromspace hs))) |
437 | 456 | ;; I am only advancing the end of the heap because we
|
438 | 457 | ;; are not reclaiming memory
|
439 | 458 | (set-box! fromspace_end (+ h-begin hs))
|
440 | 459 | (set-box! free_ptr h-begin))))))
|
441 | 460 |
|
442 | 461 | (define/public (initialize!)
|
443 | 462 | (lambda (stack-length heap_length)
|
| 463 | + (verbose "initialize!") |
444 | 464 | (set-box! memory '())
|
445 |
| - (let* ([s-begin (allocate! 'rootstack stack-size)] |
446 |
| - [h-begin (allocate! 'fromspace heap-size)]) |
| 465 | + (let* ([s-begin (allocate-page! 'rootstack stack-size)] |
| 466 | + [h-begin (allocate-page! 'fromspace heap-size)]) |
447 | 467 | (set-box! rootstack_begin s-begin)
|
448 | 468 | (set-box! rootstack_end (+ s-begin stack-size))
|
449 | 469 | (set-box! fromspace_begin h-begin)
|
450 | 470 | (set-box! fromspace_end (+ h-begin heap-size))
|
451 | 471 | (set-box! free_ptr h-begin))))
|
452 | 472 |
|
453 |
| - (define (allocate! name size) |
| 473 | + (define (allocate-page! name size) |
| 474 | + (verbose "allocate-page!" name size) |
454 | 475 | (unless (and (fixnum? size)
|
455 | 476 | (positive? size)
|
456 | 477 | (= 0 (modulo size 8)))
|
457 |
| - (error 'allocate! "expected non-negative fixnum in ~a" size)) |
| 478 | + (error 'allocate-page! "expected non-negative fixnum in ~a" size)) |
458 | 479 | ;; Find the last address
|
459 | 480 | (define max-addr
|
460 | 481 | (for/fold ([next 8])
|
|
463 | 484 | (max next stop))))
|
464 | 485 | ;; Allocate with a small pad 100 words so that it isn't likely to
|
465 | 486 | ;; accidentally use another region.
|
466 |
| - ;; The randomness is to dispell any reliance on interp always allocating the |
467 |
| - ;; same way. -Andre |
| 487 | + ;; The randomness is to dispell any reliance on interp always allocating |
| 488 | + ;; the same way. -Andre |
468 | 489 | (define start-addr (+ max-addr 800))
|
469 | 490 | ;; The range is of valid addresses in memory are [start, stop)
|
470 | 491 | (define stop-addr (+ start-addr size))
|
471 | 492 | (define vect (make-vector (arithmetic-shift size -3) uninitialized))
|
| 493 | + (verbose "allocated" name start-addr stop-addr) |
472 | 494 | (set-box! memory (cons `(page ,start-addr ,stop-addr ,name ,vect)
|
473 | 495 | (unbox memory)))
|
474 | 496 | start-addr)
|
|
529 | 551 | (verbose "R2/interp-scheme" ast)
|
530 | 552 | (match ast
|
531 | 553 | [`(void) (void)]
|
| 554 | + [`(global-value free_ptr) |
| 555 | + (unbox free_ptr)] |
| 556 | + [`(global-value fromspace_end) |
| 557 | + (unbox fromspace_end)] |
| 558 | + [`(allocate ,l ,ty) (build-vector l (lambda a uninitialized))] |
| 559 | + [`(collect ,size) |
| 560 | + (unless (exact-nonnegative-integer? ((interp-scheme env) size)) |
| 561 | + (error 'interp-C "invalid argument to collect in ~a" ast)) |
| 562 | + (void)] |
| 563 | + [`(program (type ,ty) ,e) |
| 564 | + ((interp-scheme '()) e)] |
| 565 | + [`(initialize ,stack-size ,heap-size) |
| 566 | + ((initialize!) stack-size heap-size) |
| 567 | + (void)] |
532 | 568 | [else ((super interp-scheme env) ast)]
|
533 | 569 | )))
|
534 | 570 |
|
|
559 | 595 | (vomit "R2/interp-C" ast)
|
560 | 596 | (match ast
|
561 | 597 | [`(void) (void)]
|
| 598 | + [`(global-value free_ptr) |
| 599 | + (unbox free_ptr)] |
| 600 | + [`(global-value fromspace_end) |
| 601 | + (unbox fromspace_end)] |
562 | 602 | ;; I should do better than make these noops - andre
|
563 | 603 | [`(initialize ,s ,h)
|
564 | 604 | (unless (and (exact-nonnegative-integer? s)
|
|
641 | 681 | (vomit "R2/interp-x86" (car ast)))
|
642 | 682 | (match ast
|
643 | 683 | ;; cmpq performs a subq operation and examimines the state
|
644 |
| - ;; of the result, this is done without overiting the second |
| 684 | + ;; of the result, this is done without overwriting the second |
645 | 685 | ;; register. -andre
|
646 | 686 | ;; Notice that the syntax is very confusing
|
647 | 687 | ;; (cmpq ,s2 ,s1) (jl then) (jmp else) ...
|
648 | 688 | ;; (if (< s1 s2) then else)
|
649 |
| - [`((cmpq ,s2 ,s1) . ,ss) |
| 689 | + #;[`((cmpq ,s2 ,s1) . ,ss) |
650 | 690 | (let* ([v1 ((interp-x86-exp env) s1)]
|
651 | 691 | [v2 ((interp-x86-exp env) s2)]
|
652 | 692 | [v3 (- v2 v1)]
|
|
660 | 700 | [`((callq initialize) . ,ss)
|
661 | 701 | (define stack-size ((interp-x86-exp env) '(reg rdi)))
|
662 | 702 | (define heap-size ((interp-x86-exp env) '(reg rsi)))
|
663 |
| - ((initialize!) stack-size heap-size) |
| 703 | + ((initialize!) stack-size heap-size) |
664 | 704 | ((interp-x86 env) ss)]
|
665 | 705 | [`((callq malloc) . ,ss)
|
666 | 706 | (define num-bytes ((interp-x86-exp env) '(reg rdi)))
|
667 |
| - ((interp-x86 `((rax . ,(allocate! 'malloc num-bytes)) . ,env)) ss)] |
| 707 | + ((interp-x86 `((rax . ,(allocate-page! 'malloc num-bytes)) . ,env)) |
| 708 | + ss)] |
668 | 709 | [`((callq alloc) . ,ss)
|
669 | 710 | (define num-bytes ((interp-x86-exp env) '(reg rdi)))
|
670 |
| - ((interp-x86 `((rax . ,(allocate! 'alloc num-bytes)) . ,env)) ss)] |
| 711 | + ((interp-x86 `((rax . ,(allocate-page! 'alloc num-bytes)) . ,env)) |
| 712 | + ss)] |
671 | 713 | [`((callq collect) . ,ss)
|
672 | 714 | (define rootstack ((interp-x86-exp env) '(reg rdi)))
|
673 | 715 | (define bytes-requested ((interp-x86-exp env) '(reg rsi)))
|
|
0 commit comments