Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/mono/wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,8 @@ Bumping Emscripten version involves these steps:
* update version number in docs
* update `Microsoft.NET.Runtime.Emscripten.<emscripten version>.Node.win-x64` package name, version and sha hash in https://github.com/dotnet/runtime/blob/main/eng/Version.Details.xml and in https://github.com/dotnet/runtime/blob/main/eng/Versions.props. the sha is the commit hash in https://github.com/dotnet/emsdk and the package version can be found at https://dev.azure.com/dnceng/public/_packaging?_a=feed&feed=dotnet6
* update packages in the workload manifest https://github.com/dotnet/runtime/blob/main/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in

## Code style
* Is enforced via [eslint](https://eslint.org/) and rules are in `./.eslintrc.js`
* You could check the style by running `npm run lint` in `src/mono/wasm/runtime` directory
* You can install [plugin into your VS Code](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) to show you the errors as you type
6 changes: 5 additions & 1 deletion src/mono/wasm/runtime/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ module.exports = {
"plugins": [
"@typescript-eslint"
],
"ignorePatterns": ["node_modules/**/*.*", "bin/**/*.*"],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-types": "off",
"indent": [
"error",
4,
{SwitchCase: 1}
{ SwitchCase: 1 }
],
"linebreak-style": [
"error",
Expand Down
11 changes: 6 additions & 5 deletions src/mono/wasm/runtime/buffers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import { JSHandle, MonoArray } from "./types";
import { JSHandle, MonoArray, MonoObject, MonoString } from "./types";
import { Module } from "./modules";
import { mono_wasm_get_jsobj_from_js_handle } from "./gc-handles";
import { wrap_error } from "./method-calls";
Expand Down Expand Up @@ -133,7 +133,7 @@ function typedarray_copy_from(typed_array: TypedArray, pinned_array: MonoArray,
}
}

export function mono_wasm_typed_array_copy_to(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr) {
export function mono_wasm_typed_array_copy_to(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr): MonoObject {
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (!js_obj) {
return wrap_error(is_exception, "ERR07: Invalid JS object handle '" + js_handle + "'");
Expand All @@ -144,13 +144,14 @@ export function mono_wasm_typed_array_copy_to(js_handle: JSHandle, pinned_array:
return _js_to_mono_obj(false, res);
}

export function mono_wasm_typed_array_from(pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, type: number, is_exception: Int32Ptr) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function mono_wasm_typed_array_from(pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, type: number, is_exception: Int32Ptr): MonoObject {
const res = typed_array_from(pinned_array, begin, end, bytes_per_element, type);
// returns JS typed array like Int8Array, to be wraped with JSObject proxy
return _js_to_mono_obj(true, res);
}

export function mono_wasm_typed_array_copy_from(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr) {
export function mono_wasm_typed_array_copy_from(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr): MonoObject | MonoString {
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (!js_obj) {
return wrap_error(is_exception, "ERR08: Invalid JS object handle '" + js_handle + "'");
Expand All @@ -161,7 +162,7 @@ export function mono_wasm_typed_array_copy_from(js_handle: JSHandle, pinned_arra
return _js_to_mono_obj(false, res);
}

export function has_backing_array_buffer(js_obj: any) {
export function has_backing_array_buffer(js_obj: TypedArray): boolean {
return typeof SharedArrayBuffer !== "undefined"
? js_obj.buffer instanceof ArrayBuffer || js_obj.buffer instanceof SharedArrayBuffer
: js_obj.buffer instanceof ArrayBuffer;
Expand Down
7 changes: 4 additions & 3 deletions src/mono/wasm/runtime/cancelable-promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@

import { mono_wasm_get_jsobj_from_js_handle } from "./gc-handles";
import { wrap_error } from "./method-calls";
import { JSHandle } from "./types";
import { JSHandle, MonoString } from "./types";

export const _are_promises_supported = ((typeof Promise === "object") || (typeof Promise === "function")) && (typeof Promise.resolve === "function");
const promise_control_symbol = Symbol.for("wasm promise_control");

export function isThenable(js_obj: any) {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function isThenable(js_obj: any): boolean {
// When using an external Promise library like Bluebird the Promise.resolve may not be sufficient
// to identify the object as a Promise.
return Promise.resolve(js_obj) === js_obj ||
((typeof js_obj === "object" || typeof js_obj === "function") && typeof js_obj.then === "function");
}

export function mono_wasm_cancel_promise(thenable_js_handle: JSHandle, is_exception: Int32Ptr) {
export function mono_wasm_cancel_promise(thenable_js_handle: JSHandle, is_exception: Int32Ptr): void | MonoString {
try {
const promise = mono_wasm_get_jsobj_from_js_handle(thenable_js_handle);
const promise_control = promise[promise_control_symbol];
Expand Down
15 changes: 5 additions & 10 deletions src/mono/wasm/runtime/corebindings.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import { JSHandle, GCHandle, MonoObject, t_RuntimeHelpers } from "./types";
import { JSHandle, GCHandle, MonoObject } from "./types";
import { ArgsMarshalString } from "./method-binding";
import { _create_primitive_converters } from "./method-binding";
import { PromiseControl } from "./cancelable-promise";
import { runtimeHelpers } from "./modules";

const fn_signatures: [jsname: string, csname: string, signature: ArgsMarshalString][] = [
["_get_cs_owned_object_by_js_handle", "GetCSOwnedObjectByJSHandle", "ii!"],
Expand Down Expand Up @@ -59,16 +59,11 @@ const wrapped_cs_functions: t_CSwraps = <any>{};
for (const sig of fn_signatures) {
const wf: any = wrapped_cs_functions;
// lazy init on first run
wf[sig[0]] = function () {
const fce = bind_runtime_method(sig[1], sig[2]);
wf[sig[0]] = function (...args: any[]) {
const fce = runtimeHelpers.bind_runtime_method(sig[1], sig[2]);
wf[sig[0]] = fce;
return fce.apply(undefined, arguments);
return fce(...args);
};
}

export default wrapped_cs_functions;

let bind_runtime_method: Function;
export function set_bind_runtime_method(method: Function) {
bind_runtime_method = method;
}
37 changes: 17 additions & 20 deletions src/mono/wasm/runtime/cs-to-js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { mono_wasm_new_root, WasmRoot } from "./roots";
import {
GCHandle, JSHandle, JSHandleDisposed, MonoArray,
GCHandle, JSHandleDisposed, MonoArray,
MonoArrayNull, MonoObject, MonoObjectNull, MonoString
} from "./types";
import { Module, runtimeHelpers } from "./modules";
Expand All @@ -19,7 +19,7 @@ const delegate_invoke_symbol = Symbol.for("wasm delegate_invoke");
const delegate_invoke_signature_symbol = Symbol.for("wasm delegate_invoke_signature");

// this is only used from Blazor
export function unbox_mono_obj(mono_obj: MonoObject) {
export function unbox_mono_obj(mono_obj: MonoObject): any {
if (mono_obj === MonoObjectNull)
return undefined;

Expand All @@ -38,7 +38,7 @@ function _unbox_cs_owned_root_as_js_object(root: WasmRoot<any>) {
return js_obj;
}

export function _unbox_mono_obj_root_with_known_nonprimitive_type(root: WasmRoot<any>, type: number) {
export function _unbox_mono_obj_root_with_known_nonprimitive_type(root: WasmRoot<any>, type: number): any {
if (root.value === undefined)
throw new Error(`Expected a root but got ${root}`);

Expand Down Expand Up @@ -70,14 +70,11 @@ export function _unbox_mono_obj_root_with_known_nonprimitive_type(root: WasmRoot
case 18:
throw new Error("Marshalling of primitive arrays are not supported. Use the corresponding TypedArray instead.");
case 20: // clr .NET DateTime
var dateValue = corebindings._get_date_value(root.value);
return new Date(dateValue);
return new Date(corebindings._get_date_value(root.value));
case 21: // clr .NET DateTimeOffset
var dateoffsetValue = corebindings._object_to_string(root.value);
return dateoffsetValue;
return corebindings._object_to_string(root.value);
case 22: // clr .NET Uri
var uriValue = corebindings._object_to_string(root.value);
return uriValue;
return corebindings._object_to_string(root.value);
case 23: // clr .NET SafeHandle/JSObject
return _unbox_cs_owned_root_as_js_object(root);
case 30:
Expand All @@ -87,7 +84,7 @@ export function _unbox_mono_obj_root_with_known_nonprimitive_type(root: WasmRoot
}
}

export function _unbox_mono_obj_root(root: WasmRoot<any>) {
export function _unbox_mono_obj_root(root: WasmRoot<any>): any {
if (root.value === 0)
return undefined;

Expand All @@ -110,7 +107,7 @@ export function _unbox_mono_obj_root(root: WasmRoot<any>) {
}
}

export function mono_array_to_js_array(mono_array: MonoArray) {
export function mono_array_to_js_array(mono_array: MonoArray): any[] | null {
if (mono_array === MonoArrayNull)
return null;

Expand All @@ -126,15 +123,15 @@ function is_nested_array(ele: MonoObject) {
return corebindings._is_simple_array(ele);
}

export function _mono_array_root_to_js_array(arrayRoot: WasmRoot<MonoArray>) {
export function _mono_array_root_to_js_array(arrayRoot: WasmRoot<MonoArray>): any[] | null {
if (arrayRoot.value === MonoArrayNull)
return null;

const elemRoot = mono_wasm_new_root<MonoObject>();

try {
const len = cwraps.mono_wasm_array_length(arrayRoot.value);
var res = new Array(len);
const res = new Array(len);
for (let i = 0; i < len; ++i) {
elemRoot.value = cwraps.mono_wasm_array_get(arrayRoot.value, i);

Expand All @@ -143,14 +140,13 @@ export function _mono_array_root_to_js_array(arrayRoot: WasmRoot<MonoArray>) {
else
res[i] = _unbox_mono_obj_root(elemRoot);
}
return res;
} finally {
elemRoot.release();
}

return res;
}

export function _wrap_delegate_root_as_function(root: WasmRoot<MonoObject>) {
export function _wrap_delegate_root_as_function(root: WasmRoot<MonoObject>): Function | null {
if (root.value === MonoObjectNull)
return null;

Expand All @@ -159,17 +155,17 @@ export function _wrap_delegate_root_as_function(root: WasmRoot<MonoObject>) {
return _wrap_delegate_gc_handle_as_function(gc_handle);
}

export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_listener_callback?: () => void) {
export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_listener_callback?: () => void): Function {
// see if we have js owned instance for this gc_handle already
let result = _lookup_js_owned_object(gc_handle);

// If the function for this gc_handle was already collected (or was never created)
if (!result) {
// note that we do not implement function/delegate roundtrip
result = function () {
result = function (...args: any[]) {
const delegateRoot = mono_wasm_new_root(get_js_owned_object_by_gc_handle(gc_handle));
try {
const res = call_method(result[delegate_invoke_symbol], delegateRoot.value, result[delegate_invoke_signature_symbol], arguments);
const res = call_method(result[delegate_invoke_symbol], delegateRoot.value, result[delegate_invoke_signature_symbol], args);
if (after_listener_callback) {
after_listener_callback();
}
Expand Down Expand Up @@ -210,7 +206,7 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_
return result;
}

export function mono_wasm_create_cs_owned_object(core_name: MonoString, args: MonoArray, is_exception: Int32Ptr) {
export function mono_wasm_create_cs_owned_object(core_name: MonoString, args: MonoArray, is_exception: Int32Ptr): MonoObject {
const argsRoot = mono_wasm_new_root(args), nameRoot = mono_wasm_new_root(core_name);
try {
const js_name = conv_string(nameRoot.value);
Expand All @@ -233,6 +229,7 @@ export function mono_wasm_create_cs_owned_object(core_name: MonoString, args: Mo
argsList[0] = constructor;
if (js_args)
argsList = argsList.concat(js_args);
// eslint-disable-next-line prefer-spread
const tempCtor = constructor.bind.apply(constructor, <any>argsList);
const js_obj = new tempCtor();
return js_obj;
Expand Down
4 changes: 2 additions & 2 deletions src/mono/wasm/runtime/cwraps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ const wrapped_c_functions: t_Cwraps = <any>{};
for (const sig of fn_signatures) {
const wf: any = wrapped_c_functions;
// lazy init on first run
wf[sig[0]] = function () {
wf[sig[0]] = function (...args: any[]) {
const fce = Module.cwrap(sig[0], sig[1], sig[2], sig[3]);
wf[sig[0]] = fce;
return fce.apply(undefined, arguments);
return fce(...args);
};
}

Expand Down
Loading