1. 27 Nov, 2018 1 commit
    • Yorick Peterse's avatar
      Improve remapping of initialised type parameters · 8450931d
      Yorick Peterse authored
      This improves the compiler's support for remapping type parameters to
      the appropriate type parameter instance. For example, consider type T
      that has type parameter A initialised to type parameter B, and B is
      initialised to C. Previously, when looking up the instance of A the
      compiler would produce B. As of this commit, the compiler would produce
      type C instead. This removes the need for type annotations in various
      cases, most notably when working with iterators.
      
      Fixes #117
      8450931d
  2. 26 Nov, 2018 1 commit
  3. 25 Nov, 2018 7 commits
  4. 23 Nov, 2018 1 commit
  5. 22 Nov, 2018 1 commit
  6. 21 Nov, 2018 5 commits
    • Yorick Peterse's avatar
      Remove uninitialised params from return types · d95a357c
      Yorick Peterse authored
      This changes the compiler so that type parameters that map to
      uninitialised type parameters have their instances removed. For type
      `Thing!(A -> B)` this means that the mapping of A to B is removed if B
      is an uninitialised type parameter.
      
      This change ensures that the compiler can better handle HashMap literals
      and other types that may not initialise all type parameters. This in
      turn ensures that code such as the following no longer errors:
      
          let x: HashMap!(String, String) = %[]
      
      Previously this would error because `%[]` was inferred has
      `HashMap!(Hash + Equal, V)`, and that type can not safely substitute
      `Hashmap!(String, String)`. With this change, `%[]` is basically
      inferred as `HashMap!(?, ?)`, allowing the compiler to then infer it
      into `HashMap!(String, String)`.
      d95a357c
    • Yorick Peterse's avatar
      8cd6b796
    • Yorick Peterse's avatar
      Don't use caching for the rustfmt job · 0da7f2e1
      Yorick Peterse authored
      This job doesn't need any cache, so this should reduce the job time by
      not having to download an existing cache.
      0da7f2e1
    • Yorick Peterse's avatar
      Fix caching of Ruby dependencies in CI · afa7ef9a
      Yorick Peterse authored
      afa7ef9a
    • Yorick Peterse's avatar
      Use custom Docker images for all builds · 5700a30e
      Yorick Peterse authored
      These Docker images are built automatically, removing the need for
      installing various dependencies on the fly. This in turn should reduce
      build timings a bit, depending on the number of dependencies necessary
      per build.
      5700a30e
  7. 13 Nov, 2018 2 commits
  8. 10 Nov, 2018 1 commit
  9. 09 Nov, 2018 1 commit
    • Yorick Peterse's avatar
      Fix race condition in ObjectPointer::status() · 93bbd5ee
      Yorick Peterse authored
      When promoting or evacuating an object, `ObjectPointer::status()` would
      only return Promote/Evacuate for the first caller, returning OK for all
      following calls. This could lead to a race condition where multiple
      threads try to process a pointer to the same object that has to be
      moved. In this case, one thread would win, and the other one(s) would
      lose. All threads that lose would then simply mark the object and move
      on, without resolving a forwarding pointer produced by the winning
      thread. This could then lead to pointers being used that still point to
      moved objects.
      
      To resolve this, `ObjectPointer::status()` now returns a "PendingMove"
      status whenever a thread witnesses an object that has to be moved but is
      already being moved by another thread. As long as this status is
      observed, the pointer is rescheduled for marking. This allows the thread
      to continue marking other objects, instead of having to spin for an
      undetermined amount of time.
      
      Fixes #148
      93bbd5ee
  10. 08 Nov, 2018 1 commit
  11. 07 Nov, 2018 2 commits
    • Yorick Peterse's avatar
      Use seconds instead of milliseconds for timeouts · 21b0ab04
      Yorick Peterse authored
      This ensures that we use seconds (a SI base unit) for timeouts and
      intervals in both the runtime and the VM. This means that in order to
      suspend a process for one second, you now write this:
      
          process.suspend(1)
          process.suspend(1.0) # also valid
      
      Instead of this:
      
          process.suspend(1000)
      
      Fixes #152
      21b0ab04
    • Yorick Peterse's avatar
      Cache the vm/target directory in CI · bd47576b
      Yorick Peterse authored
      This should reduce the time spent compiling the same crates between
      pipelines.
      bd47576b
  12. 06 Nov, 2018 1 commit
    • Yorick Peterse's avatar
      Move interpreter code out of the main loop · e2b5bff5
      Yorick Peterse authored
      A lot of code that used to reside directly in the interpreter loop now
      resides in separate modules and functions. This makes it a bit easier to
      maintain the code, as well as making it easier for a future JIT of sorts
      to reuse this code.
      
      Not all instructions have had their logic moved to separate functions.
      Typically, if an instruction modifies the instruction pointer its logic
      remains in the interpreter loop.
      e2b5bff5
  13. 30 Oct, 2018 4 commits
    • Yorick Peterse's avatar
      Update AppVeyor testing for libffi-sys 0.6.3 · e3e60171
      Yorick Peterse authored
      This updates the AppVeyor testing setup to support testing of libffi
      code using libffi-sys 0.6.3 or newer, which supports MSYS2.
      e3e60171
    • Yorick Peterse's avatar
      Fixed passing of excessive arguments · 2f57fa4c
      Yorick Peterse authored
      When passing a single argument to a rest argument, the rest argument
      would be set directly to the given value, not an array of it. This
      commit fixes the logic for passing excessive arguments to ensure the
      rest argument is always an array, regardless of the number of passed
      arguments.
      2f57fa4c
    • Yorick Peterse's avatar
      Stop using statically linked musl for tests · 51efd3a5
      Yorick Peterse authored
      When musl is statically linked, it doesn't support the use of dlopen().
      This would prevent the use of the `std::ffi` module for musl builds.
      Instead we'll use the default linkage, which is dynamic. This does mean
      that we can no longer provide statically linked musl builds for
      development environments, but this is better than not being able to
      provide support for `std::ffi`.
      51efd3a5
    • Yorick Peterse's avatar
      Add a Foreign Function Interface for C code · 26f535fe
      Yorick Peterse authored
      This commit adds support for a basic Foreign Function Interface to C.
      This interface allows Inko code to dynamically load C libraries, obtain
      pointers to variables, and call functions. Data types are automatically
      converted whenever possible. Passing arbitrary Inko objects to C is not
      possible, as otherwise the garbage collector could release memory of
      objects still in use by C code.
      26f535fe
  14. 26 Oct, 2018 1 commit
  15. 22 Oct, 2018 1 commit
    • Yorick Peterse's avatar
      Improve support for pinning processes · 850824b3
      Yorick Peterse authored
      When pinning a process to an OS thread, we now also prevent the
      corresponding Worker from executing any other processes. This still
      allows a process to be suspended (e.g. for garbage collection), while
      preventing another process from running on the OS thread. This makes
      `std::process.pinned` more useful for interacting with thread-local
      storage in C.
      
      Because the new approach results in an OS thread only processing a
      single process (= the process that was pinned), `std::process.pinned`
      should be used carefully.
      
      Fixes #150
      850824b3
  16. 11 Oct, 2018 1 commit
    • Yorick Peterse's avatar
      Rework handling of prototypes of built-in types · f39ce802
      Yorick Peterse authored
      This reworks how the prototypes of built-in types, such as ByteArray,
      are handled. Prior to this commit, various built-in types would use
      Object as their prototype, followed by the runtime correcting this. This
      required the use of `std::reflection` in various places, which would add
      unnecessary runtime overhead.
      
      Supporting FFI was also made more complicated in this setup. For
      example, in the FFI API a Pointer should be an instance of
      `std::pointer::Pointer`, but the VM has no built-in knowledge of this
      type, meaning it had to use Object as the prototype. This then required
      the FFI runtime code to fix the prototype every time a Pointer was
      created. This complicates the code, and in certain places requires
      different approaches to fix the prototype.
      
      In this commit, we make sure that all built-in types have a dedicated
      prototype in the VM. We also merge the various GetFooPrototype
      instructions into a single GetBuiltinPrototype instruction, reducing the
      number of instructions necessary. The compiler still exposes separate
      virtual instructions, though this is mostly to keep the prototype IDs
      out of the runtime.
      
      == Setting object names
      
      This new setup requires that for a few more types we get the prototype
      and set the object name manually. To make this easier, the compiler now
      supports the virtual instruction `set_object_name`. This allows modules
      to set the correct object name, without having to use the
      `@_object_name` instance attribute directly. This in turn means this
      attribute is now only used in two places:
      
      1. In the compiler, where it belongs.
      2. In `std::mirror`, in order to obtain the name of the object.
      
      == DefaultHasher is now in a separate module
      
      The DefaultHasher type used to reside in `std::hash_map`, but this
      didn't make much sense since it's not tied into the `HashMap` type. With
      the various prototype changes being made I decided that now was a good
      time to move `DefaultHasher` to its own module: `std::hasher`. In the
      future this module might provide hashers using other algorithms, but for
      now it only defines the `DefaultHasher` type.
      f39ce802
  17. 08 Oct, 2018 5 commits
    • Yorick Peterse's avatar
      The Platform instruction now returns a string · c1c8f5db
      Yorick Peterse authored
      The "Platform" VM instruction now returns a string, instead of an
      integer. This string contains the name of the underlying platform, such
      as "windows", "linux", or "unix" for a generic Unix (like) system. This
      simplifies the runtime, while being able to detect more platforms. This
      in turn can be useful when binding to C using the upcoming FFI API.
      c1c8f5db
    • Yorick Peterse's avatar
      Move std::vm.panic to std::process · 77fbe37d
      Yorick Peterse authored
      Since panics are scoped to processes, it doesn't make sense to keep this
      method in the std::vm module.
      
      Fixes #147
      77fbe37d
    • Yorick Peterse's avatar
      Reduce moving of threads in std::stdio · 96c362b1
      Yorick Peterse authored
      The modules std::stdio::stderr and std::stdio::stdout use
      `process.blocking` to perform blocking operations in a separate thread
      pool. The `print` method of both modules would make two separate calls
      to `write_string`, resulting in the process being moved across pools
      twice. By wrapping both `write_string` calls in a `process.blocking`
      block, we ensure we only move the process around once.
      96c362b1
    • Yorick Peterse's avatar
      Simplify setting the default thread counts · 1a6e4b41
      Yorick Peterse authored
      This changes the default configuration so that all thread pools default
      to using a number of threads equal to the number of logical CPU cores,
      instead of using different values for different pools. IVM threads tend
      to consume rather little memory. For garbage collection this can also
      result in better performance, compared to using a default of 2 threads.
      1a6e4b41
    • Yorick Peterse's avatar
      Supported nested calls to process.blocking · 3d15c20e
      Yorick Peterse authored
      This fixes `std::process.blocking` so it supports nested calls, similar
      to the recently introduced method `std::process.pinned`.
      
      Fixes #128
      3d15c20e
  18. 07 Oct, 2018 2 commits
    • Yorick Peterse's avatar
      Expose thread pinning to the runtime · b79e9e8d
      Yorick Peterse authored
      The method `process.pinned` can be used to run a block while pinning the
      process to the current OS thread, unpinning automatically once the block
      returns.
      b79e9e8d
    • Yorick Peterse's avatar
      Pinning of processes to threads · faf02ea7
      Yorick Peterse authored
      This commits adds the ability to pin a process to a particular OS thread
      in a thread pool. This is useful for the FFI, as certain C functions or
      data structures require to be run on a specific thread. For example,
      libc's "errno" variable uses thread-local storage. This means that if we
      want to run a function that uses it and read "errno", we _have_ to
      ensure both operations are performed on the same thread.
      
      To support this, each Pool structure now has a Worker structure, which
      stores the thread ID of that worker. This ID can then be stored in a
      process, allowing the scheduler to determine which worker should run the
      process.
      
      == Process pinning
      
      Pinned processes can not be moved across pools, so the MoveToPool
      instruction becomes a noop for a pinned process. We can not panic in
      this case, as this would prevent pinned processes from using methods
      that try to move a process to the secondary pool.
      faf02ea7
  19. 06 Oct, 2018 2 commits