@@ -275,9 +275,9 @@ private DynValue Processing_Loop(int instructionPtr, bool canAwait = false)
275
275
{
276
276
ref var top = ref m_ValueStack . Peek ( ) ;
277
277
if ( top . Type != DataType . Table ) throw new InternalErrorException ( "v-stack top NOT table" ) ;
278
- top . Table . Kind = ( TableKind ) i . NumVal ;
278
+ top . Table . Kind = ( TableKind ) i . NumVal2 ;
279
279
top . Table . ReadOnly = i . NumVal3 != 0 ;
280
- top . Table . ModifierFlags = ( MemberModifierFlags ) i . NumVal2 ;
280
+ top . Table . ModifierFlags = ( MemberModifierFlags ) i . NumVal ;
281
281
break ;
282
282
}
283
283
case OpCode . SetMetaTab :
@@ -387,6 +387,15 @@ private DynValue Processing_Loop(int instructionPtr, bool canAwait = false)
387
387
case OpCode . NewRange :
388
388
ExecNewRange ( i ) ;
389
389
break ;
390
+ case OpCode . SetPriv :
391
+ ExecSetPriv ( i ) ;
392
+ break ;
393
+ case OpCode . CopyPriv :
394
+ ExecCopyPriv ( i ) ;
395
+ break ;
396
+ case OpCode . MergePriv :
397
+ ExecMergePriv ( i ) ;
398
+ break ;
390
399
case OpCode . ToNum :
391
400
{
392
401
ref var top = ref m_ValueStack . Peek ( ) ;
@@ -618,6 +627,40 @@ private void ExecExpTuple(Instruction i)
618
627
619
628
}
620
629
630
+ private void ExecSetPriv ( Instruction i )
631
+ {
632
+ ref DynValue t = ref m_ValueStack . Peek ( i . NumVal ) ;
633
+ if ( t . Type != DataType . Table )
634
+ throw new InternalErrorException ( "SETPRIV called on non-table object" ) ;
635
+ t . Table . PrivateKeys = new PrivateKeyInfo ( ) ;
636
+ while ( i . NumVal -- > 0 ) {
637
+ t . Table . PrivateKeys . Fields . Add ( m_ValueStack . Pop ( ) . CastToString ( ) ) ;
638
+ }
639
+ }
640
+
641
+ private void ExecCopyPriv ( Instruction i )
642
+ {
643
+ ref DynValue dest = ref m_ValueStack . Peek ( 1 ) ;
644
+ ref DynValue src = ref m_ValueStack . Peek ( 0 ) ;
645
+ if ( dest . Type != DataType . Table || src . Type != DataType . Table )
646
+ throw new InternalErrorException ( "COPYPRIV called on non-table object" ) ;
647
+ dest . Table . PrivateKeys = src . Table . PrivateKeys ;
648
+ m_ValueStack . Pop ( ) ;
649
+ }
650
+
651
+ private void ExecMergePriv ( Instruction i )
652
+ {
653
+ ref DynValue dest = ref m_ValueStack . Peek ( i . NumVal2 ) ;
654
+ ref DynValue src = ref m_ValueStack . Peek ( i . NumVal ) ;
655
+ if ( dest . Type != DataType . Table || src . Type != DataType . Table )
656
+ throw new InternalErrorException ( "MERGEPRIV called on non-table object" ) ;
657
+ if ( src . Table . PrivateKeys != null )
658
+ {
659
+ dest . Table . PrivateKeys ??= new PrivateKeyInfo ( ) ;
660
+ dest . Table . PrivateKeys . Merge ( src . Table . PrivateKeys ) ;
661
+ }
662
+ }
663
+
621
664
private void ExecIterPrep ( )
622
665
{
623
666
DynValue v = m_ValueStack . Pop ( ) ;
@@ -1690,7 +1733,9 @@ private int ExecIndexSet(Instruction i, int instructionPtr)
1690
1733
// stack: vals.. - base - index
1691
1734
bool isNameIndex = i . OpCode == OpCode . IndexSetN ;
1692
1735
bool isMultiIndex = ( i . OpCode == OpCode . IndexSetL ) ;
1693
-
1736
+ // extract privateAccess bool from spare bit in numVal
1737
+ bool accessPrivate = ( i . NumVal & 0x40000000 ) != 0 ;
1738
+ i . NumVal &= 0x3FFFFFFF ;
1694
1739
string i_str = GetString ( ( int ) i . NumVal3 ) ;
1695
1740
DynValue originalIdx = i_str != null ? DynValue . NewString ( i_str ) : m_ValueStack . Pop ( ) ;
1696
1741
DynValue idx = originalIdx . ToScalar ( ) ;
@@ -1710,6 +1755,12 @@ private int ExecIndexSet(Instruction i, int instructionPtr)
1710
1755
1711
1756
if ( ! isMultiIndex )
1712
1757
{
1758
+ //Private fields - error on write
1759
+ if ( ! accessPrivate && obj . Table . PrivateKeys != null &&
1760
+ obj . Table . PrivateKeys . IsKeyPrivate ( idx ) )
1761
+ {
1762
+ throw new ScriptRuntimeException ( $ "cannot write to private key '{ idx . ToPrintString ( ) } '") ;
1763
+ }
1713
1764
//Don't do check for __newindex if there is no metatable to begin with
1714
1765
if ( obj . Table . MetaTable == null || ! obj . Table . Get ( idx ) . IsNil ( ) )
1715
1766
{
@@ -1796,6 +1847,7 @@ private int ExecIndex(Instruction i, int instructionPtr)
1796
1847
// stack: base - index
1797
1848
bool isNameIndex = i . OpCode == OpCode . IndexN ;
1798
1849
bool isMultiIndex = i . OpCode == OpCode . IndexL ;
1850
+ bool accessPrivate = i . NumVal3 > 0 ;
1799
1851
1800
1852
string i_str = GetString ( i . NumVal ) ;
1801
1853
DynValue originalIdx = i_str != null ? DynValue . NewString ( i_str ) : m_ValueStack . Pop ( ) ;
@@ -1815,6 +1867,14 @@ private int ExecIndex(Instruction i, int instructionPtr)
1815
1867
{
1816
1868
if ( ! isMultiIndex )
1817
1869
{
1870
+ //Don't return private fields
1871
+ if ( ! accessPrivate && obj . Table . PrivateKeys != null &&
1872
+ obj . Table . PrivateKeys . IsKeyPrivate ( idx ) )
1873
+ {
1874
+ m_ValueStack . Push ( DynValue . Nil ) ;
1875
+ return instructionPtr ;
1876
+ }
1877
+
1818
1878
var v = obj . Table . Get ( idx ) ;
1819
1879
1820
1880
if ( ! v . IsNil ( ) )
0 commit comments