Skip to content

Commit 8eed715

Browse files
committed
Expand converter map
1 parent 72ecf73 commit 8eed715

File tree

3 files changed

+177
-141
lines changed

3 files changed

+177
-141
lines changed

lib/asbind-instance/bind-function.js

Lines changed: 5 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import {
2+
getAscToJsConverterForType,
3+
getJsToAscConverterForType
4+
} from "./type-converters";
5+
16
function getFunctionFromKeyPath(baseObject, keys) {
27
let result = baseObject;
38
for (const key of keys) {
@@ -6,146 +11,6 @@ function getFunctionFromKeyPath(baseObject, keys) {
611
return result;
712
}
813

9-
// Converts web platform names for the different ArrayBufferViews
10-
// to the names that ASC understands. Currently, that only means
11-
// to cut off the `Big` in `BigInt64Array`.
12-
const stdlibTypedArrayPrefix = "~lib/typedarray/";
13-
function normalizeArrayBufferViewTypeName(typeName) {
14-
// Don’t do anything if this is not a stdlib type.
15-
if (!typeName.startsWith(stdlibTypedArrayPrefix)) {
16-
return typeName;
17-
}
18-
typeName = typeName.slice(stdlibTypedArrayPrefix.length);
19-
if (typeName.startsWith("Big")) {
20-
// Slice off `Big` as the loader doesn’t have that prefix.
21-
typeName = typeName.slice(3);
22-
}
23-
return typeName;
24-
}
25-
26-
function nop(asbindInstance, value, typeName) {
27-
return value;
28-
}
29-
30-
function getString(asbindInstance, value, typeName) {
31-
return asbindInstance.exports.__getString(value);
32-
}
33-
34-
function putString(asbindInstance, value, typeName) {
35-
return asbindInstance.exports.__newString(value);
36-
}
37-
38-
function getArrayBuffer(asbindInstance, value, typeName) {
39-
return asbindInstance.exports.__getArrayBuffer(value);
40-
}
41-
42-
function putArrayBuffer(asbindInstance, value, typeName) {
43-
const ptr = asbindInstance.exports.__new(
44-
value.byteLength,
45-
asbindInstance.getTypeId(typeName)
46-
);
47-
new Uint8Array(
48-
asbindInstance.exports.memory.buffer,
49-
ptr,
50-
value.byteLength
51-
).set(new Uint8Array(value));
52-
return ptr;
53-
}
54-
55-
function getArrayBufferView(asbindInstance, value, typeName) {
56-
return asbindInstance.exports[
57-
`__get${normalizeArrayBufferViewTypeName(typeName)}View`
58-
](value);
59-
}
60-
function putArrayBufferView(asbindInstance, value, typeName) {
61-
return asbindInstance.exports.__newArray(
62-
asbindInstance.getTypeId(typeName),
63-
value
64-
);
65-
}
66-
67-
const stdlibArray = "~lib/array/Array";
68-
function arrayInnerType(typeName) {
69-
if (!typeName.startsWith(stdlibArray)) {
70-
throw Error(`${JSON.stringify(typeName)} is not an array type`);
71-
}
72-
// Cut off stdlib path + generic angle brackets.
73-
return typeName.slice(`${stdlibArray}<`.length, -1);
74-
}
75-
76-
function getArray(asbindInstance, value, typeName) {
77-
const innerTypeName = arrayInnerType(typeName);
78-
const innerTypeConverter = getConverterForType(innerTypeName);
79-
const rawArray = asbindInstance.exports.__getArray(value);
80-
return rawArray.map(v =>
81-
innerTypeConverter.ascToJs(asbindInstance, v, innerTypeName)
82-
);
83-
}
84-
85-
function putArray(asbindInstance, value, typeName) {
86-
const innerTypeName = arrayInnerType(typeName);
87-
const innerTypeConverter = getConverterForType(innerTypeName);
88-
const convertedValues = value.map(v =>
89-
innerTypeConverter.jsToAsc(asbindInstance, v, innerTypeName)
90-
);
91-
return asbindInstance.exports.__newArray(
92-
asbindInstance.getTypeId(typeName),
93-
convertedValues
94-
);
95-
}
96-
97-
export const converters = new Map([
98-
[/^void$/, { ascToJs: nop, jsToAsc: nop }],
99-
[/^(i|u)(8|16|32)$/, { ascToJs: nop, jsToAsc: nop }],
100-
[/^f(32|64)$/, { ascToJs: nop, jsToAsc: nop }],
101-
[/^~lib\/string\/String$/, { ascToJs: getString, jsToAsc: putString }],
102-
[
103-
/^~lib\/typedarray\/(Ui|I)nt(8|16|32)Array$/,
104-
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
105-
],
106-
[
107-
/^~lib\/typedarray\/Big(Ui|I)nt64Array$/,
108-
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
109-
],
110-
[
111-
/^~lib\/typedarray\/Uint8ClampedArray$/,
112-
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
113-
],
114-
[
115-
/^~lib\/typedarray\/Float(32|64)Array$/,
116-
{ ascToJs: getArrayBuffer, jsToAsc: putArrayBufferView }
117-
],
118-
[
119-
/^~lib\/arraybuffer\/ArrayBuffer$/,
120-
{ ascToJs: getArrayBuffer, jsToAsc: putArrayBuffer }
121-
],
122-
[/^~lib\/array\/Array<.+>$/, { ascToJs: getArray, jsToAsc: putArray }]
123-
]);
124-
125-
const warned = new Set();
126-
function getConverterForType(typeName) {
127-
for (const [matcher, converter] of converters) {
128-
if (matcher.test(typeName)) {
129-
return converter;
130-
}
131-
}
132-
if (!warned.has(typeName)) {
133-
console.warn(
134-
`No converter for ${JSON.stringify(typeName)}, using pass-through`
135-
);
136-
warned.add(typeName);
137-
}
138-
return { ascToJs: nop, jsToAsc: nop };
139-
}
140-
141-
function getAscToJsConverterForType(typeName) {
142-
return getConverterForType(typeName)?.ascToJs;
143-
}
144-
145-
function getJsToAscConverterForType(typeName) {
146-
return getConverterForType(typeName)?.jsToAsc;
147-
}
148-
14914
// Function that takes in an asbindInstance, an imported function and the path to the imported function
15015
// on the import object.
15116
// (E.g ["env", "myObject", "myFunction"] for {env: myObject: {myFunction: () => {}}})
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// Converts web platform names for the different ArrayBufferViews
2+
// to the names that ASC understands. Currently, that only means
3+
// to cut off the `Big` in `BigInt64Array`.
4+
const stdlibTypedArrayPrefix = "~lib/typedarray/";
5+
function normalizeArrayBufferViewTypeName(typeName) {
6+
// Don’t do anything if this is not a stdlib type.
7+
if (!typeName.startsWith(stdlibTypedArrayPrefix)) {
8+
return typeName;
9+
}
10+
typeName = typeName.slice(stdlibTypedArrayPrefix.length);
11+
if (typeName.startsWith("Big")) {
12+
// Slice off `Big` as the loader doesn’t have that prefix.
13+
typeName = typeName.slice(3);
14+
}
15+
return typeName;
16+
}
17+
18+
function nop(asbindInstance, value, typeName) {
19+
return value;
20+
}
21+
22+
function getString(asbindInstance, value, typeName) {
23+
return asbindInstance.exports.__getString(value);
24+
}
25+
26+
function putString(asbindInstance, value, typeName) {
27+
return asbindInstance.exports.__newString(value);
28+
}
29+
30+
function getArrayBuffer(asbindInstance, value, typeName) {
31+
return asbindInstance.exports.__getArrayBuffer(value);
32+
}
33+
34+
function putArrayBuffer(asbindInstance, value, typeName) {
35+
const ptr = asbindInstance.exports.__new(
36+
value.byteLength,
37+
asbindInstance.getTypeId(typeName)
38+
);
39+
new Uint8Array(
40+
asbindInstance.exports.memory.buffer,
41+
ptr,
42+
value.byteLength
43+
).set(new Uint8Array(value));
44+
return ptr;
45+
}
46+
47+
function getArrayBufferView(asbindInstance, value, typeName) {
48+
return asbindInstance.exports[
49+
`__get${normalizeArrayBufferViewTypeName(typeName)}View`
50+
](value);
51+
}
52+
function putArrayBufferView(asbindInstance, value, typeName) {
53+
return asbindInstance.exports.__newArray(
54+
asbindInstance.getTypeId(typeName),
55+
value
56+
);
57+
}
58+
59+
const stdlibArray = "~lib/array/Array";
60+
function arrayInnerType(typeName) {
61+
if (!typeName.startsWith(stdlibArray)) {
62+
throw Error(`${JSON.stringify(typeName)} is not an array type`);
63+
}
64+
// Cut off stdlib path + generic angle brackets.
65+
return typeName.slice(`${stdlibArray}<`.length, -1);
66+
}
67+
68+
function getArray(asbindInstance, value, typeName) {
69+
const innerTypeName = arrayInnerType(typeName);
70+
const innerTypeConverter = getConverterForType(innerTypeName);
71+
const rawArray = asbindInstance.exports.__getArray(value);
72+
return rawArray.map(v =>
73+
innerTypeConverter.ascToJs(asbindInstance, v, innerTypeName)
74+
);
75+
}
76+
77+
function putArray(asbindInstance, value, typeName) {
78+
const innerTypeName = arrayInnerType(typeName);
79+
const innerTypeConverter = getConverterForType(innerTypeName);
80+
const convertedValues = value.map(v =>
81+
innerTypeConverter.jsToAsc(asbindInstance, v, innerTypeName)
82+
);
83+
return asbindInstance.exports.__newArray(
84+
asbindInstance.getTypeId(typeName),
85+
convertedValues
86+
);
87+
}
88+
89+
export const converters = new Map([
90+
["void", { ascToJs: nop, jsToAsc: nop }],
91+
[/^(i|u|f)(8|16|32)$/, { ascToJs: nop, jsToAsc: nop }],
92+
["~lib/string/String", { ascToJs: getString, jsToAsc: putString }],
93+
[
94+
"~lib/typedarray/Int8Array",
95+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
96+
],
97+
[
98+
"~lib/typedarray/Int16Array",
99+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
100+
],
101+
[
102+
"~lib/typedarray/Int32Array",
103+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
104+
],
105+
[
106+
"~lib/typedarray/Uint8Array",
107+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
108+
],
109+
[
110+
"~lib/typedarray/Uint16Array",
111+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
112+
],
113+
[
114+
"~lib/typedarray/Uint32Array",
115+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
116+
],
117+
[
118+
"~lib/typedarray/Int64Array",
119+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
120+
],
121+
[
122+
"~lib/typedarray/Uint64Array",
123+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
124+
],
125+
[
126+
"~lib/typedarray/Uint8ClampedArray",
127+
{ ascToJs: getArrayBufferView, jsToAsc: putArrayBufferView }
128+
],
129+
[
130+
"~lib/typedarray/Float32Array",
131+
{ ascToJs: getArrayBuffer, jsToAsc: putArrayBufferView }
132+
],
133+
[
134+
"~lib/typedarray/Float64Array",
135+
{ ascToJs: getArrayBuffer, jsToAsc: putArrayBufferView }
136+
],
137+
[
138+
"~lib/arraybuffer/ArrayBuffer",
139+
{ ascToJs: getArrayBuffer, jsToAsc: putArrayBuffer }
140+
],
141+
[/^~lib\/array\/Array<.+>$/, { ascToJs: getArray, jsToAsc: putArray }]
142+
]);
143+
144+
const warned = new Set();
145+
export function getConverterForType(typeName) {
146+
for (const [matcher, converter] of converters) {
147+
if (typeof matcher === "string") {
148+
if (matcher === typeName) {
149+
return converter;
150+
}
151+
continue;
152+
} else if (matcher.test(typeName)) {
153+
return converter;
154+
}
155+
}
156+
if (!warned.has(typeName)) {
157+
console.warn(
158+
`No converter for ${JSON.stringify(typeName)}, using pass-through`
159+
);
160+
warned.add(typeName);
161+
}
162+
return { ascToJs: nop, jsToAsc: nop };
163+
}
164+
165+
export function getAscToJsConverterForType(typeName) {
166+
return getConverterForType(typeName)?.ascToJs;
167+
}
168+
169+
export function getJsToAscConverterForType(typeName) {
170+
return getConverterForType(typeName)?.jsToAsc;
171+
}

lib/lib.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export { version } from "../package.json";
22
import AsbindInstance from "./asbind-instance/asbind-instance";
3-
export { converters } from "./asbind-instance/bind-function";
3+
export { converters } from "./asbind-instance/type-converters";
44

55
export async function instantiate(source, importObject) {
66
let asbindInstance = new AsbindInstance();

0 commit comments

Comments
 (0)