Other V Features
Inline assembly
Structured amd64 and x86 blocks validate the lock prefix. The prefix and its instruction
must be on the same source line. It may precede add, adc, and, btc, btr, bts,
cmpxchg, cmpxchg8b, cmpxchg16b, dec, inc, neg, not, or, sbb, sub, xor,
xadd, or xchg. The b, w, l, and q size suffixes are also recognized, for example
addq and cmpxchgq. Without a permitted same-line instruction, the parser reports
The lock prefix cannot be used on this instruction. A same-line lock: remains valid as a
label; a newline inside a comment also separates the prefix, instruction, or label colon.
The C backend also supports raw GNU assembly templates. In a raw block, V passes each
double-quoted template string through unchanged and still checks the output, input, and clobber
lists. Operands can use GNU's named form or V's constraint (expression) as alias form:
Use intel for destination-first structured x86 assembly. V surrounds the generated template
with .intel_syntax noprefix and .att_syntax prefix, and does not reorder its operands:
Structured intel blocks support only register-only r constraints for input and output
operands. V uses the GNU x86 %V operand modifier so GCC and Clang substitute register names
without AT&T's % prefix. Memory-capable constraints such as m are rejected because compilers
can still format those placeholders with AT&T addressing. In a raw intel block, the template is
passed through unchanged, so use the selected C compiler's explicit operand modifiers.
%V is the only operand modifier that omits the % prefix, and it prints the compilation
target's native register: 64 bits for 64-bit machine code and 32 bits for 32-bit machine code,
including when -m32 overrides an explicit architecture. This is independent of the architecture
declared on the assembly block. For instructions whose register operands must have the same width,
V rejects a named operand combined with an explicit hard register of a different width. For
example, in a 64-bit build, mov eax, some_value would reach the assembler as mov eax, rcx, so V
rejects it at compile time. Named operands may still use narrower V types for operations that
preserve their low-width result, such as an alias-only add whose flags are not observed later in
the block. V rejects narrower operands where the instruction meaning changes with width, including
shifts, rotates, implicit multiply and divide, bit counts, bit tests, byte swaps, and CRC32 sources.
It also rejects narrower signed operands of cmp and test, and narrow arithmetic when a later
instruction observes its flags. Named operands cannot be sources of movsx, movsxd, or movzx.
Addressed sources of movsx and movzx are also rejected because structured assembly cannot
specify their data width. Named shift counts are not supported because the r constraint cannot
select cl. Effective addresses cannot contain three register operands, and signed address
components must have the target's native width. Use a raw intel block to pick operand widths
explicitly with %k, %w and related modifiers.
The raw and intel modifiers affect GNU-style inline assembly emitted by the C backend. MSVC
does not support this form of inline assembly on 64-bit targets, and individual instructions or
constraints can still depend on the selected C compiler and target architecture.
For more examples, see vlib/v/slow_tests/assembly/asm_test.amd64.v
Hot code reloading
Build this example with v -live message.v.
You can also run this example with v -live run message.v.
Make sure that in command you use a path to a V's file,
not a path to a folder (like v -live run .) -
in that case you need to modify content of a folder (add new file, for example),
because changes in message.v will have no effect.
Functions that you want to be reloaded must have @[live] attribute
before their definition.
Right now it's not possible to modify types while the program is running.
More examples, including a graphical application: github.com/vlang/v/tree/master/examples/hot_reload.
About keeping states in hot reloading functions with v -live run
V's hot code reloading relies on marking the functions that you want to reload with @[live],
then compiling a shared library of these @[live] functions, and then
your v program loads that shared library at runtime.
V (with the -live option) starts a new thread, that monitors the source files for changes, and when it detects modifications, it recompiles the shared library, and reloads it at runtime, so that new calls to those @[live] functions will be made to the newly loaded library.
It keeps all the accumulated state (from locals outside the @[live] functions, from heap variables and from globals), allowing to tweak the code in the merged functions quickly.
When there are more substantial changes (to data structures, or to functions that were not marked), you will have to restart the running app manually.
Cross-platform shell scripts in V
V can be used as an alternative to Bash to write deployment scripts, build scripts, etc.
The advantage of using V for this, is the simplicity and predictability of the language, and cross-platform support. "V scripts" run on Unix-like systems, as well as on Windows.
To use V's script mode, save your source file with the .vsh file extension.
It will make all functions in the os module global (so that you can use mkdir() instead
of os.mkdir(), for example).
V also knows to compile & run .vsh files immediately, so you do not need a separate
step to compile them. V will also recompile an executable, produced by a .vsh file,
only when it is older than the .vsh source file, i.e. runs after the first one, will
be faster, since there is no need for a re-compilation of a script, that has not been changed.
An example deploy.vsh:
Now you can either compile this like a normal V program and get an executable you can deploy and run
anywhere:
v -skip-running deploy.vsh && ./deploy
Or run it like a traditional Bash script:
v run deploy.vsh (or simply just v deploy.vsh)
On Unix-like platforms, the file can be run directly after making it executable using chmod +x:
./deploy.vsh
Vsh scripts with no extension
Whilst V does normally not allow vsh scripts without the designated file extension, there is a way
to circumvent this rule and have a file with a fully custom name and shebang. Whilst this feature
exists it is only recommended for specific usecases like scripts that will be put in the path and
should not be used for things like build or deploy scripts. To access this feature start the
file with #!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp where tmp is the prefix for
the built executable. This will run in crun mode so it will only rebuild if changes to the script
were made and keep the binary as tmp.<scriptfilename>. Caution: if this filename already
exists the file will be overridden. If you want to rebuild each time and not keep this binary
instead use #!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp run.
Note: there is a small shell script cmd/tools/vrun, that can be useful for systems, that have an
env program (/usr/bin/env), that still does not support an -S option (like BusyBox and OpenBSD).
See https://github.com/vlang/v/blob/master/cmd/tools/vrun for more details.