(obj)
| 81 | // JSON.stringify will completely omit function objects. This function is |
| 82 | // similar but preserves functions. |
| 83 | function stringifyWithFunctions(obj) { |
| 84 | if (typeof obj == 'function') return obj.toString(); |
| 85 | if (obj === null || typeof obj != 'object') return JSON.stringify(obj); |
| 86 | if (Array.isArray(obj)) { |
| 87 | return '[' + obj.map(stringifyWithFunctions).join(',') + ']'; |
| 88 | } |
| 89 | |
| 90 | // preserve the type of the object if it is one of [Map, Set, WeakMap, WeakSet]. |
| 91 | const builtinContainers = runInMacroContext('[Map, Set, WeakMap, WeakSet]', { |
| 92 | filename: '<internal>', |
| 93 | }); |
| 94 | for (const container of builtinContainers) { |
| 95 | if (obj instanceof container) { |
| 96 | const className = container.name; |
| 97 | assert(!obj.size, `cannot stringify ${className} with data`); |
| 98 | return `new ${className}`; |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | var rtn = '{\n'; |
| 103 | for (const [key, value] of Object.entries(obj)) { |
| 104 | var str = stringifyWithFunctions(value); |
| 105 | // Handle JS method syntax where the function property starts with its own |
| 106 | // name. e.g. `foo(a) {}` (or `async foo(a) {}`) |
| 107 | if (typeof value === 'function' && (str.startsWith(key) || str.startsWith('async ' + key))) { |
| 108 | rtn += str + ',\n'; |
| 109 | } else { |
| 110 | rtn += `${escapeJSONKey(key)}:${str},\n`; |
| 111 | } |
| 112 | } |
| 113 | return rtn + '}'; |
| 114 | } |
| 115 | |
| 116 | function isDefined(symName) { |
| 117 | if (WASM_EXPORTS.has(symName) || SIDE_MODULE_EXPORTS.has(symName)) { |
no test coverage detected