Git Product home page Git Product logo

doppio's People

Contributors

amahdy avatar anishchandran avatar bmcdorman avatar brucespang avatar danxexe avatar deathcap avatar dependabot[bot] avatar emeryberger avatar fortianwei avatar gitter-badger avatar hanyuei avatar hrj avatar icodesometime avatar int3 avatar jerith666 avatar jleahey avatar lavelle avatar mdmueller avatar owaishanif786 avatar paulbgd avatar paulwagener avatar pbrazdil avatar perimosocordiae avatar qxfusion avatar solant avatar warlander avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

doppio's Issues

String tests fail

The two commented-out lines in Strings.java trigger failures. The valueOf() error seems to be thread-related.

Remove Thread* traps?

After implementing reflection, our current tests seem to pass even when all the Thread* method traps are commented out. Are there other cases that I am missing, or can we remove them?

Preload by program

Right now we preload a bunch of classes that are the union of those used by almost all our demo programs. This is somewhat slow and will only get slower if we add rhino to the mix. We should preload a simple core set of classes, and preload extra tarballs -- customized to each program -- when the user decides to run them.

Compile + optimize instead of interpret

General idea:

  • Replace opcodes with expression 'templates'. So iadd will be defined like this: in: [1,1], out: [1], exp: '$0 + $1', which means that it takes two 1-byte values from the stack and pushes a one-byte value. We can re-generate our current set of execute functions from these templates, but we could also string multiple opcodes together into one larger function.
  • When compiling, we can evaluate the stack symbolically. So when iadd is called we might have symbols (strings) 'a' and 'b' on the stack, and when we are done we have the string 'c' on the stack. We can then produce code like c = a + b. Not absolutely clear on how to analyze jumps and exception handling at the moment. See Harissa for more details.
  • Reduce virtual method lookup overhead by having compiled classes contain references to inherited functions.
  • Reconstruct 'normal' control flow code via decompilation. See Harissa, or Emscripten.

Decide on a name

I vote for doppio -- a fancy name for a double espresso. Punning on twice the amount of coffee, etc.

Misc

What is the condense() function in constant_pool.coffee supposed to do? Could you clarify the comment about fixing array references?

By the way, it's not necessary to initialize arrays using (new X for _ in [0...count]). Arrays in JS are hash tables, so we can simply assign without initialization. The length property will be automatically taken care of.

Nice work so far.

Untested Opcodes

We have these left to test:

daload
dastore
dcmpg
dcmpl
dreturn
dstore_0
dstore_2
dup2
dup2_x1
dup2_x2
dup_x2
faload
fastore
fconst_2
fload
freturn
fstore
fstore_0
goto_w
jsr_w
laload
lastore
lushr
nop
saload
sastore
swap

Try to make test cases that cover them, and update this issue when you do!

applet emulation

One of the goals we've had for a long time is the ability to use Doppio as a drop-in replacement for the native Java applet runner plugin.

Here's a sketch of how I envision it working, from a user perspective:

  • Navigate to a page with a Java applet embedded
  • Click a bookmarklet that runs the applet with Doppio

The bookmarklet would:

  • scrape the page source for the <applet> tag
  • load Doppio
  • replace the <applet> with a <canvas> of that same dimensions
  • run the applet in Doppio

The hardest part is the last step, of course, because we'd need to emulate java.awt.* on the HTML canvas, and (naturally) AWT uses a metric ton of native function calls. Just like we did with Jazzlib for java.util.zip, we could use a mostly pure-Java implementation of AWT: the PJA Toolkit. Sadly, the project is a few major JRE versions out of date, and it would need a some significant effort to get in shape for Java 1.6. Alternatively, we can bite the bullet and implement all the natives ourselves. There's a test case for the most basic AWT usage in test/special/Gfx.java.

The other non-trivial piece of code is the applet harness itself. This would be responsible for creating the Applet object and calling its lifecycle methods init, start, stop, and destroy. We don't yet have a test case for this.

Is the implementation of 'slot' correct?

