Giter VIP home page Giter VIP logo

eta's Introduction

Eta logo

Eta - Modern Haskell on the JVM

Join the chat at https://gitter.im/typelead/eta Build Status Open Source Helpers

The Eta programming language is a dialect of Haskell which runs on the JVM and has the following goals:

  • accessibility for beginners from imperative languages, especially Java
  • compatibility with GHC 7.10.3's Haskell.

Visit eta-lang.org for instructions on getting started.

Version

Version: 0.8.6

Stable Build: 0.8.6b5

Latest Build: 0.8.6b5

Subscribe to the Eta-Discuss for updates.

Getting Started

Visit the Getting Started page in the documentation.

Contribute

Visit the Contribute page in the official website for details.

You are required to sign TypeLead Individual CLA before we can merge any of your work into our code base.

Report issues

You can report issues at eta issue tracker for more details check Bug Report page in the official website for more details.

Eta Proposals

Visit the Eta Proposals page in the official website to propose changes to Eta.

License

Eta is available under the BSD 3-Clause License, see LICENSE for more information.

Contributors

We would like to specifically thank the following groups/people:

Thanks folks!

eta's People

Contributors

abhiroop avatar agocorona avatar aktowns avatar alanasp avatar alexbiehl avatar alexeyraga avatar bradrn avatar cema-sp avatar excaliburzero avatar gitter-badger avatar gordonbgood avatar hamishmack avatar hvr avatar jarekratajski avatar jbgi avatar jneira avatar jyothsnasrinivas avatar lei-hongfaan avatar mandubian avatar nequissimus avatar noahhaasis avatar ouromoros avatar pparkkin avatar prillan avatar psibi avatar puffnfresh avatar rahulmutt avatar sam-gronblom-rj avatar sgronblo avatar y-taka-23 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eta's Issues

Find a working ProGuard configuration file

Currently, a simple program like

main = putStrLn "Hello World!"

generates a ~30MB JAR file. An estimated 75-80% of that amount is dead code. The goal is to workout a proguard config file that works and include proguard as a step in EPM for optimised builds.

Rewrite CodeGen monad

Motivation

After discussion with @aloiscochard and his eagerness to provide support from the JVM assembler side, I have decided to depend on his kuna project instead of hs-java.

Implementation

  1. Observe the structure of kuna and how the currently existing parts of the code generator can be rewritten in kuna style. This exploration should happen on a separate branch called wip/kuna.
  2. Remove the dependency of the CodeGen monad on the GenerateIO monad from the hs-java library.
  3. Rewrite the existing parts of the codegen with the new kuna-based monad.

Support generics for FFI Imports

We would like something like

