More model resource work

This commit is contained in:
Dirk Baeumer
2024-04-22 20:46:20 +02:00
parent 22abcbc98a
commit 807ecbaa34
12 changed files with 367 additions and 380 deletions

View File

@ -1,59 +0,0 @@
// Generated by `wit-bindgen` 0.21.0. DO NOT EDIT!
#include "calculator.h"
__attribute__((__weak__, __export_name__("cabi_realloc")))
void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
(void) old_size;
if (new_size == 0) return (void*) align;
void *ret = realloc(ptr, new_size);
if (!ret) abort();
return ret;
}
// Helper Functions
__attribute__((__import_module__("vscode:example/types"), __import_name__("[resource-drop]machine")))
extern void __wasm_import_exports_vscode_example_types_machine_drop(int32_t handle);
void exports_vscode_example_types_machine_drop_own(exports_vscode_example_types_own_machine_t handle) {
__wasm_import_exports_vscode_example_types_machine_drop(handle.__handle);
}
__attribute__(( __import_module__("[export]vscode:example/types"), __import_name__("[resource-new]machine")))
extern int32_t __wasm_import_exports_vscode_example_types_machine_new(int32_t);
__attribute__((__import_module__("[export]vscode:example/types"), __import_name__("[resource-rep]machine")))
extern int32_t __wasm_import_exports_vscode_example_types_machine_rep(int32_t);
exports_vscode_example_types_own_machine_t exports_vscode_example_types_machine_new(exports_vscode_example_types_machine_t *rep) {
return (exports_vscode_example_types_own_machine_t) { __wasm_import_exports_vscode_example_types_machine_new((int32_t) rep) };
}
exports_vscode_example_types_machine_t* exports_vscode_example_types_machine_rep(exports_vscode_example_types_own_machine_t handle) {
return (exports_vscode_example_types_machine_t*) __wasm_import_exports_vscode_example_types_machine_rep(handle.__handle);
}
__attribute__((__export_name__("vscode:example/types#[dtor]machine")))
void __wasm_export_exports_vscode_example_types_machine_dtor(exports_vscode_example_types_machine_t* arg) {
exports_vscode_example_types_machine_destructor(arg);
}
// Component Adapters
__attribute__((__export_name__("vscode:example/types#[constructor]machine")))
int32_t __wasm_export_exports_vscode_example_types_constructor_machine(int32_t arg, int32_t arg0, int32_t arg1) {
exports_vscode_example_types_own_machine_t ret = exports_vscode_example_types_constructor_machine((uint32_t) (arg), (uint32_t) (arg0), arg1);
return (ret).__handle;
}
__attribute__((__export_name__("vscode:example/types#[method]machine.execute")))
int32_t __wasm_export_exports_vscode_example_types_method_machine_execute(int32_t arg) {
uint32_t ret = exports_vscode_example_types_method_machine_execute(((exports_vscode_example_types_machine_t*) arg));
return (int32_t) (ret);
}
extern void __component_type_object_force_link_calculator(void);
void __component_type_object_force_link_calculator_public_use_in_this_compilation_unit(void) {
__component_type_object_force_link_calculator();
}

View File