It seems to me that we would need to account for the fields in the superclasses as well when generating the slot numbers. I attempted an implementation of this but it didn't seem to work very well, so I haven't checked it in.

Simplify internal type representation

The current implementation uses parse_descriptor to generate a dict structure that represents the type. It's awkward to convert that back to the raw form, which is necessary for reflection. We should investigate whether there's any use for the dict form. I actually implemented the parsing function early on in the project before I knew whether there was a good use case for it -- I still haven't found one but I don't know if anyone else has.

Interface with cloud storage

Instead of trying to fit everything into LocalStorage or memory, we could enable users to read/write files from a cloud storage service, providing more of a true filesystem.

We could use any or all of:

Those seem to be the most friendly and widely used, at least.

jQuery console expects a return value from command handlers

We don't give a non-null return value to the command handlers javac, java, javap, or rhino (all located in browser/frontend.coffee). This causes the jQuery console to throw an exception whenever any of these commands is run. It's not visible unless you're looking at the developer console, but it's not good.

Unfortunately, the simple fix of returning true from each of these functions has the following result:

doppio > java Fib
fib(20) = 6765doppio > 

doppio >  

We need a fix for the exception that also preserves the correct reprompt behavior.

get javap and javac working

The browser frontend (on the github page) works for javap Fib (without flags), but then:

doppio > java Main -c Fib
Compiled from "Fib.java"
public class test.Fib extends java.lang.Object{
public test.Fib();
  Code:
   0:   Exception in thread "main" java.lang.NoSuchFieldError: No such field found in sun/tools/javap/Tables: opcNamesTab::[Ljava/lang/String;
    at sun.tools.javap.Tables.<clinit>(Tables.java:36)
    at sun.tools.javap.JavapPrinter.printInstr(JavapPrinter.java:352)
    at sun.tools.javap.JavapPrinter.printcodeSequence(JavapPrinter.java:312)
    at sun.tools.javap.JavapPrinter.printMethods(JavapPrinter.java:199)
    at sun.tools.javap.JavapPrinter.print(JavapPrinter.java:40)
    at sun.tools.javap.Main.displayResults(Main.java:202)
    at sun.tools.javap.Main.perform(Main.java:61)
    at sun.tools.javap.Main.entry(Main.java:49)
    at sun.tools.javap.Main.main(Main.java:34)

Subclass with field of same name as field in parent class shadows parent class field

If you have classes like so:

class AParent {
    public int a;
    public int b;
}

class BChild extends AParent {
    public int a;
}

AParent.a and BChild.a are distinct fields. Currently, Doppio aliases the two to the same field.

CJ suggested that I change field lookup to use class/fieldname, which is the format to the putfield and getfield bytecodes. Unfortunately, that does not work correctly... I discovered (the hard way) that the classname in those bytecodes is not the class that owns the field, but the type of the object that is trying to access that field. Thus, if I request BChild.b, javac will emit a bytecode of getfield with class type BChild.

Thus, a getfield or putfield request will need to navigate the class hierarchy if it cannot find a field in the effective class of the current object.

Fixing this will also require you to fix how you access fields in native methods, and when you "cheat" to construct objects like Strings by directly assigning their fields. You may want to add a level of indirection to when you get / put an object's field.

Strange issue with running tests

Running make -j4 seems to call run_one_test.rb on all the requisite files, but it stops after printing out maybe half the errors. The .result files never get deleted, so typing make -j4 a second time runs the cat and rm -f instructions but skips run_one_test.rb. I think it might be an issue with our programs exiting with a nonzero return value, but I'm not sure... I've tried marking run_one_test in the Makefile with - to tell Make to continue despite errors, but to no avail.

Fix build process

From Reddit:

  • I don't have discount installed, but markdown
  • the gnu cpp requires -traditional-cpp to work while being raped in such a way.
  • I have no clue what it put into third_party/classes. If you don't want to put that into you git (what i can understand) please add a script that downloads it. That helps alot. And if you don't tell me what i should put in there. (Java 4/5/6? does gnu classpath work? download link? What kind of file hierarchy is expected? Should they match the host's JVM or your JVM?)
  • make fails, due to the lack of third_party/classes i guess. but surprisingly some stuff compiles. test/special/ZipRead.java:5: error: package com.sun.tools.javac.zip does not exist
  • Also Coffeescript: In src/constant_pool.coffee, Parse error on line 157: Unexpected 'INDENT' In src/opcodes.coffee, Parse error on line 470: Unexpected 'FORIN'
  • Also this strage 404: localhost - - [01/May/2012 01:18:27] "GET /test/special/Fib.java HTTP/1.1" 404

Browser class loading is slow

Ideas to speed it up:

  • Pre-load as many classes as possible on startup by scanning the constant pool for class references.
  • Load these classes asynchronously (and change the server to a concurrent one -- Node seems a natural choice here)

Browser can't load in standard lib .class files

We're using the node.js filesystem module currently; we'll probably need to write a browser-based version (or find one to plug in).

We could also plug in another server-side method of getting things.

Object data structures are NYI

We can run the 'new' opcode, but it currently just makes a dummy object. Objects should live on the heap, with some sort of reference to them on the stack.

Can this run as a static page?

I think having a static html version of doppio that interprets java is far more impressive.

Having a server kind of defeats the purpose of a js jvm since you can easily write a web front-end interpreting java code with a java server backend.

Edit: Although this is already plenty impressive and is a feat of engineering that I myself cannot accomplish

Avoid 'splice'

I mentioned this in the bug about untarring, but I thought I'd break it out -- we should avoid using splice to parse byte arrays, but keep a counter instead. It doesn't allow us to use typed arrays, and I think V8 recopies the whole array when we do this -- notice how untarring gets faster as we reach the end of the array. I'm thinking of creating a wrapper object on which you can call something like next_uint8(), and have it manage a position index internally.

print and println both print with newlines

I guess it has something to do with how PrintStream.write is getting trapped. Confusingly, switching to Node's process.stdout.write (which doesn't insert automatic newlines) fixes print but causes println to not print newlines as well.

run_class - done_cb fires immediately on later versions

I've noticed that the commits post September 6th (211dbb7) have an issue in run_class where the done_cb callback fires almost immediately, rather than at the end of the run as was the case in older builds of Doppio. Looking at your commits it appears to be about the time you introduced thread support (which would make sense).

You can replicate this by running something like

for (int i = 0; i < 800; i++) System.out.println("abc ");

you'll see that the reprompt happens after the first iteration or so, i.e. the callback has fired (early).

It doesn't break the demo site too badly - you just end up with a prompt in the middle of your output - but for my use case I need to be able to call something on "program end" reliably.

Use a pure java ZipFile implementation

I found this implementation of java.util.zip in pure Java: http://jazzlib.sourceforge.net/

As a quick test, I did s/net.sf.jazzlib/java.util.zip/, dropped the files in third_party/classes/java/util/zip, compiled, and voila! We no longer need any of that brutal ZipFile mocking. It's also about 10x faster (for the ZipFile initialization, at least).

Pros:

  • we'll be able to support loading of arbitrary JARs and zip files (including the rest of the classpath/bootclasspath)
  • we'll eliminate a large set of bugs (if we tried to emulate ZipFile ourselves)

Cons:

  • we won't be able to just unzip a classes.jar into third_party/classes anymore (though if we include the patched .class files from jazzlib it won't be too hard to get things set up)
  • I haven't looked into the license on jazzlib yet, it might not be compatible
  • we'd need to include the sun.boot.class.path jars for the browser version
  • breaks both javacs and rhino, because we don't have the classpaths set up correctly

Thoughts?

Can't load files not in localStorage cache

If any Java program tries to access a file not in the localStorage cache, the lookup will fail. This is expected behavior in general, because we don't want to give away access to arbitrary files, but some programs (notably javac and rhino) need to access properties files from $JAVA_HOME or the JCL.

Specifically: trying to run javac in the browser will fail because it can't find the file third_party/classes/sun/tools/javac/resources/javac.properties.

Various browser type and version failures using demo site

I have tested the nifty demo site in several browsers on WIndows, Linux, Mac and on a Linux VM running on Mac. Some things work, some don't: To summarize, mostly the newest versions of browsers work, older ones not so much.

On an Ubuntu 10.10 32bit VM (hosted on Mac) running in Chromium 8.0.552.224 the initial console load produces:

Enter 'help' for full a list of commands. Ctrl-D is EOF.
doppio >
  
Could not load 'DiffPrint.class'.
Could not load 'Chatterbot.class'.
Could not load 'Lzw.class'.
Could not load 'RegexTestHarness.class'.

list_cache produced lines like this at the end:

-third_party/classes/!javac.class
-!javac.class

Trying to compile:

doppio > javac Fib.java
 > 
ReferenceError: Float32Array is not defined

In Chrome 18.0.1025.168 on OS X lion. I can't find anything in the list_cache output in third_part/classes/sun/tools. There are lots of other sun packages there, but not that one. Attempting to compile Fib.java there produces "Exception in thread "main"" and it hangs.

On a 64bit Ubuntu (not a VM) running Firefox 12.0 it works. Chromium 14.0.835.202 also works on that box.

WIndows 7 18.0.1025.168 m chrome, fine.
Windows 7 Firefox 3.6.2 hangs after Done!, console doesn't respond to input
Windows 7 Firefox 12.0 works fine, though running javac gets warning Note: sun.tools.javac.Main has been deprecated.

IE Hangs on loading:

Webpage error details
 > 
User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 1.1.4322)
Timestamp: Sat, 12 May 2012 15:24:48 UTC
 > 
 > 
