Design: Clarification de l'éclatement de la pile pour les branches conditionnelles

Créé le 27 mars 2017  ·  5Commentaires  ·  Source: WebAssembly/design

Je joue avec l'écriture d'un compilateur WebAssembly. Je regarde le test https://github.com/WebAssembly/spec/blob/634f0d9009404f498ef8d8bd510bd6f0941219cc/test/core/br_if.wast#L272 qui ressemble à ceci étendu un peu :

(module
    (func
      $type-arg-void-vs-num-nested
      (result i32)

      block i32
        (i32.const 0)
        block
          (i32.const 1)
          (br_if 1)
        end
      end
    )
)

L'erreur que j'obtiens est :

Error: check failed:
test.wast:10:12
type stack size too small at br_if value. got 0, expected at least 1
          (br_if 1)
           ^^^^^^^

Je pense que la taille de la pile lorsqu'elle atteint br_if est de 2, ce qui signifie qu'elle affiche 1 pour le conditionnel, puis qu'il en reste un pour satisfaire le bloc extérieur. J'ai supposé que (i32.const 0) tomberait dans le bloc imbriqué. Quelle partie me manque-t-il ? Merci d'avance.

Commentaire le plus utile

>

Cela signifie-t-il que chaque bloc a sa propre pile ?

Je ne dirais pas qu'ils ont leurs propres stacks, juste qu'il y a une limite
à ce qui peut être sauté. C'est en fait comme ça que c'est implémenté dans wabt, là
est une pile de valeurs et une pile "d'étiquettes". Chaque étiquette stocke une "limite" qui est
la taille de la pile de valeurs lorsque l'étiquette est poussée. Ensuite, chaque fois que vous
pop, vous vérifiez par rapport à la limite de l'étiquette supérieure.

Les deux sont des vues valides. Sémantiquement, la vue "block-local stack" a le
avantage qu'il ne nécessite pas d'invariants supplémentaires. Avec "pile unique"
des hypothèses d'exactitude supplémentaires sont nécessaires, telles que toutes les limites
apparaissant dans la pile d'étiquettes doit être dans les limites de la pile d'opérandes actuelle
hauteur, ils doivent se produire dans (pas nécessairement strictement) ordre croissant, et
la pile d'étiquettes ne doit jamais être vide.

Tous les 5 commentaires

Oui, le rapport d'erreur de wabt peut s'améliorer ici. Même s'il y a deux i32 sur la pile, les opérateurs ne dépasseront jamais le début d'un bloc, il n'y en a donc effectivement qu'un.

Cela signifie-t-il que chaque bloc a sa propre pile ? J'ai été confus par la déclaration suivante dans le document sémantique:

L'exécution d'une instruction de bloc ou de boucle n'a aucun effet sur la pile de valeurs.

Peut-être que cela devrait changer pour :

L'exécution d'un bloc ou d'une instruction de boucle n'a aucun effet sur la pile de valeurs, mais toutes les valeurs de pile en dehors du bloc d'exécution sont inaccessibles.

Ou est-ce que j'ai mal compris ?

Cela signifie-t-il que chaque bloc a sa propre pile ?

Je ne dirais pas qu'ils ont leurs propres stacks, juste qu'il y a une limite à ce qui peut être éclaté. C'est en fait comme ça que c'est implémenté dans wabt, il y a une pile de valeurs et une pile "label". Chaque étiquette stocke une "limite" qui correspond à la taille de la pile de valeurs lorsque l'étiquette est poussée. Ensuite, chaque fois que vous pop, vous vérifiez par rapport à la limite de l'étiquette supérieure.

L'exécution d'une instruction de bloc ou de boucle n'a aucun effet sur la pile de valeurs.

Peut-être que cela devrait changer pour :

L'exécution d'un bloc ou d'une instruction de boucle n'a aucun effet sur la pile de valeurs, mais toutes les valeurs de pile en dehors du bloc exécutant le bloc sont inaccessibles.

Ou est-ce que j'ai mal compris ?

Oui, cela vaut probablement la peine de mentionner quelque chose comme ça dans Semantics.md. Bien que je doive mentionner qu'il y a aussi du travail sur une spécification de prose formelle.

>

Cela signifie-t-il que chaque bloc a sa propre pile ?

Je ne dirais pas qu'ils ont leurs propres stacks, juste qu'il y a une limite
à ce qui peut être sauté. C'est en fait comme ça que c'est implémenté dans wabt, là
est une pile de valeurs et une pile "d'étiquettes". Chaque étiquette stocke une "limite" qui est
la taille de la pile de valeurs lorsque l'étiquette est poussée. Ensuite, chaque fois que vous
pop, vous vérifiez par rapport à la limite de l'étiquette supérieure.

Les deux sont des vues valides. Sémantiquement, la vue "block-local stack" a le
avantage qu'il ne nécessite pas d'invariants supplémentaires. Avec "pile unique"
des hypothèses d'exactitude supplémentaires sont nécessaires, telles que toutes les limites
apparaissant dans la pile d'étiquettes doit être dans les limites de la pile d'opérandes actuelle
hauteur, ils doivent se produire dans (pas nécessairement strictement) ordre croissant, et
la pile d'étiquettes ne doit jamais être vide.

Merci pour l'info. Je ferme ceci car il n'y a rien d'actionnable à en tirer et des spécifications plus formelles arrivent pour le préciser.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

aaabbbcccddd00001111 picture aaabbbcccddd00001111  ·  3Commentaires

Artur-A picture Artur-A  ·  3Commentaires

void4 picture void4  ·  5Commentaires

nikhedonia picture nikhedonia  ·  7Commentaires

jfbastien picture jfbastien  ·  6Commentaires