Skip to content

Commit

Permalink
migrate to esm
Browse files Browse the repository at this point in the history
  • Loading branch information
toyobayashi committed Nov 27, 2023
1 parent f0ccf79 commit 775f880
Show file tree
Hide file tree
Showing 17 changed files with 137 additions and 32 deletions.
20 changes: 18 additions & 2 deletions packages/emnapi/script/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,27 @@ async function build () {
compilerOptions: {
module: ts.ModuleKind.ESNext
},
include: libTsconfig.include,
include: libTsconfig.include.map(s => path.join(__dirname, '..', s)),
transformers: {
before: [
{
type: 'program',
factory: require('../transformer/out/macro.js').default
},
{
type: 'program',
factory: () => {
return (context) => {
return (src) => {
if (src.isDeclarationFile) return src
const statements = src.statements
const newStatements = statements.filter(s => {
return !(ts.isImportDeclaration(s) && ts.isStringLiteral(s.moduleSpecifier) && (s.moduleSpecifier.text === 'emnapi:emscripten-runtime'))
})
return context.factory.updateSourceFile(src, newStatements)
}
}
}
}
]
}
Expand Down Expand Up @@ -126,7 +141,8 @@ async function build () {
}),
rollupAlias({
entries: [
{ find: 'emnapi:shared', replacement: path.join(__dirname, '../src/core/init.ts') }
{ find: 'emnapi:shared', replacement: path.join(__dirname, '../src/core/init.ts') },
{ find: 'emnapi:emscripten-runtime', replacement: path.join(__dirname, '../src/core/init.ts') }
]
})
]
Expand Down
2 changes: 2 additions & 0 deletions packages/emnapi/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
emnapiTSFN,
napi_create_threadsafe_function,
napi_get_threadsafe_function_context,
napi_call_threadsafe_function,
napi_acquire_threadsafe_function,
napi_release_threadsafe_function,
napi_unref_threadsafe_function,
Expand Down Expand Up @@ -85,6 +86,7 @@ addImports(versionMod)

napiModule.imports.napi.napi_create_threadsafe_function = napi_create_threadsafe_function
napiModule.imports.napi.napi_get_threadsafe_function_context = napi_get_threadsafe_function_context
napiModule.imports.napi.napi_call_threadsafe_function = napi_call_threadsafe_function
napiModule.imports.napi.napi_acquire_threadsafe_function = napi_acquire_threadsafe_function
napiModule.imports.napi.napi_release_threadsafe_function = napi_release_threadsafe_function
napiModule.imports.napi.napi_unref_threadsafe_function = napi_unref_threadsafe_function
Expand Down
3 changes: 2 additions & 1 deletion packages/emnapi/src/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"paths": {
"emnapi:shared": ["./init"]
"emnapi:shared": ["./init"],
"emnapi:emscripten-runtime": ["./init"]
}
},
"include": [
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/emnapi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { emnapiCtx, emnapiNodeBinding } from 'emnapi:shared'
import { wasmMemory } from 'emnapi:emscripten-runtime'
import { type MemoryViewDescriptor, type ArrayBufferPointer, emnapiExternalMemory } from './memory'
import { napi_add_finalizer } from './wrap'
import { $CHECK_ARG, $PREAMBLE, $CHECK_ENV } from './macro'
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/emscripten/async.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_PTHREAD } from 'emnapi:emscripten-runtime'
import { _emnapi_set_immediate, _emnapi_next_tick } from '../util'

declare var PThread: any
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/emscripten/emnapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { emnapiCtx } from 'emnapi:shared'
import { emnapiString } from '../string'
import { $CHECK_ARG, $PREAMBLE } from '../macro'
import { Module } from 'emnapi:emscripten-runtime'

/**
* @__sig ipp
Expand Down
2 changes: 2 additions & 0 deletions packages/emnapi/src/emscripten/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
/* eslint-disable no-new-func */
/* eslint-disable @typescript-eslint/no-implied-eval */

import { abort } from 'emnapi:emscripten-runtime'

// declare const global: typeof globalThis
// declare const require: any
// declare const process: any
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/emscripten/memory.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { wasmMemory } from 'emnapi:emscripten-runtime'
import { emnapiCtx } from './init'
import { $emnapiSetValueI64 as emnapiSetValueI64 } from '../util'
import { $CHECK_ENV } from '../macro'
Expand Down
39 changes: 11 additions & 28 deletions packages/emnapi/src/emscripten/runtime.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,18 @@ declare const LibraryManager: {

declare function mergeInto (target: any, source: Record<string, any>): void

// runtime
declare var wasmMemory: WebAssembly.Memory
declare var ENVIRONMENT_IS_NODE: boolean
declare var ENVIRONMENT_IS_PTHREAD: boolean
declare module 'emnapi:emscripten-runtime' {
export const wasmMemory: WebAssembly.Memory
export const ENVIRONMENT_IS_NODE: boolean
export const ENVIRONMENT_IS_PTHREAD: boolean

// declare type I64Type = 'i64'
// declare type I32Type = 'i1' | 'i8' | 'i16' | 'i32' | 'float' | 'double'
// declare type ValueType = I32Type | I64Type
// declare type PointerType = '*' | `${ValueType}*`
export function _free (ptr: void_p): void
export function _malloc (size: number | bigint): void_p

// declare function getValue (ptr: number): number
// declare function getValue (ptr: number, type: I64Type): bigint
// declare function getValue (ptr: number, type: I32Type | PointerType): number
// declare function setValue (ptr: number, value: number | bigint, type: ValueType | PointerType): void
export function abort (msg?: string): never

declare const Module: any
export function runtimeKeepalivePush (): void
export function runtimeKeepalivePop (): void

// declare function allocateUTF8 (str: string): char_p
declare function _free (ptr: void_p): void
declare function _malloc (size: number | bigint): void_p

// declare type LifecycleCallback<Arg> = {
// func: (arg: Arg) => void
// arg: Arg
// }
// declare const __ATINIT__: Array<(Module: any) => void>
// declare function addOnInit (callback: number | ((Module: any) => void) | LifecycleCallback<any>): void
// declare function addOnExit (callback: number | ((Module: any) => void) | LifecycleCallback<any>): void
declare function abort (msg?: string): never

declare function runtimeKeepalivePush (): void
declare function runtimeKeepalivePop (): void
export const Module: any
}
1 change: 1 addition & 0 deletions packages/emnapi/src/error.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { abort } from 'emnapi:emscripten-runtime'
import { emnapiCtx, emnapiNodeBinding } from 'emnapi:shared'
import { $PREAMBLE, $CHECK_ARG, $CHECK_ENV_NOT_IN_GC } from './macro'
import { emnapiString } from './string'
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/memory.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { _free, wasmMemory, _malloc } from 'emnapi:emscripten-runtime'
import { emnapiCtx } from 'emnapi:shared'

export type ViewConstuctor =
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/string.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/indent */

import { wasmMemory } from 'emnapi:emscripten-runtime'
import { emnapiCtx } from 'emnapi:shared'
import { $CHECK_NEW_STRING_ARGS } from './macro'

Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/threadsafe-function.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/indent */

import { ENVIRONMENT_IS_NODE, _malloc, wasmMemory, _free, ENVIRONMENT_IS_PTHREAD, abort } from 'emnapi:emscripten-runtime'
import { emnapiCtx, emnapiNodeBinding } from 'emnapi:shared'
import { $CHECK_ENV_NOT_IN_GC, $CHECK_ARG } from './macro'
import { _emnapi_node_emit_async_destroy, _emnapi_node_emit_async_init } from './node'
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/indent */

import { runtimeKeepalivePop, runtimeKeepalivePush } from 'emnapi:emscripten-runtime'
import { emnapiCtx } from 'emnapi:shared'

/**
Expand Down
1 change: 1 addition & 0 deletions packages/emnapi/src/value/create.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { emnapiCtx } from 'emnapi:shared'
import { wasmMemory, _malloc } from 'emnapi:emscripten-runtime'
import { emnapiString } from '../string'
import { type MemoryViewDescriptor, emnapiExternalMemory } from '../memory'
import { emnapi_create_memory_view } from '../emnapi'
Expand Down
2 changes: 2 additions & 0 deletions packages/emnapi/src/value/global.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { emnapiCtx } from 'emnapi:shared'
import { $CHECK_ENV_NOT_IN_GC, $CHECK_ARG } from '../macro'

/** @__sig ipip */
Expand Down
91 changes: 90 additions & 1 deletion packages/emnapi/transformer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
} from 'typescript'

import * as ts from 'typescript'
import { join } from 'path'

