Code Monkey home page Code Monkey logo

Comments (25)

MaxGraey avatar MaxGraey commented on May 22, 2024 2

Also you can overload operators that not support in TS/JS:

class Point {
    x: f64;
    y: f64;

    constructor(x: f64, y: f64) {
        this.x = x;
        this.y = y;
    }

    @operator('+')
    add(point: Point): Point {
        return new Point(this.x + point.x, this.y + point.y);
    }
}

var p1 = new Point(100, 100);
var p2 = new Point(100, 100);
var result = p1 + p2;

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024 1

@dcodeIO That helps a great deal and just after I wrote the above I found a ticket related to

import "allocator/tlsf"

Thank you for providing so much information. I have enough to keep me busy for a while I think. I attempted to do some work on the Kotlin Native project around the implementation of their JS / Dom interop for WASM but they seemed uninterested (closed my ticket without saying a word) even though I solved an issue they didn't believe they had... anyway you are already a million times more helpful already. Thank you.
Kind Regards
/W

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

To support working with classes as you would in TS it is necessary to support instance creation with the new keyword. The current implementation of new, if working at all, is unfinished and simply allocates a region of memory for the instantiated class instance to utilize (see). A memory allocator must be included in the project for this to work, i.e. through import "allocator/tlsf"; in the entry file. Since garbage collection isn't yet implemented, its memory also isn't automatically deallocated but at this point requires manually 'free'ing it with free_memory(changetype<usize>(classInstance)).

Additionally, some details haven't been implemented or sufficiently tested, yet. The implements keyword, interfaces in general or abstract methods are not implemented. These will require indirect function calls on fields that store the respective implementing function's table index. The extends keyword is somewhat implemented but hasn't been extensively tested when it comes to specializing (overriding) existing fields or their types.

Interally, memory allocators and standard library implementations use a special sort of unmanaged classes (see). One can think of them as structs with methods, basically a lower level form of classes without automatic memory management, but these don't support some things a C struct does, for example static inclusion of other struct-like elements because all structures in AssemblyScript are referenced and not passed by value. Hence, these implementations use some tricks to mimic the behaviour by managing offsets manually (see).

In short, full class support still requires some sort of GC, maybe some sort of finalizers (think arrays that also have to deallocate their backing memory), posssibly some sort of classId stored alongside each instance (think instanceof checks) and compiler-level support of virtual members by utilizing the function table.

Hope this helps :)

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024

The following works just fine:
WASM Side

import "allocator/arena";
export { allocate_memory, free_memory };

namespace console {
    export declare function log(int: f64): void;
}

class Point {
    x: f64;
    y: f64;
    constructor(x: f64, y: f64) {
        this.x = x;
        this.y = y;
    }
    add(point: Point): Point {
        return new Point(this.x + point.x, this.y + point.y);
    }
}

var _point = new Point(100, 100);
console.log(_point.x);

var _newPoint = new Point(100, 100);
var result = _point.add(_newPoint);

console.log(result.x);

JS Side

function main(){
    /** Fetch the .wasm */
    fetch("/webgl.wasm").then(response => response.arrayBuffer()).then(binary => {
        /** Instantiate the module */
        let module = new WebAssembly.Module(binary);
        window.instance = new WebAssembly.Instance(module, {
            console: {
                log: function(value){
                    console.log(value);
                }
            }
        });
    }).catch(err => { console.log(err); })
}

result
image

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

Here, using the arena allocator also has the potential to work around some of the current limitations in that it provides a reset_memory function that can be called to reset the entire memory to its initial state so one doesn't have to free manually. Special care must be taken where globals might still reference something afterwards. It simply just accumulates things and throws them all away at once. Use cases are somewhat limited of course because it might not always be applicable depending on the application, but it's also the smallest and fastest allocator for the same reasons. You probably know that already, just pinning it here so others can find it as well :)

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024

Excellent, good tip thanks. I updated the example above (I just got that from the TS By Example site.. I don't actually write TypeScript on a regular basis my interest is in exploring WASM from a higher level language than the C's / Rust etc. I do use Kotlin daily which is why I found that project interesting but TS is fine, the concepts are all the same.... I'm primarily interested in playing with JS / DOM interop related to WebGL... I understand the limitations regarding access to the dom and the need for proxying using ints to reference JS side objects...

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024

That is very helpful! What about overloaded constructors? I found the TS implementation a bit limiting.

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

Syntactially those things walk on a thin line between staying compatible to TS and implementing what's necessary. Method overloading (if that's applicable here as well) is something that can be done in TS, but somewhat limited to falling back to the dynamic nature of JS through utilizing definitions for JS code or using union types. At this point in time my feeling is that we shouldn't split too much from TS and rather leave it up to the developer to find appropriate alternatives, syntax-wise. Here, this might be a single common, possibly private, constructor with multiple static createXY methods using it in different ways. But super should be supported, if it isn't broken.

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024

