Skip to content

Releases: dfinity/motoko

0.8.5

20 Mar 15:47
5fc5632
Compare
Choose a tag to compare
  • motoko (moc)

    • Performance improvement: Values of variant type that are compile-time known
      are relegated to the static heap now and don't get allocated each time (#3878).

    • bugfix: the global timer expiration callback was called unnecessarily in the
      default mechanism (#3883).

0.8.4

11 Mar 13:42
9f9ea33
Compare
Choose a tag to compare
  • motoko (moc)

    • Performance improvement: UTF-8 coding and validation is now properly tail recursive (#3842).

    • Performance improvement: eliminated bounds checking for certain array accesses (thanks to nomeata) (#3853).

    • Performance improvement: optimized {array, blob, text}.size() operations (thanks to nomeata) (#3863).

    • Performance improvement: efficient tuple results in switch statements (thanks to nomeata) (#3865).

    • Performance improvement: more efficient untagging operation (#3873).

    • bugfix: restored a grammar regression caused by let-else (#3869).

  • motoko-base

0.8.3

24 Feb 16:39
73330dd
Compare
Choose a tag to compare
  • motoko (moc)

    • new 'let-else' construct for handling pattern-match failure (#3836).
      This is a frequently asked-for feature that allows to change the control-flow
      of programs when pattern-match failure occurs, thus providing a means against
      the famous "pyramid of doom" issue. A common example is look-ups:

      shared func getUser(user : Text) : async Id {
        let ?id = Map.get(users, user) else { throw Error.reject("no such user") };
        id
      }

      Similarly, an expression like

      (label v : Bool { let <pat> = <exp> else break v false; true })

      evaluates to a Bool, signifying whether <pat> matches <exp>.

    • Improve recursive deserialization capacity to match recursive serialization capacity by reducing
      Wasm stack consumption (#3809).
      Because of the bounds on recursion depth imposed by fixed-size stack, the
      advice remains the same: avoid deeply nested recursive data structures.
      Think "shallow trees good, very long lists bad".

    • bugfix: stack overflow in UTF-8 encode/decode for moc.js (#3825).

  • motoko-base

    • add missing unshare : Tree<K, V> -> () method to class RBTree<K, V>
      to restore objects from saved state (dfinity/motoko-base#532).

0.8.2

17 Feb 11:23
a7fc031
Compare
Choose a tag to compare
  • motoko (moc)

    • Add compiler flag --rts-stack-pages <n> to override default number of
      pages dedicated to fixed runtime system stack. Now defaults to 32 pages
      (2MiB) (up from previous 2 pages/128KiB) (#3782).
      In emergencies, increasing this setting may improve your ability to deserialize
      deeply nested Candid or stable variable data.

    • Add stack overflow detection utilising reserved page (#3793).

    • Performance improvement: heap allocator speedup (#3090, #3790).

    • bugfix: avoid more heap-out-bounds errors during deserialization of stable variables
      by increasing default runtime system stack from 128KiB to 2MiB (#3782).
      Note: this is a partial fix, as issues with stack growth remain.

  • motoko-base

0.8.1

03 Feb 20:23
a0f6958
Compare
Choose a tag to compare
  • motoko (moc)

    • Performance improvement: faster heap allocation (#3765).

    • bugfix: async returns involving abbreviated tuple types no longer crash the compiler (#3740, #3741).

    • bugfix: avoid quadratic code expansion due to imported, but unused, actor classes (#3758).

0.8.0

01 Feb 02:32
766abbf
Compare
Choose a tag to compare
  • motoko (moc)

    • BREAKING CHANGE

      Motoko now implements Candid 1.4 (dfinity/candid#311).

      In particular, when deserializing an actor or function reference,
      Motoko will now first check that the type of the deserialized reference
      is a subtype of the expected type and act accordingly.

      Very few users should be affected by this change in behaviour.

    • BREAKING CHANGE

      Failure to send a message no longer traps but, instead, throws a catchable Error with new error code #call_error (#3630).

      On the IC, the act of making a call to a canister function can fail, so that the call cannot (and will not be) performed.
      This can happen due to a lack of canister resources, typically because the local message queue for the destination canister is full,
      or because performing the call would reduce the current cycle balance of the calling canister to a level below its freezing threshold.
      Such call failures are now reported by throwing an Error with new ErrorCode #call_error { err_code = n },
      where n is the non-zero err_code value returned by the IC.
      Like other errors, call errors can be caught and handled using try ... catch ... expressions, if desired.

      The constructs that now throw call errors, instead of trapping as with previous version of Motoko are:

      • calls to shared functions (including oneway functions that return ()).
        These involve sending a message to another canister, and can fail when the queue for the destination canister is full.
      • calls to local functions with return type async. These involve sending a message to self, and can fail when the local queue for sends to self is full.
      • async expressions. These involve sending a message to self, and can fail when the local queue for sends to self is full.
      • await expressions. These can fail on awaiting an already completed future, which requires sending a message to self to suspend and commit state.

      (On the other hand, async* (being delayed) cannot throw, and evaluating await* will at most propagate an error from its argument but not, in itself, throw.)

      Note that exiting a function call via an uncaught throw, rather than a trap, will commit any state changes and currently queued messages.
      The previous behaviour of trapping would, instead, discard, such changes.

      To appreciate the change in semantics, consider the following example:

      actor {
        var count = 0;
        public func inc() : async () {
          count += 1;
        };
        public func repeat() : async () {
          loop {
            ignore inc();
          }
        };
        public func repeatUntil() : async () {
          try {
            loop {
             ignore inc();
            }
          } catch (e) {
          }
        };
      }

      In previous releases of Motoko, calling repeat() and repeatUntil() would trap, leaving count at 0, because
      each infinite loop would eventually exhaust the message queue and issue a trap, rolling back the effects of each call.
      With this release of Motoko, calling repeat() will enqueue several inc() messages (around 500), then throw an Error
      and exit with the error result, incrementing the count several times (asynchronously).
      Calling repeatUntil() will also enqueue several inc() messages (around 500) but the error is caught so the call returns,
      still incrementing count several times (asynchronously).

      The previous semantics of trapping on call errors can be enabled with compiler option --trap-on-call-error, if desired,
      or selectively emulated by forcing a trap (e.g. assert false) when an error is caught.

      For example,

        public func allOrNothing() : async () {
          try {
            loop {
             ignore inc();
            }
          } catch (e) {
            assert false; // trap!
          }
        };

      Calling allOrNothing() will not send any messages: the loop exits with an error on queue full,
      the error is caught, but assert false traps so all queued inc() messages are aborted.

    • bugfix: system method inspect involving message with single tuple argument no longer crashes the compiler (#3732, #3733).

0.7.6

20 Jan 17:10
c6d1af0
Compare
Choose a tag to compare
  • motoko (moc)

    • Added support for ManagementCanister.raw_rand in interpreters (#3693).

    • Added preliminary Viper support for old expressions in specifications and calls to private methods (#3675).

    • bugfix: in the default timer mechanism cancelTimer sometimes wouldn't actually stop a recurring timer (#3695).

    • bugfix: zero negation for floating point numbers in compiled code (#3676).

  • motoko-base

0.7.5

23 Dec 21:52
1c2f749
Compare
Choose a tag to compare
  • motoko (moc)

    • Add new primitives for a default timer mechanism (#3542). These are

      setTimer : (delayNanos : Nat64, recurring : Bool, job : () -> async ()) -> (id : Nat)
      cancelTimer : (id : Nat) -> ()

      By defining a system func timer the default mechanism can now be overridden by a custom
      implementation. Additionally by supplying the command-line flag -no-timer all aspects
      of timers can be suppressed, e.g. for space- or security-sensitive purposes, thus effectively
      reverting canisters to the pre-timers era.

    • bugfix: silence bogus cascading errors in stable compatibility check (#3645).

0.7.4

07 Dec 15:56
857b878
Compare
Choose a tag to compare
  • motoko (moc)

    • Add new keywords async* and await* (note the *) for efficient abstraction of asynchronous code (#3609).

        <typ> ::= ...
          async* <typ>             delayed, asynchronous computation
        <exp> ::= ...
          async* <block-or-exp>    delay an asynchronous computation
          await* <block-or-exp>    execute a delayed computation (only in async, async*)
      

      This avoids the resource consumption and latency of async/await by only committing state and suspending execution
      when necessary in the await*-ed computation, not necessarily at the await* itself.

      WARNING: Unlike async/await:

      • an async* value has no effect unless await*-ed;
      • each await* of the same async* value repeats its effects.

      This feature is experimental and may evolve in future. Use with discretion.
      See the manual for details.

    • Suppress GC during IC canister_heartbeat, deferring any GC to the scheduled Motoko heartbeat system method (#3623).
      This is a temporary workaround, to be removed once DTS is supported for canister_heartbeat itself (#3622).

    • Add a new generational GC, enabled with new moc flag --generational-gc (#3495).
      The generational garbage collector optimizes for fast reclamation of short-lived objects.
      New objects are allocated in a young generation that is more frequently collected than the older objects
      that have already survived a GC run.

      For many cases, the generational GC is more efficient than the existing compacting GC and copying GCs:

      • Lower runtimes: Less number of executed instructions on average.
      • Shorter interruptions: Young generation collection entails shorter program interruptions.

      To activate the generational GC under dfx, the following command-line argument needs to be specified in dfx.json:

      ...
        "type" : "motoko"
        ...
        "args" : "--generational-gc"
      ...
      
    • moc.js : add trampoline and step limiter to interpreter, avoiding (some) stackoverflows and
      hangs (#3618, #3541).
      Enables execution of larger examples on web pages.

    • BREAKING CHANGE (Minor):

      Consider records with mutable fields as non-static (#3586).
      Consequently, an imported library declaring a mutable record is now
      rejected, not accepted, to be consistent with the declarations of
      mutable fields and mutable objects.

    • Experimental Viper integration by compiling a very narrow subset of
      Motoko to the verification intermediate language. See src/viper/README.md
      and the PR for details. (#3477).

  • motoko-base

0.7.3

01 Nov 14:13
7704993
Compare
Choose a tag to compare
  • motoko (moc)

    • Statically reject shared functions and function types with type parameters (#3519, #3522).

    • Performance improvement: Array.init and Array.tabulate (#3526).

  • motoko-base