aboutsummaryrefslogtreecommitdiffstats
path: root/test/src
diff options
context:
space:
mode:
authorPhilipp Stephani2017-05-13 16:29:40 +0200
committerPhilipp Stephani2017-05-20 15:32:52 +0200
commit31fded0370c3aa6d2c4370cae21cdb7475873483 (patch)
treeacf2a7fda2d1b801b3aaf4cc9f168d3b6da77ec0 /test/src
parent6c7bf039e9c2e6daf548a95204740eeaf4c61abd (diff)
downloademacs-31fded0370c3aa6d2c4370cae21cdb7475873483.tar.gz
emacs-31fded0370c3aa6d2c4370cae21cdb7475873483.zip
Reimplement module functions
Instead of a lambda, create a new type containing all data required to call the function, and support it in the evaluator. Because this type now also needs to store the function documentation, it is too big for Lisp_Misc; use a pseudovector instead. That also has the nice benefit that we don't have to add special support to the garbage collector. Since the new type is user-visible, give it a predicate. Now we can easily support 'help-function-args' and 'func-arity'; add unit tests for these. * src/lisp.h (allocate_module_function, MODULE_FUNCTIONP) (XMODULE_FUNCTION): New pseudovector type 'module function'. * src/eval.c (FUNCTIONP): Also treat module functions as functions. (funcall_lambda, Ffuncall, eval_sub): Add support for calling module functions. (Ffunc_arity): Add support for detecting the arity of module functions. * src/emacs-module.c (module_make_function): Adapt to new structure. Return module function object directly instead of wrapping it in a lambda; remove FIXME. (funcall_module): New function to call module functions. Replaces `internal--module-call' and is called directly from eval.c. (syms_of_module): Remove internal helper function, which is no longer needed. (module_function_arity): New helper function. * src/data.c (Ftype_of): Adapt to new implementation. (Fmodule_function_p, syms_of_data): New user-visible function. Now that module functions are first-class objects, they deserve a predicate. Define it even if not compiled with --enable-modules so that Lisp code doesn't have to check for the function's existence. * src/doc.c (Fdocumentation): Support module functions. * src/print.c (print_object): Adapt to new implementation. * src/alloc.c (mark_object): Specialized garbage collector support is no longer needed. * lisp/help.el (help-function-arglist): Support module functions. While there, simplify the arity calculation by using `func-arity', which does the right thing for all kinds of functions. * test/data/emacs-module/mod-test.c: Amend docstring so we can test the argument list. * test/src/emacs-module-tests.el (mod-test-sum-docstring): Adapt to new docstring. (mod-test-non-local-exit-signal-test): Because `internal--module-call' is gone, the backtrace has changed and no longer leaks the implementation. (module--func-arity): New test for `func-arity'. (module--help-function-arglist): New test for `help-function-arglist'.
Diffstat (limited to 'test/src')
-rw-r--r--test/src/emacs-module-tests.el51
1 files changed, 27 insertions, 24 deletions
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index 0f4bfae00a2..5e78aebf7c3 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -57,33 +57,22 @@
57 :type 'overflow-error)) 57 :type 'overflow-error))
58 58
59(ert-deftest mod-test-sum-docstring () 59(ert-deftest mod-test-sum-docstring ()
60 (should (string= (documentation 'mod-test-sum) "Return A + B"))) 60 (should (string= (documentation 'mod-test-sum) "Return A + B\n\n(fn a b)")))
61 61
62(ert-deftest module-function-object () 62(ert-deftest module-function-object ()
63 "Extract and test the implementation of a module function. 63 "Extract and test the implementation of a module function.
64This test needs to be changed whenever the implementation 64This test needs to be changed whenever the implementation
65changes." 65changes."
66 (let ((func (symbol-function #'mod-test-sum))) 66 (let ((func (symbol-function #'mod-test-sum)))
67 (should (consp func)) 67 (should (module-function-p func))
68 (should (equal (length func) 4)) 68 (should (equal (type-of func) 'module-function))
69 (should (equal (nth 0 func) 'lambda)) 69 (should (string-match-p
70 (should (equal (nth 1 func) '(&rest args))) 70 (rx bos "#<module function "
71 (should (equal (nth 2 func) "Return A + B")) 71 (or "Fmod_test_sum"
72 (let ((body (nth 3 func))) 72 (and "at 0x" (+ hex-digit)))
73 (should (consp body)) 73 (? " from " (* nonl) "mod-test" (* nonl) )
74 (should (equal (length body) 4)) 74 ">" eos)
75 (should (equal (nth 0 body) #'apply)) 75 (prin1-to-string func)))))
76 (should (equal (nth 1 body) '#'internal--module-call))
77 (should (equal (nth 3 body) 'args))
78 (let ((obj (nth 2 body)))
79 (should (equal (type-of obj) 'module-function))
80 (should (string-match-p
81 (rx "#<module function "
82 (or "Fmod_test_sum"
83 (and "at 0x" (+ hex-digit)))
84 (? " from " (* nonl) "mod-test" (* nonl) )
85 ">")
86 (prin1-to-string obj)))))))
87 76
88;; 77;;
89;; Non-local exists (throw, signal). 78;; Non-local exists (throw, signal).
@@ -101,9 +90,7 @@ changes."
101 (mod-test-signal))) 90 (mod-test-signal)))
102 (should (equal debugger-args '(error (error . 56)))) 91 (should (equal debugger-args '(error (error . 56))))
103 (should (string-match-p 92 (should (string-match-p
104 (rx bol " internal--module-call(" (+ nonl) ?\) ?\n 93 (rx bol " mod-test-signal()" eol)
105 " apply(internal--module-call " (+ nonl) ?\) ?\n
106 " mod-test-signal()" eol)
107 backtrace)))) 94 backtrace))))
108 95
109(ert-deftest mod-test-non-local-exit-throw-test () 96(ert-deftest mod-test-non-local-exit-throw-test ()
@@ -172,3 +159,19 @@ changes."
172 159
173 (should (eq (mod-test-vector-fill v-test e) t)) 160 (should (eq (mod-test-vector-fill v-test e) t))
174 (should (eq (mod-test-vector-eq v-test e) eq-ref)))))) 161 (should (eq (mod-test-vector-eq v-test e) eq-ref))))))
162
163(ert-deftest module--func-arity ()
164 (should (equal (func-arity #'mod-test-return-t) '(1 . 1)))
165 (should (equal (func-arity #'mod-test-sum) '(2 . 2))))
166
167(ert-deftest module--help-function-arglist ()
168 (should (equal (help-function-arglist #'mod-test-return-t :preserve-names)
169 '(arg1)))
170 (should (equal (help-function-arglist #'mod-test-return-t)
171 '(arg1)))
172 (should (equal (help-function-arglist #'mod-test-sum :preserve-names)
173 '(a b)))
174 (should (equal (help-function-arglist #'mod-test-sum)
175 '(arg1 arg2))))
176
177;;; emacs-module-tests.el ends here