Bug fixes to leb128 library. Improvements to wasm library
This commit is contained in:
parent
baffd88509
commit
1662abad7c
|
|
@ -137,7 +137,7 @@
|
||||||
(define (read-leb128 port)
|
(define (read-leb128 port)
|
||||||
(when (not (binary-port? port))
|
(when (not (binary-port? port))
|
||||||
(error "read-leb128: port must be binary-port" port))
|
(error "read-leb128: port must be binary-port" port))
|
||||||
(cdr (read-leb128-and-length port)))
|
(car (read-leb128-and-length port)))
|
||||||
|
|
||||||
(define (read-uleb128-and-length port)
|
(define (read-uleb128-and-length port)
|
||||||
(when (not (binary-port? port))
|
(when (not (binary-port? port))
|
||||||
|
|
@ -163,4 +163,4 @@
|
||||||
(define (read-uleb128 port)
|
(define (read-uleb128 port)
|
||||||
(when (not (binary-port? port))
|
(when (not (binary-port? port))
|
||||||
(error "read-uleb128: port must be binary-port" port))
|
(error "read-uleb128: port must be binary-port" port))
|
||||||
(cdr (read-uleb128-and-length port)))
|
(car (read-uleb128-and-length port)))
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
1.0.0
|
1.1.1
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,124 @@
|
||||||
(define (wasm-bytevector? bytes)
|
(define (list-slice l start end)
|
||||||
(equal? (bytevector-copy bytes 0 4) (bytevector #x0 #x61 #x73 #x6D)))
|
(vector->list (vector-copy (list->vector l) start end)))
|
||||||
|
|
||||||
(define (wasm-version bytes)
|
(define (byte->type byte)
|
||||||
(bytevector-copy bytes 4 8))
|
(cond ((= byte 0) 'void)
|
||||||
|
;; Number types
|
||||||
|
((= byte #x7C) 'f64)
|
||||||
|
((= byte #x7D) 'f32)
|
||||||
|
((= byte #x7E) 'i64)
|
||||||
|
((= byte #x7F) 'i32)
|
||||||
|
;; Vector type
|
||||||
|
((= byte #x7B) 'V128)
|
||||||
|
;; Heap types
|
||||||
|
((= byte #x69) 'exn)
|
||||||
|
((= byte #x6A) 'array)
|
||||||
|
((= byte #x6B) 'struct)
|
||||||
|
((= byte #x6C) 'i31)
|
||||||
|
((= byte #x6D) 'eq)
|
||||||
|
((= byte #x6E) 'any)
|
||||||
|
((= byte #x6F) 'extern)
|
||||||
|
((= byte #x70) 'func)
|
||||||
|
((= byte #x71) 'none)
|
||||||
|
((= byte #x72) 'noextern)
|
||||||
|
((= byte #x73) 'nofunc)
|
||||||
|
((= byte #x74) 'noexn)
|
||||||
|
(else
|
||||||
|
(display "byte->type warning: Unknown type ")
|
||||||
|
(display (bytevector byte))
|
||||||
|
(newline)
|
||||||
|
'unknown)))
|
||||||
|
|
||||||
|
(define (read-types type-count section-size port result)
|
||||||
|
(letrec*
|
||||||
|
((type-delimiter #x60)
|
||||||
|
(type-signature-byte->name
|
||||||
|
(lambda (byte)
|
||||||
|
(cond ((= byte #x5E) 'array)
|
||||||
|
((= byte #x5F) 'struct)
|
||||||
|
((= byte #x60) 'func)
|
||||||
|
(else 'unknown))))
|
||||||
|
(type-signature-byte?
|
||||||
|
(lambda (byte)
|
||||||
|
(not (symbol=? (type-signature-byte->name byte) 'unknown))))
|
||||||
|
(type-bytes->type
|
||||||
|
(lambda (bytes)
|
||||||
|
(let*
|
||||||
|
((argument-count (list-ref bytes 1))
|
||||||
|
(argument-types (map byte->type (list-slice bytes 2 (+ 2 argument-count))))
|
||||||
|
(return-type (byte->type (car (reverse bytes)))))
|
||||||
|
(append
|
||||||
|
`(,(type-signature-byte->name (list-ref bytes 0))
|
||||||
|
,(if (null? argument-types) '() `(param ,@argument-types))
|
||||||
|
,(if (symbol=? return-type 'void) '() `(result ,return-type)))))))
|
||||||
|
(read-type
|
||||||
|
(lambda (type-result)
|
||||||
|
(cond
|
||||||
|
((and (or (eof-object? (peek-u8 port))
|
||||||
|
(type-signature-byte? (peek-u8 port))
|
||||||
|
(= (+ (apply + (map length result))
|
||||||
|
(+ (length type-result) 1))
|
||||||
|
section-size))
|
||||||
|
(> (length type-result) 0))
|
||||||
|
(reverse type-result))
|
||||||
|
(else
|
||||||
|
(read-type (cons (read-u8 port) type-result)))))))
|
||||||
|
(cond
|
||||||
|
((= (length result) type-count)
|
||||||
|
(map type-bytes->type (reverse result)))
|
||||||
|
(else (read-types type-count section-size port (cons (read-type '()) result))))))
|
||||||
|
|
||||||
|
(define (read-import import-count section-size port result)
|
||||||
|
(if (= (length result) import-count)
|
||||||
|
result
|
||||||
|
(letrec*
|
||||||
|
((import-kind->type (lambda (type) (cond ((= type 0) 'func) (else 'unknown))))
|
||||||
|
(module-name-length (read-u8 port))
|
||||||
|
(module-name (utf8->string (read-bytevector module-name-length port)))
|
||||||
|
(field-name-length (read-u8 port))
|
||||||
|
(field-name (utf8->string (read-bytevector field-name-length port)))
|
||||||
|
(import-kind (read-u8 port))
|
||||||
|
(type-index (read-u8 port)))
|
||||||
|
(display "HERE: ")
|
||||||
|
(write import-count)
|
||||||
|
(newline)
|
||||||
|
(write result)
|
||||||
|
(newline)
|
||||||
|
(read-import import-count
|
||||||
|
section-size
|
||||||
|
port
|
||||||
|
(cons `(import (module ,module-name)
|
||||||
|
(field ,field-name)
|
||||||
|
(type ,type-index))
|
||||||
|
result)))))
|
||||||
|
|
||||||
|
(define (read-functions type-count section-size port result)
|
||||||
|
`((bytes ,(read-bytevector (- section-size 1) port))))
|
||||||
|
|
||||||
|
(define (read-tables type-count section-size port result)
|
||||||
|
`((bytes ,(read-bytevector (- section-size 1) port))))
|
||||||
|
|
||||||
|
(define (read-memory type-count section-size port result)
|
||||||
|
`((bytes ,(read-bytevector (- section-size 1) port))))
|
||||||
|
|
||||||
|
(define (read-global type-count section-size port result)
|
||||||
|
`((bytes ,(read-bytevector (- section-size 1) port))))
|
||||||
|
|
||||||
|
(define (read-section name size port)
|
||||||
|
(list name
|
||||||
|
(cond
|
||||||
|
((symbol=? name 'custom) (read-bytevector size port))
|
||||||
|
((symbol=? name 'type) (read-types (read-u8 port) size port '()))
|
||||||
|
((symbol=? name 'import) (read-import (read-u8 port) size port '()))
|
||||||
|
((symbol=? name 'function) (read-functions (read-u8 port) size port '()))
|
||||||
|
((symbol=? name 'table) (read-tables (read-u8 port) size port '()))
|
||||||
|
((symbol=? name 'memory) (read-memory (read-u8 port) size port '()))
|
||||||
|
((symbol=? name 'global) (read-global (read-u8 port) size port '()))
|
||||||
|
((symbol=? name 'export) (read-bytevector size port))
|
||||||
|
((symbol=? name 'start) (read-bytevector size port))
|
||||||
|
((symbol=? name 'element) (read-bytevector size port))
|
||||||
|
((symbol=? name 'code) (read-bytevector size port))
|
||||||
|
((symbol=? name 'data) (read-bytevector size port)))))
|
||||||
|
|
||||||
(define (section-id->name id)
|
(define (section-id->name id)
|
||||||
(cond ((= id 0) 'custom)
|
(cond ((= id 0) 'custom)
|
||||||
|
|
@ -21,101 +137,26 @@
|
||||||
((= id 13) 'tag)
|
((= id 13) 'tag)
|
||||||
(else (error "section-id->name: unrecognized section id" id))))
|
(else (error "section-id->name: unrecognized section id" id))))
|
||||||
|
|
||||||
(define (bytes->type bytes)
|
(define (wasm->sexp-loop port result)
|
||||||
(let ((first-byte (bytevector-u8-ref bytes 0)))
|
(let* ((section-id (read-u8 port))
|
||||||
(cond
|
(section-name (section-id->name section-id))
|
||||||
((equal? first-byte #x7C) 'f64)
|
(size (read-uleb128 port))
|
||||||
((equal? first-byte #x7D) 'f32)
|
(section (read-section section-name size port)))
|
||||||
((equal? first-byte #x7E) 'f64)
|
(display "Section name: ")
|
||||||
((equal? first-byte #x7F) 'f32)
|
(display section-name)
|
||||||
(else 'unknown)
|
|
||||||
;(else (error "Unsupported type byte" first-byte))
|
|
||||||
)))
|
|
||||||
|
|
||||||
(define (bytes->types bytes)
|
|
||||||
(letrec*
|
|
||||||
((bytes-length (bytevector-length bytes))
|
|
||||||
(looper
|
|
||||||
(lambda (index types)
|
|
||||||
(if (>= index bytes-length)
|
|
||||||
types
|
|
||||||
(looper (+ index 1) (bytes->type (bytevector-copy bytes index)))))))
|
|
||||||
(looper 0 '())))
|
|
||||||
|
|
||||||
(define (section-bytes->sexp name bytes)
|
|
||||||
(let* ((id-and-id-length (leb128->integer-and-length bytes))
|
|
||||||
(data-bytes (bytevector-copy bytes (cdr id-and-id-length)))
|
|
||||||
(data-length (bytevector-length data-bytes))
|
|
||||||
)
|
|
||||||
(cond
|
|
||||||
#;((equal? name 'type)
|
|
||||||
(let* ((number-of-types (leb128->integer-and-length bytes))
|
|
||||||
(types (bytes->types (bytevector-copy bytes (cdr number-of-types)))))
|
|
||||||
(display "TYPE: type, content = ")
|
|
||||||
(write bytes)
|
|
||||||
(newline)
|
(newline)
|
||||||
`((number-of-types . ,(car number-of-types))
|
(display "Section size: ")
|
||||||
(types . ,types))))
|
(write size)
|
||||||
((equal? name 'type)
|
|
||||||
(let ((number-of-types (bytevector-u8-ref bytes 0)))
|
|
||||||
(display "TYPE: type ")
|
|
||||||
(write data-length)
|
|
||||||
(newline)
|
(newline)
|
||||||
(write data-bytes)
|
(if (eof-object? (peek-u8 port))
|
||||||
(newline)
|
(reverse result)
|
||||||
(write number-of-types)
|
(wasm->sexp-loop port (cons section result)))))
|
||||||
(newline)
|
|
||||||
'()))
|
|
||||||
(else '()))))
|
|
||||||
|
|
||||||
(define (wasm->sexp-old bytes)
|
|
||||||
(let* ((bytes-length (bytevector-length bytes))
|
|
||||||
(magic-bytes (if (> bytes-length 3) (bytevector-copy bytes 0 4) #u8())))
|
|
||||||
(when (not (equal? magic-bytes #u8(#x00 #x61 #x73 #x6D)))
|
|
||||||
(error "Binary is not wasm (missing magic bytes)"))
|
|
||||||
(letrec*
|
|
||||||
((wasm-version (bytevector-copy bytes 4 8))
|
|
||||||
(section-data '())
|
|
||||||
(index 8) ;; Jump over magic bytes and version
|
|
||||||
(looper (lambda ()
|
|
||||||
(when (< index bytes-length)
|
|
||||||
(let* ((id (bytevector-u8-ref bytes index))
|
|
||||||
(name (section-id->name id))
|
|
||||||
(len (uleb128->integer-and-length bytes (+ index 1) 0 0))
|
|
||||||
(data-bytes (bytevector-copy bytes index (+ index (car len)))))
|
|
||||||
(display "HERE: index ")
|
|
||||||
(write index)
|
|
||||||
(newline)
|
|
||||||
(display "HERE: data-bytes ")
|
|
||||||
(write data-bytes)
|
|
||||||
(newline)
|
|
||||||
(set! section-data
|
|
||||||
(append section-data
|
|
||||||
`((id . ,id)
|
|
||||||
(name . ,name)
|
|
||||||
(data . ,(section-bytes->sexp name data-bytes)))))
|
|
||||||
(set! index (+ index 1 (car len) (cdr len)))
|
|
||||||
(looper)
|
|
||||||
)))))
|
|
||||||
(looper)
|
|
||||||
section-data)))
|
|
||||||
|
|
||||||
(define (wasm->sexp port)
|
(define (wasm->sexp port)
|
||||||
(let ((magic-bytes (read-bytevector 4 port)))
|
(let ((magic-bytes (read-bytevector 4 port)))
|
||||||
(when (not (equal? magic-bytes #u8(#x00 #x61 #x73 #x6D)))
|
(when (not (equal? magic-bytes #u8(#x00 #x61 #x73 #x6D)))
|
||||||
(error "Binary is not wasm (missing magic bytes)"))
|
(error "Binary is not wasm (missing magic bytes)"))
|
||||||
(let ((version (read-bytevector 4 port)))
|
(letrec*
|
||||||
|
((version (read-bytevector 4 port)))
|
||||||
(display "HERE: ")
|
(wasm->sexp-loop port '()))))
|
||||||
(write magic-bytes)
|
|
||||||
(newline)
|
|
||||||
(write version)
|
|
||||||
(newline)
|
|
||||||
(write (read-uleb128 port))
|
|
||||||
(newline)
|
|
||||||
(write (read-uleb128 port))
|
|
||||||
(newline)
|
|
||||||
|
|
||||||
|
|
||||||
)))
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
int plus(int a, int b) {
|
int x = 100;
|
||||||
|
|
||||||
|
extern int plus(int a, int b) {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
int plus_three(int a, int b, int c) {
|
int plus_three(int a, int b, int c) {
|
||||||
return a + b + c;
|
return a + b + c;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,8 @@
|
||||||
|
|
||||||
(define testdir "retropikzel/wasm")
|
(define testdir "retropikzel/wasm")
|
||||||
(define testfile1 (string-append testdir "/" "plus.wasm"))
|
(define testfile1 (string-append testdir "/" "plus.wasm"))
|
||||||
|
(define testfile2 (string-append "/tmp/tr7/a.out.wasm"))
|
||||||
;(when (not (file-exists? testfile1)) (error (string-append testfile1 " does not exist")))
|
(define sexp (wasm->sexp (open-binary-input-file testfile2)))
|
||||||
|
(show #t (pretty sexp))
|
||||||
;(define bytes (with-input-from-file testfile1 (lambda () (read-bytevector 10000))))
|
|
||||||
|
|
||||||
(define sexp (with-input-from-file testfile1 (lambda () (wasm->sexp (current-input-port)))))
|
|
||||||
(write sexp)
|
|
||||||
(newline)
|
|
||||||
|
|
||||||
(test-end "wasm")
|
(test-end "wasm")
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
(scheme file)
|
(scheme file)
|
||||||
(scheme process-context)
|
(scheme process-context)
|
||||||
(srfi 64)
|
(srfi 64)
|
||||||
|
(srfi 166)
|
||||||
;(retropikzel mouth)
|
;(retropikzel mouth)
|
||||||
;(retropikzel ctrf)
|
;(retropikzel ctrf)
|
||||||
(retropikzel LIBRARY))
|
(retropikzel LIBRARY))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue