μ΄ μ μμ @fmccabe , @thibaudmichaud , @lukewagner λ° @kripken κ³Όμ νλ ₯μΌλ‘ κ°λ°λμμΌλ©° Stacks νμ κ·Έλ£Ήμ νΌλλ°±κ³Ό ν¨κ» κ°λ°λμμ΅λλ€(μ€λ 0λ¨κ³λ‘ μ§ννλ κ²μ μΉμΈνλ λΉκ³΅μ ν¬ν ν¬ν¨). μκ° μ μ½μΌλ‘ μΈν΄ κ³νμ λ§€μ° λΉ λ₯Έ(μ¦, 5λΆ) νλ μ ν μ΄μ μ νκ³ 8μ 3μΌμ 1λ¨κ³λ‘ μ§ννκΈ° μν΄ ν¬νν μμ μ λλ€. μ΄λ₯Ό μ΄μ§νκΈ° μν΄ μ¬λλ€μ΄ 미리 μ¬κΈ°μ μ°λ € μ¬νμ μ κΈ°νμ¬ νλ μ ν μ΄μ +ν¬νλ₯Ό λ λ§μ μκ°κ³Ό ν¨κ» λμ€μ λ μ§λ‘ λ―Έλ£° λ§ν μ£Όμ μ°λ € μ¬νμ΄ μλμ§ κ²°μ ν μ μλλ‘ κ°λ ₯ν κΆμ₯ν©λλ€.
μ΄ μ μμ λͺ©μ μ JavaScript Promiseμ WebAssembly κ°μ μλμ μΌλ‘ ν¨μ¨μ μ΄κ³ μλμ μΌλ‘ μΈμ²΄κ³΅νμ μΈ μνΈ μ΄μ©μ±μ μ 곡νμ§λ§ ν΅μ¬ wasmμ΄ μλ JS APIμ λν λ³κ²½ μ¬νλ§ μλ€λ μ μ½ μ‘°κ±΄ νμμ μμ
νλ κ²μ
λλ€.
Stack-Switching μ μ μ΄ κ²°κ΅ ν΅μ¬ WebAssemblyλ₯Ό νμ₯νμ¬ μ΄ μ μμμ μ 곡νλ μμ
μ WebAssembly λ΄μμ μ§μ ꡬννλ κΈ°λ₯κ³Ό ν¨κ» λ€λ₯Έ λ§μ κ°μΉ μλ μ€ν μ ν μμ
μ μνν κ²μΌλ‘ κΈ°λν©λλ€. κ·Έλ¬λ μ€ν μ νμ λν μ΄ νΉμ μ¬μ© μ¬λ‘λ JS APIλ₯Ό ν΅ν΄ λ λΉ λ₯Έ κ²½λ‘λ₯Ό μ 곡νκΈ°μ μΆ©λΆν κΈ΄κΈμ±μ
λλ€.
μμΈν λ΄μ© μ 2021λ
6μ 28μΌ μ€ν νμ κ·Έλ£Ή νμ μ λ
ΈνΈμ μ¬λΌμ΄λλ₯Ό μ°Έμ‘°νμμμ€. μ¬κΈ°μμλ μ¬μ© μλ리μ€μ κ³ λ €ν μμλ₯Ό μμΈν μ€λͺ
νκ³ λ€μ μ€κ³μ λλ¬ν κ·Όκ±°λ₯Ό μμ½ν©λλ€.
μ
λ°μ΄νΈ: Stacks Subgroupμ΄ TC39λ‘λΆν° λ°μ νΌλλ°±μ λ°λΌ μ΄ μ μμ WebAssembly μ€ν λ§ μΌμ μ€λ¨νλλ‘ νμ©ν©λλ€. JavaScript μΈμ΄λ₯Ό λ³κ²½νμ§ μμΌλ©° νΉν λΆλ¦¬λ asycn
λν μ§μμ κ°μ μ μΌλ‘ νμ±ννμ§ μμ΅λλ€. μλ°μ€ν¬λ¦½νΈμμ await
.
μ΄κ²μ WebAssembly.Function
λ₯Ό Function
μ νμ ν΄λμ€λ‘ μκ°νλ js-types μ μμ (λμ¨νκ²) μμ‘΄ν©λλ€.
μ μμ λ€μκ³Ό κ°μ μΈν°νμ΄μ€, μμ±μ λ° λ©μλλ₯Ό JS APIμ μΆκ°νλ κ²μ λλ€. μμΈν λ΄μ©μ μλμμ μ€λͺ ν©λλ€.
interface Suspender {
constructor();
Function suspendOnReturnedPromise(Function func); // import wrapper
// overloaded: WebAssembly.Function suspendOnReturnedPromise(WebAssembly.Function func);
WebAssembly.Function returnPromiseOnSuspend(WebAssembly.Function func); // export wrapper
}
λ€μμ μ΄ APIλ₯Ό μ¬μ©νλ λ°©λ²μ μμ
λλ€.
μ°λ¦¬μ μ¬μ© μλ리μ€μμ WebAssembly λͺ¨λμ΄ κ°λ
μ μΌλ‘ "λκΈ°" λ° "λΉλκΈ°" κ°μ Έμ€κΈ° λ° λ΄λ³΄λ΄κΈ°λ₯Ό κ°λ κ²μ κ³ λ €νλ κ²μ΄ μ μ©νλ€λ κ²μ μμμ΅λλ€.
νμ¬ JS APIλ "λκΈ°" κ°μ Έμ€κΈ° λ° λ΄λ³΄λ΄κΈ°λ§ μ§μν©λλ€.
Suspender μΈν°νμ΄μ€μ λ©μλλ "λΉλκΈ°"λ₯Ό λ§λ€κΈ° μν΄ κ΄λ ¨ κ°μ Έμ€κΈ° λ° λ΄λ³΄λ΄κΈ°λ₯Ό λννλ λ° μ¬μ©λλ©° Suspender κ°μ²΄ μ체λ ꡬνκ³Ό κ΅¬μ± κ°λ₯μ±μ μ©μ΄νκ² νκΈ° μν΄ μ΄λ¬ν κ°μ Έμ€κΈ° λ° λ΄λ³΄λ΄κΈ°λ₯Ό λͺ
μμ μΌλ‘ ν¨κ» μ°κ²°ν©λλ€.
μΉ μ΄μ
λΈλ¦¬( demo.wasm
):
(module
(import "js" "init_state" (func $init_state (result f64)))
(import "js" "compute_delta" (func $compute_delta (result f64)))
(global $state f64)
(func $init (global.set $state (call $init_state)))
(start $init)
(func $get_state (export "get_state") (result f64) (global.get $state))
(func $update_state (export "update_state") (result f64)
(global.set (f64.add (global.get $state) (call $compute_delta)))
(global.get $state)
)
)
ν
μ€νΈ( data.txt
):
19827.987
μλ°μ€ν¬λ¦½νΈ:
var suspender = new Suspender();
var init_state = () => 2.71;
var compute_delta = () => fetch('data.txt').then(res => res.text()).then(txt => parseFloat(txt));
var importObj = {js: {
init_state: init_state,
compute_delta: suspender.suspendOnReturnedPromise(compute_delta)
}};
fetch('demo.wasm').then(response =>
response.arrayBuffer()
).then(buffer =>
WebAssembly.instantiate(buffer, importObj)
).then(({module, instance}) => {
var get_state = instance.exports.get_state;
var update_state = suspender.returnPromiseOnSuspend(instance.exports.update_state);
...
});
μ΄ μμ μλ λ§€μ° λ¨μν μν λ¨Έμ μΈ WebAssembly λͺ¨λμ΄ μμ΅λλ€. μνλ₯Ό μ
λ°μ΄νΈν λλ§λ€ μνμ μΆκ°ν λΈνλ₯Ό κ³μ°νκΈ° μν΄ κ°μ Έμ€κΈ°λ₯Ό νΈμΆνκΈ°λ§ νλ©΄ λ©λλ€.
κ·Έλ¬λ JavaScript μΈ‘μμλ λΈνλ₯Ό κ³μ°νλ λ° μ¬μ©νλ €λ ν¨μλ₯Ό λΉλκΈ°μμΌλ‘ μ€νν΄μΌ ν©λλ€. μ¦, μ«μ μμ²΄κ° μλ μ«μμ μ½μμ λ°νν©λλ€.
μ°λ¦¬λ μλ‘μ΄ JS APIλ₯Ό μ¬μ©νμ¬ μ΄ λκΈ°ν κ°κ²©μ λ©μΈ μ μμ΅λλ€.
μμ μμ WebAssembly λͺ¨λμ κ°μ Έμ€κΈ°λ suspender.suspendOnReturnedPromise
μ¬μ©νμ¬ λνλκ³ λ΄λ³΄λ΄κΈ°λ suspender.returnPromiseOnSuspend
μ¬μ©νμ¬ λνλ©λλ€. λ λ€ λμΌν suspender
ν©λλ€.
κ·Έ suspender
λ λμ ν¨κ» μ°κ²°ν©λλ€.
(λνλμ§ μμ) κ°μ Έμ€κΈ°κ° Promiseλ₯Ό λ°ννλ κ²½μ° (λνλ) λ΄λ³΄λ΄κΈ°κ° Promiseλ₯Ό λ°ννλλ‘ νλ©°, κ·Έ μ¬μ΄μ λͺ¨λ κ³μ°μ κ°μ Έμ€κΈ°μ Promiseκ° ν΄κ²°λ λκΉμ§ "μΌμ μ€λ¨"λ©λλ€.
λ΄λ³΄λ΄κΈ° λνμ κΈ°λ³Έμ μΌλ‘ async
λ§μ»€λ₯Ό μΆκ°νκ³ κ°μ Έμ€κΈ° λνμ κΈ°λ³Έμ μΌλ‘ await
λ§μ»€λ₯Ό μΆκ°νμ§λ§ JavaScriptμ λ¬λ¦¬ λͺ
μμ μΌλ‘ async
μ€λ λν νμκ° μμ΅λλ€ await
λͺ¨λ μ€κ° WebAssembly κΈ°λ₯μ ν΅ν΄!
ννΈ, μ΄κΈ°ν μ€μ init_state
λν νΈμΆμ λ°λμ μΌμ μ€λ¨ μμ΄ λ°νλκ³ λ΄λ³΄λ΄κΈ° get_state
μ λν νΈμΆλ νμ μΌμ μ€λ¨ μμ΄ λ°νλλ―λ‘ μ μμλ μ¬μ ν κΈ°μ‘΄ "λκΈ°μ" κ°μ Έμ€κΈ° λ° λ΄λ³΄λ΄κΈ°λ₯Ό μ§μν©λλ€. WebAssembly μνκ³λ μ€λλ μ¬μ©ν©λλ€.
λ¬Όλ‘ λκΈ° λ΄λ³΄λ΄κΈ°κ° λΉλκΈ° κ°μ Έμ€κΈ°λ₯Ό νΈμΆνλ κ²½μ° κ°μ Έμ€κΈ°κ° μΌμ μ€λ¨λλ©΄ νλ‘κ·Έλ¨μ΄ νΈλ©λλ€λ μ¬μ€κ³Ό κ°μ΄ νμ΄λ³΄κ³ μλ λ§μ μΈλΆ μ¬νμ΄ μμ΅λλ€.
λ€μμ λ³΄λ€ μμΈν μ¬μκ³Ό μΌλΆ ꡬν μ λ΅μ μ 곡ν©λλ€.
Suspender
λ λ€μ μν μ€ νλμ
λλ€.
caller
] - 컨νΈλ‘€μ Suspender
μ μμΌλ©° caller
λ Suspender
λ₯Ό νΈμΆνκ³ externref
κΈ°λνλ ν¨μμ
λλ€ μκΈ° λ°©λ²μ suspender.returnPromiseOnSuspend(func)
μ£Όμ₯ func
Aλ WebAssembly.Function
ννμ ν¨μ μ ν [ti*] -> [to]
ν λ¦¬ν΄ WebAssembly.Function
μ ν¨μ νμ [ti*] -> [externref]
μΈμμ ν¨κ» νΈμΆλ λ λ€μμ μννλ args
:
suspender
μ μνκ° λΉνμ± μ΄ μλ κ²½μ° νΈλ©suspender
μ μνλ₯Ό νμ± [ caller
]μΌλ‘ λ³κ²½ν©λλ€(μ¬κΈ°μ caller
λ νμ¬ νΈμΆμμ).result
func(args)
(λλ λͺ¨λ νΈλ© λλ throwλ μμΈ)λ₯Ό νΈμΆν κ²°κ³Όλ‘ μ€μ ν©λλ€.suspender
μ μνκ° νμ± μΈ [ caller'
]μ λν λͺ κ°μ§ caller'
(보μ₯λμ΄μΌνλ€, νΈμΆμκ° λ³κ²½λμμ μ μμ§λ§)suspender
μ μνλ₯Ό λΉνμ±μΌλ‘ λ³κ²½result
λ₯Ό caller'
λ°ν(λλ λ€μ λμ§)λ°©λ² suspender.suspendOnReturnedPromise(func)
func
κ° WebAssembly.Function
μΈ κ²½μ° ν¨μ μ νμ΄ [t*] -> [externref]
νμμ΄λΌκ³ μ£Όμ₯νκ³ [t*] -> [externref]
ν¨μ μ νμ κ°μ§ WebAssembly.Function
λ₯Ό λ°νν©λλ€. ;func
κ° Function
λΌκ³ μ£Όμ₯νκ³ Function
λ°νν©λλ€.λ κ²½μ° λͺ¨λ suspender.suspendOnReturnedPromise(func)
λ°νλ ν¨μλ args
μΈμμ ν¨κ» νΈμΆλ λ λ€μμ μνν©λλ€.
result
κ° func(args)
(λλ λͺ¨λ νΈλ© λλ throwλ μμΈ)λ₯Ό νΈμΆν κ²°κ³Όκ° λλλ‘ ν©λλ€.result
κ° λ°νλ Promiseκ° μλλ©΄ result
λ₯Ό λ°ν(λλ λ€μ λμ§)ν©λλ€.suspender
μ μνκ° caller
λν΄ [ caller
] νμ± μ΄ μλ κ²½μ° νΈλ©frames
μ΄ν μ€ν νλ μ μ caller
frames
μΌμ μ€λ¨ν μ μλ ν¨μμ νλ μμ΄ μλ κ²½μ° νΈλ©suspender
μ μνλ₯Ό Suspendedλ‘ λ³κ²½onFulfilled
λ° onRejected
ν¨μκ° μλ result.then(onFulfilled, onRejected)
μ κ²°κ³Όλ₯Ό λ°νν©λλ€.suspender
μ μνκ° Suspended μμ νμΈν©λλ€(보μ₯λμ΄μΌ ν¨).suspender
μ μνλ₯Ό νμ± [ caller'
]μΌλ‘ λ³κ²½ν©λλ€. μ¬κΈ°μ caller'
λ onFulfilled
/ onRejected
μ νΈμΆμμ
λλ€.onFulfilled
λ‘ μ§μ λ κ°μ λ³ν externref
λλμ κ²κ³Ό frames
onRejected
μ κ²½μ° Exception Handling μ μμ JS APIμ λ°λΌ μ΅λ frames
κΉμ§ μ£Όμ΄μ§ κ°μ μμΈλ‘ λμ§λλ€.λ€μκ³Ό κ°μ κ²½μ° κΈ°λ₯μ΄ μΌμ μ€λ¨ κ°λ₯ν©λλ€.
suspendOnReturnedPromise
μμ λ°ν ,returnPromiseOnSuspend
μμ λ°ν ,μ€μν κ²μ JavaScriptλ‘ μμ±λ ν¨μλ TC39 λ©€λ²μ νΌλλ°±μ μ€μνμ¬ μΌμ μ€λ¨ν μ μμΌλ©° , νΈμ€νΈ κΈ°λ₯(μμ λμ΄λ λͺ κ°μ§ μ μΈ)μ μμ§ μ μ§ κ΄λ¦¬μμ νΌλλ°±μ μ€μνμ¬ μΌμ μ€λ¨ν μ μμ΅λλ€ .
λ€μμ μ΄ μ μμ λν μ€ν μ λ΅μ
λλ€.
κ·Έκ²μ λ¬Όλ‘ μ£Όμ ꡬν κ³Όμ κ° μλ μ€ν μ€μμΉμ λν μμ§ μ§μμ κ°μ ν©λλ€.
μ€νμλ νΈμ€νΈ(λ° JavaScript) μ€νκ³Ό WebAssembly μ€νμ λ κ°μ§ μ’
λ₯κ° μμ΅λλ€. λͺ¨λ WebAssembly μ€νμλ suspender
λΌλ μμ€νλ νλκ° μμ΅λλ€. λͺ¨λ μ€λ λμλ νΈμ€νΈ μ€νμ΄ μμ΅λλ€.
λͺ¨λ Suspender
μλ λ κ°μ μ€ν μ°Έμ‘° νλκ° μμ΅λλ€. νλλ caller
μ΄κ³ λ€λ₯Έ νλλ suspended
μ
λλ€.
caller
νλλ νΈμΆμμ (μΌμ μ€λ¨λ) μ€νμ μ°Έμ‘°νκ³ suspended
νλλ nullμ
λλ€.suspended
νλλ νμ¬ suspenderμ μ°κ²°λ (suspended) WebAssembly μ€νμ μ°Έμ‘°νκ³ caller
νλλ nullμ
λλ€.suspender.returnPromiseOnSuspend(func)(args)
λ λ€μμ μν΄ κ΅¬νλ©λλ€.
suspender.caller
λ° suspended.suspended
κ° nullμΈμ§ νμΈ(κ·Έλ μ§ μμΌλ©΄ νΈλν)stack
λ₯Ό suspender
μ μ°κ²°λ μλ‘ ν λΉλ WebAssembly μ€νμΌλ‘ μ€μ stack
μ ννκ³ μ΄μ μ€νμ suspender.caller
result
κ° func(args)
(λλ λͺ¨λ νΈλ© λλ throwλ μμΈ)μ κ²°κ³Όκ° λλλ‘ ν©λλ€.suspender.caller
μ ννκ³ nullλ‘ μ€μ stack
ν΄μ result
suspender.suspendOnReturnedPromise(func)(args)
λ λ€μμ μν΄ κ΅¬νλ©λλ€.
func(args)
νΈμΆ , νΈλ© λλ throwλ μμΈ μ‘κΈ°result
κ° λ°νλ Promiseκ° μλλ©΄ result
λ°ν(λλ λ€μ λμ§)suspender.caller
κ° nullμ΄ μλμ§ νμΈ(κ·Έλ μ§ μμΌλ©΄ νΈλν)stack
νμ¬ μ€νμΌλ‘ λ‘λλ€.stack
λ suspender
μ μ°κ²°λ WebAssembly μ€νμ΄ μλλλ€.stack
κ° WebAssembly μ€νμΈμ§ νμΈ(κ·Έλ μ§ μμΌλ©΄ νΈλν)stack
μ stack.suspender.caller
suspender.caller
μ ννκ³ nullλ‘ μ€μ νκ³ μ΄μ μ€νμ suspender.suspended
onFulfilled
λ° onRejected
ν¨μκ° κ΅¬νλ result.then(onFulfilled, onRejected)
μ κ²°κ³Ό λ°νsuspender.suspended
μ ννκ³ nullλ‘ μ€μ νκ³ μ΄μ μ€νμ suspender.caller
onFulfilled
κ²½μ° μ£Όμ΄μ§ κ°μ externref
λ‘ λ³ννμ¬ λ°νonRejected
κ²½μ° μ£Όμ΄μ§ κ°μ λ€μ λμ§λλ€.μΌμ μ€λ¨ κ°λ₯ν ν¨μμ λν μμ±νμ¬ μμ±λ ν¨μμ ꡬνμ λ¨Όμ νμ¬ μ€λ λμ νΈμ€νΈ μ€ν(μμ§ μμ§ μμ κ²½μ°)μΌλ‘ μ ννκ³ λ§μ§λ§μΌλ‘ μ΄μ μ€νμΌλ‘ λ€μ μ ννλλ‘ λ³κ²½λ©λλ€.
λΉλκΈ° ν¨μ/μμ±κΈ°(λκΈ°ν λλ λΉλκΈ°ν)λ₯Ό μμ ν APIλ₯Ό λ ΈμΆν λ€μ μΌμ μ€λ¨ κ°λ₯ν ν¨μλ‘ μ νν μ μμ΅λκΉ?
μμ¬ μ½λλ μ¬μ© μ¬λ‘λ₯Ό ν΅ν΄ λ¬΄μ¨ λ§μΈμ§ λͺ νν ν μ μμ΅λκΉ? μ νν λ΅λ³μ λλ¦¬κ³ μΆμ΅λλ€.
Suspender
μ΄ JSμ μΌλΆκ° λ μλμ
λκΉ μλλ©΄ λ³λμ APIμ
λκΉ? wasm μ μ©μΈκ°μ( WebAssembly.Suspender
)? μ΄ μ μμ TC39μμ λ
Όμλμ΄μΌ νλ€κ³ μκ°ν©λλ€.
νΉλ³ν JS νλ‘κ·Έλ¨μ μν₯μ λ―ΈμΉκΈ° μν κ²μ΄ μλλλ€. λ³΄λ€ μ ννκ²λ JS κΈ°λ₯μ μΌμ μ€λ¨νλ €κ³ νλ©΄ νΈλ©μ΄ λ°μν©λλ€. μ΄λ₯Ό 보μ₯νκΈ° μν΄ λͺ κ°μ§ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
κ·Έλ¬λ λλ Shu-yuμ ν¨κ» κ·Έκ²μ μ κΈ°νμ¬ κ·Έμ μ견μ μ»μ μ μμ΅λλ€.
μ£μ‘ν©λλ€. @chicoxyzzy , Stacks νμ κ·Έλ£Ήμ μΌλΆ 컨ν μ€νΈ/μ λ°μ΄νΈλ₯Ό ν¬ν¨νλ κ²μ μμμ΅λλ€. μ΄μ μ€ν μ ν μ μμ μΌμ μ€λ¨λ μ€νμμ JavaScript/νΈμ€νΈ νλ μμ μΊ‘μ²ν μ μμ΄μΌ νλ€λ μμμΌλ‘ μμ±λμμ΅λλ€. κ·Έλ¬λ μ°λ¦¬λ TC39μ μ¬λλ€λ‘λΆν° μ΄κ²μ΄ JS μνκ³μ λ무 ν° μν₯μ λ―ΈμΉ κ²μ΄λΌλ μ°λ €κ° μλ€λ νΌλλ°±μ λ°μκ³ νΈμ€νΈ ꡬνμλ€λ‘λΆν° λͺ¨λ νΈμ€νΈ νλ μμ΄ μΌμ μ€λ¨μ νμ©ν μ μλ€λ μ°λ €κ° μλ€λ νΌλλ°±μ λ°μμ΅λλ€. λ°λΌμ Stacks Subgroupμ κ·Έ μ΄νλ‘ μ€κ³κ° μ€λ¨λ μ€νμμ WebAssembly(κ΄λ ¨) νλ μλ§ μΊ‘μ²νλλ‘ νμΌλ©° μ΄ μ μμ ν΄λΉ μμ±μ μΆ©μ‘±ν©λλ€. μ΄ μ€μν λ©λͺ¨λ₯Ό ν¬ν¨νλλ‘ OPλ₯Ό μ λ°μ΄νΈνμ΅λλ€.
μ¬κΈ°μμ μ§ν μν©μ 보λ κ²μ΄ μ’μ΅λλ€. μ΄κ²μ΄ Wasmμ© ESM ν΅ν©μμ μ΄λ»κ² μ¬μ©λλμ§μ λν μκ° μμ΅λκΉ?
λμ μμμ μ΄κ²μ΄ λͺ¨λ JS APIμ μκΈ° λλ¬Έμ λ¨μν ESM wasm λͺ¨λμ κ°μ Έμ€κ³ μ΄λ¬ν μ½μμ λν μ€ν μ ν μ§μμ μ»μ μ μλ€λ κ²μ λλ€. μ’μ μμμ μΌλΆ JS ESM λͺ¨λμ μ μ°©μ λ‘ μ¬μ©νμ¬ μ΄ APIμ ν¨κ» ESM λͺ¨λμ κ³μ μ¬μ©ν μ μλ€λ κ²μ λλ€.
νΉν foo-exports.js
, foo-wasm.wasm
λ° foo-imports.js
μΈ κ°μ§ ESM λͺ¨λμ μ€μ ν©λλ€. foo-imports.js
λͺ¨λμ μμ€νλλ₯Ό μμ±νκ³ μ΄λ₯Ό μ¬μ©νμ¬ foo-wasm.wasm
νμν λͺ¨λ "λΉλκΈ°μ" μ½μ μμ± κ°μ Έμ€κΈ°λ₯Ό λννκ³ μμ€νλμ ν΄λΉ κ°μ Έμ€κΈ°λ₯Ό λ΄λ³΄λ
λλ€. foo-wasm.wasm
κ·Έλ° λ€μ foo-imports.js
μμ λͺ¨λ "λΉλκΈ°" κ°μ Έμ€κΈ°λ₯Ό κ°μ Έμ€κ³ ν΄λΉ λͺ¨λμμ λͺ¨λ "λκΈ°" κ°μ Έμ€κΈ°λ₯Ό μ§μ κ°μ Έμ΅λλ€(λλ foo-imports.js
ν΅ν΄ νλ‘μν μλ μμ΅λλ€ foo-exports.js
λ foo-imports.js
μμ μμ€νλλ₯Ό κ°μ Έμ€κ³ foo-wasm.wasm
μ λ΄λ³΄λ΄κΈ°λ₯Ό κ°μ Έμ€κ³ μμ€νλλ₯Ό μ¬μ©νμ¬ "λΉλκΈ°μ" λ΄λ³΄λ΄κΈ°λ₯Ό λνν λ€μ (λνλμ§ μμ) "λκΈ°μ" λ΄λ³΄λ΄κΈ°λ₯Ό λ΄λ³΄λ
λλ€. λ΄λ³΄λ΄κΈ° λ° λνλ "λΉλκΈ°" λ΄λ³΄λ΄κΈ°. κ·Έλ° λ€μ ν΄λΌμ΄μΈνΈλ foo-exports.js
μμ κ°μ Έμ€κ³ foo-wasm.wasm
λλ foo-imports.js
μ§μ λ§μ§κ±°λ μ΄μ λν μ§μμ΄ νμνμ§ μμ΅λλ€.
λΆνν μ₯μ λ¬Όμ΄μ§λ§ ν΅μ¬ wasmμ μμ νμ§ μλλ€λ μ μ½ μ‘°κ±΄μ κ°μν λ μ°λ¦¬κ° λ¬μ±ν μ μλ μ΅μ μ΄μμ΅λλ€. κ·Έλ¬λ μ°λ¦¬λ μ΄ λμμΈμ΄ ν΅μ¬ wasmμ νμ₯νλ μ μκ³Ό μμΌλ‘ νΈν κ°λ₯νλλ‘ νλ κ²μ λͺ©νλ‘ νκ³ μμ΅λλ€. λ°λΌμ μ μμ΄ λ°°μ‘λ λ μ΄ μΈ κ°μ§ λͺ¨λμ νλμ νμ₯λ wasm λͺ¨λλ‘ κ΅μ²΄ν μ μκ³ μ무λ μλ―Έλ‘ μ μΌλ‘ ν μ μμ΅λλ€. μ°¨μ΄μ μ μλ €μ£ΌμΈμ(λͺ¨λλ‘ νμΌ μ΄λ¦ λ°κΎΈκΈ°).
κ·Έκ²μ΄ μ΄ν΄ν μ μμκ³ , κ·Έκ²μ΄ λΉμ μ νμλ₯Ό μΆ©μ‘±μν¬ κ²μ΄λΌκ³ μκ°ν©λκΉ(λΉλ‘ μ΄μνκΈ΄ νμ§λ§)?
μ μ΄λ WebAssembly.Module μ ν Wasm κ°μ Έμ€κΈ°κ° μμ§ κ°λ₯νμ§ μμ λμ(κ·Έλ¦¬κ³ μ μ ν μκΈ°μ μ΄λ£¨μ΄μ§κΈ°λ₯Ό λ°λλλ€) λνμ νμμ±μ μ΄ν΄ν©λλ€.
μ’ λ ꡬ체μ μΌλ‘ λ§νμλ©΄, ESM ν΅ν©μμ μ΄λ¬ν ν¨ν΄μ μ₯μν μ μλ λ²μκ° μλμ§ κΆκΈνμ¬ λ©λΉ΅ μ μ°©μ μ μλ©΄μ λ μ κ΄λ¦¬ν μ μμ΅λλ€. μλ₯Ό λ€μ΄ μ΄μ§ νμμΌλ‘ λ΄λ³΄λΈ κΈ°λ₯κ³Ό κ°μ Έμ¨ κΈ°λ₯μ μ°κ²°νλ μΌλΆ λ©νλ°μ΄ν°κ° μλ κ²½μ° ESM ν΅ν©μ μ΄λ₯Ό μ‘°μ¬νκ³ μμΈ‘ κ°λ₯ν νΉμ κ·μΉμ κΈ°λ°μΌλ‘ ν΅ν© κ³μΈ΅μ μΌλΆλ‘ μ΄μ€ κ°μ Έμ€κΈ°/λ΄λ³΄λ΄κΈ° λν μμ€νλ κΈ°λ₯μ λ΄λΆμ μΌλ‘ μΌμΉμν¬ μ μμ΅λλ€.
μ. νμ¬λ‘μλ κ·Έλ¬ν κ³νμ΄ μμ΅λλ€. λ΄κ° λ°μ νΌλλ°±μ ESM ν΅ν©λ λ³κ²½νμ§ μμΌλ €λ λ°λμ΄ μλ€λ κ²μ΄μμ΅λλ€. μ컨λ, μ΄ λͺ¨λ κ²μ΄ κ²°κ΅ μ½μ΄ wasmμμ κ°λ₯νκΈ°λ₯Ό ν¬λ§νλ©°, λ°λΌμ μ°λ¦¬λ μ΄ μ μμ΄ κ°λ₯ν ν μμ λ°μκ΅μ λ¨κΈ°κΈ°λ₯Ό μν©λλ€.
λ΄κ° λ°μ νΌλλ°±μ ESM ν΅ν©λ λ³κ²½νμ§ μμΌλ €λ λ°λμ΄ μλ€λ κ²μ΄μμ΅λλ€.
μ΄ νΌλλ°±μ΄ μ΄λμμ μ€λμ§ μμΈν μ€λͺ ν΄ μ£Όμκ² μ΅λκΉ? λ λμ μμ€μ ν΅ν© μλ―Έλ‘ μΌλ‘ ESM ν΅ν©μ νμ₯ν μ μλ λ§μ λ²μκ° μμ΅λλ€. λ΄κ° μκ°νλ 곡κ°μ΄ μμ ν νμλμ§ μμκΈ° λλ¬Έμ μ΄ λ¬Έμ λ₯Ό μ κΈ°ν κ²μ λλ€. λλ κ³Όκ±°μ μ΄ μμμ κ°μ νλ κ²μ λν μ νμ λν΄ λ€μ΄λ³Έ μ μ΄ μμ΅λλ€. μ΄κ²μ μκ°λ§(sugaring)μ μν μμμΌλ‘ 보λ κ²μ μ§μ Promise κ°μ Έμ€κΈ°/λ΄λ³΄λ΄κΈ°λ₯Ό νμ©νλ JS κ°λ°μμκ² μ΄μ μ΄ λ μ μμ΅λλ€.
μ΄ μ μμ ESM ν΅ν©μμ JS μ£ΌκΈ° κΈ°λ₯ νΈμ΄μ€ν λλΆμ νμ¬ ν¨μ κ°μ Έμ€κΈ°λ₯Ό μν΄ μ¬μ ν μλν μ μλ Wasm λͺ¨λμ λν κ°μ Έμ€κΈ° λ° κ°μ Έμ€κΈ°κ° λλ μ£ΌκΈ°μ λ¨μΌ JS λͺ¨λ κΈ°λ₯μ λ°©ν΄νλ€λ μ μ μ£Όλͺ©ν κ°μΉκ° μμ΅λλ€. , κ·Έλ¬λ κ°μ Έμ¨ ν¨μ μ£Όμμ Suspender ννμ λνΌλ₯Ό μ¬μ©νμ¬ μ΄ μ£ΌκΈ° νΈμ΄μ€ν μ μ§μνμ§ μμ΅λλ€.
@lukewagnerμκ² μ΄λ° μΈμμ λ°μμ΅λλ€. ESM ν΅ν©μ νμ₯ν μ μλ λ²μκ° μλ€λ λ° λμνμ§λ§, μ΄λ₯Ό μν΄μλ wasm νμΌμ λν λ³κ²½/νμ₯μ΄ νμνλ€λ μ μ λμν©λλ€(μκ·λͺ¨ λͺ©νμ μΌνμΌλ‘). κ·Έλμ μ°λ¦¬λ κ·Έλ¬ν λ³κ²½μ μνμ§ μμμ΅λλ€/ μ΄ μ μμ μΌλΆλ‘ νμ₯λ©λλ€. λ¬Όλ‘ μ΄λ¬ν λ³κ²½/νμ₯μ΄ ESM μ μμ μΆκ°λλ©΄ μ΄ μ μμ΄ μ 곡νλ κΈ°λ₯μ μ»κΈ° μν΄ JS λνΌ λͺ¨λμ΄ νμνμ§ μλλ‘ μ΄ μ μμ μ΄μμ μΌλ‘ 보μν κ²μ λλ€.
@Jack-Worksμ μ견μ μλͺ» μ½κ³ μμ μ견μ μμ νμ΅λλ€.
μ€λͺ μ λν΄ @RossTate μκ² κ°μ¬λ립λλ€. μ, νΈμ€νΈ ν΅ν©μ μ리기 μν΄ λ°μ΄λ리 μ체μ λ©νλ°μ΄ν°λ₯Ό ν΅ν΄ μ΄λ¬ν κ°μ Έμ€κΈ° λ° λ΄λ³΄λ΄κΈ° μΌμ μ€λ¨ 컨ν μ€νΈλ₯Ό μΌμΉμν¬ κ°λ₯μ±μ νμνλ κ²μ΄ μ’μ΅λλ€. κ·Έλ¬λ MVPμμλ μ΄λ₯Ό κΈ°λνμ§ μμ΅λλ€. λλ λν ESM ν΅ν©μ΄ κΈ°λ³Έ JS APIμ λ³λλ‘ μ€νμΌλ‘λΆν° λ μΌλ°μ μΌλ‘ ννμ λ°μ μ μλ 곡κ°μμ μ§μ ν κΈ°νλ₯Ό κ°μ΅λλ€.
λͺ
νν νμλ©΄, λ΄κ° μ§μ ν λ¬Έμ λ μ°λ¦¬κ° WebAssembly.instantiate()
μΆκ°ν μ΅μ
(λλ μ 맀κ°λ³μκ° μλ WebAssembly.instantiate()
μ μ λ²μ )λ wasmμ΄ ESMμ ν΅ν΄ λ‘λλ λ μ΄λ»κ²λ νμλμ΄μΌ νλ€λ κ²μ
λλ€. -ν΅ν©, ESM ν΅ν©μ΄ λ³κ²½ λΆκ°λ₯νλ€λ κ²μ΄ μλλλ€.
μ, λ©μ§κ΅°μ. κ·Έλμ μ°λ¦¬λ νμμ λ°λΌ ESMκ³Ό κ΄λ ¨νμ¬ μκ°νλ κ²λ³΄λ€ λ λ§μ μ μ°μ±μ κ°μ§κ³ μμ΅λλ€. μ μ€ν΄λ₯Ό κ³ μ³μ£Όμ μ κ°μ¬ν©λλ€.
λ΄λ³΄λΈ νΉμ Wasm ν¨μκ° JSμ Promise κΈ°λ° APIλ‘ νμλμ΄μΌ νλ λ°©λ²κ³Ό λ°λλ‘ Wasmμμ κ°μ Έμ€κΈ°λ₯Ό JS Promise κΈ°λ° APIμμ μ΄λ€ μ’ λ₯λ‘ λ³νν μ μλμ§ μ§μ νλ μΌμ’ μ μ¬μ©μ μ μ μΉμ μ λν΄ μ΄μΌκΈ°νκ³ μλ κ² κ°μ΅λλ€. μ€ν μ€μμΉμ. λ΄κ° μ¬λ°λ₯΄κ² μ΄ν΄νκ³ μμ΅λκΉ?
λλ μ΄ μμ΄λμ΄λ₯Ό μ’μνλ€. λλ μ°λ¦¬κ° Wasm GC/JS-ESM ν΅ν©μ μν μ μ¬ν μ¬μ©μ μ μ μΉμ (λλ λμΌν μΉμ μ μΌλΆ)μ μν κ²μ΄λΌκ³ μκ°ν©λλ€. μ΄ μ¬μ©μ μ μ μΉμ μ΄ μΈμ΄ κ° μ΄λ μ λμΈμ§λ νμ€νμ§ μμ§λ§ λ κ²½μ° λͺ¨λ μΈν°νμ΄μ€ μ νλ³΄λ€ λ 보νΈμ μ΄λ©° κ΅¬μ± μμ μ¬μ΄λΏλ§ μλλΌ κ΅¬μ± μμ λ΄ μμ μ¬μ©λλ κ²½ν₯μ΄ μμ΅λλ€.
μ΄ μ¬μ©μ μ μ μΉμ μ κΈ°λ³Έ λμμΈμ μ€λͺ νλ μΌμ’ μ μμ§ λλ READMEλ₯Ό μμ±νκ³ μΆμ μ¬λμ΄ μμ΅λκΉ?
κ°λ₯ν μ΅μ μΈ κ² κ°μ΅λλ€. μΈκΈνλ―μ΄ WebAssembly/gc#203κ³Ό κ°μ GC μ μμμ μ μ¬ν μ΅μ μ΄ λ Όμλμμ΅λλ€. JS-ν΅ν©μ λ΄μΌ GC νμ κ·Έλ£Ήμμ λ Όμλ μμ μ΄λ―λ‘ ν΄λΉ ν λ‘ μ€μ μ΄ μ μκ³Όμ κ°λ₯ν μ°κ²°μ μΌλμ λλ κ²μ΄ μ’μ΅λλ€(λλ ν λ‘ μ΄ μ΄λ»κ² μ§νλλμ§μ λ°λΌ κ΄λ ¨μ΄ μλ κ²μΌλ‘ νλͺ λ μ μμ).