Message: Exception thrown and not caught
Line: 11
Char: 25598
Code: 0
URI: http://int3.github.com/doppio/compressed.js
 > 
 > 
Message: Exception thrown and not caught
Line: 11
Char: 25598
Code: 0
URI: http://int3.github.com/doppio/compressed.js
 > 
 > 
Message: 'null' is null or not an object
Line: 1
Char: 3198
Code: 0
URI: http://int3.github.com/doppio/ace.js
 > 
 > 
Message: Exception thrown and not caught
Line: 11
Char: 25598
Code: 0

Array Store Opcodes Do Not Check Bounds

Opcodes like iastore do not verify that they are writing within the bounds of the given array. The expected behavior is to throw an ArrayIndexOutOfBoundsException.

I have not personally seen this cause a bug in an actual program, but I can easily see a Java programmer being 'clever' and writing into an array until this exception is triggered rather than explicitly checking array.length. :)

Weird mismatch between browser and console disassembly

Look at the disassembly for this case:

class Test {
public static void main(String[] args) {
int a = 3-14;
}
}

And look at the arg to bipush. In the console version, it's correct (-11), but in the browser it's very wrong (63221).

Run tests in parallel?

Right now the -c flag tells run_tests.rb to run only a specific test. Could we hook this up with Make so as to get tests to run in parallel using -j4? I'd do this myself but I think @perimosocordiae knows how to write better Makefiles.

errors in README

  1. test/Println.* does not exist
  2. when running make release, the following error message is displayed:
    ...
    make: *** No rule to make target 'third_party/ace/build/src/ace.js', needed by 'build/ace.js'. Stop.
    ...

native function 'DSL'

What I've done so far: packages are now represented as a nested series of dicts. Also, in the method descriptor, if a method is under the package java/lang/foo/Bar, !/!/!/AnotherBar will expand to java/lang/foo/AnotherBar. The o function was used because I initially thought I might want to annotate each method with some extra properties -- I'm not so sure about this now but I'm going to leave it there for the time being.

Next up: Since we know the type signature of the native method, we can automate the dereferencing of the function's arguments in the local variable table, and pass it to the function as normal JS arguments. We could automatically push the function's return values on the caller stack too.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.