Skip to content

Commit 4321d2a

Browse files
committed
wip
1 parent 2d6e2c0 commit 4321d2a

File tree

4 files changed

+70
-43
lines changed

4 files changed

+70
-43
lines changed

reflector/src/sci/impl/Reflector.java

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -145,24 +145,37 @@ private static String noMethodReport(String methodName, Class contextClass, Obje
145145
private static Method matchMethod(List methods, Object[] args) {
146146
return matchMethod(methods, args, null);
147147
}
148+
// private static int exactTypesMatch(Class[] expected, Class[] actual) {
149+
// int ret = 0;
150+
// for (int i = 0; i < expected.length; i++) {
151+
// if (expected[i] == actual[i]) ret++;
152+
// }
153+
// return ret;
154+
// }
148155
private static Method matchMethod(List methods, Object[] args, Class[] argTypes) {
149156
Method foundm = null;
157+
// int exactTypesMatch = 0;
150158
for(Iterator i = methods.iterator(); i.hasNext();) {
151159
Method m = (Method) i.next();
152-
System.err.println("Trying method: " + m);
160+
// System.err.println("Trying method: " + m);
153161
Class[] params = m.getParameterTypes();
154-
System.err.print("param classes: ");
155-
for (int p = 0; p < params.length; p++) {
156-
System.err.print(params[p].toString());
162+
// System.err.print("param classes: ");
163+
// for (int p = 0; p < params.length; p++) {
164+
// System.err.print(params[p].toString());
165+
// }
166+
// System.err.println();
167+
// System.err.println("isCongruent: " + isCongruent(params, args, argTypes));
168+
// if (foundm != null)
169+
// System.err.println("subsumes: " + Compiler.subsumes(params, foundm.getParameterTypes()));
170+
// int typesMatch = 0;
171+
// // if (argTypes != null) exactTypesMatch(argTypes, params);
172+
// System.err.println("typesMatch: " + typesMatch);
173+
if(isCongruent(params, args, argTypes) && (foundm == null || Compiler.subsumes(params, foundm.getParameterTypes()) /* || (argTypes != null && typesMatch > exactTypesMatch) */ )) {
174+
foundm = m;
175+
// exactTypesMatch = typesMatch;
157176
}
158-
System.err.println();
159-
System.err.println("isCongruent: " + isCongruent(params, args));
160-
if (foundm != null)
161-
System.err.println("subsumes: " + Compiler.subsumes(params, foundm.getParameterTypes()));
162-
if(isCongruent(params, args, argTypes) && (foundm == null || Compiler.subsumes(params, foundm.getParameterTypes())))
163-
foundm = m;
164177
}
165-
System.err.println("found method: " + foundm);
178+
// System.err.println("found method: " + foundm);
166179
return foundm;
167180
}
168181

@@ -206,7 +219,7 @@ else if(methods.size() == 1)
206219
}
207220
else //overloaded w/same arity
208221
{
209-
m = matchMethod(methods, args);
222+
m = matchMethod(methods, args, argTypes);
210223
if(m == null) // widen boxed args and re-try matchMethod
211224
{
212225
args = widenBoxedArgs(args);
@@ -227,10 +240,10 @@ else if(methods.size() == 1)
227240
}
228241
try
229242
{
230-
System.err.println("retTYpe: " + m.getReturnType());
231-
System.err.println("ctxClass: " + contextClass);
232-
System.err.println("meth: " + m);
233-
System.err.println("boxedArgs " + boxArgs(m.getParameterTypes(), args));
243+
// System.err.println("retTYpe: " + m.getReturnType());
244+
// System.err.println("ctxClass: " + contextClass);
245+
// System.err.println("meth: " + m);
246+
// System.err.println("boxedArgs " + boxArgs(m.getParameterTypes(), args));
234247
return prepRet(m.getReturnType(), m.invoke(target, boxArgs(m.getParameterTypes(), args)));
235248
}
236249
catch(Exception e)
@@ -727,12 +740,14 @@ static boolean isCongruent(Class[] params, Object[] args, Class[] argTypes){
727740
{
728741
Class argType = null;
729742
Object arg = args[i];
743+
// System.err.println("argTypes: " + argTypes);
730744
if (argTypes != null) {
731745
Object t = argTypes[i];
732746
if (t == null && arg != null) {
733747
argType = arg.getClass();
734748
} else {
735749
argType = argTypes[i];
750+
// System.err.println("argType " + argType);
736751
}
737752
} else {
738753
argType = (arg == null) ? null : arg.getClass();

src/sci/impl/analyzer.cljc

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -598,11 +598,10 @@
598598
binding-name)
599599
binding-meta (meta binding-name)
600600
t (when m (:tag binding-meta))
601-
binding-name (if t (vary-meta binding-name
602-
assoc :tag
603-
(or (interop/resolve-class ctx t)
604-
t))
605-
binding-name)
601+
binding-name (if (symbol? t)
602+
(vary-meta binding-name
603+
assoc :tag-class (interop/resolve-type-hint ctx t))
604+
binding-name)
606605
v (analyze ctx binding-value)
607606
new-iden (gensym)
608607
cb (:closure-bindings ctx)
@@ -996,7 +995,9 @@
996995
instance-expr
997996
(fn [m]
998997
(if-let [t (:tag m)]
999-
(let [clazz (or (interop/resolve-class ctx t)
998+
(let [clazz (or (when (class? t)
999+
t)
1000+
(interop/resolve-class ctx t)
10001001
(records/resolve-record-class ctx t)
10011002
(throw-error-with-location
10021003
(str "Unable to resolve classname: " t) t))]
@@ -1863,7 +1864,7 @@
18631864
(let [m (meta expr)]
18641865
(cond
18651866
(constant? expr) (->constant expr)
1866-
(symbol? expr) (let [v (resolve/resolve-symbol ctx expr false (:tag m))
1867+
(symbol? expr) (let [v (resolve/resolve-symbol ctx expr false m)
18671868
mv (meta v)]
18681869
(cond (constant? v) (->constant v)
18691870
(utils/var? v)

src/sci/impl/interop.cljc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,22 @@
4444
(throw (js/Error. (str "Could not find instance method: " method-name))))]
4545
:clj
4646
[[ctx bindings obj ^Class target-class method ^objects args arg-count]
47-
(let [methods
47+
(let [^"[Ljava.util.List;" methods
4848
(meth-cache ctx target-class method arg-count #(Reflector/getMethods target-class arg-count method false) :instance-methods)]
4949
(if (and (zero? arg-count) (.isEmpty ^java.util.List methods))
5050
(invoke-instance-field obj target-class method)
5151
(do (let [args-array (object-array arg-count)
52-
;; TODO: not necessary when method count is 1
53-
types-array (object-array arg-count)]
52+
^"[Ljava.lang.Class;" types-array (when (> (count methods) 1)
53+
(make-array Class arg-count))]
5454
(areduce args idx _ret nil
5555
(do (aset args-array idx (sci.impl.types/eval (aget args idx) ctx bindings))
56-
(aset types-array idx (:tag (meta (aget args idx))))))
56+
(when types-array
57+
(when-let [t (:tag-class (meta (aget args idx)))]
58+
(when (class? t)
59+
(aset types-array idx t))))))
5760
;; Note: I also tried caching the method that invokeMatchingMethod looks up, but retrieving it from the cache was actually more expensive than just doing the invocation!
5861
;; See getMatchingMethod in Reflector
59-
(Reflector/invokeMatchingMethod method methods obj target-class args-array types-array)))))]))
62+
(Reflector/invokeMatchingMethod method methods target-class obj args-array types-array)))))]))
6063

6164
(defn get-static-field [^Class class field-name-sym]
6265
#?(:clj (Reflector/getStaticField class (str field-name-sym))
@@ -161,6 +164,10 @@
161164
'char Character/TYPE
162165
'chars (Class/forName "[C")}))
163166

167+
(defn resolve-type-hint [ctx sym]
168+
(or (get prim->class sym)
169+
(:class (resolve-class-opts ctx sym))))
170+
164171
#?(:clj
165172
(def ->array-class
166173
(memoize (fn [clazz dim]

src/sci/impl/resolve.cljc

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@
159159

160160
(defn lookup
161161
([ctx sym call?] (lookup ctx sym call? nil))
162-
([ctx sym call? tag] (lookup ctx sym call? tag nil))
163-
([ctx sym call? #?(:clj tag :cljs _tag) only-var?]
162+
([ctx sym call? m] (lookup ctx sym call? m nil))
163+
([ctx sym call? #?(:clj m :cljs _) only-var?]
164164
(let [bindings (faster/get-2 ctx :bindings)
165165
track-mutable? (faster/get-2 ctx :deftype-fields)]
166166
(or
@@ -170,8 +170,10 @@
170170
(let [oi (:outer-idens ctx)
171171
ob (oi v)]
172172
(update-parents ctx (:closure-bindings ctx) ob)))
173-
#?@(:clj [tag (or tag
174-
(some-> k meta :tag))])
173+
#?@(:clj [[tag tag-class] (if-let [t (:tag m)]
174+
[t (:tag-class m)]
175+
(when-let [m (meta k)]
176+
[(:tag m)]))])
175177
mutable? (when track-mutable?
176178
(when-let [m (some-> k meta)]
177179
#?(:clj (or (:volatile-mutable m)
@@ -191,7 +193,9 @@
191193
(aget ^objects bindings idx)
192194
nil))
193195
#?@(:clj [tag (with-meta
194-
{:tag tag})])
196+
{:tag tag
197+
:tag-class (or tag-class
198+
(interop/resolve-type-hint ctx tag))})])
195199
mutable? (vary-meta assoc :mutable true))]
196200
v))]
197201
[k v]))
@@ -204,9 +208,9 @@
204208
(vreset! utils/lookup lookup)
205209

206210
(defn resolve-symbol*
207-
[ctx sym call? tag]
211+
[ctx sym call? m]
208212
(or
209-
(lookup ctx sym call? tag)
213+
(lookup ctx sym call? m)
210214
(let [n (name sym)]
211215
(cond
212216
;; NOTE: move this to analyzer when resolve-symbol returns nil?
@@ -221,7 +225,7 @@
221225

222226
#?(:cljs
223227
(defn resolve-prefix+path
224-
[ctx sym tag]
228+
[ctx sym m]
225229
(let [sym-ns (namespace sym)
226230
sym-name (name sym)
227231
segments (.split sym-name ".")
@@ -238,16 +242,16 @@
238242
prefix)
239243
(symbol prefix
240244
fst-segment))]
241-
(if-let [v (resolve-symbol* ctx new-sym false tag)]
245+
(if-let [v (resolve-symbol* ctx new-sym false m)]
242246
[(second v) nxt-segments]
243247
(if-let [v2 (when new-sym-2
244-
(resolve-symbol* ctx new-sym-2 false tag))]
248+
(resolve-symbol* ctx new-sym-2 false m))]
245249
[(second v2) nxt-segments]
246250
(recur (str new-sym) nxt-segments)))))))))
247251

248-
#?(:cljs (defn resolve-dotted-access [ctx sym call? tag]
252+
#?(:cljs (defn resolve-dotted-access [ctx sym call? m]
249253
#?(:cljs
250-
(when-let [[v segments] (resolve-prefix+path ctx sym tag)]
254+
(when-let [[v segments] (resolve-prefix+path ctx sym m)]
251255
(let [v (if (utils/var? v) (deref v) v)
252256
segments (into-array segments)]
253257
;; NOTE: there is a reloading implication here...
@@ -273,10 +277,10 @@
273277
(defn resolve-symbol
274278
([ctx sym] (resolve-symbol ctx sym false nil))
275279
([ctx sym call?] (resolve-symbol ctx sym call? nil))
276-
([ctx sym call? tag]
280+
([ctx sym call? m]
277281
(second
278-
(or (resolve-symbol* ctx sym call? tag)
279-
#?(:cljs (let [resolved (resolve-dotted-access ctx sym call? tag)]
282+
(or (resolve-symbol* ctx sym call? m)
283+
#?(:cljs (let [resolved (resolve-dotted-access ctx sym call? m)]
280284
resolved))
281285
(throw-error-with-location
282286
(str "Could not resolve symbol: " sym)

0 commit comments

Comments
 (0)