Strings
Whamm has very basic support for strings; they are injected into the instrumented Wasm program
and are represented as the tuple: (memory_address, length). Only static strings can be defined,
e.g. "i'm a string", no dynamic string creation is supported (yet), e.g. "i " + " am " + " groot".
However, as a workaround, you can pull a string from a user library to get this functionality.
var a: str = "";
var b: str = "The quick brown fox";
// var c: string = null; // INVALID -- strings cannot be set to null
Escapes
Strings can use the \ character to escape some sequences including:
\nnewline\ttab\"double quote\'single quote\\backslash\0null byte\x(HEX_DIGIT{2})to insert hex\u(HEX_DIGIT+)to insert unicode
// encodes the string literal: "hello dropππA"
report var s: str = "hello drop\u{1F600}π\x41\n";
Utilities
The following utilities are provided for string operations:
var s: str = "test";
/// Returns the length of the string.
/// This length is in bytes, not chars or graphemes. In other words, it might not be
/// what a human considers the length of the string.
var l: u32 = s.len();
/// Returns true if the given pattern matches a prefix of this string slice.
/// Returns false if it does not.
var r0: bool = s.starts_with("te"); // `true`
var r1: bool = s.starts_with("st"); // `false`
/// Returns true if the given pattern matches a suffix of this string slice.
/// Returns false if it does not.
var r2: bool = s.ends_with("te"); // `false`
var r3: bool = s.ends_with("st"); // `true`
/// Returns true if the given pattern matches a sub-slice of this string.
/// Returns false if it does not.
var r4: bool = s.contains("te"); // `true`
var r5: bool = s.contains("NA"); // `false`
Strings and Libraries
Strings can be passed to / pulled from libraries through memory operations. To have this work in your own libraries, you will have to expose functions to allocate/free memory.
Write to a library:
use whamm_core;
wasm:opcode:drop:before {
// initialize the string to pass
var s: str = "hello world!";
var l: u32 = s.len();
// allocate the right number of bytes to store the string
var ptr: i32 = whamm_core.mem_alloc(l as i32);
// write the string to the target library's memory
write_str(memid(whamm_core), ptr, s);
// call a function in the library that uses the passed string
// (this just prints the string)
whamm_core.puts(ptr, l as i32);
// free the allocated memory
whamm_core.mem_free(ptr);
}
Pull from a library:
use alpha;
wasm:opcode:drop:before {
// allocate some space in memory to store the library's string
var MAX: i32 = 100;
var ptr: i32 = alpha.mem_alloc(MAX);
// write a string to memory, return the length of the string written
var l: i32 = alpha.write_alphabet(ptr, MAX);
// read the string from the library's memory
var s: str = read_str(memid(alpha), ptr, l as u32);
// free the memory we've just used
alpha.mem_free(ptr);
}