@@ -26,6 +26,9 @@ internal sealed class LuaRunner : IDisposable
26
26
readonly TxnKeyEntries txnKeyEntries ;
27
27
readonly bool txnMode ;
28
28
29
+ LuaTable keyTable , argvTable ;
30
+ int keyLength , argvLength ;
31
+
29
32
/// <summary>
30
33
/// Creates a new runner with the source of the script
31
34
/// </summary>
@@ -61,6 +64,8 @@ function redis.status_reply(text)
61
64
function redis.error_reply(text)
62
65
return { err = text }
63
66
end
67
+ KEYS = {}
68
+ ARGV = {}
64
69
sandbox_env = {
65
70
tostring = tostring;
66
71
next = next;
@@ -81,13 +86,17 @@ function redis.error_reply(text)
81
86
math = math;
82
87
table = table;
83
88
string = string;
89
+ KEYS = KEYS;
90
+ ARGV = ARGV;
84
91
}
85
92
function load_sandboxed(source)
86
93
if (not source) then return nil end
87
94
return load(source, nil, nil, sandbox_env)
88
95
end
89
96
" ) ;
90
97
sandbox_env = ( LuaTable ) state [ "sandbox_env" ] ;
98
+ keyTable = ( LuaTable ) state [ "KEYS" ] ;
99
+ argvTable = ( LuaTable ) state [ "ARGV" ] ;
91
100
}
92
101
93
102
/// <summary>
@@ -252,7 +261,7 @@ public object Run(int count, SessionParseState parseState)
252
261
if ( nKeys > 0 )
253
262
{
254
263
// Lua uses 1-based indexing, so we allocate an extra entry in the array
255
- keys = new string [ nKeys + 2 ] ;
264
+ keys = new string [ nKeys ] ;
256
265
for ( int i = 0 ; i < nKeys ; i ++ )
257
266
{
258
267
if ( txnMode )
@@ -262,9 +271,8 @@ public object Run(int count, SessionParseState parseState)
262
271
if ( ! respServerSession . storageSession . objectStoreLockableContext . IsNull )
263
272
txnKeyEntries . AddKey ( key , true , Tsavorite . core . LockType . Exclusive ) ;
264
273
}
265
- keys [ i + 1 ] = parseState . GetString ( offset ++ ) ;
274
+ keys [ i ] = parseState . GetString ( offset ++ ) ;
266
275
}
267
- keys [ nKeys + 1 ] = null ;
268
276
count -= nKeys ;
269
277
270
278
//TODO: handle slot verification for Lua script keys
@@ -278,12 +286,11 @@ public object Run(int count, SessionParseState parseState)
278
286
if ( count > 0 )
279
287
{
280
288
// Lua uses 1-based indexing, so we allocate an extra entry in the array
281
- argv = new string [ count + 2 ] ;
289
+ argv = new string [ count ] ;
282
290
for ( int i = 0 ; i < count ; i ++ )
283
291
{
284
- argv [ i + 1 ] = parseState . GetString ( offset ++ ) ;
292
+ argv [ i ] = parseState . GetString ( offset ++ ) ;
285
293
}
286
- argv [ count + 1 ] = null ;
287
294
}
288
295
289
296
if ( txnMode && nKeys > 0 )
@@ -344,40 +351,52 @@ object RunTransactionInternal(string[] keys, string[] argv)
344
351
345
352
object RunInternal ( string [ ] keys , string [ ] argv )
346
353
{
347
- if ( keys != this . keys )
354
+ if ( keys != null )
348
355
{
349
- if ( keys == null )
350
- {
351
- this . keys = null ;
352
- sandbox_env [ "KEYS" ] = this . keys ;
353
- }
354
- else
356
+ if ( keyLength != keys . Length )
355
357
{
356
- if ( this . keys != null && keys . Length == this . keys . Length )
357
- Array . Copy ( keys , this . keys , keys . Length ) ;
358
- else
358
+ if ( keyLength > 0 )
359
359
{
360
- this . keys = keys ;
361
- sandbox_env [ "KEYS" ] = this . keys ;
360
+ keyTable . Dispose ( ) ;
361
+ keyTable = ( LuaTable ) state . DoString ( "return {}" ) [ 0 ] ;
362
+ sandbox_env [ "KEYS" ] = keyTable ;
362
363
}
364
+ keyLength = keys . Length ;
363
365
}
366
+ for ( int i = 0 ; i < keys . Length ; i ++ )
367
+ keyTable [ i + 1 ] = keys [ i ] ;
364
368
}
365
- if ( argv != this . argv )
369
+ else
366
370
{
367
- if ( argv == null )
371
+ if ( keyLength > 0 )
368
372
{
369
- this . argv = null ;
370
- sandbox_env [ "ARGV" ] = this . argv ;
373
+ keyTable = ( LuaTable ) state . DoString ( "return {}" ) [ 0 ] ;
374
+ sandbox_env [ "KEYS" ] = keyTable ;
375
+ keyLength = 0 ;
371
376
}
372
- else
377
+ }
378
+ if ( argv != null )
379
+ {
380
+ if ( argvLength != argv . Length )
373
381
{
374
- if ( this . argv != null && argv . Length == this . argv . Length )
375
- Array . Copy ( argv , this . argv , argv . Length ) ;
376
- else
382
+ if ( argvLength > 0 )
377
383
{
378
- this . argv = argv ;
379
- sandbox_env [ "ARGV" ] = this . argv ;
384
+ argvTable . Dispose ( ) ;
385
+ argvTable = ( LuaTable ) state . DoString ( "return {}" ) [ 0 ] ;
386
+ sandbox_env [ "ARGV" ] = argvTable ;
380
387
}
388
+ argvLength = argv . Length ;
389
+ }
390
+ for ( int i = 0 ; i < argv . Length ; i ++ )
391
+ argvTable [ i + 1 ] = argv [ i ] ;
392
+ }
393
+ else
394
+ {
395
+ if ( argvLength > 0 )
396
+ {
397
+ argvTable = ( LuaTable ) state . DoString ( "return {}" ) [ 0 ] ;
398
+ sandbox_env [ "ARGV" ] = argvTable ;
399
+ argvLength = 0 ;
381
400
}
382
401
}
383
402
0 commit comments