From da89da48cbe538521790f8a1bdc64ffae21161b5 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 31 Oct 2021 00:40:58 -0400 Subject: Fixed a bug when calling JVM functions from Ruby code. --- lux-ruby/source/program.lux | 193 +++++++++++++-------- stdlib/source/library/lux/target/ruby.lux | 13 +- .../tool/compiler/language/lux/phase/analysis.lux | 64 +++---- 3 files changed, 158 insertions(+), 112 deletions(-) diff --git a/lux-ruby/source/program.lux b/lux-ruby/source/program.lux index 7e3f4ef91..9aa71067f 100644 --- a/lux-ruby/source/program.lux +++ b/lux-ruby/source/program.lux @@ -25,7 +25,7 @@ ["[0]" utf8]]] [collection ["[0]" array {"+" Array}] - ["[0]" list]]] + ["[0]" list ("[1]#[0]" functor)]]] ["[0]" macro [syntax {"+" syntax:}] ["[0]" template]] @@ -245,17 +245,6 @@ (again (++ idx) (array.write! idx lux_value output)))) {try.#Success output})))) -(def: function_abstract_class - (|> ..read_tuple - (:as java/lang/Object) - java/lang/Object::getClass - java/lang/Class::getSuperclass)) - -(def: (function? value) - (-> Any Bit) - (java/lang/Class::isInstance (:as java/lang/Object value) - ..function_abstract_class)) - (exception: (unknown_kind_of_object [object java/lang/Object]) (exception.report ["Class" (java/lang/Object::toString (java/lang/Object::getClass object))] @@ -361,6 +350,74 @@ ["[1]::[0]" ("static" [t] copyOfRange [[t] int int] [t])]) +(exception: (invalid_arity [arity Nat]) + (exception.report + ["Arity" (%.nat arity)])) + +(def: (lux_wrapper_call useful_object_class lux_structure value) + (-> (-> (-> (Array java/lang/Object) org/jruby/runtime/builtin/IRubyObject) + (Array java/lang/Object) + org/jruby/RubyClass) + (-> (Array java/lang/Object) org/jruby/runtime/builtin/IRubyObject) + (-> (Array java/lang/Object) org/jruby/internal/runtime/methods/DynamicMethod)) + (ffi.object [] org/jruby/internal/runtime/methods/DynamicMethod [] + [java/lang/String "call"] + + (org/jruby/internal/runtime/methods/DynamicMethod + [] (call self [thread_context org/jruby/runtime/ThreadContext + self org/jruby/runtime/builtin/IRubyObject + module org/jruby/RubyModule + method java/lang/String + args [org/jruby/runtime/builtin/IRubyObject] + block org/jruby/runtime/Block]) + org/jruby/runtime/builtin/IRubyObject + (let [arity (ffi.length args)] + (try.trusted + (do [! try.monad] + [args (|> arity + list.indices + (list#each (function (_ index) + (ffi.read! index args))) + (monad.each ! (|>> (:as java/lang/Object) ..read))) + output (case args + (^ (list arg/0)) + (in ((:as (-> Any Any) value) + arg/0)) + + (^ (list arg/0 arg/1)) + (in ((:as (-> Any Any Any) value) + arg/0 arg/1)) + + (^ (list arg/0 arg/1 arg/2)) + (in ((:as (-> Any Any Any Any) value) + arg/0 arg/1 arg/2)) + + (^ (list arg/0 arg/1 arg/2 arg/3)) + (in ((:as (-> Any Any Any Any Any) value) + arg/0 arg/1 arg/2 arg/3)) + + (^ (list arg/0 arg/1 arg/2 arg/3 arg/4)) + (in ((:as (-> Any Any Any Any Any Any) value) + arg/0 arg/1 arg/2 arg/3 arg/4)) + + (^ (list arg/0 arg/1 arg/2 arg/3 arg/4 arg/5)) + (in ((:as (-> Any Any Any Any Any Any Any) value) + arg/0 arg/1 arg/2 arg/3 arg/4 arg/5)) + + (^ (list arg/0 arg/1 arg/2 arg/3 arg/4 arg/5 arg/6)) + (in ((:as (-> Any Any Any Any Any Any Any Any) value) + arg/0 arg/1 arg/2 arg/3 arg/4 arg/5 arg/6)) + + (^ (list arg/0 arg/1 arg/2 arg/3 arg/4 arg/5 arg/6 arg/7)) + (in ((:as (-> Any Any Any Any Any Any Any Any Any) value) + arg/0 arg/1 arg/2 arg/3 arg/4 arg/5 arg/6 arg/7)) + + _ + (exception.except ..invalid_arity [arity]))] + (in (|> output + (:as java/lang/Object) + (wrapped_lux_value useful_object_class lux_structure))))))))) + (def: (lux_wrapper_access useful_object_class lux_structure value) (-> (-> (-> (Array java/lang/Object) org/jruby/runtime/builtin/IRubyObject) (Array java/lang/Object) @@ -379,70 +436,61 @@ block org/jruby/runtime/Block]) org/jruby/runtime/builtin/IRubyObject (let [member (ffi.read! 0 args)] - (if (function? value) - (case (..read (:as java/lang/Object member)) - {try.#Success input} - (|> ((:as (-> Any Any) value) input) - (:as java/lang/Object) - (wrapped_lux_value useful_object_class lux_structure)) - - {try.#Failure error} - (panic! error)) - (<| (case (ffi.check org/jruby/RubyFixnum member) - {.#Some member} - (case (array.read! (org/jruby/RubyFixnum::getLongValue member) value) + (<| (case (ffi.check org/jruby/RubyFixnum member) + {.#Some member} + (case (array.read! (org/jruby/RubyFixnum::getLongValue member) value) + {.#Some value} + (wrapped_lux_value useful_object_class lux_structure value) + + {.#None} + ..ruby_nil) + + {.#None}) + (case (ffi.check org/jruby/RubyString member) + {.#Some member} + (case (:as Text (org/jruby/RubyString::asJavaString member)) + (^ (static runtime.variant_tag_field)) + (|> value + (array.read! 0) + maybe.trusted + (:as java/lang/Integer) + java/lang/Integer::longValue + (org/jruby/RubyFixnum::new ..initial_ruby_runtime)) + + (^ (static runtime.variant_flag_field)) + (case (array.read! 1 value) + {.#None} + ..ruby_nil + + {.#Some flag} + ..lux_unit) + + (^ (static runtime.variant_value_field)) + (case (array.read! 2 value) {.#Some value} (wrapped_lux_value useful_object_class lux_structure value) {.#None} - ..ruby_nil) - - {.#None}) - (case (ffi.check org/jruby/RubyString member) - {.#Some member} - (case (:as Text (org/jruby/RubyString::asJavaString member)) - (^ (static runtime.variant_tag_field)) - (|> value - (array.read! 0) - maybe.trusted - (:as java/lang/Integer) - java/lang/Integer::longValue - (org/jruby/RubyFixnum::new ..initial_ruby_runtime)) - - (^ (static runtime.variant_flag_field)) - (case (array.read! 1 value) - {.#None} - ..ruby_nil - - {.#Some flag} - ..lux_unit) - - (^ (static runtime.variant_value_field)) - (case (array.read! 2 value) - {.#Some value} - (wrapped_lux_value useful_object_class lux_structure value) + (panic! (exception.error ..nil_has_no_lux_representation []))) - {.#None} - (panic! (exception.error ..nil_has_no_lux_representation []))) - - field - (panic! (exception.error ..invalid_variant_access [field]))) - - {.#None}) - (case (ffi.check org/jruby/RubyRange member) - {.#Some member} - (case [(|> member (org/jruby/RubyRange::first thread_context) (ffi.check org/jruby/RubyFixnum)) - (|> member (org/jruby/RubyRange::size thread_context) (ffi.check org/jruby/RubyFixnum))] - [{.#Some first} {.#Some size}] - (let [first (org/jruby/RubyFixnum::getLongValue first) - size (org/jruby/RubyFixnum::getLongValue size)] - (lux_structure (java/util/Arrays::copyOfRange value first (i.+ first size)))) - - _ - (panic! (exception.error ..invalid_index (:as java/lang/Object member)))) - - {.#None}) - (panic! (exception.error ..invalid_index (:as java/lang/Object member))))))))) + field + (panic! (exception.error ..invalid_variant_access [field]))) + + {.#None}) + (case (ffi.check org/jruby/RubyRange member) + {.#Some member} + (case [(|> member (org/jruby/RubyRange::first thread_context) (ffi.check org/jruby/RubyFixnum)) + (|> member (org/jruby/RubyRange::size thread_context) (ffi.check org/jruby/RubyFixnum))] + [{.#Some first} {.#Some size}] + (let [first (org/jruby/RubyFixnum::getLongValue first) + size (org/jruby/RubyFixnum::getLongValue size)] + (lux_structure (java/util/Arrays::copyOfRange value first (i.+ first size)))) + + _ + (panic! (exception.error ..invalid_index (:as java/lang/Object member)))) + + {.#None}) + (panic! (exception.error ..invalid_index (:as java/lang/Object member)))))))) (def: (lux_wrapper_equality value) (-> (Array java/lang/Object) org/jruby/internal/runtime/methods/DynamicMethod) @@ -552,6 +600,9 @@ [] (searchWithCache self [method java/lang/String]) org/jruby/runtime/callsite/CacheEntry (case (:as Text method) + "call" + (org/jruby/runtime/callsite/CacheEntry::new (..lux_wrapper_call useful_object_class lux_structure value) 0) + "[]" (org/jruby/runtime/callsite/CacheEntry::new (..lux_wrapper_access useful_object_class lux_structure value) 0) diff --git a/stdlib/source/library/lux/target/ruby.lux b/stdlib/source/library/lux/target/ruby.lux index 8344f1fa9..3a5ac1901 100644 --- a/stdlib/source/library/lux/target/ruby.lux +++ b/stdlib/source/library/lux/target/ruby.lux @@ -220,15 +220,6 @@ (format (:representation func)) :abstraction)) - (def: .public (apply_lambda/* args lambda) - (-> (List Expression) Expression Computation) - (|> args - (list#each (|>> :representation)) - (text.interposed ..input_separator) - (text.enclosed ["[" "]"]) - (format (:representation lambda)) - :abstraction)) - (def: .public (the field object) (-> Text Expression Access) (:abstraction (format (:representation object) "." field))) @@ -425,6 +416,10 @@ (-> Text (List Expression) Expression Computation) (|> object (..the method) (..apply/* args))) +(def: .public (apply_lambda/* args lambda) + (-> (List Expression) Expression Computation) + (..do "call" args lambda)) + (def: .public (cond clauses else!) (-> (List [Expression Statement]) Statement Statement) (list#mix (.function (_ [test then!] next!) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux index dbe208844..9db69a2c3 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux @@ -1,37 +1,37 @@ (.using - [library - [lux "*" - [abstract - [monad {"+" do}]] - [control - ["[0]" exception {"+" exception:}]] - [data - [text - ["%" format {"+" format}]] - [collection - ["[0]" list]]] - [math - [number - ["n" nat]]] - ["[0]" meta - ["[0]" location]]]] - ["[0]" / "_" - ["[1][0]" type] - ["[1][0]" primitive] - ["[1][0]" structure] - ["[1][0]" reference] - ["[1][0]" case] - ["[1][0]" function] + [library + [lux "*" + [abstract + [monad {"+" do}]] + [control + ["[0]" exception {"+" exception:}]] + [data + [text + ["%" format {"+" format}]] + [collection + ["[0]" list]]] + [math + [number + ["n" nat]]] + ["[0]" meta + ["[0]" location]]]] + ["[0]" / "_" + ["[1][0]" type] + ["[1][0]" primitive] + ["[1][0]" structure] + ["[1][0]" reference] + ["[1][0]" case] + ["[1][0]" function] + ["/[1]" // "_" + ["[1][0]" extension] ["/[1]" // "_" - ["[1][0]" extension] - ["/[1]" // "_" - ["/" analysis {"+" Analysis Operation Phase} - ["[1][0]" macro {"+" Expander}]] - [/// - ["//" phase] - ["[0]" reference] - [meta - [archive {"+" Archive}]]]]]]) + ["/" analysis {"+" Analysis Operation Phase} + ["[1][0]" macro {"+" Expander}]] + [/// + ["//" phase] + ["[0]" reference] + [meta + [archive {"+" Archive}]]]]]]) (exception: .public (unrecognized_syntax [code Code]) (exception.report -- cgit v1.2.3