Skip to content

Commit 05540af

Browse files
authored
Add script function flags in the module API (#2836)
This commit adds script function flags to the module API, which allows function scripts to specify the function flags programmatically. When the scripting engine compiles the script code can extract the flags from the code and set the flags on the compiled function objects. --------- Signed-off-by: Ricardo Dias <[email protected]>
1 parent ed8856b commit 05540af

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed

src/script.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
#include "module.h"
3535

3636
scriptFlag scripts_flags_def[] = {
37-
{.flag = SCRIPT_FLAG_NO_WRITES, .str = "no-writes"},
38-
{.flag = SCRIPT_FLAG_ALLOW_OOM, .str = "allow-oom"},
39-
{.flag = SCRIPT_FLAG_ALLOW_STALE, .str = "allow-stale"},
40-
{.flag = SCRIPT_FLAG_NO_CLUSTER, .str = "no-cluster"},
41-
{.flag = SCRIPT_FLAG_ALLOW_CROSS_SLOT, .str = "allow-cross-slot-keys"},
37+
{.flag = VMSE_SCRIPT_FLAG_NO_WRITES, .str = "no-writes"},
38+
{.flag = VMSE_SCRIPT_FLAG_ALLOW_OOM, .str = "allow-oom"},
39+
{.flag = VMSE_SCRIPT_FLAG_ALLOW_STALE, .str = "allow-stale"},
40+
{.flag = VMSE_SCRIPT_FLAG_NO_CLUSTER, .str = "no-cluster"},
41+
{.flag = VMSE_SCRIPT_FLAG_ALLOW_CROSS_SLOT, .str = "allow-cross-slot-keys"},
4242
{.flag = 0, .str = NULL}, /* flags array end */
4343
};
4444

src/script.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ struct scriptRunCtx {
9292

9393
/* Defines a script flags */
9494
typedef struct scriptFlag {
95-
uint64_t flag;
95+
ValkeyModuleScriptingEngineScriptFlag flag;
9696
const char *str;
9797
} scriptFlag;
9898

src/valkeymodule.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,15 @@ typedef enum ValkeyModuleScriptingEngineExecutionState {
907907
VMSE_STATE_KILLED,
908908
} ValkeyModuleScriptingEngineExecutionState;
909909

910+
typedef enum ValkeyModuleScriptingEngineScriptFlag {
911+
VMSE_SCRIPT_FLAG_NO_WRITES = (1ULL << 0),
912+
VMSE_SCRIPT_FLAG_ALLOW_OOM = (1ULL << 1),
913+
VMSE_SCRIPT_FLAG_ALLOW_STALE = (1ULL << 2),
914+
VMSE_SCRIPT_FLAG_NO_CLUSTER = (1ULL << 3),
915+
VMSE_SCRIPT_FLAG_EVAL_COMPAT_MODE = (1ULL << 4), /* EVAL Script backwards compatible behavior, no shebang provided */
916+
VMSE_SCRIPT_FLAG_ALLOW_CROSS_SLOT = (1ULL << 5),
917+
} ValkeyModuleScriptingEngineScriptFlag;
918+
910919
typedef struct ValkeyModuleScriptingEngineCallableLazyEnvReset {
911920
void *context;
912921

tests/modules/helloscripting.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* RETURN # returns the current value on the top of the stack and marks
2828
* # the end of the function declaration
2929
*
30-
* FUNCTION bar # declaration of function 'bar'
30+
* RFUNCTION bar # declaration of read-only function 'bar'
3131
* CONSTI 432 # pushes the value 432 to the top of the stack
3232
* RETURN # returns the current value on the top of the stack and marks
3333
* # the end of the function declaration.
@@ -55,6 +55,7 @@
5555
*/
5656
typedef enum HelloInstKind {
5757
FUNCTION = 0,
58+
RFUNCTION,
5859
CONSTI,
5960
CONSTS,
6061
ARGS,
@@ -69,6 +70,7 @@ typedef enum HelloInstKind {
6970
*/
7071
const char *HelloInstKindStr[] = {
7172
"FUNCTION",
73+
"RFUNCTION",
7274
"CONSTI",
7375
"CONSTS",
7476
"ARGS",
@@ -119,6 +121,7 @@ typedef struct HelloFunc {
119121
HelloInst instructions[256];
120122
uint32_t num_instructions;
121123
uint32_t index;
124+
int read_only;
122125
} HelloFunc;
123126

124127
/*
@@ -207,11 +210,12 @@ static HelloInstKind helloLangParseInstruction(const char *token) {
207210
/*
208211
* Parses the function param.
209212
*/
210-
static void helloLangParseFunction(HelloFunc *func) {
213+
static void helloLangParseFunction(HelloFunc *func, int read_only) {
211214
char *token = strtok(NULL, " \n");
212215
ValkeyModule_Assert(token != NULL);
213216
func->name = ValkeyModule_Alloc(sizeof(char) * strlen(token) + 1);
214217
strcpy(func->name, token);
218+
func->read_only = read_only;
215219
}
216220

217221
/*
@@ -283,12 +287,13 @@ static int helloLangParseCode(const char *code,
283287

284288
switch (kind) {
285289
case FUNCTION:
290+
case RFUNCTION:
286291
ValkeyModule_Assert(currentFunc == NULL);
287292
currentFunc = ValkeyModule_Alloc(sizeof(HelloFunc));
288293
memset(currentFunc, 0, sizeof(HelloFunc));
289294
currentFunc->index = program->num_functions;
290295
program->functions[program->num_functions++] = currentFunc;
291-
helloLangParseFunction(currentFunc);
296+
helloLangParseFunction(currentFunc, kind == RFUNCTION);
292297
break;
293298
case CONSTI:
294299
ValkeyModule_Assert(currentFunc != NULL);
@@ -424,6 +429,7 @@ static void helloDebuggerLogCurrentInstr(uint32_t pc, HelloInst *instr) {
424429
msg = ValkeyModule_CreateStringPrintf(NULL, ">>> %3u: %s", pc, HelloInstKindStr[instr->kind]);
425430
break;
426431
case FUNCTION:
432+
case RFUNCTION:
427433
case _NUM_INSTRUCTIONS:
428434
ValkeyModule_Assert(0);
429435
}
@@ -528,6 +534,7 @@ static HelloExecutionState executeHelloLangFunction(ValkeyModuleCtx *module_ctx,
528534
return FINISHED;
529535
}
530536
case FUNCTION:
537+
case RFUNCTION:
531538
case _NUM_INSTRUCTIONS:
532539
ValkeyModule_Assert(0);
533540
}
@@ -646,7 +653,7 @@ static ValkeyModuleScriptingEngineCompiledFunction **createHelloLangEngine(Valke
646653
.name = ValkeyModule_CreateString(NULL, func->name, strlen(func->name)),
647654
.function = func,
648655
.desc = NULL,
649-
.f_flags = 0,
656+
.f_flags = func->read_only ? VMSE_SCRIPT_FLAG_NO_WRITES : 0,
650657
};
651658

652659
compiled_functions[i] = cfunc;

tests/unit/moduleapi/scriptingengine.tcl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
set testmodule [file normalize tests/modules/helloscripting.so]
22

3-
set HELLO_PROGRAM "#!hello name=mylib\nFUNCTION foo\nARGS 0\nRETURN\nFUNCTION bar\nCONSTI 432\nRETURN"
3+
set HELLO_PROGRAM "#!hello name=mylib\nRFUNCTION foo\nARGS 0\nRETURN\nFUNCTION bar\nCONSTI 432\nRETURN"
44

55
start_server {tags {"modules"}} {
66
r module load $testmodule
@@ -197,6 +197,16 @@ start_server {tags {"modules"}} {
197197
RETURN
198198
} 0
199199
}
200+
201+
r function load {#!hello name=errlib
202+
RFUNCTION callcmd
203+
CONSTS x
204+
CONSTI 43
205+
CONSTI 2
206+
CALL SET
207+
RETURN
208+
}
209+
assert_error {ERR Write commands are not allowed*} {r fcall callcmd 0}
200210
}
201211

202212
test {Call server command when OOM} {
@@ -301,6 +311,7 @@ start_server {tags {"modules"}} {
301311
}
302312

303313
test {List scripting engine functions} {
314+
r function flush sync
304315
r function load replace "#!hello name=mylib\nFUNCTION foobar\nARGS 0\nRETURN"
305316
r function list
306317
} {{library_name mylib engine HELLO functions {{name foobar description {} flags {}}}}}

0 commit comments

Comments
 (0)