public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* Fully dynamically compiling/dexing/loading Kawa on Android
@ 2014-12-06  8:40 F. Rafael Leon
  2014-12-07  7:26 ` Per Bothner
  0 siblings, 1 reply; 2+ messages in thread
From: F. Rafael Leon @ 2014-12-06  8:40 UTC (permalink / raw)
  To: kawa

I think I may have discovered something rather significant ...

I started with the work of Helmut Eller from this post:

https://sourceware.org/ml/kawa/2012-q1/msg00040.html

It didn't work on the first try, so I added this line to AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET"/>

and I rebuilt the hello app and installed and ran it and then ran this
command on my computer:

rlwrap telnet 192.168.1.157 4444

and I saw this prompt and tried the repl:

Trying 192.168.1.157...
Connected to 192.168.1.157.
Escape character is '^]'.
#|kawa:1|# (+ 1 1)
2
#|kawa:2|#

I was very pleased, but then I tried compiling a scm file and loading
the jar and did not have any success.

At first. But then ...

My test file was called "plusone.scm" and looked like this:

(define-simple-class myclass ()
  ((plusone (x::int))::int allocation: 'static
   (+ 1 x)
   ))

I read a few previous posts in the kawa mail archive about loading and
dexing and it all sounded rather discouraging.

But then I was browsing the android build scripts and tools and found
this jewel:

$ANDROID_HOME/build-tools/21.1.1/lib/dx.jar

so I copied it into my project /libs directory and added it to my
app/build.gradle so it looked like this:

dependencies {
    compile files('libs/kawa.jar')
    compile files('libs/dx.jar')
}

And I built and installed and ran and telnetted and I was back to this:

#|kawa:1|#

and then things became really interesting when I started browsing the
source code for dx.jar:

https://android.googlesource.com/platform/dalvik/+/master/dx/src/com/android/dx/command/dexer/Main.java

After fixing paths and errors and warnings and avoiding calls to
System.exit(), I came up with this:

(define compiledexload
  ;; classname and filename
  (lambda (cls::String fn::String)
    (let* (
           (act::android.app.Activity *activity*)
           (bn (fn:replaceAll ".*/([^/]+).scm$" "$1"))
           (fdir ((act:getFilesDir):toString))
           (cdir ((act:getCacheDir):toString))
           (jarfn (string-append fdir "/" bn ".jar"))
           (dexfn (string-append fdir "/" bn ".dex"))
           (cfn (string-append cdir "/" bn ".dex"))
           ;; the args to dexer as a string array
           (dexsa (String[] (string-append "--output=" dexfn) jarfn))
           ;; the args to dexer as a parsed object
           (dexargs (com.android.dx.command.dexer.Main$Arguments))
           (cloader (act:getClassLoader))
           )
      ;; compile it.
      (compile-file fn jarfn)
      ;; dex it.
      (dexargs:parse dexsa)
      (com.android.dx.command.dexer.Main:run dexargs)
      ;;load it and return the loaded class.
      (if ((<java.io.File> cfn):exists)
          ((<java.io.File> cfn):delete))
      ((<dalvik.system.DexClassLoader> dexfn cdir #!null cloader):loadClass cls)
      )))

 ^^^ This thing does what you think it does. ^^^

I put it in a file called "cdl.scm" and ran this:

adb push cdl.scm /sdcard/Download

and then I ran this:

adb push plusone.scm /sdcard/Download

and then back to the repl:

#|kawa:5|# (load "/sdcard/Download/cdl.scm")
#|kawa:6|# (define loadedclass (compiledexload "myclass"
"/sdcard/Download/plusone.scm"))
#|kawa:7|# (invoke-static loadedclass 'plusone 1)
2
#|kawa:8|#

I did not use proguard. I used Dalvik runtime, not ART. I am on KitKat
4.4. I have no idea if any of this matters.

That is my story.

I was hoping someone else could try this and confirm that it actually works.

I solved of all the errors and warnings that I saw, but I always have doubts.

Thanks.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Fully dynamically compiling/dexing/loading Kawa on Android
  2014-12-06  8:40 Fully dynamically compiling/dexing/loading Kawa on Android F. Rafael Leon
@ 2014-12-07  7:26 ` Per Bothner
  0 siblings, 0 replies; 2+ messages in thread
From: Per Bothner @ 2014-12-07  7:26 UTC (permalink / raw)
  To: F. Rafael Leon, kawa



On 12/06/2014 12:40 AM, F. Rafael Leon wrote:
> I think I may have discovered something rather significant ...
>
> But then I was browsing the android build scripts and tools and found
> this jewel:
> ....
> $ANDROID_HOME/build-tools/21.1.1/lib/dx.jar

That does sound very promising!  Cool.

The next step would be modify ArrayClassLoader so it automatically
does the .class to .dex translation.  Or whatever is the cleanest
way to tie a DexClassLoader to uses the classes of the ArrayClassLoader.

Could you find in the sources a way to convert .class to .dex
*without* actually writing a file in the file-system?  I.e. take a byte
array representing a kawa-generated-class, convert it to another byte
array representing the converted dex class, and then pass that
to ClassLoader.defineClass?

If there is a simple call to do that, then it seems like it's a matter
of adding a few lines in ArrayClassLoader.loadClass, to do the
conversion before calling defineClass.

OTOH if the conversion needs to work on a *set* of classes (like in a
jar file), then the changes are a little more difficult.  Could we convert
all the byte arrays in an ArrayClassLoader in a single operation?
Preferably if we didn't have to actually read and write files, but if
we have to do that, that's ok.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-12-07  7:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-06  8:40 Fully dynamically compiling/dexing/loading Kawa on Android F. Rafael Leon
2014-12-07  7:26 ` Per Bothner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).