341 |
341 |
342 // Any access to LET and CONST variables before their declaration must throw ReferenceError. |
342 // Any access to LET and CONST variables before their declaration must throw ReferenceError. |
343 // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a |
343 // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a |
344 private void checkTemporalDeadZone(final IdentNode identNode) { |
344 private void checkTemporalDeadZone(final IdentNode identNode) { |
345 if (identNode.isDead()) { |
345 if (identNode.isDead()) { |
346 method.load(identNode.getSymbol().getName()); |
346 method.load(identNode.getSymbol().getName()).invoke(ScriptRuntime.THROW_REFERENCE_ERROR); |
347 method.invoke(ScriptRuntime.THROW_REFERENCE_ERROR); |
347 } |
|
348 } |
|
349 |
|
350 // Runtime check for assignment to ES6 const |
|
351 private void checkAssignTarget(final Expression expression) { |
|
352 if (expression instanceof IdentNode && ((IdentNode)expression).getSymbol().isConst()) { |
|
353 method.load(((IdentNode)expression).getSymbol().getName()).invoke(ScriptRuntime.THROW_CONST_TYPE_ERROR); |
348 } |
354 } |
349 } |
355 } |
350 |
356 |
351 private boolean isRestOf() { |
357 private boolean isRestOf() { |
352 return continuationEntryPoints != null; |
358 return continuationEntryPoints != null; |
785 return false; |
791 return false; |
786 } |
792 } |
787 |
793 |
788 @Override |
794 @Override |
789 public boolean enterASSIGN(final BinaryNode binaryNode) { |
795 public boolean enterASSIGN(final BinaryNode binaryNode) { |
|
796 checkAssignTarget(binaryNode.lhs()); |
790 loadASSIGN(binaryNode); |
797 loadASSIGN(binaryNode); |
791 return false; |
798 return false; |
792 } |
799 } |
793 |
800 |
794 @Override |
801 @Override |
795 public boolean enterASSIGN_ADD(final BinaryNode binaryNode) { |
802 public boolean enterASSIGN_ADD(final BinaryNode binaryNode) { |
|
803 checkAssignTarget(binaryNode.lhs()); |
796 loadASSIGN_ADD(binaryNode); |
804 loadASSIGN_ADD(binaryNode); |
797 return false; |
805 return false; |
798 } |
806 } |
799 |
807 |
800 @Override |
808 @Override |
801 public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) { |
809 public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) { |
|
810 checkAssignTarget(binaryNode.lhs()); |
802 loadASSIGN_BIT_AND(binaryNode); |
811 loadASSIGN_BIT_AND(binaryNode); |
803 return false; |
812 return false; |
804 } |
813 } |
805 |
814 |
806 @Override |
815 @Override |
807 public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) { |
816 public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) { |
|
817 checkAssignTarget(binaryNode.lhs()); |
808 loadASSIGN_BIT_OR(binaryNode); |
818 loadASSIGN_BIT_OR(binaryNode); |
809 return false; |
819 return false; |
810 } |
820 } |
811 |
821 |
812 @Override |
822 @Override |
813 public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) { |
823 public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) { |
|
824 checkAssignTarget(binaryNode.lhs()); |
814 loadASSIGN_BIT_XOR(binaryNode); |
825 loadASSIGN_BIT_XOR(binaryNode); |
815 return false; |
826 return false; |
816 } |
827 } |
817 |
828 |
818 @Override |
829 @Override |
819 public boolean enterASSIGN_DIV(final BinaryNode binaryNode) { |
830 public boolean enterASSIGN_DIV(final BinaryNode binaryNode) { |
|
831 checkAssignTarget(binaryNode.lhs()); |
820 loadASSIGN_DIV(binaryNode); |
832 loadASSIGN_DIV(binaryNode); |
821 return false; |
833 return false; |
822 } |
834 } |
823 |
835 |
824 @Override |
836 @Override |
825 public boolean enterASSIGN_MOD(final BinaryNode binaryNode) { |
837 public boolean enterASSIGN_MOD(final BinaryNode binaryNode) { |
|
838 checkAssignTarget(binaryNode.lhs()); |
826 loadASSIGN_MOD(binaryNode); |
839 loadASSIGN_MOD(binaryNode); |
827 return false; |
840 return false; |
828 } |
841 } |
829 |
842 |
830 @Override |
843 @Override |
831 public boolean enterASSIGN_MUL(final BinaryNode binaryNode) { |
844 public boolean enterASSIGN_MUL(final BinaryNode binaryNode) { |
|
845 checkAssignTarget(binaryNode.lhs()); |
832 loadASSIGN_MUL(binaryNode); |
846 loadASSIGN_MUL(binaryNode); |
833 return false; |
847 return false; |
834 } |
848 } |
835 |
849 |
836 @Override |
850 @Override |
837 public boolean enterASSIGN_SAR(final BinaryNode binaryNode) { |
851 public boolean enterASSIGN_SAR(final BinaryNode binaryNode) { |
|
852 checkAssignTarget(binaryNode.lhs()); |
838 loadASSIGN_SAR(binaryNode); |
853 loadASSIGN_SAR(binaryNode); |
839 return false; |
854 return false; |
840 } |
855 } |
841 |
856 |
842 @Override |
857 @Override |
843 public boolean enterASSIGN_SHL(final BinaryNode binaryNode) { |
858 public boolean enterASSIGN_SHL(final BinaryNode binaryNode) { |
|
859 checkAssignTarget(binaryNode.lhs()); |
844 loadASSIGN_SHL(binaryNode); |
860 loadASSIGN_SHL(binaryNode); |
845 return false; |
861 return false; |
846 } |
862 } |
847 |
863 |
848 @Override |
864 @Override |
849 public boolean enterASSIGN_SHR(final BinaryNode binaryNode) { |
865 public boolean enterASSIGN_SHR(final BinaryNode binaryNode) { |
|
866 checkAssignTarget(binaryNode.lhs()); |
850 loadASSIGN_SHR(binaryNode); |
867 loadASSIGN_SHR(binaryNode); |
851 return false; |
868 return false; |
852 } |
869 } |
853 |
870 |
854 @Override |
871 @Override |
855 public boolean enterASSIGN_SUB(final BinaryNode binaryNode) { |
872 public boolean enterASSIGN_SUB(final BinaryNode binaryNode) { |
|
873 checkAssignTarget(binaryNode.lhs()); |
856 loadASSIGN_SUB(binaryNode); |
874 loadASSIGN_SUB(binaryNode); |
857 return false; |
875 return false; |
858 } |
876 } |
859 |
877 |
860 @Override |
878 @Override |