@ -1,43 +0,0 @@
// Generated by `wit-bindgen` 0.21.0. DO NOT EDIT!
#ifndef __BINDINGS_CALCULATOR_H
#define __BINDINGS_CALCULATOR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
typedef uint8_t exports_vscode_example_types_operation_t;
#define EXPORTS_VSCODE_EXAMPLE_TYPES_OPERATION_ADD 0
#define EXPORTS_VSCODE_EXAMPLE_TYPES_OPERATION_SUB 1
#define EXPORTS_VSCODE_EXAMPLE_TYPES_OPERATION_MUL 2
#define EXPORTS_VSCODE_EXAMPLE_TYPES_OPERATION_DIV 3
typedef struct exports_vscode_example_types_own_machine_t {
int32_t __handle;
} exports_vscode_example_types_own_machine_t;
typedef struct exports_vscode_example_types_machine_t exports_vscode_example_types_machine_t;
typedef exports_vscode_example_types_machine_t* exports_vscode_example_types_borrow_machine_t;
// Exported Functions from `vscode:example/types`
exports_vscode_example_types_own_machine_t exports_vscode_example_types_constructor_machine(uint32_t left, uint32_t right, exports_vscode_example_types_operation_t operation);
uint32_t exports_vscode_example_types_method_machine_execute(exports_vscode_example_types_borrow_machine_t self);
// Helper Functions
extern void exports_vscode_example_types_machine_drop_own(exports_vscode_example_types_own_machine_t handle);
extern exports_vscode_example_types_own_machine_t exports_vscode_example_types_machine_new(exports_vscode_example_types_machine_t *rep);
extern exports_vscode_example_types_machine_t* exports_vscode_example_types_machine_rep(exports_vscode_example_types_own_machine_t handle);
void exports_vscode_example_types_machine_destructor(exports_vscode_example_types_machine_t *rep);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,15 +1,15 @@
{
"name": "wasm-component-model",
"name": "wasm-component-model-resource",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wasm-component-model",
"name": "wasm-component-model-resource",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@vscode/wasm-component-model": "0.1.0-pre.3"
"@vscode/wasm-component-model": "0.1.0-pre.4"
},
"devDependencies": {
"@types/node": "^18.14.6",
@ -794,9 +794,9 @@
"dev": true
},
"node_modules/@vscode/wasm-component-model": {
"version": "0.1.0-pre.3",
"resolved": "https://registry.npmjs.org/@vscode/wasm-component-model/-/wasm-component-model-0.1.0-pre.3.tgz",
"integrity": "sha512-1QgbcblhfBD3crZswJ3JchlwXvVSyYrxNMvVRxEkhjmW9LXYiOXFLT+iyc7yk95LSgYVWDrE5g4CRD2dXmB3sg==",
"version": "0.1.0-pre.4",
"resolved": "https://registry.npmjs.org/@vscode/wasm-component-model/-/wasm-component-model-0.1.0-pre.4.tgz",
"integrity": "sha512-HQmolFWr3cwvAY9jOX1J/OoGNJDT9lM/JpuAJplKOY4qcRZiyTVDFLkTp/kRExITz1su/7ERIYcG3QajrKSw8A==",
"dependencies": {
"semver": "^7.6.0",
"uuid": "^9.0.1",

View File

@ -29,7 +29,7 @@
]
},
"dependencies": {
"@vscode/wasm-component-model": "0.1.0-pre.3"
"@vscode/wasm-component-model": "0.1.0-pre.4"
},
"devDependencies": {
"@types/vscode": "1.88.0",

View File

@ -60,22 +60,22 @@ pub mod exports {
#[derive(Debug)]
#[repr(transparent)]
pub struct Machine{
handle: _rt::Resource<Machine>,
pub struct Engine{
handle: _rt::Resource<Engine>,
}
type _MachineRep<T> = Option<T>;
type _EngineRep<T> = Option<T>;
impl Machine{
impl Engine{
/// Creates a new resource from the specified representation.
///
/// This function will create a new resource handle by moving `val` onto
/// the heap and then passing that heap pointer to the component model to
/// create a handle. The owned handle is then returned as `Machine`.
pub fn new<T: GuestMachine>(val: T) -> Self {
/// create a handle. The owned handle is then returned as `Engine`.
pub fn new<T: GuestEngine>(val: T) -> Self {
Self::type_guard::<T>();
let val: _MachineRep<T> = Some(val);
let ptr: *mut _MachineRep<T> =
let val: _EngineRep<T> = Some(val);
let ptr: *mut _EngineRep<T> =
_rt::Box::into_raw(_rt::Box::new(val));
unsafe {
Self::from_handle(T::_resource_new(ptr.cast()))
@ -83,20 +83,20 @@ pub mod exports {
}
/// Gets access to the underlying `T` which represents this resource.
pub fn get<T: GuestMachine>(&self) -> &T {
pub fn get<T: GuestEngine>(&self) -> &T {
let ptr = unsafe { &*self.as_ptr::<T>() };
ptr.as_ref().unwrap()
}
/// Gets mutable access to the underlying `T` which represents this
/// resource.
pub fn get_mut<T: GuestMachine>(&mut self) -> &mut T {
pub fn get_mut<T: GuestEngine>(&mut self) -> &mut T {
let ptr = unsafe { &mut *self.as_ptr::<T>() };
ptr.as_mut().unwrap()
}
/// Consumes this resource and returns the underlying `T`.
pub fn into_inner<T: GuestMachine>(self) -> T {
pub fn into_inner<T: GuestEngine>(self) -> T {
let ptr = unsafe { &mut *self.as_ptr::<T>() };
ptr.take().unwrap()
}
@ -118,7 +118,7 @@ pub mod exports {
_rt::Resource::handle(&self.handle)
}
// It's theoretically possible to implement the `GuestMachine` trait twice
// It's theoretically possible to implement the `GuestEngine` trait twice
// so guard against using it with two different types here.
#[doc(hidden)]
fn type_guard<T: 'static>() {
@ -137,25 +137,25 @@ pub mod exports {
#[doc(hidden)]
pub unsafe fn dtor<T: 'static>(handle: *mut u8) {
Self::type_guard::<T>();
let _ = _rt::Box::from_raw(handle as *mut _MachineRep<T>);
let _ = _rt::Box::from_raw(handle as *mut _EngineRep<T>);
}
fn as_ptr<T: GuestMachine>(&self) -> *mut _MachineRep<T> {
Machine::type_guard::<T>();
fn as_ptr<T: GuestEngine>(&self) -> *mut _EngineRep<T> {
Engine::type_guard::<T>();
T::_resource_rep(self.handle()).cast()
}
}
/// A borrowed version of [`Machine`] which represents a borrowed value
/// A borrowed version of [`Engine`] which represents a borrowed value
/// with the lifetime `'a`.
#[derive(Debug)]
#[repr(transparent)]
pub struct MachineBorrow<'a> {
pub struct EngineBorrow<'a> {
rep: *mut u8,
_marker: core::marker::PhantomData<&'a Machine>,
_marker: core::marker::PhantomData<&'a Engine>,
}
impl<'a> MachineBorrow<'a>{
impl<'a> EngineBorrow<'a>{
#[doc(hidden)]
pub unsafe fn lift(rep: usize) -> Self {
Self {
@ -165,7 +165,7 @@ pub mod exports {
}
/// Gets access to the underlying `T` in this resource.
pub fn get<T: GuestMachine>(&self) -> &T {
pub fn get<T: GuestEngine>(&self) -> &T {
let ptr = unsafe { &mut *self.as_ptr::<T>() };
ptr.as_ref().unwrap()
}
@ -173,14 +173,14 @@ pub mod exports {
// NB: mutable access is not allowed due to the component model allowing
// multiple borrows of the same resource.
fn as_ptr<T: 'static>(&self) -> *mut _MachineRep<T> {
Machine::type_guard::<T>();
fn as_ptr<T: 'static>(&self) -> *mut _EngineRep<T> {
Engine::type_guard::<T>();
self.rep.cast()
}
}
unsafe impl _rt::WasmResource for Machine{
unsafe impl _rt::WasmResource for Engine{
#[inline]
unsafe fn drop(_handle: u32) {
#[cfg(not(target_arch = "wasm32"))]
@ -190,7 +190,7 @@ pub mod exports {
{
#[link(wasm_import_module = "[export]vscode:example/types")]
extern "C" {
#[link_name = "[resource-drop]machine"]
#[link_name = "[resource-drop]engine"]
fn drop(_: u32);
}
@ -201,100 +201,120 @@ pub mod exports {
#[doc(hidden)]
#[allow(non_snake_case)]
pub unsafe fn _export_constructor_machine_cabi<T: GuestMachine>(arg0: i32,arg1: i32,arg2: i32,) -> i32 {#[cfg(target_arch="wasm32")]
_rt::run_ctors_once();let result0 = Machine::new(T::new(arg0 as u32, arg1 as u32, Operation::_lift(arg2 as u8)));
pub unsafe fn _export_constructor_engine_cabi<T: GuestEngine>() -> i32 {#[cfg(target_arch="wasm32")]
_rt::run_ctors_once();let result0 = Engine::new(T::new());
(result0).take_handle() as i32
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub unsafe fn _export_method_machine_execute_cabi<T: GuestMachine>(arg0: *mut u8,) -> i32 {#[cfg(target_arch="wasm32")]
_rt::run_ctors_once();let result0 = T::execute(MachineBorrow::lift(arg0 as u32 as usize).get());
_rt::as_i32(result0)
}
pub trait Guest {
type Machine: GuestMachine;
}
pub trait GuestMachine: 'static {
#[doc(hidden)]
unsafe fn _resource_new(val: *mut u8) -> u32
where Self: Sized
{
#[cfg(not(target_arch = "wasm32"))]
{
let _ = val;
unreachable!();
}
#[cfg(target_arch = "wasm32")]
{
#[link(wasm_import_module = "[export]vscode:example/types")]
extern "C" {
#[link_name = "[resource-new]machine"]
fn new(_: *mut u8) -> u32;
}
new(val)
}
}
#[doc(hidden)]
fn _resource_rep(handle: u32) -> *mut u8
where Self: Sized
{
#[cfg(not(target_arch = "wasm32"))]
{
let _ = handle;
unreachable!();
}
#[cfg(target_arch = "wasm32")]
{
#[link(wasm_import_module = "[export]vscode:example/types")]
extern "C" {
#[link_name = "[resource-rep]machine"]
fn rep(_: u32) -> *mut u8;
}
unsafe {
rep(handle)
}
}
}
fn new(left: u32,right: u32,operation: Operation,) -> Self;
fn execute(&self,) -> u32;
pub unsafe fn _export_method_engine_push_operand_cabi<T: GuestEngine>(arg0: *mut u8,arg1: i32,) {#[cfg(target_arch="wasm32")]
_rt::run_ctors_once();T::push_operand(EngineBorrow::lift(arg0 as u32 as usize).get(), arg1 as u32);
}
#[doc(hidden)]
macro_rules! __export_vscode_example_types_cabi{
($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = {
#[export_name = "vscode:example/types#[constructor]machine"]
unsafe extern "C" fn export_constructor_machine(arg0: i32,arg1: i32,arg2: i32,) -> i32 {
$($path_to_types)*::_export_constructor_machine_cabi::<<$ty as $($path_to_types)*::Guest>::Machine>(arg0, arg1, arg2)
}
#[export_name = "vscode:example/types#[method]machine.execute"]
unsafe extern "C" fn export_method_machine_execute(arg0: *mut u8,) -> i32 {
$($path_to_types)*::_export_method_machine_execute_cabi::<<$ty as $($path_to_types)*::Guest>::Machine>(arg0)
}
const _: () = {
#[doc(hidden)]
#[export_name = "vscode:example/types#[dtor]machine"]
#[allow(non_snake_case)]
unsafe extern "C" fn dtor(rep: *mut u8) {
$($path_to_types)*::Machine::dtor::<
<$ty as $($path_to_types)*::Guest>::Machine
>(rep)
}
};
};);
}
#[doc(hidden)]
pub(crate) use __export_vscode_example_types_cabi;
#[allow(non_snake_case)]
pub unsafe fn _export_method_engine_push_operation_cabi<T: GuestEngine>(arg0: *mut u8,arg1: i32,) {#[cfg(target_arch="wasm32")]
_rt::run_ctors_once();T::push_operation(EngineBorrow::lift(arg0 as u32 as usize).get(), Operation::_lift(arg1 as u8));
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub unsafe fn _export_method_engine_execute_cabi<T: GuestEngine>(arg0: *mut u8,) -> i32 {#[cfg(target_arch="wasm32")]
_rt::run_ctors_once();let result0 = T::execute(EngineBorrow::lift(arg0 as u32 as usize).get());
_rt::as_i32(result0)
}
pub trait Guest {
type Engine: GuestEngine;
}
pub trait GuestEngine: 'static {
#[doc(hidden)]
unsafe fn _resource_new(val: *mut u8) -> u32
where Self: Sized
{
#[cfg(not(target_arch = "wasm32"))]
{
let _ = val;
unreachable!();
}
#[cfg(target_arch = "wasm32")]
{
#[link(wasm_import_module = "[export]vscode:example/types")]
extern "C" {
#[link_name = "[resource-new]engine"]
fn new(_: *mut u8) -> u32;
}
new(val)
}
}
#[doc(hidden)]
fn _resource_rep(handle: u32) -> *mut u8
where Self: Sized
{
#[cfg(not(target_arch = "wasm32"))]
{
let _ = handle;
unreachable!();
}
#[cfg(target_arch = "wasm32")]
{
#[link(wasm_import_module = "[export]vscode:example/types")]
extern "C" {
#[link_name = "[resource-rep]engine"]
fn rep(_: u32) -> *mut u8;
}
unsafe {
rep(handle)
}
}
}
fn new() -> Self;
fn push_operand(&self,operand: u32,);
fn push_operation(&self,operation: Operation,);
fn execute(&self,) -> u32;
}
#[doc(hidden)]
macro_rules! __export_vscode_example_types_cabi{
($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = {
#[export_name = "vscode:example/types#[constructor]engine"]
unsafe extern "C" fn export_constructor_engine() -> i32 {
$($path_to_types)*::_export_constructor_engine_cabi::<<$ty as $($path_to_types)*::Guest>::Engine>()
}
#[export_name = "vscode:example/types#[method]engine.push-operand"]
unsafe extern "C" fn export_method_engine_push_operand(arg0: *mut u8,arg1: i32,) {
$($path_to_types)*::_export_method_engine_push_operand_cabi::<<$ty as $($path_to_types)*::Guest>::Engine>(arg0, arg1)
}
#[export_name = "vscode:example/types#[method]engine.push-operation"]
unsafe extern "C" fn export_method_engine_push_operation(arg0: *mut u8,arg1: i32,) {
$($path_to_types)*::_export_method_engine_push_operation_cabi::<<$ty as $($path_to_types)*::Guest>::Engine>(arg0, arg1)
}
#[export_name = "vscode:example/types#[method]engine.execute"]
unsafe extern "C" fn export_method_engine_execute(arg0: *mut u8,) -> i32 {
$($path_to_types)*::_export_method_engine_execute_cabi::<<$ty as $($path_to_types)*::Guest>::Engine>(arg0)
}
const _: () = {
#[doc(hidden)]
#[export_name = "vscode:example/types#[dtor]engine"]
#[allow(non_snake_case)]
unsafe extern "C" fn dtor(rep: *mut u8) {
$($path_to_types)*::Engine::dtor::<
<$ty as $($path_to_types)*::Guest>::Engine
>(rep)
}
};
};);
}
#[doc(hidden)]
pub(crate) use __export_vscode_example_types_cabi;
}
}
}
@ -505,15 +525,16 @@ pub(crate) use __export_calculator_impl as export;
#[cfg(target_arch = "wasm32")]
#[link_section = "component-type:wit-bindgen:0.24.0:calculator:encoded world"]
#[doc(hidden)]
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 338] = *b"\
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xd1\x01\x01A\x02\x01\
A\x02\x01B\x09\x01m\x04\x03add\x03sub\x03mul\x03div\x04\0\x09operation\x03\0\0\x04\
\0\x07machine\x03\x01\x01i\x02\x01@\x03\x04lefty\x05righty\x09operation\x01\0\x03\
\x04\0\x14[constructor]machine\x01\x04\x01h\x02\x01@\x01\x04self\x05\0y\x04\0\x17\
[method]machine.execute\x01\x06\x04\x01\x14vscode:example/types\x05\0\x04\x01\x19\
vscode:example/calculator\x04\0\x0b\x10\x01\0\x0acalculator\x03\0\0\0G\x09produc\
ers\x01\x0cprocessed-by\x02\x0dwit-component\x070.202.0\x10wit-bindgen-rust\x060\
.24.0";
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 419] = *b"\
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xa2\x02\x01A\x02\x01\
A\x02\x01B\x0d\x01m\x04\x03add\x03sub\x03mul\x03div\x04\0\x09operation\x03\0\0\x04\
\0\x06engine\x03\x01\x01i\x02\x01@\0\0\x03\x04\0\x13[constructor]engine\x01\x04\x01\
h\x02\x01@\x02\x04self\x05\x07operandy\x01\0\x04\0\x1b[method]engine.push-operan\
d\x01\x06\x01@\x02\x04self\x05\x09operation\x01\x01\0\x04\0\x1d[method]engine.pu\
sh-operation\x01\x07\x01@\x01\x04self\x05\0y\x04\0\x16[method]engine.execute\x01\
\x08\x04\x01\x14vscode:example/types\x05\0\x04\x01\x19vscode:example/calculator\x04\
\0\x0b\x10\x01\0\x0acalculator\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0d\
wit-component\x070.202.0\x10wit-bindgen-rust\x060.24.0";
#[inline(never)]
#[doc(hidden)]

View File

@ -14,26 +14,28 @@ export namespace example {
div = 'div'
}
export namespace Machine {
export interface Interface {
$handle?: $wcm.ResourceHandle;
$drop?(): void;
export namespace Engine {
export interface Interface extends $wcm.JInterface {
pushOperand(operand: u32): void;
pushOperation(operation: Operation): void;
execute(): u32;
}
export type Statics = {
};
export type Class = Statics & {
new(left: u32, right: u32, operation: Operation): Interface;
new(): Interface;
};
}
export type Machine = Machine.Interface;
export type Engine = Engine.Interface;
}
export type Types = {
Machine: Types.Machine.Class;
Engine: Types.Engine.Class;
};
export namespace calculator {
export type Imports = {
foo: () => u32;
};
export type Exports = {
types: example.Types;
@ -44,91 +46,140 @@ export namespace example {
export namespace example {
export namespace Types.$ {
export const Operation = new $wcm.EnumType<example.Types.Operation>(['add', 'sub', 'mul', 'div']);
export const Machine = new $wcm.ResourceType<example.Types.Machine>('machine', 'vscode:example/types/machine');
export const Machine_Handle = new $wcm.ResourceHandleType('machine');
Machine.addDestructor('$drop', new $wcm.DestructorType('[resource-drop]machine', [['inst', Machine]]));
Machine.addConstructor('constructor', new $wcm.ConstructorType<example.Types.Machine.Class['constructor']>('[constructor]machine', [
['left', $wcm.u32],
['right', $wcm.u32],
export const Engine = new $wcm.ResourceType<example.Types.Engine>('engine', 'vscode:example/types/engine');
export const Engine_Handle = new $wcm.ResourceHandleType('engine');
Engine.addDestructor('$drop', new $wcm.DestructorType('[resource-drop]engine', [['inst', Engine]]));
Engine.addConstructor('constructor', new $wcm.ConstructorType<example.Types.Engine.Class['constructor']>('[constructor]engine', [], new $wcm.OwnType(Engine_Handle)));
Engine.addMethod('pushOperand', new $wcm.MethodType<example.Types.Engine.Interface['pushOperand']>('[method]engine.push-operand', [
['operand', $wcm.u32],
], undefined));
Engine.addMethod('pushOperation', new $wcm.MethodType<example.Types.Engine.Interface['pushOperation']>('[method]engine.push-operation', [
['operation', Operation],
], new $wcm.OwnType(Machine_Handle)));
Machine.addMethod('execute', new $wcm.MethodType<example.Types.Machine.Interface['execute']>('[method]machine.execute', [], $wcm.u32));
], undefined));
Engine.addMethod('execute', new $wcm.MethodType<example.Types.Engine.Interface['execute']>('[method]engine.execute', [], $wcm.u32));
}
export namespace Types._ {
export const id = 'vscode:example/types' as const;
export const witName = 'types' as const;
export const types: Map<string, $wcm.GenericComponentModelType> = new Map<string, $wcm.GenericComponentModelType>([
['Operation', $.Operation],
['Machine', $.Machine]
]);
export const resources: Map<string, $wcm.ResourceType> = new Map<string, $wcm.ResourceType>([
['Machine', $.Machine]
]);
export namespace Machine {
export namespace Engine {
export type WasmInterface = {
'[constructor]machine': (left: i32, right: i32, operation_Operation: i32) => i32;
'[method]machine.execute': (self: i32) => i32;
'[resource-drop]machine': (self: i32) => void;
'[constructor]engine': () => i32;
'[method]engine.push-operand': (self: i32, operand: i32) => void;
'[method]engine.push-operation': (self: i32, operation_Operation: i32) => void;
'[method]engine.execute': (self: i32) => i32;
};
type ObjectModule = {
constructor(left: u32, right: u32, operation: Operation): own<$wcm.ResourceHandle>;
$drop(self: Machine): void;
execute(self: Machine): u32;
export type ObjectModule = {
constructor(): own<$wcm.ResourceHandle>;
pushOperand(self: Engine, operand: u32): void;
pushOperation(self: Engine, operation: Operation): void;
execute(self: Engine): u32;
};
class Impl extends $wcm.Resource implements example.Types.Machine.Interface {
private readonly _om: ObjectModule;
constructor(left: u32, right: u32, operation: Operation, om: ObjectModule) {
super();
this._om = om;
this.$handle = om.constructor(left, right, operation);
export namespace imports {
export type WasmInterface = Engine.WasmInterface & { '[resource-drop]engine': (self: i32) => void };
}
export namespace exports {
export type WasmInterface = Engine.WasmInterface & { '[dtor]engine': (self: i32) => void };
class Impl extends $wcm.Resource implements example.Types.Engine.Interface {
private readonly _om: ObjectModule;
constructor(om: ObjectModule);
constructor(handleTag: Symbol, handle: $wcm.ResourceHandle, om: ObjectModule);
constructor(...args: any[]);
constructor(...args: any[]) {
if (args[0] === $wcm.ResourceManager.handleTag) {
super(args[1] as $wcm.ResourceHandle);
this._om = args[2] as ObjectModule;
} else {
const om = args[0] as ObjectModule;
super(om.constructor());
this._om = om;
}
}
public pushOperand(operand: u32): void {
return this._om.pushOperand(this, operand);
}
public pushOperation(operation: Operation): void {
return this._om.pushOperation(this, operation);
}
public execute(): u32 {
return this._om.execute(this);
}
}
public $drop(): void {
return this._om.$drop(this);
}
public execute(): u32 {
return this._om.execute(this);
export function Class(wasmInterface: WasmInterface, context: $wcm.WasmContext): example.Types.Engine.Class {
const resource = example.Types.$.Engine;
const om: ObjectModule = $wcm.Module.createObjectModule(resource, wasmInterface, context);
const rm: $wcm.ResourceManager = context.resources.ensure('vscode:example/types/engine');
return class extends Impl {
constructor();
constructor(handleTag: Symbol, handle: $wcm.ResourceHandle);
constructor(...args: any[]) {
super(...args, om);
rm.registerProxy(this);
}
};
}
}
export function Class(wasmInterface: WasmInterface, context: $wcm.WasmContext): example.Types.Machine.Class {
const resource = example.Types.$.Machine;
const om: ObjectModule = $wcm.Module.createObjectModule(resource, wasmInterface, context);
return class extends Impl {
constructor(left: u32, right: u32, operation: Operation) {
super(left, right, operation, om);
}
}
export const types: Map<string, $wcm.GenericComponentModelType> = new Map<string, $wcm.GenericComponentModelType>([
['Operation', $.Operation],
['Engine', $.Engine]
]);
export const resources: Map<string, { resource: $wcm.ResourceType; factory: $wcm.ClassFactory<any>}> = new Map<string, { resource: $wcm.ResourceType; factory: $wcm.ClassFactory<any>}>([
['Engine', { resource: $.Engine, factory: Engine.exports.Class }]
]);
export type WasmInterface = {
};
export namespace imports {
export type WasmInterface = _.WasmInterface & Engine.imports.WasmInterface;
}
export namespace exports {
export type WasmInterface = _.WasmInterface & Engine.exports.WasmInterface;
export namespace imports {
export type WasmInterface = {
'[resource-new]engine': (rep: i32) => i32;
'[resource-rep]engine': (handle: i32) => i32;
'[resource-drop]engine': (handle: i32) => i32;
};
}
}
export type WasmInterface = {
} & Machine.WasmInterface;
export function createImports(service: example.Types, context: $wcm.WasmContext): WasmInterface {
return $wcm.Imports.create<WasmInterface>(undefined, resources, service, context);
}
export function filterExports(exports: object, context: $wcm.WasmContext): WasmInterface {
return $wcm.Exports.filter<WasmInterface>(exports, undefined, resources, id, undefined, context);
}
export function bindExports(wasmInterface: WasmInterface, context: $wcm.WasmContext): example.Types {
return $wcm.Exports.bind<example.Types>(undefined, [['Machine', $.Machine, Machine.Class]], wasmInterface, context);
}
}
export namespace calculator.$ {
export namespace Imports {
export const foo = new $wcm.FunctionType<calculator.Imports['foo']>('foo', [], $wcm.u32);
}
}
export namespace calculator._ {
export const id = 'vscode:example/calculator' as const;
export const witName = 'calculator' as const;
export const Imports = {};
export type Imports = {};
export namespace Exports {
export type $Root = {
'foo': () => i32;
};
export type Imports = {
'[export]vscode:example/types': example.Types._.exports.imports.WasmInterface;
};
export namespace imports {
export const functions: Map<string, $wcm.FunctionType> = new Map([
['foo', $.Imports.foo]
]);
export function create(service: calculator.Imports, context: $wcm.WasmContext): Imports {
return $wcm.Imports.create<Imports>(_, service, context);
}
export function loop(service: calculator.Imports, context: $wcm.WasmContext): calculator.Imports {
return $wcm.Imports.loop(_, service, context);
}
}
export type Exports = {
'vscode:example/types#[constructor]engine': () => i32;
'vscode:example/types#[method]engine.push-operand': (self: i32, operand: i32) => void;
'vscode:example/types#[method]engine.push-operation': (self: i32, operation_Operation: i32) => void;
'vscode:example/types#[method]engine.execute': (self: i32) => i32;
};
export namespace exports {
export const interfaces: Map<string, $wcm.InterfaceType> = new Map<string, $wcm.InterfaceType>([
['Types', Types._]
]);
}
export type Exports = {
};
export function bindExports(exports: Exports, context: $wcm.WasmContext): calculator.Exports {
const result: calculator.Exports = Object.create(null);
result.types = example.Types._.bindExports(example.Types._.filterExports(exports, context), context);
return result;
export function bind(exports: Exports, context: $wcm.WasmContext): calculator.Exports {
return $wcm.Exports.bind<calculator.Exports>(_, exports, context);
}
}
}
}

View File

@ -27,37 +27,21 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
const wasmContext: WasmContext.Default = new WasmContext.Default();
// Instantiate the module and create the necessary imports from the service implementation
const instance = await WebAssembly.instantiate(module, {
'[export]vscode:example/types' : {
'[resource-drop]machine': (...args: any[]) => {
console.log(args);
},
'[resource-new]machine': (...args: any[]) => {
console.log(args);
return args[0];
}
}
});
const instance = await WebAssembly.instantiate(module, calculator._.imports.create({ foo: () => 20 }, wasmContext));
// Bind the WASM memory to the context
wasmContext.initialize(new Memory.Default(instance.exports));
// Bind the JavaScript Api
const api = calculator._.bindExports(instance.exports as calculator._.Exports, wasmContext);
const api = calculator._.exports.bind(instance.exports as calculator._.Exports, wasmContext);
context.subscriptions.push(vscode.commands.registerCommand('vscode-samples.wasm-component-model.run', () => {
channel.show();
channel.appendLine('Running calculator example');
const add = new api.types.Machine(1, 2, Types.Operation.add);
channel.appendLine(`Add ${add.execute()}`);
const sub = new api.types.Machine(10, 8, Types.Operation.sub);
channel.appendLine(`Sub ${sub.execute()}`);
const mul = new api.types.Machine(3, 7, Types.Operation.mul);
channel.appendLine(`Mul ${mul.execute()}`);
const div = new api.types.Machine(10, 2, Types.Operation.div);
channel.appendLine(`Div ${div.execute()}`);
// add.$drop!();
// sub.$drop!();
// mul.$drop!();
// div.$drop!();
const calculator = new api.types.Engine();
calculator.pushOperand(10);
calculator.pushOperand(20);
calculator.pushOperation(Types.Operation.add);
const result = calculator.execute();
channel.appendLine(`Result: ${result}`);
}));
}

View File

@ -1,33 +1,102 @@
// Use a procedural macro to generate bindings for the world we specified in
// `host.wit`
wit_bindgen::generate!({
// the name of the world in the `*.wit` input file
world: "calculator",
});
// wit_bindgen::generate!({
// // the name of the world in the `*.wit` input file
// world: "calculator",
// });
use exports::vscode::example::types::Guest;
mod bindings;
use crate::exports::vscode::example::types::{ GuestEngine, Operation };
use std::cell::RefCell;
use crate::bindings::exports::vscode::example::types::{ Guest, GuestEngine, Operation };
enum StackElement {
Operand(u32),
Operation(Operation),
}
struct Stack {
values: Vec<StackElement>
}
impl Stack {
fn new() -> Self {
Stack {
values: Vec::new()
}
}
fn push_operand(&mut self, operand: u32) {
self.values.push(StackElement::Operand(operand));
}
fn push_operation(&mut self, operation: Operation) {
self.values.push(StackElement::Operation(operation));
}
fn execute(&mut self) -> u32 {
let mut result = 0;
let mut left = 0;
let mut right = 0;
let mut operation: &Operation = &Operation::Add;
self.values.reverse();
let iter = self.values.iter();
for element in iter {
match element {
StackElement::Operand(operand) => {
if left == 0 {
left = *operand;
} else {
right = *operand;
}
},
StackElement::Operation(op) => {
match operation {
Operation::Add => {
result = left + right;
},
Operation::Sub => {
result = left - right;
},
Operation::Mul => {
result = left * right;
},
Operation::Div => {
result = left / right;
},
}
operation = op;
}
}
}
self.values.clear();
return result;
}
}
struct CalcEngine {
left: u32,
right: u32,
operation: Operation,
stack: RefCell<Stack>,
}
impl GuestEngine for CalcEngine {
fn new(left: u32, right: u32, operation: Operation) -> Self {
Self { left, right, operation }
fn new() -> Self {
CalcEngine {
stack: RefCell::new(Stack::new())
}
}
fn push_operand(&self, operand: u32) {
self.stack.borrow_mut().push_operand(operand);
}
fn push_operation(&self,operation:Operation,) {
self.stack.borrow_mut().push_operation(operation);
}
fn execute(&self) -> u32 {
match self.operation {
Operation::Add => self.left + self.right,
Operation::Sub => self.left - self.right,
Operation::Mul => self.left * self.right,
Operation::Div => self.left / self.right,
}
return self.stack.borrow_mut().execute();
}
}
@ -36,4 +105,4 @@ impl Guest for Implementation {
type Engine = CalcEngine;
}
export!(Implementation);
bindings::export!(Implementation with_types_in bindings);

View File

@ -1,39 +0,0 @@
// Use a procedural macro to generate bindings for the world we specified in
// `host.wit`
wit_bindgen::generate!({
// the name of the world in the `*.wit` input file
world: "calculator",
});
use exports::vscode::example::types::Guest;
use crate::exports::vscode::example::types::{ GuestMachine, Operation };
struct CalcMachine {
left: u32,
right: u32,
operation: Operation,
}
impl GuestMachine for CalcMachine {
fn new(left: u32, right: u32, operation: Operation) -> Self {
Self { left, right, operation }
}
fn execute(&self) -> u32 {
match self.operation {
Operation::Add => self.left + self.right,
Operation::Sub => self.left - self.right,
Operation::Mul => self.left * self.right,
Operation::Div => self.left / self.right,
}
}
}
struct Implementation;
impl Guest for Implementation {
type Machine = CalcMachine;
}
export!(Implementation);

View File

@ -11,7 +11,9 @@ interface types {
}
resource engine {
constructor(left: u32, right: u32, operation: operation);
constructor();
push-operand: func(operand: u32);
push-operation: func(operation: operation);
execute: func() -> u32;
}
}

View File

@ -0,0 +1 @@
Some text.