Skip to content

Commit 2d6888c

Browse files
author
Vladimir Sedach
committed
Added support for Function.caller/arguments.callee.caller property. Since this adds overhead to every function call, it is off by default and can be enabled with the *enable-Function.caller* flag before compiling JS code
1 parent 084b30f commit 2d6888c

File tree

5 files changed

+26
-5
lines changed

5 files changed

+26
-5
lines changed

api.lisp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
(defun reset ()
77
(setf *env* (create-env *printlib*)))
88

9+
(defvar *enable-Function.caller* nil
10+
"If T, enables support for arguments.callee.caller/Function.caller property in newly compiled JavaScript code")
11+
912
(defun run-js (str &key (compile t) (wrap-parse-errors nil) (optimize nil) (wrap-as-module nil))
1013
(unless (boundp '*env*) (reset))
1114
(let* ((ast (handler-bind ((js-parse-error
@@ -56,8 +59,9 @@
5659
(format t (if continue " " "> "))))))
5760

5861
(defun tests ()
59-
(with-js-env (*printlib*)
60-
(run-js-file (asdf:system-relative-pathname :cl-js "test.js"))))
62+
(let ((*enable-function.caller* t))
63+
(with-js-env (*printlib*)
64+
(run-js-file (asdf:system-relative-pathname :cl-js "test.js")))))
6165

6266
(defun js-obj (&optional proto struct-type)
6367
(let ((cls (etypecase proto

package.lisp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
(:use :cl :parse-js)
33
(:export #:run-js-file #:run-js #:js-repl
44
#:*env* #:with-js-env #:create-env #:add-to-env
5+
#:*enable-Function.caller*
56

67
#:*printlib* #:requirelib
78

runtime.lisp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@
172172
(.func "decodeURIComponent" (str)
173173
(with-uri-err (url-encode:url-decode (to-string str) "")))))
174174

175+
(defvar *Function.caller-stack* '(:null :null))
176+
175177
(add-to-lib *stdlib*
176178
(flet ((defprops (obj props)
177179
(let ((props (to-object props)))
@@ -251,7 +253,8 @@
251253
(build-func (lambda (this &rest args-inner)
252254
(declare (ignore this))
253255
(apply proc self (append args args-inner)))
254-
(max 0 (- arity (length args)))))))))
256+
(max 0 (- arity (length args))))))
257+
(.active-r "caller" (second *Function.caller-stack*)))))
255258

256259
(add-to-lib *stdlib*
257260
(.constructor "Array" (&rest args)

test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,14 @@ function test_39() {
541541
true);
542542
}
543543

544+
function test_40() {
545+
var foo = function foo() { return arguments.callee.caller; };
546+
var bar = function bar() { return foo(); };
547+
if (typeof bar() != "function") {
548+
throw "arguments.callee.caller doesn't work";
549+
}
550+
}
551+
544552
function runTests() {
545553
var failures = [];
546554
var run = 0;

translate.lisp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@
410410
(uses-args (or uses-eval (references-arguments body)))
411411
(eval-scope (gensym "eval-scope"))
412412
(base-locals (cons "this" args))
413-
(fname (and uses-args (or name (symbol-name (gensym))))))
413+
(fname (and (or uses-args *enable-Function.caller*)
414+
(or name (symbol-name (gensym))))))
414415
(when name (push name base-locals))
415416
(when uses-args (push "arguments" base-locals))
416417
(multiple-value-bind (locals internal) (find-locals body base-locals)
@@ -420,7 +421,11 @@
420421
(make-simple-scope :vars locals))
421422
(when uses-eval
422423
(push (make-with-scope :var eval-scope) *scope*))
423-
(let ((body1 `((let* (,@(loop :for var :in internal :collect `(,var :undefined))
424+
(let ((body1 `((let* (,@(when *enable-Function.caller*
425+
`((*Function.caller-stack*
426+
(cons ,(as-sym fname)
427+
*Function.caller-stack*))))
428+
,@(loop :for var :in internal :collect `(,var :undefined))
424429
;; TODO sane object init
425430
,@(and uses-eval `((,eval-scope (make-obj (find-cls :object)))
426431
(eval-env ,(capture-scope)))))

0 commit comments

Comments
 (0)