Skip to content

Commit

Permalink
[#483] deref vars at analysis time that have :inline metadata in clojure
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude committed Dec 21, 2020
1 parent 707b98b commit de7e5a9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 33 deletions.
5 changes: 4 additions & 1 deletion src/sci/impl/analyzer.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,10 @@
(types/->EvalForm v)
:else (analyze ctx v))]
expanded)
(mark-eval-call (cons f (analyze-children ctx (rest expr)))))
(if-let [f (:sci.impl/inlined f-meta)]
(mark-eval-call (cons f (analyze-children ctx (rest expr)))
:sci.impl/f-meta f-meta)
(mark-eval-call (cons f (analyze-children ctx (rest expr))))))
(catch #?(:clj Exception :cljs js/Error) e
(rethrow-with-location-of-node ctx e
;; adding metadata for error reporting
Expand Down
19 changes: 10 additions & 9 deletions src/sci/impl/callstack.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
(defn expr->data [expr]
(let [m (meta expr)
f (when (seqable? expr) (first expr))
fm (some-> f meta)
fm (if (symbol? f)
(assoc fm
:local-name f
:local true
:ns (:ns m)
:macro (or (:sci/macro fm)
(:macro fm)))
fm)]
fm (or (:sci.impl/f-meta m)
(some-> f meta))
fm (or (if (symbol? f)
(assoc fm
:local-name f
:local true
:ns (:ns m)
:macro (or (:sci/macro fm)
(:macro fm)))
fm))]
(filter not-empty [(select m) (select fm)])))

(defn stacktrace [callstack]
Expand Down
23 changes: 17 additions & 6 deletions src/sci/impl/namespaces.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@

(def clojure-core-ns (vars/->SciNamespace 'clojure.core nil))

;; The following is produced with:
;; (def inlined (filter (comp :inline meta) (vals (ns-publics 'clojure.core))))
;; (map (comp :name meta) inlined)
(def inlined-vars
'#{+' unchecked-remainder-int unchecked-subtract-int dec' short-array bit-shift-right aget = boolean bit-shift-left aclone dec < char unchecked-long unchecked-negate unchecked-inc-int floats pos? boolean-array alength bit-xor unsigned-bit-shift-right neg? unchecked-float num reduced? booleans int-array inc' <= -' * min get long double bit-and-not unchecked-add-int short quot unchecked-double longs unchecked-multiply-int int > unchecked-int unchecked-multiply unchecked-dec double-array float - byte-array zero? unchecked-dec-int rem nth nil? bit-and *' unchecked-add identical? unchecked-divide-int unchecked-subtract / bit-or >= long-array object-array doubles unchecked-byte unchecked-short float-array inc + aset chars ints bit-not byte max == count char-array compare shorts unchecked-negate-int unchecked-inc unchecked-char bytes})

(macros/deftime
;; Note: self hosted CLJS can't deal with multi-arity macros so this macro is split in 2
(defmacro copy-var
Expand All @@ -37,12 +43,17 @@
m# (-> (var ~sym) meta)
ns-name# (vars/getName ns#)
name# (:name m#)
name-sym# (symbol (str ns-name#) (str name#))]
(vars/->SciVar ~sym name-sym# {:doc (:doc m#)
:name name#
:arglists (:arglists m#)
:ns ns#
:sci.impl/built-in true}
name-sym# (symbol (str ns-name#) (str name#))
val# ~sym]
(vars/->SciVar val# name-sym# (cond->
{:doc (:doc m#)
:name name#
:arglists (:arglists m#)
:ns ns#
:sci.impl/built-in true}
(and (identical? clojure-core-ns ns#)
(contains? inlined-vars name#))
(assoc :sci.impl/inlined val#))
false))))
(defmacro copy-core-var
([sym]
Expand Down
44 changes: 27 additions & 17 deletions src/sci/impl/utils.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@
(def kw-identical? #?(:clj identical? :cljs keyword-identical?))

(defn mark-eval-call
[expr]
(vary-meta
expr
(fn [m]
(assoc m
:sci.impl/op :call
:ns @vars/current-ns
:file @vars/current-file))))
([expr]
(vary-meta
expr
(fn [m]
(-> m
(assoc :sci.impl/op :call)
(assoc :ns @vars/current-ns)
(assoc :file @vars/current-file)))))
([expr extra-key extra-val]
(vary-meta
expr
(fn [m]
(-> m
(assoc :sci.impl/op :call)
(assoc :ns @vars/current-ns)
(assoc :file @vars/current-file)
(assoc extra-key extra-val))))))

(defn mark-eval
[expr]
Expand Down Expand Up @@ -57,15 +66,16 @@
(defn rethrow-with-location-of-node [ctx ^Throwable e node]
(let [m (meta node)
f (when (seqable? node) (first node))
fm (some-> f meta)
op (when fm (.get ^java.util.Map m :sci.impl/op))]
(when (not (or
;; special call like def
(and (symbol? f) (not op))
;; anonymous function
(kw-identical? :fn op)
;; special thing like require
(identical? needs-ctx op)))
fm (or (:sci.impl/f-meta node) (some-> f meta))
op (when fm (.get ^java.util.Map m :sci.impl/op))
special? (or
;; special call like def
(and (symbol? f) (not op))
;; anonymous function
(kw-identical? :fn op)
;; special thing like require
(identical? needs-ctx op))]
(when (not special?)
(swap! (:env ctx) update-in [:sci.impl/callstack (:id ctx)]
(fn [vt]
(if vt
Expand Down

0 comments on commit de7e5a9

Please sign in to comment.