11// @ts -check
22
33const { StackOpcode, InputOpcode, InputType} = require ( './enums.js' ) ;
4+ const log = require ( '../util/log' ) ;
45
56// These imports are used by jsdoc comments but eslint doesn't know that
67/* eslint-disable no-unused-vars */
@@ -16,7 +17,7 @@ const {
1617class TypeState {
1718 constructor ( ) {
1819 /** @type {Object.<string, InputType | 0> }*/
19- this . variables = { } ;
20+ this . variables = Object . create ( null ) ;
2021 }
2122
2223 /**
@@ -30,7 +31,7 @@ class TypeState {
3031 break ;
3132 }
3233 }
33- this . variables = { } ;
34+ this . variables = Object . create ( null ) ;
3435 return modified ;
3536 }
3637
@@ -93,7 +94,7 @@ class TypeState {
9394 after ( other ) {
9495 return this . mutate ( other , varId => {
9596 const otherType = other . variables [ varId ] ;
96- if ( otherType !== 0 ) return otherType ;
97+ if ( otherType ) return otherType ;
9798 return this . variables [ varId ] ?? InputType . ANY ;
9899 } ) ;
99100 }
@@ -541,29 +542,37 @@ class IROptimizer {
541542 state = state . clone ( ) ;
542543 }
543544
544- modified = this . analyzeInputs ( inputs , state ) || modified ;
545-
546545 switch ( stackBlock . opcode ) {
547546 case StackOpcode . VAR_SET :
547+ modified = this . analyzeInputs ( inputs , state ) || modified ;
548548 modified = state . setVariableType ( inputs . variable , inputs . value . type ) || modified ;
549549 break ;
550550 case StackOpcode . CONTROL_WHILE :
551551 case StackOpcode . CONTROL_FOR :
552552 case StackOpcode . CONTROL_REPEAT :
553+ modified = this . analyzeInputs ( inputs , state ) || modified ;
553554 modified = this . analyzeLoopedStack ( inputs . do , state , stackBlock ) || modified ;
554555 break ;
555556 case StackOpcode . CONTROL_IF_ELSE : {
557+ modified = this . analyzeInputs ( inputs , state ) || modified ;
556558 const trueState = state . clone ( ) ;
557559 modified = this . analyzeStack ( inputs . whenTrue , trueState ) || modified ;
558560 modified = this . analyzeStack ( inputs . whenFalse , state ) || modified ;
559561 modified = state . or ( trueState ) || modified ;
560562 break ;
561563 }
562564 case StackOpcode . CONTROL_STOP_SCRIPT : {
565+ modified = this . analyzeInputs ( inputs , state ) || modified ;
563566 this . addPossibleExitState ( state ) ;
564567 break ;
565568 }
569+ case StackOpcode . CONTROL_WAIT_UNTIL : {
570+ modified = state . clear ( ) || modified ;
571+ modified = this . analyzeInputs ( inputs , state ) || modified ;
572+ break ;
573+ }
566574 case StackOpcode . PROCEDURE_CALL : {
575+ modified = this . analyzeInputs ( inputs , state ) || modified ;
567576 modified = this . analyzeInputs ( inputs . inputs , state ) || modified ;
568577 const script = this . ir . procedures [ inputs . variant ] ;
569578
@@ -575,6 +584,7 @@ class IROptimizer {
575584 break ;
576585 }
577586 case StackOpcode . COMPATIBILITY_LAYER : {
587+ modified = this . analyzeInputs ( inputs , state ) || modified ;
578588 this . analyzeInputs ( inputs . inputs , state ) ;
579589 for ( const substackName in inputs . substacks ) {
580590 const newState = state . clone ( ) ;
@@ -583,6 +593,9 @@ class IROptimizer {
583593 }
584594 break ;
585595 }
596+ default :
597+ modified = this . analyzeInputs ( inputs , state ) || modified ;
598+ break ;
586599 }
587600
588601 return modified ;
@@ -635,7 +648,7 @@ class IROptimizer {
635648 do {
636649 // If we are stuck in an apparent infinite loop, give up and assume the worst.
637650 if ( iterations > 10000 ) {
638- console . error ( 'analyzeLoopedStack stuck in likely infinite loop; quitting' , block , state ) ;
651+ log . error ( 'analyzeLoopedStack stuck in likely infinite loop; quitting' , block , state ) ;
639652 modified = state . clear ( ) ;
640653 block . entryState = state . clone ( ) ;
641654 block . exitState = state . clone ( ) ;
@@ -646,8 +659,8 @@ class IROptimizer {
646659
647660 const newState = state . clone ( ) ;
648661 modified = this . analyzeStack ( stack , newState ) || modified ;
649- modified = this . analyzeInputs ( block . inputs , newState ) || modified ;
650662 modified = ( keepLooping = state . or ( newState ) ) || modified ;
663+ modified = this . analyzeInputs ( block . inputs , state ) || modified ;
651664 } while ( keepLooping ) ;
652665 block . entryState = state . clone ( ) ;
653666 return modified ;
0 commit comments