Last active
September 19, 2019 19:39
-
-
Save morj/53516068abd49e14a2ed7874df20bc3e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def bootstrap-invoke | |
'(fn | |
[^java.lang.invoke.MethodHandles$Lookup caller | |
^String methodName | |
^java.lang.invoke.MethodType methodType | |
^String varName] | |
(do | |
(when (nil? huj.SampleNS/var_x_var) | |
(set! huj.SampleNS/var_x_var | |
(clojure.lang.Var. huj.SampleNS/ns (clojure.lang.Symbol/intern varName)))) | |
(when (nil? huj.SampleNS/var_x_invoke_fallback_mh) | |
(set! huj.SampleNS/var_x_invoke_fallback_mh | |
(.findVirtual caller clojure.lang.Var "invoke" methodType))) | |
(cond | |
huj.SampleNS/var_x_invalid | |
(java.lang.invoke.ConstantCallSite. huj.SampleNS/var_x_invoke_fallback_mh) | |
(identical? huj.SampleNS/var_x_value huj.SampleNS/UNBOUND) | |
(java.lang.invoke.ConstantCallSite. huj.SampleNS/var_x_invoke_fallback_mh) | |
(some? huj.SampleNS/var_x_invoke_mh) | |
(java.lang.invoke.ConstantCallSite. huj.SampleNS/var_x_invoke_mh) | |
:else | |
(do | |
(when (nil? huj.SampleNS/var_x_switchPoint) | |
(set! huj.SampleNS/var_x_switchPoint | |
(java.lang.invoke.SwitchPoint.))) | |
(if (identical? huj.SampleNS/var_x_value huj.SampleNS/UNINITIALIZED_FN) | |
(java.lang.invoke.ConstantCallSite. | |
(.guardWithTest huj.SampleNS/var_x_switchPoint | |
(.findStatic caller huj.MyLambda "invokeStatic" methodType) | |
huj.SampleNS/var_x_invoke_fallback_mh)) | |
(java.lang.invoke.ConstantCallSite. | |
(.guardWithTest huj.SampleNS/var_x_switchPoint | |
(.bindTo | |
(.findVirtual caller clojure.lang.IFn "invoke" methodType) huj.SampleNS/var_x_value) | |
huj.SampleNS/var_x_invoke_fallback_mh)))))))) | |
(def loader-test | |
(res (list clojure.tools.emitter.temp/bootstrap-invoke) cl)) | |
(def class-name (:class-name (first (:bytecode loader-test)))) | |
; bytecode for "dispatch" method | |
(def boot-up {:op :method, | |
:attr #{:public :static}, | |
:method [:bootstrap-dispatch | |
[java.lang.invoke.MethodHandles$Lookup | |
java.lang.String | |
java.lang.invoke.MethodType | |
java.lang.String] | |
java.lang.invoke.CallSite], | |
:code | |
[[:start-method] | |
[:load-arg 0] | |
[:load-arg 1] | |
[:load-arg 2] | |
[:load-arg 3] | |
[:push "x"] | |
; start repeat | |
[:jump-insn :IF_ACMPEQ :after-x-label] | |
[:invoke-static | |
"class-name/bootstrap-invoke-x" | |
[java.lang.invoke.MethodHandles$Lookup | |
java.lang.String | |
java.lang.invoke.MethodType | |
java.lang.String] | |
java.lang.invoke.CallSite] | |
[:mark :after-x-label] | |
; end repeat | |
[:new-instance "java.lang.IllegalArgumentException"] | |
[:dup] | |
[:invoke-constructor | |
[:java.lang.IllegalArgumentException/<init>] | |
:void] | |
[:check-cast java.lang.Throwable] | |
[:throw-exception] | |
[:insn :ACONST_NULL] | |
[:mark :label__8230] | |
[:mark :label__8227] | |
[:return-value] | |
[:end-method]]}) | |
(clojure.pprint/pprint | |
(map | |
(fn [m] | |
(let [[[method-name & other] return] (:method m)] | |
(cond | |
(= :invoke method-name) | |
(conj | |
(update m :code | |
(fn [code] | |
(map | |
(fn [instruction] | |
(replace | |
{class-name "class-name", | |
"x" "var-name", | |
huj.SampleNS "class-name" | |
"huj.MyLambda" "lambda-name"} | |
instruction)) | |
code))) | |
{:method [:bootstrap-invoke ; add x to method name | |
[java.lang.invoke.MethodHandles$Lookup | |
java.lang.String | |
java.lang.invoke.MethodType | |
java.lang.String] | |
java.lang.invoke.CallSite]}) | |
(= :<clinit> method-name) | |
(update m :code | |
(fn [code] | |
(map | |
(fn [instruction] | |
(replace | |
{class-name "class-name", | |
huj.SampleNS "class-name" | |
"huj.MyLambda" "lambda-name"} | |
instruction)) | |
code)))))) | |
(:methods (first (:bytecode loader-test))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment