Ce didacticiel est destiné aux utilisateurs maîtrisant la programmation en C ou C++, ainsi que l'architecture de la Simple Virtual Machine.
Dans ce didacticiel, vous allez découvrir la notion de variable Simple Virtual Machine.
Le temps de lecture de ce didacticiel est estimé à 25 minutes.
Pour commencer, créez le canevas de l'extension dans le fichier variables.svm_plugin en utilisant ce code :
PLUGIN variables
DEFINE
INSTRUCTION variables.repeat INT STR -> STR
%{
%}
INSTRUCTION variables.set VALUE
%{
%}
INSTRUCTION variables.get -> VALUE
%{
%}
INSTRUCTION variables.print -> STR
%{
%}
INSTRUCTION variables.reset
%{
%}
Modifiez le fichier d'extension pour ajouter l'implémentation de la première instruction :
PLUGIN variables
DEFINE
INSTRUCTION variables.repeat INT STR -> STR
%{
SVM_Value_Integer vi = ::svm_parameter_value_get(svm,argv[0]);
long long int i = ::svm_value_integer_get(svm,vi);
SVM_Value_String vs = ::svm_parameter_value_get(svm,argv[1]);
SVM_String s = ::svm_value_string_get(svm,vs);
std::string rs(s.string,s.size);
std::string r;
if(i<0)
{
::svm_processor_current_raise_error_internal__raw(svm,FAILURE,"Invalid repetition");
}
for(size_t ii=0 ; ii<i ; ++ii)
{
r += rs;
}
SVM_Value_String vsres = ::svm_value_string_new__buffer(svm,r.c_str(),r.size());
return vsres;
%}
INSTRUCTION variables.set VALUE
%{
%}
INSTRUCTION variables.get -> VALUE
%{
%}
INSTRUCTION variables.print -> STR
%{
%}
INSTRUCTION variables.reset
%{
%}
Ici, l'implémentation est volontairement détaillée, en remplaçant les macros du générateur d'extension par leur contenu.
A y regarder de plus près, nous pouvons constater que :
Dans le fichier d'interface programmatique, on trouve ces définitions :
Ces pointeurs sont non seulement retournés par l'interface, mais aussi consommés en tant que paramètres de fonctions de l'interface. De plus, lorsque la fonction svm_processor_current_raise_error_internal__raw
interrompt brutalement l'exécution de l'instruction, ces pointeurs ne semblent pas provoquer de fuite mémoire (ce qui peut être vérifié en exécutant la machine avec l'utilitaire valgrind).
Ces pointeurs sont en réalité liés aux valeurs qu'ils représentent, mais celles-ci sont conservées par la machine virtuelle dans l'environnement d'exécution de l'instruction. Ces pointeurs, jouant le rôle de clef pour retrouver les valeurs dans l'environnement, sont des variables Simple Virtual Machine.
Modifiez le fichier d'extension pour ajouter une variable Simple Virtual Machine en statique et l'implémentation des instructions set, get et print :
PLUGIN variables
code:
%{
SVM_Value _value = nullptr;
%}
DEFINE
INSTRUCTION variables.repeat INT STR -> STR
%{
SVM_Value_Integer vi = ::svm_parameter_value_get(svm,argv[0]);
long long int i = ::svm_value_integer_get(svm,vi);
SVM_Value_String vs = ::svm_parameter_value_get(svm,argv[1]);
SVM_String s = ::svm_value_string_get(svm,vs);
std::string rs(s.string,s.size);
std::string r;
if(i<0)
{
::svm_processor_current_raise_error_internal__raw(svm,FAILURE,"Invalid repetition");
}
for(size_t ii=0 ; ii<i ; ++ii)
{
r += rs;
}
SVM_Value_String vsres = ::svm_value_string_new__buffer(svm,r.c_str(),r.size());
return vsres;
%}
INSTRUCTION variables.set VALUE
%{
_value = ::svm_parameter_value_get(svm,argv[0]);
%}
INSTRUCTION variables.get -> VALUE
%{
return _value;
%}
INSTRUCTION variables.print -> STR
%{
SVM_String s = ::svm_value_print(svm,_value);
return NEW_VALUE(string,s);
%}
INSTRUCTION variables.reset
%{
%}
Puis générez l'extension et compilez la. Enfin, crééz un fichier exécutable variables.svm avec ce code :
#!/usr/bin/env svm
LOG
PLUGIN "svmcom.so"
LOCAL PLUGIN "svmpluginvariables/libsvmvariables.so"
PROCESS "variables"
CODE "main" INLINE
:memory INT/i, STR/s
:variables.set 17
:variables.print -> &s
:com.message @&s
END
END
Cette application utilise la valeur statique de l'extension pour réaliser une action. Lancez l'application :
./variables.svm
### Simple Virtual Machine 12345 : PROCESS variables | 2023-01-01 00:00:00 GMT #######################################################################
Kernel interrupted: @(main, line 3) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 3) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Processor:
State:
Next instruction: <main:1/3> (Current one: <main:1/2>)
Current memory : &0*0
Allocated memory: &0*2
Aliases : i s
Flags :
Cascaded flags :
Local interruption handlers:
Cascaded local interruption handlers:
Saved states:
Global interruption handlers:
Code at <main:1/2>:
:memory INT/i , STR/s # <0> @(main, line 1)
:variables.set 17 # <1> @(main, line 2)
====== HERE ======
:variables.print -> &s # <2> @(main, line 3)
==================
:com.message @&s # <3> @(main, line 4)
Labels:
Symbols:
Memory:
&0: INT
&1: STR
Aliases:
i -> &0*1
s -> &1*1
Free space:
### Simple Virtual Machine 12345 : SYSTEM | 2023-01-01 00:00:00 GMT ##################################################################################
Process variables interrupted: @(main, line 3) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Et là, une erreur pour le moins étrange apparaît ! Dans l'instruction print, la fonction de l'interface svm_value_print
ne reconnaît plus la variable "_value".
Et pour cause, par défaut, une variable n'est valable que dans le bloc de code où elle est définie : la variable Simple Virtual Machine est ici locale (au bloc de code).
En particulier, cela signifie que la valeur associée peut être détruite à la sortie de l'instruction : il n'est donc pas nécessaire de supprimer les variables Simple Virtual Machine lorsque celles-ci ne sont utilisées que dans le bloc de code où elles sont définies, en C ou en C++.
Modifiez à nouveau le code de l'extension :
PLUGIN variables
code:
%{
SVM_Value _value = nullptr;
%}
DEFINE
INSTRUCTION variables.repeat INT STR -> STR
%{
SVM_Value_Integer vi = ::svm_parameter_value_get(svm,argv[0]);
long long int i = ::svm_value_integer_get(svm,vi);
SVM_Value_String vs = ::svm_parameter_value_get(svm,argv[1]);
SVM_String s = ::svm_value_string_get(svm,vs);
std::string rs(s.string,s.size);
std::string r;
if(i<0)
{
::svm_processor_current_raise_error_internal__raw(svm,FAILURE,"Invalid repetition");
}
for(size_t ii=0 ; ii<i ; ++ii)
{
r += rs;
}
SVM_Value_String vsres = ::svm_value_string_new__buffer(svm,r.c_str(),r.size());
return vsres;
%}
INSTRUCTION variables.set VALUE
%{
_value = ::svm_parameter_value_get(svm,argv[0]);
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.get -> VALUE
%{
return _value;
%}
INSTRUCTION variables.print -> STR
%{
SVM_String s = ::svm_value_print(svm,_value);
return NEW_VALUE(string,s);
%}
INSTRUCTION variables.reset
%{
::svm_variable_scope_set_local(svm,_value);
%}
Puis regénérez l'extension et recompilez la. Modifiez également le fichier variables.svm pour obtenir :
#!/usr/bin/env svm
LOG
PLUGIN "svmcom.so"
LOCAL PLUGIN "svmpluginvariables/libsvmvariables.so"
PROCESS "variables"
CODE "main" INLINE
:memory INT/i, STR/s
:variables.set 17
:variables.print -> &s
:com.message "print: " @&s
:variables.get -> &i
:com.message "get: " @&i
:variables.reset
:variables.print -> &s
:com.message "print: " @&s
END
END
Lancez maintenant l'application :
./variables.svm
print: 17
get: 17
### Simple Virtual Machine 1234 : PROCESS variables | 2023-01-01 00:00:00 GMT ########################################################################
Kernel interrupted: @(main, line 8) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 8) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Processor:
State:
Next instruction: <main:1/8> (Current one: <main:1/7>)
Current memory : &0*0
Allocated memory: &0*2
Aliases : i s
Flags :
Cascaded flags :
Local interruption handlers:
Cascaded local interruption handlers:
Saved states:
Global interruption handlers:
Code at <main:1/7>:
:memory INT/i , STR/s # <0> @(main, line 1)
:variables.set 17 # <1> @(main, line 2)
:variables.print -> &s # <2> @(main, line 3)
:com.message "print: " @&s # <3> @(main, line 4)
:variables.get -> &i # <4> @(main, line 5)
:com.message "get: " @&i # <5> @(main, line 6)
:variables.reset # <6> @(main, line 7)
====== HERE ======
:variables.print -> &s # <7> @(main, line 8)
==================
:com.message "print: " @&s # <8> @(main, line 9)
Labels:
Symbols:
Memory:
&0: INT 17
&1: STR "17"
Aliases:
i -> &0*1
s -> &1*1
Free space:
### Simple Virtual Machine 1234 : SYSTEM | 2023-01-01 00:00:00 GMT ###################################################################################
Process variables interrupted: @(main, line 8) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Observez attentivement où est générée l'erreur cette fois : après l'appel à l'instruction reset. Cependant, les deux premières lignes du résultat montrent que la variable était maintenant connue des instructions get et print !
L'appel à la fonction svm_variable_scope_set_global
a permis de changer la portée de la variable Simple Virtual Machine et la rendre visible aux autres blocs de code présents dans l'extension : la variable Simple Virtual Machine est devenue globale.
Avec l'appel à la fonction svm_variable_scope_set_local
, la variable redevient locale au bloc de code où cette fonction de l'interface programmatique est appellée.
Dans certains cas, il peut être important de révoquer immédiatement une variable Simple Virtual Machine, sans attendre la fin du bloc de code.
Modifiez le code de l'extension :
PLUGIN variables
code:
%{
SVM_Value _value = nullptr;
%}
DEFINE
INSTRUCTION variables.repeat INT STR -> STR
%{
SVM_Value_Integer vi = ::svm_parameter_value_get(svm,argv[0]);
long long int i = ::svm_value_integer_get(svm,vi);
SVM_Value_String vs = ::svm_parameter_value_get(svm,argv[1]);
SVM_String s = ::svm_value_string_get(svm,vs);
std::string rs(s.string,s.size);
std::string r;
if(i<0)
{
::svm_processor_current_raise_error_internal__raw(svm,FAILURE,"Invalid repetition");
}
for(size_t ii=0 ; ii<i ; ++ii)
{
r += rs;
}
SVM_Value_String vsres = ::svm_value_string_new__buffer(svm,r.c_str(),r.size());
return vsres;
%}
INSTRUCTION variables.set VALUE
%{
_value = ::svm_parameter_value_get(svm,argv[0]);
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.get -> VALUE
%{
return _value;
%}
INSTRUCTION variables.print -> STR
%{
SVM_String s = ::svm_value_print(svm,_value);
return NEW_VALUE(string,s);
%}
INSTRUCTION variables.reset
%{
::svm_variable_delete(svm,_value);
SVM_String s = ::svm_value_print(svm,_value);
%}
Puis regénérez l'extension et recompilez la. Lancez maintenant l'application :
./variables.svm
print: 17
get: 17
### Simple Virtual Machine 1234 : PROCESS variables | 2023-01-01 00:00:00 GMT ########################################################################
Kernel interrupted: @(main, line 7) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 7) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Processor:
State:
Next instruction: <main:1/7> (Current one: <main:1/6>)
Current memory : &0*0
Allocated memory: &0*2
Aliases : i s
Flags :
Cascaded flags :
Local interruption handlers:
Cascaded local interruption handlers:
Saved states:
Global interruption handlers:
Code at <main:1/6>:
:memory INT/i , STR/s # <0> @(main, line 1)
:variables.set 17 # <1> @(main, line 2)
:variables.print -> &s # <2> @(main, line 3)
:com.message "print: " @&s # <3> @(main, line 4)
:variables.get -> &i # <4> @(main, line 5)
:com.message "get: " @&i # <5> @(main, line 6)
====== HERE ======
:variables.reset # <6> @(main, line 7)
==================
:variables.print -> &s # <7> @(main, line 8)
:com.message "print: " @&s # <8> @(main, line 9)
Labels:
Symbols:
Memory:
&0: INT 17
&1: STR "17"
Aliases:
i -> &0*1
s -> &1*1
Free space:
### Simple Virtual Machine 1234 : SYSTEM | 2023-01-01 00:00:00 GMT ###################################################################################
Process variables interrupted: @(main, line 7) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Cette fois, l'erreur apparaît bien directement dans l'instruction reset, après l'appel à la fonction svm_variable_delete
. La variable a bien été supprimée, et la valeur correspondante également si la machine virtuelle ne la référence plus par ailleurs.
svm_variable_scope_set_global
et svm_variable_scope_set_local
permettent de changer la portée d'une variable Simple Virtual Machine.svm_variable_delete
permet de révoquer immédiatement une variable Simple Virtual Machine.Les fonctions qui changent la portée d'une variable Simple Virtual Machine ne fonctionnent bien que lorsqu'une seule entité gère la portée d'une variable. En effet, les appels à ces fonctions sont idempotents par défaut : cela signifie qu'un seul appel à la fonction svm_variable_scope_set_local
changera la portée d'une variable même si plusieurs appels à svm_variable_scope_set_global
ont été faits sur cette variable.
Modifiez le code de l'extension pour obtenir :
PLUGIN variables
code:
%{
SVM_Value _value = nullptr;
%}
DEFINE
INSTRUCTION variables.set VALUE
%{
_value = ::svm_parameter_value_get(svm,argv[0]);
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.get -> VALUE
%{
return _value;
%}
INSTRUCTION variables.print -> STR
%{
SVM_String s = ::svm_value_print(svm,_value);
return NEW_VALUE(string,s);
%}
INSTRUCTION variables.global
%{
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.local
%{
::svm_variable_scope_set_local(svm,_value);
%}
Regénérez et recompilez l'extension, puis modifiez à nouveau le fichier variables.svm pour obtenir :
#!/usr/bin/env svm
LOG
PLUGIN "svmcom.so"
LOCAL PLUGIN "svmpluginvariables/libsvmvariables.so"
PROCESS "variables"
CODE "main" INLINE
:memory INT/i, STR/s
:variables.set 17
:variables.print -> &s
:com.message "print 1: " @&s
:variables.global
:variables.print -> &s
:com.message "print 2: " @&s
:variables.global
:variables.print -> &s
:com.message "print 3: " @&s
:variables.local
:variables.print -> &s
:com.message "print 4: " @&s
END
END
Enfin, lancez l'application et observez à quel moment l'interruption est levée :
./variables.svm
print 1: 17
print 2: 17
print 3: 17
### Simple Virtual Machine 12345 : PROCESS variables | 2023-01-01 00:00:00 GMT #######################################################################
Kernel interrupted: @(main, line 12) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 12) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Processor:
State:
Next instruction: <main:1/12> (Current one: <main:1/11>)
Current memory : &0*0
Allocated memory: &0*2
Aliases : i s
Flags :
Cascaded flags :
Local interruption handlers:
Cascaded local interruption handlers:
Saved states:
Global interruption handlers:
Code at <main:1/11>:
:memory INT/i , STR/s # <0> @(main, line 1)
:variables.set 17 # <1> @(main, line 2)
:variables.print -> &s # <2> @(main, line 3)
:com.message "print 1: " @&s # <3> @(main, line 4)
:variables.global # <4> @(main, line 5)
:variables.print -> &s # <5> @(main, line 6)
:com.message "print 2: " @&s # <6> @(main, line 7)
:variables.global # <7> @(main, line 8)
:variables.print -> &s # <8> @(main, line 9)
:com.message "print 3: " @&s # <9> @(main, line 10)
:variables.local # <10> @(main, line 11)
====== HERE ======
:variables.print -> &s # <11> @(main, line 12)
==================
:com.message "print 4: " @&s # <12> @(main, line 13)
Labels:
Symbols:
Memory:
&0: INT
&1: STR "17"
Aliases:
i -> &0*1
s -> &1*1
Free space:
### Simple Virtual Machine 12345 : SYSTEM | 2023-01-01 00:00:00 GMT ##################################################################################
Process variables interrupted: @(main, line 12) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Un seul appel à la fonction svm_variable_scope_set_local
a suffit à rendre la variable locale, alors que plusieurs appels à la fonction svm_variable_scope_set_global
ont été réalisés.
Cela peut poser problème lorsque plusieurs entités veulent contrôler de manière indépendante la portée d'une variable : la variable doit être marquée comme partagée. Dans ce cas, il faudra un nombre équivalent d'appels à la fonction svm_variable_scope_set_local
au nombre d'appels à la fonction svm_variable_scope_set_global
pour que la variable redevienne locale.
Modifiez le code de l'extension :
PLUGIN variables
code:
%{
SVM_Value _value = nullptr;
%}
DEFINE
INSTRUCTION variables.set VALUE
%{
_value = ::svm_parameter_value_get(svm,argv[0]);
::svm_variable_scope_set_shared(svm,_value);
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.get -> VALUE
%{
return _value;
%}
INSTRUCTION variables.print -> STR
%{
SVM_String s = ::svm_value_print(svm,_value);
return NEW_VALUE(string,s);
%}
INSTRUCTION variables.global
%{
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.local
%{
::svm_variable_scope_set_local(svm,_value);
%}
Regénérez et recompilez l'extension, puis modifiez à nouveau le fichier variables.svm pour obtenir :
#!/usr/bin/env svm
LOG
PLUGIN "svmcom.so"
LOCAL PLUGIN "svmpluginvariables/libsvmvariables.so"
PROCESS "variables"
CODE "main" INLINE
:memory INT/i, STR/s
:variables.set 17
:variables.print -> &s
:com.message "print 1: " @&s
:variables.global
:variables.print -> &s
:com.message "print 2: " @&s
:variables.global
:variables.print -> &s
:com.message "print 3: " @&s
:variables.local
:variables.print -> &s
:com.message "print 4: " @&s
:variables.local
:variables.print -> &s
:com.message "print 5: " @&s
:variables.local
:variables.print -> &s
:com.message "print 6: " @&s
:variables.local
:variables.print -> &s
:com.message "print 7: " @&s
END
END
Et relancez l'application :
./variables.svm
print 1: 17
print 2: 17
print 3: 17
print 4: 17
print 5: 17
### Simple Virtual Machine 12345 : PROCESS variables | 2023-01-01 00:00:00 GMT #######################################################################
Kernel interrupted: @(main, line 18) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 18) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Processor:
State:
Next instruction: <main:1/18> (Current one: <main:1/17>)
Current memory : &0*0
Allocated memory: &0*2
Aliases : i s
Flags :
Cascaded flags :
Local interruption handlers:
Cascaded local interruption handlers:
Saved states:
Global interruption handlers:
Code at <main:1/17>:
:memory INT/i , STR/s # <0> @(main, line 1)
:variables.set 17 # <1> @(main, line 2)
:variables.print -> &s # <2> @(main, line 3)
:com.message "print 1: " @&s # <3> @(main, line 4)
:variables.global # <4> @(main, line 5)
:variables.print -> &s # <5> @(main, line 6)
:com.message "print 2: " @&s # <6> @(main, line 7)
:variables.global # <7> @(main, line 8)
:variables.print -> &s # <8> @(main, line 9)
:com.message "print 3: " @&s # <9> @(main, line 10)
:variables.local # <10> @(main, line 11)
:variables.print -> &s # <11> @(main, line 12)
:com.message "print 4: " @&s # <12> @(main, line 13)
:variables.local # <13> @(main, line 14)
:variables.print -> &s # <14> @(main, line 15)
:com.message "print 5: " @&s # <15> @(main, line 16)
:variables.local # <16> @(main, line 17)
====== HERE ======
:variables.print -> &s # <17> @(main, line 18)
==================
:com.message "print 6: " @&s # <18> @(main, line 19)
:variables.local # <19> @(main, line 20)
:variables.print -> &s # <20> @(main, line 21)
:com.message "print 7: " @&s # <21> @(main, line 22)
Labels:
Symbols:
Memory:
&0: INT
&1: STR "17"
Aliases:
i -> &0*1
s -> &1*1
Free space:
### Simple Virtual Machine 12345 : SYSTEM | 2023-01-01 00:00:00 GMT ##################################################################################
Process variables interrupted: @(main, line 18) Interruption FAILURE not handled: Invalid call to API function svm_value_print: value is not a value.
Cette fois, trois appels à la fonction svm_variable_scope_set_local
ont été nécessaires pour rendre à nouveau la variable locale.
Parfois, certaines opérations (comme des libérations de ressources) ne doivent être entreprises que lorsqu'une variable redevient locale. Or, la fonction svm_variable_scope_set_local
ne précise pas la portée de la variable.
Le test de portée peut être réalisé grâce à la fonction svm_variable_scope_is_local
.
Modifiez le code de l'extension :
PLUGIN variables
code:
%{
SVM_Value _value = nullptr;
%}
DEFINE
INSTRUCTION variables.set VALUE
%{
_value = ::svm_parameter_value_get(svm,argv[0]);
::svm_variable_scope_set_shared(svm,_value);
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.get -> VALUE
%{
return _value;
%}
INSTRUCTION variables.print -> STR
%{
SVM_String s = ::svm_value_print(svm,_value);
return NEW_VALUE(string,s);
%}
INSTRUCTION variables.global
%{
::svm_variable_scope_set_global(svm,_value);
%}
INSTRUCTION variables.local -> BLN
%{
::svm_variable_scope_set_local(svm,_value);
return NEW_VALUE(boolean,::svm_variable_scope_is_local(svm,_value));
%}
Regénérez et recompilez l'extension une dernière fois, puis modifiez enfin le fichier variables.svm pour obtenir :
#!/usr/bin/env svm
LOG
PLUGIN "svmcom.so"
LOCAL PLUGIN "svmpluginvariables/libsvmvariables.so"
PROCESS "variables"
CODE "main" INLINE
:memory INT/i, STR/s, BLN/b
:variables.set 17
:variables.print -> &s
:com.message "print 1: " @&s
:variables.global
:variables.print -> &s
:com.message "print 2: " @&s
:variables.global
:variables.print -> &s
:com.message "print 3: " @&s
:variables.local -> &b
:shutdown :when @&b TRUE
:variables.print -> &s
:com.message "print 4: " @&s
:variables.local -> &b
:shutdown :when @&b TRUE
:variables.print -> &s
:com.message "print 5: " @&s
:variables.local -> &b
:shutdown :when @&b TRUE
:variables.print -> &s
:com.message "print 6: " @&s
:variables.local -> &b
:shutdown :when @&b TRUE
:variables.print -> &s
:com.message "print 7: " @&s
END
END
Lancez l'application :
./variables.svm
print 1: 17
print 2: 17
print 3: 17
print 4: 17
print 5: 17
L'application arrête le processeur lorsque la variable redevient locale, évitant l'interruption.
svm_variable_scope_set_shared
est appellée sur la variable après sa création.svm_variable_scope_set_local
et svm_variable_scope_set_global
modifient la portée de la variable.svm_variable_scope_is_local
peut être invoquée sur la variable.svm_variable_delete
.Vous venez de voir les variables Simple Virtual Machine permettant d'accéder aux valeurs de la machine virtuelle depuis le code des extensions.
L'interêt principal des variables Simple Virtual Machine est la suppression automatique des valeurs une fois qu'elles ne sont plus nécessaires, que ce soit en C ou en C++.
Cependant, ce confort d'utilisation vient avec une complexité qui se manifeste lorsqu'une variable a une portée qui dépasse le bloc de code où elle est définie.
La maîtrise de la portée des variables peut sembler être un peu tel un casse-tête au départ, mais la plupart des utilisations de variables globales suivent des schémas simples qui seront présentés dans des didacticiels ultérieurs.