Bigint function error

I remember Joachim talking about “unbound integers” that can’t overflow. Does this concept also apply on Arrays? When trying to populate an Array this way:

import Iter "mo:stdlib/iter";
import Debug "mo:stdlib/debug";
import Array "mo:stdlib/array";

actor universe {
    type cell = { #dead; #alive};
    type universe = {
                     var width : Nat;
                     var height : Nat;
                     var cells : [var cell];
                     };
 
    let universe : universe ={
        var width : Nat = 0;
        var height : Nat = 0;
        var cells : [var cell] = [var]  };

    public func populate(width : Nat, height : Nat): async (){
        universe.width := width;
        universe.height := height;
        universe.cells := Array.tabulateVar<cell>(width*height,func(index: Nat){
            if ((index % 2 == 0) or (index % 7 == 0)){
                #alive
            }else{
                #dead
            }
        } );        
    };
};

Calling canister call my_canister populate '(10000000,10000000)' leads to the following error:
Client error (code 5): IC0503: Canister ic:9E70563D976354BCD8 trapped explicitly: bigint function error
@enzo @nomeata

5 Likes

From the docurmentation:

The following limitations apply for IDL arguments:

  • No support for type annotations.
  • No support for Bignum.

Although I’m not sure where a Nat becomes Bignum as there is bounded Nat64 and the documentation states that Nat is of arbitrary precision. The size of the array should be within Nat64 boundaries.

2 Likes

Still investigating this…

2 Likes

I’ve got a slightly simpler repro case:

import Array "mo:stdlib/array"
actor Example {
  public func example(n : Nat, m : Nat) {
    let _ = Array.init<Bool>(n * m, false);
  }
}
3 Likes

Any progress on this?
I came across another problem and will crosslink here as it’s kind of related.

2 Likes

I think the problem here is that you are just allocating an extremely large array, although the error suggests otherwise. Athough Nat is unbounded, there are physical limits to the size of an array that we shouid document if we don’t already.

I’m filing an internal issue so a developer takes a look at it.

Sorry for the delay and thanks for the report.

Claudio

3 Likes

Or maybe the real problem is that dfx doesn’t or didn’t support passing (bignum) Nats as arguments?

2 Likes

Can you elaborate on where those boundaries come from? Is this something related to WASM? I think one team member stated that dfinity uses 32bit WASM, with this i should be able to access 4gb of memory, right?

1 Like

Sorry for the delay.

Although we use Nats to index arrays, the maximum array length is 2^32. The code in that example was attempting to allocate an array with (10000000^2) > (2^32) items so failed. The error is reasonable, but cryptic and we are improving it for a future release.
Note that allocating an array of length 2^32 would also fail as it will exhaust memory.

FTR, the current Motoko GC only gives you access to roughly 2GB of the WASM address space, though we have plans to up that in future.

4 Likes

Thanks for the reply! Are there any plans dfinity will document this kind of „behind the scenes“ stuff? Great work on motoko btw :slight_smile:

1 Like