AssemblyScript & WebGL (Available on WebRepo)

Hi All,

WebRepo Download Link

Building on my recent JavaScript project, I’ve been working toward my main goal of having access to a bare WebGL API.

Though this could simply be done in JavaScript, WebAssembly provides some performance benefits. This is where AssemblyScript comes in; it’s a TypeScript-like language that compiles to WebAssembly and even better still the compiler can run entirely within a browser environment!

The WebGL AS project is a work-in-progress and currently only serves as a proof of concept & example of more advanced usage of the AssemblyScript Codea library.

Here are a few demos of the API in action:

Simple script

local webview = WebView()
local asc = ASCompiler()

-- Compile a simple script
local bin = asc:compile([[
    export function main(): u32 {
        print("[demo_simple] Hello Codea!");
        return 5;
    }
]])
print("[demo_simple] compiled")
    
-- Load it into the webview
local module = bin:load(webview)
    
-- Call the exported main() function
print("[demo_simple] returned: " .. module:call("main"))

Multiple sources

local webview = WebView()
local asc = ASCompiler()

-- Sources
local src_lib1 = ASSource(
    'lib1',                             -- Source name
    "export const DEMO_VAL: u32 = 32;"  -- Source
)
    
local src_lib2 = ASSource('lib2', [[
    export function Times4(val: u32): u32 {
        return val * 4;
    }
]])
    
local src_main = ASSource('main', [[
    import { DEMO_VAL } from 'lib1';
    import { Times4 } from 'lib2';
    
    export function main(): u32 {
        return Times4(DEMO_VAL);
    }
]],
nil, -- No imports
{ src_lib1, src_lib2 }) -- 2 dependencies
    
-- Compile a the main script
local bin = asc:compile(src_main)
print("[demo_multi_source] compiled")
    
-- Load it into the webview
local module = bin:load(webview)
    
-- Call the exported main() function
print("[demo_multi_source] returned: " .. module:call("main"))

Imports

local webview = WebView()
local asc = ASCompiler()

-- Source
local src_main = ASSource('main', [[
    declare function getLuaVersion(): string;
    declare const LUA_VERSION: string;
    declare const IMPORT_VAL: u32;
    
    export function main(): void {
        print(`[demo_imports] Lua: ${getLuaVersion()}`);
        print(`[demo_imports] Imported val: ${IMPORT_VAL}`);
        print(`[demo_imports] Lua string: ${LUA_VERSION}`);
    }
]],
{
    -- Imports, these map values declared in AssemblyScript
    -- to values provided by JavaScript.
    --
    -- These can provide functions
    ["getLuaVersion(): string"] = [[
        () => codea.lua_version // Read JS imported value
    ]],
        
    -- Or values directly
    ["IMPORT_VAL: u32"] = 970932,
        
    -- String values are NOT currently supported
    -- and will always evaluate to 'undefined'
    ["LUA_VERSION: string"] = "codea.lua_version"
})
    
-- Import the Lua version into JS
webview:import("codea", {
    lua_version = _VERSION
})
    
-- Compile a the main script
local bin = asc:compile(src_main)
print("[demo_imports] compiled")
    
-- Load it into the webview
local module = bin:load(webview)
    
-- Call the exported main() function
module:call("main")

Pioneering work, extended the application scenario of Codea, I just can learn on Codea WebAssembly, thank you for the basic tools?

When I tried the AssemblyScript, I got this:

[AS] String imports are not supported! Import: 'LUA_VERSION'

Is it correct?

@binaryblues Yep, that’s totally intended :smile:

If you check the comment in the Main tab on line 153, it mentions that passing a string directly via a variable import is NOT supported. It’s just a demonstration to show that. In cases where you want to make a string available, import a function instead to just return the value (shown on line 146).

It’s due to the order things are initialised, we can’t convert a JS string into an AssemblyScript string until after imports are processed. I have ideas of how it could be done but it’s not currently a priority as there’s a workaround.

I see. Thank you for explaining that. It looks like I need to learn more about wasm.