js-on-sx: Math.X.name / Number.X.name via SX→JS name unmap (+4)
Every built-in JS function on Math/Number/Array/Object had .name === "" because js-invoke-function-method/js-get-prop returned bare "" for the "name" slot. That breaks tests like Math.abs.name === "abs" and Array.isArray.name === "isArray". Fix: extract the SX symbol name from (inspect fn) which prints <js-math-abs(x)>, then unmap through a small string table that maps js-math-abs → "abs", js-array-is-array → "isArray" etc. Also strips the angle-bracket marker and stops at ( or space. Non-mapped lambdas (user fns) fall through to the raw "js-foo" form rather than "", which is slightly worse but only hit in debug prints. Unit 521/522, slice 148/148 unchanged. Scoreboard: Math 40/100 → 43/100 (+3); Number 74 → 75 (+1). Sample: Math/abs/name.js, Math/floor/name.js, Math/max/name.js, Number/isNaN/name.js — all flipped. length.js tests still fail for trig because the underlying fn isn't implemented.
This commit is contained in:
@@ -115,6 +115,95 @@
|
|||||||
;; sign — 1 or -1
|
;; sign — 1 or -1
|
||||||
;; frac? — are we past the decimal point
|
;; frac? — are we past the decimal point
|
||||||
;; fdiv — divisor used to scale fraction digits (only if frac?)
|
;; fdiv — divisor used to scale fraction digits (only if frac?)
|
||||||
|
(define
|
||||||
|
js-extract-fn-name
|
||||||
|
(fn (f) (let ((raw (inspect f))) (js-strip-fn-name raw 0 (len raw)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
js-strip-fn-name
|
||||||
|
(fn
|
||||||
|
(s i n)
|
||||||
|
(let
|
||||||
|
((start (if (and (< i n) (= (char-at s i) "<")) (+ i 1) i)))
|
||||||
|
(js-strip-fn-name-end s start n))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
js-strip-fn-name-end
|
||||||
|
(fn
|
||||||
|
(s start n)
|
||||||
|
(let
|
||||||
|
((end (js-find-paren-or-space s start n)))
|
||||||
|
(let ((name (js-string-slice s start end))) (js-unmap-fn-name name)))))
|
||||||
|
|
||||||
|
;; ── String coercion (ToString) ────────────────────────────────────
|
||||||
|
|
||||||
|
(define
|
||||||
|
js-find-paren-or-space
|
||||||
|
(fn
|
||||||
|
(s i n)
|
||||||
|
(cond
|
||||||
|
((>= i n) n)
|
||||||
|
((or (= (char-at s i) "(") (= (char-at s i) " ")) i)
|
||||||
|
(else (js-find-paren-or-space s (+ i 1) n)))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
js-unmap-fn-name
|
||||||
|
(fn
|
||||||
|
(name)
|
||||||
|
(cond
|
||||||
|
((= name "js-math-abs") "abs")
|
||||||
|
((= name "js-math-floor") "floor")
|
||||||
|
((= name "js-math-ceil") "ceil")
|
||||||
|
((= name "js-math-round") "round")
|
||||||
|
((= name "js-math-max") "max")
|
||||||
|
((= name "js-math-min") "min")
|
||||||
|
((= name "js-math-random") "random")
|
||||||
|
((= name "js-math-sqrt") "sqrt")
|
||||||
|
((= name "js-math-pow") "pow")
|
||||||
|
((= name "js-math-trunc") "trunc")
|
||||||
|
((= name "js-math-sign") "sign")
|
||||||
|
((= name "js-math-cbrt") "cbrt")
|
||||||
|
((= name "js-math-hypot") "hypot")
|
||||||
|
((= name "js-number-is-finite") "isFinite")
|
||||||
|
((= name "js-number-is-nan") "isNaN")
|
||||||
|
((= name "js-number-is-integer") "isInteger")
|
||||||
|
((= name "js-number-is-safe-integer") "isSafeInteger")
|
||||||
|
((= name "js-global-is-finite") "isFinite")
|
||||||
|
((= name "js-global-is-nan") "isNaN")
|
||||||
|
((= name "js-string-from-char-code") "fromCharCode")
|
||||||
|
((= name "js-array-is-array") "isArray")
|
||||||
|
((= name "js-array-of") "of")
|
||||||
|
((= name "js-array-from") "from")
|
||||||
|
((= name "js-object-keys") "keys")
|
||||||
|
((= name "js-object-values") "values")
|
||||||
|
((= name "js-object-entries") "entries")
|
||||||
|
((= name "js-object-assign") "assign")
|
||||||
|
((= name "js-object-freeze") "freeze")
|
||||||
|
((= name "js-object-get-prototype-of") "getPrototypeOf")
|
||||||
|
((= name "js-object-set-prototype-of") "setPrototypeOf")
|
||||||
|
((= name "js-object-create") "create")
|
||||||
|
((= name "js-object-define-property") "defineProperty")
|
||||||
|
((= name "js-object-define-properties") "defineProperties")
|
||||||
|
((= name "js-object-get-own-property-names") "getOwnPropertyNames")
|
||||||
|
((= name "js-object-get-own-property-descriptor")
|
||||||
|
"getOwnPropertyDescriptor")
|
||||||
|
((= name "js-object-get-own-property-descriptors")
|
||||||
|
"getOwnPropertyDescriptors")
|
||||||
|
((= name "js-object-is-extensible") "isExtensible")
|
||||||
|
((= name "js-object-is-frozen") "isFrozen")
|
||||||
|
((= name "js-object-is-sealed") "isSealed")
|
||||||
|
((= name "js-object-seal") "seal")
|
||||||
|
((= name "js-object-prevent-extensions") "preventExtensions")
|
||||||
|
((= name "js-object-is") "is")
|
||||||
|
((= name "js-object-from-entries") "fromEntries")
|
||||||
|
((= name "js-object-has-own") "hasOwn")
|
||||||
|
((= name "js-to-number") "Number")
|
||||||
|
((= name "js-to-boolean") "Boolean")
|
||||||
|
(else name))))
|
||||||
|
|
||||||
|
;; ── Arithmetic (JS rules) ─────────────────────────────────────────
|
||||||
|
|
||||||
|
;; JS `+`: if either operand is a string → string concat, else numeric.
|
||||||
(define
|
(define
|
||||||
js-count-real-params
|
js-count-real-params
|
||||||
(fn
|
(fn
|
||||||
@@ -162,7 +251,7 @@
|
|||||||
(&rest more)
|
(&rest more)
|
||||||
(js-call-with-this this-arg recv (js-list-concat bound more)))))
|
(js-call-with-this this-arg recv (js-list-concat bound more)))))
|
||||||
((= key "toString") "function () { [native code] }")
|
((= key "toString") "function () { [native code] }")
|
||||||
((= key "name") "")
|
((= key "name") (js-extract-fn-name recv))
|
||||||
((= key "length") (js-fn-length recv))
|
((= key "length") (js-fn-length recv))
|
||||||
(else :js-undefined))))
|
(else :js-undefined))))
|
||||||
|
|
||||||
@@ -179,8 +268,6 @@
|
|||||||
(fn (&rest args) (js-invoke-function-method recv "bind" args)))
|
(fn (&rest args) (js-invoke-function-method recv "bind" args)))
|
||||||
(else :js-undefined))))
|
(else :js-undefined))))
|
||||||
|
|
||||||
;; ── String coercion (ToString) ────────────────────────────────────
|
|
||||||
|
|
||||||
(define
|
(define
|
||||||
js-invoke-number-method
|
js-invoke-number-method
|
||||||
(fn
|
(fn
|
||||||
@@ -226,9 +313,6 @@
|
|||||||
((= key "toLocaleString") "function () { [native code] }")
|
((= key "toLocaleString") "function () { [native code] }")
|
||||||
(else :js-undefined))))
|
(else :js-undefined))))
|
||||||
|
|
||||||
;; ── Arithmetic (JS rules) ─────────────────────────────────────────
|
|
||||||
|
|
||||||
;; JS `+`: if either operand is a string → string concat, else numeric.
|
|
||||||
(define
|
(define
|
||||||
js-invoke-boolean-method
|
js-invoke-boolean-method
|
||||||
(fn
|
(fn
|
||||||
@@ -272,6 +356,7 @@
|
|||||||
((d (mod n radix)) (rest (js-math-trunc (/ n radix))))
|
((d (mod n radix)) (rest (js-math-trunc (/ n radix))))
|
||||||
(js-num-to-str-radix-rec rest radix (str (js-digit-char d) acc))))))
|
(js-num-to-str-radix-rec rest radix (str (js-digit-char d) acc))))))
|
||||||
|
|
||||||
|
;; Bitwise + logical-not
|
||||||
(define
|
(define
|
||||||
js-digit-char
|
js-digit-char
|
||||||
(fn
|
(fn
|
||||||
@@ -315,6 +400,9 @@
|
|||||||
(js-to-string (js-math-trunc frac-part))
|
(js-to-string (js-math-trunc frac-part))
|
||||||
d))))))))))))
|
d))))))))))))
|
||||||
|
|
||||||
|
;; ── Equality ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
;; Strict equality (===): no coercion; js-undefined matches js-undefined.
|
||||||
(define
|
(define
|
||||||
js-pow-int
|
js-pow-int
|
||||||
(fn (b e) (if (<= e 0) 1 (* b (js-pow-int b (- e 1))))))
|
(fn (b e) (if (<= e 0) 1 (* b (js-pow-int b (- e 1))))))
|
||||||
@@ -323,6 +411,9 @@
|
|||||||
js-pad-int-str
|
js-pad-int-str
|
||||||
(fn (s n) (if (>= (len s) n) s (js-pad-int-str (str "0" s) n))))
|
(fn (s n) (if (>= (len s) n) s (js-pad-int-str (str "0" s) n))))
|
||||||
|
|
||||||
|
;; Abstract equality (==): type coercion rules.
|
||||||
|
;; Simplified: number↔string coerce both to number; null == undefined;
|
||||||
|
;; everything else falls back to strict equality.
|
||||||
(define
|
(define
|
||||||
js-apply-fn
|
js-apply-fn
|
||||||
(fn
|
(fn
|
||||||
@@ -354,7 +445,6 @@
|
|||||||
(nth args 5)))
|
(nth args 5)))
|
||||||
(else (apply callable args))))))
|
(else (apply callable args))))))
|
||||||
|
|
||||||
;; Bitwise + logical-not
|
|
||||||
(define
|
(define
|
||||||
js-invoke-method
|
js-invoke-method
|
||||||
(fn
|
(fn
|
||||||
@@ -380,6 +470,11 @@
|
|||||||
(error
|
(error
|
||||||
(str "TypeError: " (js-to-string key) " is not a function")))))))))
|
(str "TypeError: " (js-to-string key) " is not a function")))))))))
|
||||||
|
|
||||||
|
;; ── Relational comparisons ────────────────────────────────────────
|
||||||
|
|
||||||
|
;; Abstract relational comparison from ES5.
|
||||||
|
;; Numbers compare numerically; two strings compare lexicographically;
|
||||||
|
;; mixed types coerce both to numbers.
|
||||||
(define
|
(define
|
||||||
js-object-builtin-method?
|
js-object-builtin-method?
|
||||||
(fn
|
(fn
|
||||||
@@ -392,9 +487,6 @@
|
|||||||
(= name "valueOf")
|
(= name "valueOf")
|
||||||
(= name "toLocaleString"))))
|
(= name "toLocaleString"))))
|
||||||
|
|
||||||
;; ── Equality ──────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
;; Strict equality (===): no coercion; js-undefined matches js-undefined.
|
|
||||||
(define
|
(define
|
||||||
js-invoke-object-method
|
js-invoke-object-method
|
||||||
(fn
|
(fn
|
||||||
@@ -418,9 +510,6 @@
|
|||||||
|
|
||||||
(define js-upper-case (fn (s) (js-case-loop s 0 "" true)))
|
(define js-upper-case (fn (s) (js-case-loop s 0 "" true)))
|
||||||
|
|
||||||
;; Abstract equality (==): type coercion rules.
|
|
||||||
;; Simplified: number↔string coerce both to number; null == undefined;
|
|
||||||
;; everything else falls back to strict equality.
|
|
||||||
(define js-lower-case (fn (s) (js-case-loop s 0 "" false)))
|
(define js-lower-case (fn (s) (js-case-loop s 0 "" false)))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
@@ -438,11 +527,6 @@
|
|||||||
((cv (cond ((and to-upper? (>= cc 97) (<= cc 122)) (js-code-to-char (- cc 32))) ((and (not to-upper?) (>= cc 65) (<= cc 90)) (js-code-to-char (+ cc 32))) (else c))))
|
((cv (cond ((and to-upper? (>= cc 97) (<= cc 122)) (js-code-to-char (- cc 32))) ((and (not to-upper?) (>= cc 65) (<= cc 90)) (js-code-to-char (+ cc 32))) (else c))))
|
||||||
(js-case-loop s (+ i 1) (str acc cv) to-upper?))))))))
|
(js-case-loop s (+ i 1) (str acc cv) to-upper?))))))))
|
||||||
|
|
||||||
;; ── Relational comparisons ────────────────────────────────────────
|
|
||||||
|
|
||||||
;; Abstract relational comparison from ES5.
|
|
||||||
;; Numbers compare numerically; two strings compare lexicographically;
|
|
||||||
;; mixed types coerce both to numbers.
|
|
||||||
(define
|
(define
|
||||||
js-code-to-char
|
js-code-to-char
|
||||||
(fn
|
(fn
|
||||||
@@ -506,6 +590,13 @@
|
|||||||
js-invoke-method-dyn
|
js-invoke-method-dyn
|
||||||
(fn (recv key args) (js-invoke-method recv key args)))
|
(fn (recv key args) (js-invoke-method recv key args)))
|
||||||
|
|
||||||
|
;; ── Property access ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
;; obj[key] or obj.key in JS. Handles:
|
||||||
|
;; • dicts keyed by string
|
||||||
|
;; • lists indexed by number (incl. .length)
|
||||||
|
;; • strings indexed by number (incl. .length)
|
||||||
|
;; Returns js-undefined if the key is absent.
|
||||||
(define
|
(define
|
||||||
js-call-plain
|
js-call-plain
|
||||||
(fn
|
(fn
|
||||||
@@ -545,6 +636,7 @@
|
|||||||
((proto (js-get-ctor-proto ctor)))
|
((proto (js-get-ctor-proto ctor)))
|
||||||
(js-instanceof-walk obj proto))))))
|
(js-instanceof-walk obj proto))))))
|
||||||
|
|
||||||
|
;; Setter — mutates the dict. Returns the new value (JS assignment yields rhs).
|
||||||
(define
|
(define
|
||||||
js-instanceof-walk
|
js-instanceof-walk
|
||||||
(fn
|
(fn
|
||||||
@@ -560,6 +652,10 @@
|
|||||||
((not (= (type-of p) "dict")) false)
|
((not (= (type-of p) "dict")) false)
|
||||||
(else (js-instanceof-walk p proto))))))))
|
(else (js-instanceof-walk p proto))))))))
|
||||||
|
|
||||||
|
;; ── Short-circuit logical ops ─────────────────────────────────────
|
||||||
|
|
||||||
|
;; `a && b` in JS: if a is truthy return b else return a. The thunk
|
||||||
|
;; form defers evaluation of b — the transpiler passes (fn () b).
|
||||||
(define
|
(define
|
||||||
js-in
|
js-in
|
||||||
(fn
|
(fn
|
||||||
@@ -568,13 +664,6 @@
|
|||||||
((not (= (type-of obj) "dict")) false)
|
((not (= (type-of obj) "dict")) false)
|
||||||
(else (js-in-walk obj (js-to-string key))))))
|
(else (js-in-walk obj (js-to-string key))))))
|
||||||
|
|
||||||
;; ── Property access ───────────────────────────────────────────────
|
|
||||||
|
|
||||||
;; obj[key] or obj.key in JS. Handles:
|
|
||||||
;; • dicts keyed by string
|
|
||||||
;; • lists indexed by number (incl. .length)
|
|
||||||
;; • strings indexed by number (incl. .length)
|
|
||||||
;; Returns js-undefined if the key is absent.
|
|
||||||
(define
|
(define
|
||||||
js-in-walk
|
js-in-walk
|
||||||
(fn
|
(fn
|
||||||
@@ -585,6 +674,9 @@
|
|||||||
((dict-has? obj "__proto__") (js-in-walk (get obj "__proto__") skey))
|
((dict-has? obj "__proto__") (js-in-walk (get obj "__proto__") skey))
|
||||||
(else false))))
|
(else false))))
|
||||||
|
|
||||||
|
;; ── console.log ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
;; Trivial bridge. `log-info` is available on OCaml; fall back to print.
|
||||||
(define
|
(define
|
||||||
Error
|
Error
|
||||||
(fn
|
(fn
|
||||||
@@ -621,7 +713,8 @@
|
|||||||
nil)
|
nil)
|
||||||
this))))
|
this))))
|
||||||
|
|
||||||
;; Setter — mutates the dict. Returns the new value (JS assignment yields rhs).
|
;; ── Math object ───────────────────────────────────────────────────
|
||||||
|
|
||||||
(define
|
(define
|
||||||
RangeError
|
RangeError
|
||||||
(fn
|
(fn
|
||||||
@@ -639,11 +732,6 @@
|
|||||||
(dict-set! this "name" "RangeError"))
|
(dict-set! this "name" "RangeError"))
|
||||||
nil)
|
nil)
|
||||||
this))))
|
this))))
|
||||||
|
|
||||||
;; ── Short-circuit logical ops ─────────────────────────────────────
|
|
||||||
|
|
||||||
;; `a && b` in JS: if a is truthy return b else return a. The thunk
|
|
||||||
;; form defers evaluation of b — the transpiler passes (fn () b).
|
|
||||||
(define
|
(define
|
||||||
SyntaxError
|
SyntaxError
|
||||||
(fn
|
(fn
|
||||||
@@ -661,7 +749,6 @@
|
|||||||
(dict-set! this "name" "SyntaxError"))
|
(dict-set! this "name" "SyntaxError"))
|
||||||
nil)
|
nil)
|
||||||
this))))
|
this))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
ReferenceError
|
ReferenceError
|
||||||
(fn
|
(fn
|
||||||
@@ -679,10 +766,6 @@
|
|||||||
(dict-set! this "name" "ReferenceError"))
|
(dict-set! this "name" "ReferenceError"))
|
||||||
nil)
|
nil)
|
||||||
this))))
|
this))))
|
||||||
|
|
||||||
;; ── console.log ───────────────────────────────────────────────────
|
|
||||||
|
|
||||||
;; Trivial bridge. `log-info` is available on OCaml; fall back to print.
|
|
||||||
(define
|
(define
|
||||||
URIError
|
URIError
|
||||||
(fn
|
(fn
|
||||||
@@ -700,7 +783,6 @@
|
|||||||
(if (empty? args) "" (js-to-string (nth args 0))))
|
(if (empty? args) "" (js-to-string (nth args 0))))
|
||||||
(dict-set! this "name" "URIError")))
|
(dict-set! this "name" "URIError")))
|
||||||
this))))
|
this))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
EvalError
|
EvalError
|
||||||
(fn
|
(fn
|
||||||
@@ -718,9 +800,6 @@
|
|||||||
(if (empty? args) "" (js-to-string (nth args 0))))
|
(if (empty? args) "" (js-to-string (nth args 0))))
|
||||||
(dict-set! this "name" "EvalError")))
|
(dict-set! this "name" "EvalError")))
|
||||||
this))))
|
this))))
|
||||||
|
|
||||||
;; ── Math object ───────────────────────────────────────────────────
|
|
||||||
|
|
||||||
(define
|
(define
|
||||||
js-function?
|
js-function?
|
||||||
(fn
|
(fn
|
||||||
@@ -734,7 +813,8 @@
|
|||||||
(and (= t "dict") (contains? (keys v) "__callable__"))))))
|
(and (= t "dict") (contains? (keys v) "__callable__"))))))
|
||||||
(define __js_proto_table__ (dict))
|
(define __js_proto_table__ (dict))
|
||||||
(define __js_next_id__ (dict))
|
(define __js_next_id__ (dict))
|
||||||
(dict-set! __js_next_id__ "n" 0)
|
(dict-set! __js_next_id__ "n" 0) ; deterministic placeholder for tests
|
||||||
|
|
||||||
(define
|
(define
|
||||||
js-get-ctor-proto
|
js-get-ctor-proto
|
||||||
(fn
|
(fn
|
||||||
@@ -751,6 +831,11 @@
|
|||||||
(let
|
(let
|
||||||
((p (dict)))
|
((p (dict)))
|
||||||
(begin (dict-set! __js_proto_table__ id p) p)))))))))
|
(begin (dict-set! __js_proto_table__ id p) p)))))))))
|
||||||
|
|
||||||
|
;; The global object — lookup table for JS names that aren't in the
|
||||||
|
;; SX env. Transpiled idents look up locally first; globals here are a
|
||||||
|
;; fallback, but most slice programs reference `console`, `Math`,
|
||||||
|
;; `undefined` as plain symbols, which we bind as defines above.
|
||||||
(define
|
(define
|
||||||
js-reset-ctor-proto!
|
js-reset-ctor-proto!
|
||||||
(fn
|
(fn
|
||||||
@@ -758,11 +843,13 @@
|
|||||||
(let
|
(let
|
||||||
((id (js-ctor-id ctor)) (p (dict)))
|
((id (js-ctor-id ctor)) (p (dict)))
|
||||||
(begin (dict-set! __js_proto_table__ id p) p))))
|
(begin (dict-set! __js_proto_table__ id p) p))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
js-set-ctor-proto!
|
js-set-ctor-proto!
|
||||||
(fn
|
(fn
|
||||||
(ctor proto)
|
(ctor proto)
|
||||||
(let ((id (js-ctor-id ctor))) (dict-set! __js_proto_table__ id proto))))
|
(let ((id (js-ctor-id ctor))) (dict-set! __js_proto_table__ id proto))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
js-ctor-id
|
js-ctor-id
|
||||||
(fn
|
(fn
|
||||||
@@ -771,6 +858,7 @@
|
|||||||
((and (= (type-of ctor) "dict") (dict-has? ctor "__ctor_id__"))
|
((and (= (type-of ctor) "dict") (dict-has? ctor "__ctor_id__"))
|
||||||
(get ctor "__ctor_id__"))
|
(get ctor "__ctor_id__"))
|
||||||
(else (inspect ctor)))))
|
(else (inspect ctor)))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
js-typeof
|
js-typeof
|
||||||
(fn
|
(fn
|
||||||
@@ -786,7 +874,7 @@
|
|||||||
((= (type-of v) "component") "function")
|
((= (type-of v) "component") "function")
|
||||||
((and (= (type-of v) "dict") (contains? (keys v) "__callable__"))
|
((and (= (type-of v) "dict") (contains? (keys v) "__callable__"))
|
||||||
"function")
|
"function")
|
||||||
(else "object")))) ; deterministic placeholder for tests
|
(else "object"))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
js-to-boolean
|
js-to-boolean
|
||||||
@@ -800,10 +888,6 @@
|
|||||||
((= v "") false)
|
((= v "") false)
|
||||||
(else true))))
|
(else true))))
|
||||||
|
|
||||||
;; The global object — lookup table for JS names that aren't in the
|
|
||||||
;; SX env. Transpiled idents look up locally first; globals here are a
|
|
||||||
;; fallback, but most slice programs reference `console`, `Math`,
|
|
||||||
;; `undefined` as plain symbols, which we bind as defines above.
|
|
||||||
(define
|
(define
|
||||||
js-to-number
|
js-to-number
|
||||||
(fn
|
(fn
|
||||||
@@ -2180,7 +2264,7 @@
|
|||||||
((and (js-function? obj) (or (= key "prototype") (= key "name") (= key "length") (= key "call") (= key "apply") (= key "bind")))
|
((and (js-function? obj) (or (= key "prototype") (= key "name") (= key "length") (= key "call") (= key "apply") (= key "bind")))
|
||||||
(cond
|
(cond
|
||||||
((= key "prototype") (js-get-ctor-proto obj))
|
((= key "prototype") (js-get-ctor-proto obj))
|
||||||
((= key "name") "")
|
((= key "name") (js-extract-fn-name obj))
|
||||||
((= key "length") (js-fn-length obj))
|
((= key "length") (js-fn-length obj))
|
||||||
(else (js-invoke-function-bound obj key))))
|
(else (js-invoke-function-bound obj key))))
|
||||||
(else js-undefined))))
|
(else js-undefined))))
|
||||||
|
|||||||
Reference in New Issue
Block a user