Skip to content

Commit 70fd6b9

Browse files
committed
Make sure that jscl can only load files generated with the same version
1 parent f9d124f commit 70fd6b9

6 files changed

Lines changed: 53 additions & 13 deletions

File tree

src/boot.lisp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
(%compile-defmacro ',name ,expander))
4646

4747
)))))
48-
48+
4949
(%compile-defmacro 'defmacro defmacro-macroexpander)))
5050

5151
(defmacro backquote (form)
@@ -462,7 +462,7 @@
462462
;; todo: subtypep - remove mop-object from tables
463463
(clos-object . mop-object-p) (mop-object . mop-object-p) (character . characterp)
464464
(symbol . symbolp) (keyword . keywordp)
465-
(function . functionp)
465+
(function . functionp)
466466
(number . numberp) (real . realp) (rational . rationalp) (float . floatp)
467467
(integer . integerp)
468468
(sequence . sequencep) (list . listp) (cons . consp) (array . arrayp)
@@ -537,7 +537,7 @@
537537

538538

539539
#+jscl-target
540-
(defmacro print-unreadable-object ((object stream &key type identity) &body body)
540+
(defmacro print-unreadable-object ((object stream &key type identity) &body body)
541541
`(!print-unreadable-object (,object ,stream :type ,type :identity ,identity) ,@body))
542542

543543

@@ -613,4 +613,6 @@
613613
object)
614614
(t (fail)))))
615615

616+
(defvar *git-commit-hash* #.(get-current-git-commit))
617+
616618
;;; EOF

src/compile-file.lisp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,6 @@ typeof window !== 'undefined'? window.jscl: self.jscl )"
6565
(function(internals){ var values = internals.values;" out)
6666
(with-compilation-environment
6767
(!compile-file input-file out :verbose verbose :print print))
68-
(write-string "})(jscl.internals);};" out))
68+
(write-string "})(jscl.internals);};" out)
69+
(format out "module.exports.jsclVersion = ~S;" *git-commit-hash*))
6970
output-file)

src/load.lisp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@
5656
(let ((*package* *package*))
5757
(if (find :node *features*)
5858
(let ((init (require (concat (clstring (#j:process:cwd)) "/" name))))
59+
(let ((file-version (oget init "jsclVersion")))
60+
(when (or (eq (typeof file-version) #j"undefined")
61+
(not (string= (clstring file-version) *git-commit-hash*)))
62+
(error "Cannot load ~a: compiled with JSCL ~a but current is ~a"
63+
name
64+
(if (eq (typeof file-version) #j"undefined") "unknown" (clstring file-version))
65+
*git-commit-hash*)))
5966
(funcall init (%js-vref "jscl")))
6067
(load-js name)))
6168
t)

tests.lisp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,15 @@
130130
(let ((entry (jscl/ffi:clstring (aref entries i))))
131131
(when (and (> (length entry) 5)
132132
(string= (subseq entry (- (length entry) 5)) ".lisp")
133-
(not (search ".fixtures." entry)))
133+
(not (search ".fixtures." entry))
134+
(not (string= entry "helpers.lisp")))
134135
(push (concatenate 'string "tests/" entry) files)))))
135136
(push "tests/loop/validate.lisp" files)
136137
(push "tests/loop/base-tests.lisp" files)
137138
(nreverse files))
138139
#-jscl
139-
(append (remove-if (lambda (p) (search ".fixtures." (namestring p)))
140+
(append (remove-if (lambda (p) (or (search ".fixtures." (namestring p))
141+
(search "helpers.lisp" (namestring p))))
140142
(directory (make-pathname :directory `(:relative "tests") :name :wild :type "lisp" :defaults *load-pathname*)))
141143
(list (make-pathname :directory `(:relative "tests" "loop") :name "validate" :type "lisp" :defaults *load-pathname*)
142144
(make-pathname :directory `(:relative "tests" "loop") :name "base-tests" :type "lisp" :defaults *load-pathname*))))
@@ -163,6 +165,9 @@ In SBCL, test files are loaded directly."
163165
;; Start timing after compilation
164166
(setq *timestamp* (get-internal-real-time))
165167
(terpri)
168+
;; Load shared test helpers
169+
(load #+jscl "tests/helpers.lisp"
170+
#-jscl (make-pathname :directory '(:relative "tests") :name "helpers" :type "lisp" :defaults *load-pathname*))
166171
;; Load test files (tests execute immediately via test macro)
167172
(dolist (file files-to-load)
168173
(handler-case

tests/compile-file.lisp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
;;; compile-file.lisp --- Tests for compile-file
2+
3+
(in-package :jscl-tests)
4+
5+
;;; Version checking (JSCL + Node.js only)
6+
#+jscl
7+
(when (find :node *features*)
8+
(let ((wrong-version-file (make-test-tmp-file "version-wrong.js"))
9+
(correct-version-file (make-test-tmp-file "version-correct.js"))
10+
(no-version-file (make-test-tmp-file "version-none.js")))
11+
12+
;; File with wrong jsclVersion should fail to load
13+
(with-open-file (out wrong-version-file :direction :output :if-exists :supersede)
14+
(write-string "module.exports = function(jscl){};" out)
15+
(write-string "module.exports.jsclVersion = \"wrong-version\";" out))
16+
(test (handler-case (progn (load wrong-version-file) nil)
17+
(error () t)))
18+
19+
;; File with correct jsclVersion should load successfully
20+
(with-open-file (out correct-version-file :direction :output :if-exists :supersede)
21+
(write-string "module.exports = function(jscl){};" out)
22+
(format out "module.exports.jsclVersion = ~S;" jscl::*git-commit-hash*))
23+
(test (load correct-version-file))
24+
25+
;; File without jsclVersion should fail to load
26+
(with-open-file (out no-version-file :direction :output :if-exists :supersede)
27+
(write-string "module.exports = function(jscl){};" out))
28+
(test (handler-case (progn (load no-version-file) nil)
29+
(error () t)))))

tests/file.lisp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@
22

33
#+node
44
(progn
5-
(let ((fs (require "fs")))
6-
((jscl/ffi:oget fs "mkdirSync") #j".jscl_test" (jscl/ffi:object "recursive" #j:true))
7-
(defvar *tmp-dir* (jscl/ffi:clstring ((jscl/ffi:oget fs "mkdtempSync") #j".jscl_test/test-"))))
8-
95
(test
106
(progn
11-
(with-open-file (s (concatenate 'string *tmp-dir* "/file-1.txt")
7+
(with-open-file (s (make-test-tmp-file "file-1.txt")
128
:direction :output :if-exists :supersede)
139
(write-line "abc" s)
1410
(write-line "foo" s))
15-
(with-open-file (s (concatenate 'string *tmp-dir* "/file-1.txt"))
11+
(with-open-file (s (make-test-tmp-file "file-1.txt"))
1612
(and (equal (read-line s nil) "abc")
1713
(equal (read-line s nil) "foo")
1814
(equal (read-line s nil) nil)))))
1915

20-
(test (probe-file (concatenate 'string *tmp-dir* "/file-1.txt"))))
16+
(test (probe-file (make-test-tmp-file "file-1.txt"))))

0 commit comments

Comments
 (0)