Design: suporte assíncrono / promessa

Criado em 7 jan. 2018  ·  7Comentários  ·  Fonte: WebAssembly/design

Muitas bibliotecas JavaScript são assíncronas e ainda não vi se o WebAssembly oferece suporte a promessas.
Para escrever facilmente aplicativos de alto desempenho que aproveitam o ecossistema JS, sugiro adicionar suporte de promessas em funções importadas.

Por exemplo, isso deve funcionar:

const importObject = { 
  returnOneAsync: () => new Promise(done => done(1)) 
};
extern "C" int returnOneAsync();

int main(){
  int x = returnOneAsync(); // should suspend main until promise resolved.
  return x+x;
}

Comentários muito úteis

Acho que você entendeu mal o modelo computacional da web. O JavaScript não é multi-threaded, portanto, suspender uma computação interromperia o mecanismo e, na verdade, todo o renderizador que o hospeda. A página congelaria e nenhum outro código poderia ser executado (exceto workers separados). Você precisaria de uma maneira de reificar e depois restaurar as continuações para fazer a suspensão voar, o que não é algo que os motores podem fazer atualmente.

Todos 7 comentários

Qualquer suporte de promessas de JS teria que fazer parte da proposta de vinculações de host JS .

Mas temo que não possa funcionar como seu exemplo sugere, já que isso exigiria que o próprio C entendesse a execução e suspensão assíncrona, o que não acontece. Além disso, não há nada assíncrono em seu exemplo, ele apenas cria uma promessa, então o código equivalente nem mesmo seria suspenso no próprio JS, mas apenas produzisse uma string como "[object Promise][object Promise]" .

Além disso, não há nada assíncrono em seu exemplo

Bem, o valor não está disponível até que o eventloop processe a promessa.
A ideia é suspender a execução do mecanismo de montagem da web até que o valor esteja disponível.
O exemplo fornecido é muito trivial. Um exemplo mais concreto poderia ser fazer uma consulta de banco de dados na rede: getAgeOf: (name) => db.find({name}).then(x=>x.age)

C para entender a execução e suspensão assíncrona, que ele não

Isso está incorreto. Existem várias implementações de co-rotina para C.
Além disso, o LLVM-5.0 e posteriores suportam corrotinas e async / await.

https://llvm.org/docs/Coroutines.html

E como um adendo ao C ++ 17, há a co-rotina-ts que foi implementada desde o clang-5.0.
Já existem algumas bibliotecas experimentais que o utilizam:
https://github.com/lewissbaker/cppcoro#generator

Implementações de corrotinas em C não interoperam magicamente com o loop de eventos do JavaScript. Além disso, eles geralmente dependem do comportamento específico da implementação. Para implementar de maneira confiável e portátil algo como corrotinas ou assíncrono, você precisa de uma forma de continuações delimitadas na linguagem. O mais próximo que C tem a oferecer é longjmp, o que não é suficiente e não pode ser implementado no próprio Wasm (com Emscripten, longjmp é implementado em JS com exceções JS). Wasm atualmente não pode expressar suspensão, embora haja planos para adicionar algo nesse sentido, eventualmente. As corrotinas C ++ ainda não são padrão e não podem ser manipuladas pelo Emscripten AFAICT.

Eu vejo de onde você está vindo.
Acho que não expressei minha ideia bem o suficiente.
Não estou sugerindo dar suporte a corrotinas nem promessas em C / C ++ ou perceber isso no bytecode wasm.

Mas temo que não possa funcionar como seu exemplo sugere, já que isso exigiria que o próprio C entendesse a execução e suspensão assíncrona, o que não

Por que você acha que é necessário para C entender a execução assíncrona?

Qual é a dificuldade técnica para suspender o mecanismo de execução do wasm até que a promessa seja resolvida?

Eu entendo que o wasm deve ser compilado antecipadamente para x86, mas isso não significa que você não tem controle sobre o fluxo de execução.
Uma maneira comum de parar a execução é usar interrupções de hardware e syscalls como ptrace; é assim que o depurador funciona. Nós sabemos exatamente quais funções são importadas e poderíamos injetar os opcodes apropriados (x86) para fazer isso. Embora isso vá desacelerar a execução dessas funções - não faria diferença, pois, nesses casos, estamos esperando que a promessa seja resolvida de qualquer maneira.
É assim que implementamos suspender / depurar / retomar em nosso C ++ JIT / AoT baseado em LLVM.

Acho que esse problema deve ser arquivado no repositório de ligações de host ...

Acho que você entendeu mal o modelo computacional da web. O JavaScript não é multi-threaded, portanto, suspender uma computação interromperia o mecanismo e, na verdade, todo o renderizador que o hospeda. A página congelaria e nenhum outro código poderia ser executado (exceto workers separados). Você precisaria de uma maneira de reificar e depois restaurar as continuações para fazer a suspensão voar, o que não é algo que os motores podem fazer atualmente.

Acho que você entendeu mal o modelo computacional da web. O JavaScript não é multi-threaded, portanto, suspender uma computação interromperia o mecanismo e, na verdade, todo o renderizador que o hospeda. A página congelaria e nenhum outro código poderia ser executado (exceto workers separados). Você precisaria de uma maneira de reificar e depois restaurar as continuações para fazer a suspensão voar, o que não é algo que os motores podem fazer atualmente.

Exatamente, o wasm deve ser executado dentro dos workers, pois ambos são criados para tarefas de computação, em vez de lidar com a IU.

Esta página foi útil?
0 / 5 - 0 avaliações