export interface DefineOptions {
defines?: Record<string, any>
Expand Down Expand Up @@ -213,12 +214,21 @@ function updateBody<N extends FunctionLikeDeclaration> (factory: NodeFactory, no
class Transform {
ctx: TransformationContext
defines: Record<string, any>
insertWasmMemoryImport: boolean
insertWasmTableImport: boolean

constructor (context: TransformationContext, defines: Record<string, any>) {
this.ctx = context
this.defines = defines
this.visitor = this.visitor.bind(this)
this.functionLikeDeclarationVisitor = this.functionLikeDeclarationVisitor.bind(this)
this.insertWasmMemoryImport = false
this.insertWasmTableImport = false
}

resetSource (): void {
this.insertWasmMemoryImport = false
this.insertWasmTableImport = false
}

createHeapDataViewDeclaration (): VariableStatement {
Expand Down Expand Up @@ -270,6 +280,9 @@ class Transform {
let includeGetOrSet = false
const statementVisitor: Visitor = (n) => {
if (ts.isIdentifier(n) && n.text === 'HEAP_DATA_VIEW') {
if (!this.insertWasmMemoryImport) {
this.insertWasmMemoryImport = true
}
includeGetOrSet = true
}
return ts.visitEachChild(n, statementVisitor, this.ctx)
Expand Down Expand Up @@ -590,6 +603,10 @@ class Transform {
const pointerName = argv1.text
if (!pointerName) return node

if (!this.insertWasmTableImport) {
this.insertWasmTableImport = true
}

return this.ctx.factory.createParenthesizedExpression(this.ctx.factory.createCallExpression(
this.ctx.factory.createPropertyAccessExpression(
this.ctx.factory.createIdentifier('wasmTable'),
Expand Down Expand Up @@ -675,6 +692,32 @@ class Transform {
}
}

function getImportsOfModule (src: SourceFile): string[] {
const collection = new Set<string>()
for (let i = 0; i < src.statements.length; ++i) {
const s = src.statements[i]
if (ts.isImportDeclaration(s)) {
if (s.importClause && !s.importClause.isTypeOnly) {
if (s.importClause.name) {
collection.add(s.importClause.name.text)
}
if (s.importClause.namedBindings) {
if (ts.isNamedImports(s.importClause.namedBindings)) {
s.importClause.namedBindings.elements.filter(e => !e.isTypeOnly).forEach(sp => {
collection.add(sp.name.text)
})
} else if (ts.isNamespaceImport(s.importClause.namedBindings)) {
collection.add(s.importClause.namedBindings.name.text)
}
}
}
} else if (ts.isImportEqualsDeclaration(s)) {
collection.add(s.name.text)
}
}
return [...collection]
}

function createTransformerFactory (_program: Program, config: DefineOptions): TransformerFactory<SourceFile> {
const defines = config.defines ?? {}
// const defineKeys = Object.keys(defines)
Expand All @@ -684,10 +727,56 @@ function createTransformerFactory (_program: Program, config: DefineOptions): Tr

return (src) => {
if (src.isDeclarationFile) return src
transform.resetSource()
// expand emscripten macros
const transformedSrc = ts.visitEachChild(src, transform.visitor, context)
// inject HEAP_DATA_VIEW
return ts.visitEachChild(transformedSrc, transform.functionLikeDeclarationVisitor, context)
const injectedSrc = ts.visitEachChild(transformedSrc, transform.functionLikeDeclarationVisitor, context)

const doNotInsertImport = join(__dirname, '../../src/core/init.ts')
if (src.fileName === doNotInsertImport) {
return injectedSrc
}

let resultSrc = injectedSrc
let importNames: string[] | null = null
const factory = context.factory
if (transform.insertWasmMemoryImport) {
importNames = getImportsOfModule(resultSrc)
if (!importNames.includes('wasmMemory')) {
resultSrc = factory.updateSourceFile(resultSrc, [
factory.createImportDeclaration(undefined,
factory.createImportClause(false, undefined,
factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier('wasmMemory'))
])
),
factory.createStringLiteral('emnapi:emscripten-runtime'),
undefined
),
...resultSrc.statements
])
}
}
if (transform.insertWasmTableImport) {
importNames = getImportsOfModule(resultSrc)
if (!importNames.includes('wasmTable')) {
resultSrc = factory.updateSourceFile(resultSrc, [
factory.createImportDeclaration(undefined,
factory.createImportClause(false, undefined,
factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier('wasmTable'))
])
),
factory.createStringLiteral('emnapi:emscripten-runtime'),
undefined
),
...resultSrc.statements
])
}
}

return resultSrc
}
}
}
Expand Down

0 comments on commit 775f880

Please sign in to comment.