@dcodeIO I can totally appreciate and respect that... I forked Assembly Script with a view to adding some dom interop based on the work I started on the Kotlin Native project (which they weren't interested in).. I get the feeling that you guys would be receptive to this kind of thing... Like I said my primary interest is WebGL but if I'm going to do dom interop I may as well deal with the whole thing... Most of my initial work / prototyping will be around WebGL however :-)

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

Sure, go ahead. Just note that host-bindings and reference types have the potential to change the interop game entirely. There's this old parser test with my initial thoughts.

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024

@dcodeIO .. nice thanks. Who knows how long it will take for host-bindings to make it to the dev channel release builds for the four major browsers... I'm very curious to know how WASM performs now, even if there is a JS step in-between. @MaxGraey I tried your operator overloading and I'm sorry to report that it doesn't appear to be working. It compiles and runs but returns the original value. I've added the example with both a direct call to add and the operator overload example to my fork in examples/jsinterop
https://github.com/WolfieWerewolf/assemblyscript

from assemblyscript.

MaxGraey avatar MaxGraey commented on May 22, 2024

@dcodeIO It seems operator overloading working only for specific values yet.

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

Yeah, operator overloading is largely unfinished. I believe indexed get/set on arrays is the only thing that is somewhat checked.

from assemblyscript.

MaxGraey avatar MaxGraey commented on May 22, 2024

@WolfieWerewolf
Try this:

@operator("+")
static add(a: Point, b: Point): Point {
   ...
}

PS Nope, this doesn't work as well unfortunately

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024

@MaxGraey thanks... that panics V8 in some cool ways but doesn't compile unfortunately.

@operator("+")
    static add(point: Point): Point {
        return new Point(this.x + point.x, this.y + point.y);
    }

compiles but also doesn't work... Now I'm curious so I will see if I can find where you defined this...

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

https://github.com/AssemblyScript/assemblyscript/blob/master/src/compiler.ts#L2771 :)

from assemblyscript.

MaxGraey avatar MaxGraey commented on May 22, 2024

@WolfieWerewolf
Actually you write different.

static add(point: Point): Point

Istead

static add(a: Point, b: Point): Point

But nevermind this non-workable in current stage

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

Operator overloads for + and == should be implemented for binary expressions now. Overloads must be static methods. Not a lot of sanity checking going on yet, so make sure parameters are correct. Example 1, 2, Test

from assemblyscript.

WolfieWerewolf avatar WolfieWerewolf commented on May 22, 2024

@dcodeIO this is great! I really only expressed interest in this because @MaxGraey mentioned it. I'll have more time over the weekend to review this but you can be sure that I will.

from assemblyscript.

trusktr avatar trusktr commented on May 22, 2024

full class support still requires some sort of GC

Why is that? Why not just have a something like a destroy method that users can define, which can free stuff, and finally behind the scene free the class? I think being able to control memory is the nice part about AS Wasm. :)

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

We've settled for ARC meanwhile. Took a while to get right. Instead of destroy, there is a traversal mechanism now that integrates with the runtime by iterating all reference-typed children of a class with custom memory management. Array, Set and Map use this for example, and "normal" classes use minimal compiler-generated code. This makes AS a fully garbage collected language with a mechanism somewhat similar to Swift's. Of course everyone is free to include their own stdlib classes and use this mechanism (makes the most sense for collection-like classes).

from assemblyscript.

trusktr avatar trusktr commented on May 22, 2024

Wow, That's some serious stuff. Amazing.

How does that affect runtime behavior? Is it GC'ing continuously? Or in chunks, like JS?

One thing I'm interested in is, as far as Wasm, the possibility that even if we're running in Wasm without much performance benefit for the use case, that we may still be able to have consistent predictable behavior (in contrast to JS causing pauses every second due to GC pauses).

How does AS GC compare to JS GC?

from assemblyscript.

dcodeIO avatar dcodeIO commented on May 22, 2024

How does that affect runtime behavior? Is it GC'ing continuously? Or in chunks, like JS?

The mechanism used here is described in this paper, with modifications to what the compiler considers inherently acyclic objects, explained a bit in the readme of that repo.

My expectation is that ARC will be relatively predictable in that it does most of its work concurrently with the program, on assignments and exiting scopes, with most objects being known to be inherently acyclic due to static evaluation the compiler performs, but to know for sure we'll need some real world testing. Future interface could have a gc.collect, gc.pause and gc.resume or something to give a user more control (currently one has to call __collect manually to collect cycles). The compiler could technically even emit diagnostics to hint a programmer on possibly cyclic objects so these could be avoided altogether.

from assemblyscript.

trusktr avatar trusktr commented on May 22, 2024

concurrently with the program, on assignments and exiting scopes

Nice.

from assemblyscript.

John-Oldman-Wang avatar John-Oldman-Wang commented on May 22, 2024

how to compiler it

from assemblyscript.

Related Issues (20)

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.