data {-# CLASS "java.util.ArrayList" #-} ArrayList a = ArrayList (Object# (ArrayList a))

foreign import java unsafe "add" add :: a -> Java (ArrayList a) ()
foreign import java unsafe "get" get :: Int -> Java (ArrayList a) a

This is very close to becoming a reality - we just need to add a new primitive unsafeClassCast# :: Object# a -> Object# b that will generate a checkcast bytecode. This primitive is useful in general for manual casting of Java objects inside of Haskell code.

Speed up linking of jars

The current naive implementation of jar linking extracts all the class files and puts them all into a single jar. Using a streaming abstraction should make this faster. The CodeGen monad needs to be slightly updated to support streaming (write classfiles as soon as the code is generated for a given closure).

Package class files into JAR

Motivation

Currently, GHCVM generates a new inner class for almost every top-level declaration and hence there will be a lot of files of the form Module$toplevel.class generated at the same level of the source module or wherever the target directory is specified using the -o flag. It would be better to stick them all into a JAR file.

Implementation

  1. The codeGen function in GHCVM.CodeGen.Main will return a set of Class values that can be serialized into a Java class. The next step after serialization should be to package them all up into a JAR file.

Provide utility to package class files into JAR

Motivation

Currently, ghcvm has a dependency on libzip (transitive from the hs-java dependency) which is making it difficult to build (see #7).

Implementation

Write a utility module that can JAR class files together, making use of the pure Haskell library zip.

Foreign export VerifyError Operand stack underflow

Commit: cfd5914

Haskell side:

{-# LANGUAGE MagicHash #-}
module Export where

import Primes
import GHC.Base

data {-# CLASS "hello.Export" #-} Export = Export (Object# Export)

foreign export java takePrime :: Int -> Java Export Int

takePrime i = return . fromIntegral $ primes !! i

module Primes where

primes = filterPrime [2..]
  where filterPrime (p:xs) =
          p : filterPrime [x | x <- xs, x `mod` p /= 0]

Java side:

import hello.Export;

public class HelloWorld {
    public static void main(String[] args) {
        String v = Integer.toString(new Export().takePrime(1));
        System.out.println(v);
    }
}

Error:

java.lang.VerifyError: Operand stack underflow
Exception Details:
  Location:
    hello/Export.takePrime(I)I @31: getfield
  Reason:
    Attempt to pop empty stack.
  Current Frame:
    bci: @31
    flags: { }
    locals: { 'hello/Export', integer }
    stack: { }
  Bytecode:
    0x0000000: b800 182a bb00 1a59 b200 20bb 000b 591b
    0x0000010: b700 23b7 0026 b800 2ab4 002e b800 32b4
    0x0000020: 0035 c000 0bb4 0039 ac                 

ghcvm-pkg list gives up multiple entries

@sibi::jane { ~/github/ghcvm-hackage/test/array-0.5.1.1 }-> ghcvm-pkg list
/home/sibi/.ghcvm/package.conf.d
   array-0.5.1.1
   base-4.8.2.0
   ghc-prim-0.4.0.0
   integer-0.5.1.0
   rts-0.1.0.0
/home/sibi/.ghcvm/package.conf.d
   array-0.5.1.1
   base-4.8.2.0
   ghc-prim-0.4.0.0
   integer-0.5.1.0
   rts-0.1.0.0
/home/sibi/.ghcvm/package.conf.d
   array-0.5.1.1
   base-4.8.2.0
   ghc-prim-0.4.0.0
   integer-0.5.1.0
   rts-0.1.0.0
/home/sibi/.ghcvm/package.conf.d
   array-0.5.1.1
   base-4.8.2.0
   ghc-prim-0.4.0.0
   integer-0.5.1.0
   rts-0.1.0.0

Probably this happens because of multiple installation (i.e cleaninstall.sh) ?

Foreign exports

While foreign imports allow us to call java functions from within Haskell in a type-safe way, foreign exports allow us to export a Haskell function that can be called as a java function. More specifically, to accommodate the way Java frameworks are managed, we should allow existing classes to be subclasses within Haskell itself and implement interfaces. The alternative would be to roll out your own subclass and make each method call an exported Haskell function which would be unnecessary boilerplate.

Example of instance methods:

data {-# CLASS "mypackage.SomeClass" #-} SomeClass = SomeClass (Object# SomeClass)

someMethod :: Int -> Java SomeClass ()
someMethod = ...

foreign export java someMethod :: Int -> Java SomeClass ()

This will create a new class with name "SomeClass.class" and with a method called "void someMethod(int)" which takes an int and returns void.

add :: Int -> Int -> Int
add = ...

foreign export java add :: Int -> Int -> Int

This will statically export "int add(int, int)" as a static method of the current class.

Program hangs on print

module Main where

main = do
  print $ 2 + 15
  print $ 49 * 100

This program prints out 17 and then hangs.

Project scope/naming

Hi Rahul,

I was wondering about the naming and the scope you want to cover here, the reason I ask is because with a name with ghcvm I would expect it to potentially try to target different vm, or to implement a vm itself.

Wouldn't be ghcjvm more appropriate? (it also reflect the naming used by the JS backend)

Cheers!

Supporting annotations with retention policies CLASS and RUNTIME

Some Java frameworks use annotations as triggers for bytecode instrumentation and other purposes. It would be useful to be able to export Haskell functions with certain annotations.

The main requirement for support is to use the existing features of GHC to convey the annotation information. If that is too restrictive, we'll have to consider a syntactic extension.

There is one tricky aspect: specifying values for annotations. This is not THAT common so it's fine if we leave it for some time.

Open to proposals on how the syntax should look. Preferably with examples of usage in commonly used Java frameworks (such as Spring).

Port the process-1.6.1.0 package

Steps to do the port:

  1. etlas get process-1.6.1.0
  2. cd process-1.6.1.0
  3. etlas build
  • This will show you that directory >=1.1 && <1.4, filepath >=1.2 && <1.5, unix >=2.5 && <2.8 are needed. As a general rule, you should comment out the unix and Win32 dependency when doing ports since it's hard to shim the full package on the JVM (uses lots of platform-dependent C FFI calls) and we want to keep packages as portable as possible. We can offer platform-dependent versions for performance later on.
  1. Open the process.cabal file and comment out all platform-dependent stuff, including:
  • the c-sources:, includes:, and install-includes: fields (i.e. anything that contains .c or .h files).
  • any conditional dependencies based on platform (i.e the entire if os(windows) clause should be commented out.)
    You can use -- for single-line comments.
  1. Change the build-type: field to Simple as that's the only build type supported by etlas, for now.
  2. Run etlas install directory-1.3.1.0 (the future versions are not supported for now) followed by etlas install --dependencies-only to install the rest.
  3. Run etlas build.
  4. You'll find lots of errors about missing modules. Remove those modules and you'll find now that functions are missing. Now your task is to study what's happening around that missing function, and figure out which Java API you need to use to substitute that functionality.
  5. Keep fixing stuff, run etlas build, and keep going until the package builds successfully.

Bindings to Java's ProcessBuilder API most likely have to be made.

See the instructions here to create and submit the patch once you're done.

Implement deriving mechanism for Class

The current instance definitions for Class involve boilerplate.

data {-# CLASS "java.lang.Object" #-} Object = Object (Object# Object)

instance Class Object where
  obj = Object
  unobj (Object x) = x

This would be great to reduce to

data {-# CLASS "java.lang.Object" #-} Object = Object (Object# Object)
  deriving Class

Implement better naming scheme for closures

Currently, the following function declarations

module Test.Main where
putStrLn = ...

putstrln = ...

generate a class test/Main$putStrLn.class and test/Main$putstrln.class but JARs are case-insensitive so both of them clash and only one arbitrary class file gets chosen while the other disappears, yielding a NoClassDef error at runtime. The current naming scheme is GHC's Z-encoding, but we need to extend it to make sure two functions names that are equivalent modulo case produce names that are not equivalent modulo case.

The function GHCVM.CodeGen.Name.nameText is the central function which regulates naming for closure identifiers. Looking for a naming scheme that keeps the names clean.

Integrate compilation of java, class, jar files

ghcvm --make SomeClass.class SomeOtherClass.java SomeJar.jar SomePure.hs

Should convert all the given files to class files accordingly and properly put them in the resulting jar. Currently, it's partially implemented (should work in batch mode -c) but needs to be tweaked for --make mode. In particular, we need to make sure we set the -classpath flag of javac properly, taking into account references to the module closures compiled in the same batch.

Implementation Sketch:
Separate out .java files and compile them only after all other compilation units and include all the compiled .jars as dependencies.

IllegalAccessError with repeat

module Main where

main = do
  print $ take 10 (repeat 5)

This gives:

Exception in thread "main" java.lang.IllegalAccessError
    at base.ghc.List$repeat.enter(Unknown Source)
    at ghcvm.runtime.apply.StgFun.apply(StgFun.java:116)
    at ghcvm.runtime.apply.Apply$8.enter(Apply.java:75)
    at main.Main$main2.thunkEnter(Unknown Source)
    at ghcvm.runtime.thunk.StgIndStatic.enter(StgIndStatic.java:30)
    at ghcvm.runtime.stg.StgClosure.evaluate(StgClosure.java:20)
    at base.ghc.List$take.enter(Unknown Source)
    at ghcvm.runtime.apply.StgFun.apply(StgFun.java:189)
    at ghcvm.runtime.apply.Apply$11.enter(Apply.java:104)
    at main.Main$main1.thunkEnter(Unknown Source)
    at ghcvm.runtime.thunk.StgIndStatic.enter(StgIndStatic.java:30)
    at ghcvm.runtime.stg.StgClosure.evaluate(StgClosure.java:20)
    at base.ghc.Show$showListzuzu.enter(Unknown Source)
    at base.ghc.Show$zdLrFHWzdcshowList22.enter(Unknown Source)
    at ghcvm.runtime.apply.StgFun.apply(StgFun.java:189)
    at ghcvm.runtime.apply.ApPP.stackEnter(ApPP.java:19)
    at ghcvm.runtime.stg.StackFrame.enter(StackFrame.java:43)
    at ghcvm.runtime.stg.StackFrame.enter(StackFrame.java:26)
    at ghcvm.runtime.stg.StgContext.checkForStackFrames(StgContext.java:75)
    at base.ghc.io.handle.Text$shoveStringzus7ZZSF.enter(Unknown Source)
    at base.ghc.io.handle.Text$zdLr7V3SwriteBlocks.enter(Unknown Source)
    at base.ghc.io.handle.Text$satzus7ZZVC.enter(Unknown Source)
    at ghcvm.runtime.apply.StgFun.apply(StgFun.java:134)
    at ghcvm.runtime.apply.Apply$9.enter(Apply.java:84)
    at base.ghc.Base$zdLr4JLa3.enter(Unknown Source)
    at ghcvm.runtime.apply.Apply$20.enter(Apply.java:210)
    at ghcvm.runtime.apply.StgPAP.apply(StgPAP.java:46)
    at ghcvm.runtime.apply.ApV.stackEnter(ApV.java:12)
    at ghcvm.runtime.stg.StackFrame.enter(StackFrame.java:43)
    at ghcvm.runtime.stg.StackFrame.enter(StackFrame.java:26)
    at ghcvm.runtime.stg.StackFrame.enter(StackFrame.java:26)
    at ghcvm.runtime.stg.Capability.schedule(Capability.java:245)
    at ghcvm.runtime.RtsScheduler.scheduleWaitThread(RtsScheduler.java:57)
    at ghcvm.runtime.Rts.evalLazyIO(Rts.java:91)
    at ghcvm.runtime.Rts.hsMain(Rts.java:36)
    at ghcvm.main.main(Unknown Source)

Problem with cycle function

module Main where

main = do
  print $ take 10 (cycle [1,2,3])

It works for take 1, 2 & 3, beyond that it hangs. It seems to be a problem with the cycle function.

Remove dependency on GHC installation files

The GHCVM installation process currently copies over

ghc-usage.txt
settings
include/ghcversion.h
include/ghcplatform.h

This is only a temporary solution to quickly get access to GHC settings, and there are much better ways of solving the problem, like refactoring the main ghcvm executable project.

We should remove the dependency on the location of the GHC installation directory and provide a GHCVM-specific solution instead.

Named inner classes

Currently, anonymous inner classes are used to declare RtsFuns. Instead, we should used named inner classes so that debugging becomes clearer. An example is eta.runtime.apply.Apply which contains a lot of them which are frequently used. It's easier to decipher what Apply$ApPFast is rather than Apply$8.

take returns [] for everything with -O0

For some reason, take returns [] when compiled with -O0 but the correct answer when compiled with -O2. This deviation should be checked. The current workaround is to use the elementary implementation of take.

Support for C FFI

Motivation

A suggestion was given on reddit about supporting the C FFI for greater library support on Hackage.

My reservations on this matter are:

  1. Using JNI locks you onto the platforms that the C library supports.
    Comment: After further thought, most server-side applications in production will typically not shift between architectures/hardware very frequently and during the time they migrate then can link a different version of the library that supports that platform. @mgsloan also notes that some of the Hackage libraries make use of cross-platform C libraries, so this may not be a serious issue.
  2. Too many context switches.
    Comment: In order to call to the C FFI, first you must call a native Java method (which is a Java FFI call) and then the JVM does a context switch to the native world. So essentially, you're switching from Haskell world -> Java world -> Native world and then you have to follow that sequence of switches in reverse. I expect this to be costly, but we can test it out and see what happens. Moreover, there may be cases where it is actually faster to use the Java method that performs the same task if it exists in some library. This needs to be checked.

Implementation

The RTS needs no special support other than that of Java FFI. The entire implementation will be in the codegen.

  1. When a foreign import declaration with the ccall calling convention is used
foreign import ccall "someheader.h somefunc" somefunc :: Int -> Int

an appropriate native method declaration is made with the Z-encoded Haskell name in the declaration.

  1. A field is generated which generates a function closure of matching arity which upon entry should call the generated native method, taking in the appropriate arguments and casting as appropriate.
  2. A static initializer block is generated to load the dynamic library containing the native method implementation.
  3. After code generation, another step is performed using javah to generate the header file for the class and the native method declaration and to generate a .c file that will call the C function mentioned above in quotes.
  4. After the C file generation, gcc should be run to compile the generated C file into a .dll (if windows) or .so (if linux). This part will be tricky handling all the platforms.

The ghcvm-hackage system

There are minor differences between GHC and GHCVM and those minor differences must be accounted for to allow libraries on Hackage to compile. To consult with every package maintainer about coming up with the fixes themselves is a time-consuming task as well as waiting for them to release a new version that will contain GHCVM support via a conditional #ifdef __GHCVM_VERSION__ check.

I propose that we:

  • introduce a new repo called ghcvm-hackage which contains information on package, version, and how to patch that specific package version so that GHCVM can compile it. (This will literally be a git patch file).
  • Add a new feature in cabalvm that will clone the ghcvm-hackage repo locally and keep updating it. Whenever a user invokes cabalvm install [package], the package will be looked up in ghcvm-hackage and the source distribution will be patched with the patch file just before cabalvm starts the build.

The resulting flow:

  1. A user tries installing a package and finds that the build fails.
  2. He files an issue to the ghcvm-packages repository
  3. People who want to help out will:
  • download that package from hackage locally
  • make the necessary changes to fix the build
  • submit a PR with the patch file to the ghcvm-hackage repo
  • the end-user will be able to successfully install the package upon another invocation of cabalvm install

Looking forward to feedback.

Add travis CI integration

For the initial start, the test can be just a simple hello world and the prime number example which is documented in the wiki.

VerifyError: Expecting a stackmap frame at branch target 12

lvl1_r7rH = 1
seven1 = 2
s2 = 0

wg1_r7rI ww_s7mE w_s7mA ww1_s7mI =
    case (rem w_s7mA seven1) == s2 of 
      False ->
        case w_s7mA == lvl1_r7rH of 
          False ->
            wg1_r7rI
              (ww_s7mE * ww_s7mE)
              (quot (w_s7mA - lvl1_r7rH) seven1)
              (ww_s7mE * ww1_s7mI)
          True -> ww_s7mE * ww1_s7mI
      True ->
        wg1_r7rI
          (ww_s7mE * ww_s7mE) (quot w_s7mA seven1) ww1_s7mI

wf ww_s7mS w_s7mP =
    case (rem w_s7mP seven1) == s2 of
      False ->
        case w_s7mP == lvl1_r7rH of 
          False ->
            wg1_r7rI
              (ww_s7mS * ww_s7mS)
              (quot (w_s7mP - lvl1_r7rH) seven1)
              ww_s7mS
          True -> ww_s7mS
      True -> wf (ww_s7mS * ww_s7mS) (quot w_s7mP seven1)

main7 = 1000000 :: Int -- 16777216 :: Int 
lvl2_r7rJ = [5, 7 .. ]
main3 = 3 : main4

lvl3_r7rK x_aBf =
    let y_a4LG = x_aBf in
    case (4 <= y_a4LG) of
      False -> True
      True ->
        case rem y_a4LG 2 of
          0 -> False
          _ ->
            let go_a4Mt ds_a4Mu =
                  case ds_a4Mu of
                    [] -> True
                    y1_X4NA : ys_X4NC ->
                      let x1_X4Pu = y1_X4NA in
                      case ((x1_X4Pu * x1_X4Pu) <= y_a4LG) of 
                        False -> True
                        True ->
                          case x1_X4Pu of
                            (-1) -> False
                            -- 0 -> case divZeroError of wild7_00 { }
                            _ -> case rem y_a4LG x1_X4Pu of
                    0 -> False
                                    _ -> go_a4Mt ys_X4NC
            in go_a4Mt main3

main4 = filter lvl3_r7rK lvl2_r7rJ
main_primes = 2 : main3

wgo w_s7n5 ww_s7n9 = case w_s7n5 of 
      [] -> ww_s7n9
      y_a4Mz : ys_a4MA ->
        let x_a4LC = y_a4Mz in
        let y1_a4LG = main7 in
        case x_a4LC <= y1_a4LG of 
          False -> ww_s7n9;
          True ->
              let wgo1_X7qh w1_X7oa ww1_X7of = case w1_X7oa of
                    [] -> ww1_X7of
                    y2_X4NH : ys1_X4NJ ->
                      let x1_X4MP = y2_X4NH in
                      case (x1_X4MP <= y1_a4LG) of
                        False -> ww1_X7of
                        True -> wgo1_X7qh ys1_X4NJ (ww1_X7of + 1)
              in wgo1_X7qh ys_a4MA (ww_s7n9 + 1)

main = print $ wgo main_primes 0
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 12
Exception Details:
  Location:
    main/Main$mainzuwgo1zuX7qh.enter(Lghcvm/runtime/stg/StgContext;)V @149: goto
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: 2b05 b600 184d 2b06 b600 184e 2bb6 001e
    0x0000010: 3605 2c2b b600 222b 1505 b600 252b 04b6
    0x0000020: 0018 3a04 1904 c000 29b6 002b 049f 0073
    0x0000030: 1904 c000 0959 b400 303a 0659 b400 343a
    0x0000040: 0757 2bb6 001e 3609 2bb4 0037 59bb 003d
    0x0000050: 5919 06b2 003f b700 42b6 0045 572b 05b2
    0x0000060: 004b b600 50b2 0053 2bb6 002e 2b15 09b6
    0x0000070: 0025 2b04 b600 183a 0819 08c0 0029 b600
    0x0000080: 2b04 9f00 16bb 000c 592d b700 563a 0a19
    0x0000090: 074d 190a 4ea7 ff77 2d2b b600 2ea7 0008
    0x00000a0: 2d2b b600 2eb1                         
  Stackmap Table:
    full_frame(@152,{Object[#4],Object[#22],Object[#28],Object[#28],Object[#28],Integer,Object[#28],Object[#28],Object[#28],Integer},{})
    full_frame(@157,{Object[#4],Object[#22],Object[#28],Object[#28],Object[#28],Integer,Object[#28],Object[#28],Object[#28],Integer},{})
    full_frame(@160,{Object[#4],Object[#22],Object[#28],Object[#28],Object[#28],Integer},{})
    full_frame(@165,{Object[#4],Object[#22],Object[#28],Object[#28],Object[#28],Integer},{})

    at main.Main.<clinit>(Unknown Source)
    at ghcvm.main.main(Unknown Source)

Make return points as StackFrames

The code for return points comes within the same closure rather than a separate block. This prevents us from being able to safely context switch which relies on the property that a TSO's state of execution can be restored purely from its stack.

The solution is to create a StackFrame with stackEnter() overriden with the code for the return point. In cgCase, we need to generate a new StackFrame and then push that stack frame before we evaluate the scrutinee.

The main disadvantage is that this generates a lot more class files, but that's a necessary sacrifice for implementing concurrency/parallelism, an essential feature. The excess class files can be overcome with invoke dynamic if found to be a problem.

Implement context switching

This requires adding a bit of logic in StgClosure.enter that checks if context switch needs, and if so, stores the current closure's entry on the stack and safety. The latter bit is tricky and needs to handle the different types of closures. A virtual function saveContext() can de declared and overriden for the different closure types.

Has a dependency on #22.

Port GHC's benchmark suite (nofib) into shake

It'd be nice to detect performance regressions as we make new commits and fix them on the spot. There should be some integration into shake that uses JMH, since Java benchmarking is quite tricky due to JIT.

Build Failure

Hi there,
Thanks for this cool project. I tried to build it on my mac but I got some errors: looks like some dependencies are missing

>./build.sh                                                
mtl-2.2.1: using precompiled package
data-default-0.5.3: configure
monadloc-0.7.1: download
binary-state-0.1.1: download
data-default-0.5.3: build
bindings-libzip-0.10.2: configure
data-default-0.5.3: copy/register
monadloc-0.7.1: configure
monadloc-0.7.1: build
binary-state-0.1.1: configure
binary-state-0.1.1: build
monadloc-0.7.1: copy/register
binary-state-0.1.1: copy/register
Progress: 5/23
--  While building package bindings-libzip-0.10.2 using:
      /Users/prat/.stack/setup-exe-cache/x86_64-osx/setup-Simple-Cabal-1.22.5.0-ghc-7.10.3 --builddir=.stack-work/dist/x86_64-osx/Cabal-1.22.5.0 configure --with-ghc=/usr/local/bin/ghc --with-ghc-pkg=/usr/local/bin/ghc-pkg --user --package-db=clear --package-db=global --package-db=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/pkgdb --libdir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/lib --bindir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/bin --datadir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/share --libexecdir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/libexec --sysconfdir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/etc --docdir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/doc/bindings-libzip-0.10.2 --htmldir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/doc/bindings-libzip-0.10.2 --haddockdir=/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/doc/bindings-libzip-0.10.2 --dependency=base=base-4.8.2.0-bfcc6de9ee2962ae54db40ece3022dc5 --dependency=bindings-DSL=bindings-DSL-1.0.23-75369fdfdd50bafd3a7650315e217654
    Process exited with code: ExitFailure 1
    Logs have been written to: /Users/prat/prt/ghcvm/.stack-work/logs/bindings-libzip-0.10.2.log

    Configuring bindings-libzip-0.10.2...
    setup-Simple-Cabal-1.22.5.0-ghc-7.10.3: The pkg-config package 'libzip'
    version ==0.10.* is required but it could not be found.
Executable named rtsbuild not found on path: ["/Users/prat/prt/ghcvm/.stack-work/install/x86_64-osx/lts-5.11/7.10.3/bin","/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/bin","/Users/prat/.stack/programs/x86_64-osx/ghc-7.10.2/bin/ghc","/Users/prat/.local/bin","/Users/prat/.cabal/bin","/usr/local/bin","/usr/local/sbin","/usr/bin","/bin","/usr/sbin","/sbin","/usr/local/git/bin","/usr/local/munki","/Users/prat/Library/Android/sdk/tools","/Users/prat/Library/Android/sdk/platform-tools","/Users/prat/.cargo/bin","/Users/prat/.cabal/bin"]
Executable named rtsbuild not found on path: ["/Users/prat/prt/ghcvm/.stack-work/install/x86_64-osx/lts-5.11/7.10.3/bin","/Users/prat/.stack/snapshots/x86_64-osx/lts-5.11/7.10.3/bin","/Users/prat/.stack/programs/x86_64-osx/ghc-7.10.2/bin/ghc","/Users/prat/.local/bin","/Users/prat/.cabal/bin","/usr/local/bin","/usr/local/sbin","/usr/bin","/bin","/usr/sbin","/sbin","/usr/local/git/bin","/usr/local/munki","/Users/prat/Library/Android/sdk/tools","/Users/prat/Library/Android/sdk/platform-tools","/Users/prat/.cargo/bin","/Users/prat/.cabal/bin"]

Any suggestion? Thanks again!

Integrate cpphs into driver pipeline

Motivation

Currently, the build has a dependency on cpp, the C preprocessor in linux which is making it difficult to build (see #7).

Implementation

Integrate cpphs, a pure Haskell pre-processor into the Shake build system in shake/Build.hs.

Doubles don't work

module Main where

main = do
  print $ min 3.4 3.2
Exception in thread "main" java.lang.NoSuchMethodError: ghcvm.base.Utils.isDoubleNegativeZero(D)I
    at base.ghc.Float$isDoubleNegativeZZero.enter(Unknown Source)
    at base.ghc.Float$zdLr1MAYzdcisNegativeZZero1.enter(Unknown Source)
    at ghcvm.runtime.apply.StgFun.apply(StgFun.java:116)
    at ghcvm.runtime.apply.ApP.stackEnter(ApP.java:17)

NullPointerException at Capability.java

primes = 2:3:filter isPrime [5,7..] :: [Int]
isPrime x = all (/= 0) . map (rem x) . takeWhile ((<= x) . (^2)) $ primes
main = print . length . takeWhile (<= 2^24) $ primes
$ java -classpath sievej.jar ghcvm.main
Exception in thread "main" java.lang.NullPointerException
    at ghcvm.runtime.stg.Capability.schedule(Capability.java:296)
    at ghcvm.runtime.RtsScheduler.scheduleWaitThread(RtsScheduler.java:57)
    at ghcvm.runtime.Rts.evalLazyIO(Rts.java:91)
    at ghcvm.runtime.Rts.hsMain(Rts.java:36)
    at ghcvm.main.main(Unknown Source)

takeWhile (<= 100)

$ java -classpath sievej.jar ghcvm.main
25

ghc-usage.txt does not exist

Currently when running ghcvm --help after install ghcvm, an error message is given.

$ ghcvm --help
/home/chris/.ghcvm/ghc-usage.txt: openFile: does not exist (No such file or directory)

List comprehension hanging

module Main where

main = do
  print $ boomBangs [13,9]

boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

Works

module Main where

main = do
  print $ boomBangs [7,9]

boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

Hangs

module Main where

main = do
  print $ boomBangs [7,13]

boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

Works

module Main where

main = do
  print $ boomBangs [13,15]

boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

Hangs

Port GHC's test suite into shake

The current implementation of GHCVM is fairly unoptimised. Before pursuing optimisations, it'd be nice to have a set of test suites that discover any breakages along the way. A good way to quickly get a test suite would be to re-use GHC's, but they use Makefiles. To keep the building/testing/benchmarking cross-platform, we should port those Makefiles to shake scripts.

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.