diff --git a/build_docs.sh b/build_docs.sh index 66fab79126..b2ec6c4867 100644 --- a/build_docs.sh +++ b/build_docs.sh @@ -5,8 +5,8 @@ set -o errexit shopt -s globstar # build individual documentation -(cd plugin && cargo doc --no-deps) -(cd runtime && cargo doc --no-deps) +(cd plugin && cargo doc) +(cd runtime && cargo doc) # remove old docs build rm -rf build_docs @@ -18,15 +18,19 @@ mkdir ./build_docs/plugin mkdir ./build_docs/runtime # build plugin docs -for f in ./plugin/doc/*.md; do - rustdoc $f -o ./build_docs/language --html-before-content=./plugin/doc/pre.html --html-after-content=./plugin/doc/post.html --markdown-css=./formatting.css +for f in ./doc/*.md; do + rustdoc $f -o ./build_docs/language --markdown-no-toc --html-before-content=./doc/pre.html --html-after-content=./doc/post.html --markdown-css=./formatting.css done -cp ./plugin/doc/formatting.css ./build_docs/language/formatting.css +cp ./doc/formatting.css ./build_docs/language/formatting.css # copy over the docs folders cp -r ./plugin/target/doc/* ./build_docs/plugin cp -r ./runtime/target/doc/* ./build_docs/runtime +# hack in javascript +cat ./doc/hack.js >> ./build_docs/plugin/search-index.js +cat ./doc/hack.js >> ./build_docs/runtime/search-index.js + if [ "$1" == "commit" ]; then git clone --branch gh-pages --depth 1 "git@github.com:CensoredUsername/dynasm-rs.git" deploy_docs cd deploy_docs diff --git a/doc/formatting.css b/doc/formatting.css new file mode 100644 index 0000000000..e62045fcf7 --- /dev/null +++ b/doc/formatting.css @@ -0,0 +1,2 @@ +@import url('../plugin/rustdoc.css'); +@import url('../plugin/main.css'); diff --git a/doc/hack.js b/doc/hack.js new file mode 100644 index 0000000000..7e2ecc6ac7 --- /dev/null +++ b/doc/hack.js @@ -0,0 +1,34 @@ +var path = $(".location").text(); +var nest_count; +if (path) { + nest_count = path.split("::").length + 1; +} else { + nest_count = 1; +} +if (window.location.pathname.endsWith("index.html")) { + nest_count += 1; +} + +var base_path = ""; +for (i = 0; i < nest_count; i++) { + base_path += "../"; +} + +$(".sidebar").prepend('\ +

\ + dynasm-rs\ +

\ +
\ +

Components

\ + \ +
'); diff --git a/doc/index.md b/doc/index.md new file mode 100644 index 0000000000..c5abcdc9cc --- /dev/null +++ b/doc/index.md @@ -0,0 +1,26 @@ +% Dynasm-rs + +In the search for faster interpreters, Just-In-Time compilation is often a useful tool. +This compiler extension attempts to make the writing of such programs easier and faster. + +At its core, dynasm-rs is an assembler compiler. It reads assembly templates which it then +compiles into code that when executed will result in the proper machine code being emitted. + +Dynasm is split up into two parts. The first is the compiler extension that performs the +translation of assembly templates into rust code, the second part is a +[small runtime](../runtime/dynasmrt/index.html) that handles the generation of the wanted +machine code. + +For now dynasm-rs only supports the x64 instruction set. + +Dynasm-rs is inspired by the LuaJIT DynASM project for C and C++. + +# Documentation + +The documentation of dynasm-rs is split up into several parts. To get started, you're advised +to read through the [tutorial](./tutorial.html). After this, you can read through the +[language reference](./langref.html) to learn about the syntax used by dynasm-rs. You can +also read through the [runtime documentation](../runtime/dynasmrt/index.html) to learn about the +runtime API. The [instruction reference](./instructionref.html) lists all assembly mnemnonics +and formats supported by dynasm-rs. Finally, documentation on the +[internals on dynasm-rs](../plugin/dynasm/index.html) can be referenced. diff --git a/doc/instructionref.md b/doc/instructionref.md new file mode 100644 index 0000000000..6cb9a28d93 --- /dev/null +++ b/doc/instructionref.md @@ -0,0 +1,3 @@ +% Instruction Reference + +Coming soon. \ No newline at end of file diff --git a/doc/langref.md b/doc/langref.md new file mode 100644 index 0000000000..57fcb8137f --- /dev/null +++ b/doc/langref.md @@ -0,0 +1,181 @@ +% Language Reference + +# Lexical structure definition + +## Base units + +The following syntax units used in dynasm syntax are defined by the [rust grammar](https://doc.rust-lang.org/grammar.html) itself: + +- `num_lit` +- `ident` +- `expr_path` +- `expr` + +Dynasm-rs defines the following base syntax units: + +- `prefix : "cs" | "ds" | "es" | "fs" | "gs" | "ss" | "lock" | "rep" | "repne" | "repe" | "repnz" | "repz" ;` +- `static_reg` matches any valid register name as seen in table 3 +- `dynamic_reg_family` matches any valid register family from table 3 +- `size : "BYTE" | "WORD" | "DWORD" | "AWORD" | "QWORD" | "OWORD" | "HWORD"` + +## Entry point + +The entry point of dynasm-rs is the dynasm! macro. It is structured as following + +`dynasm : "dynasm" "!" "(" ident (";" line)* ")" ;` + +Where line can be one of the following: + +`line : directive | label | instruction ;` + +## Directives + +Directives are special commands given to the assembler that do not correspond to instructions directly. + +`directive : "." ident (arg ("," arg)* )? ;` + +## Labels + +`label : ident ":" | "->" ident ":" | "=>" expr ;` + +## Instructions + +`instruction : prefix* ident (arg ("," arg)* )? ;` + +## Arguments + +`arg : register | (size? ( memoryref | labelref | typemap | expr ));` + +`memoryref : "[" (regref | labelref) "]" ;` + +`regref : regrefitem ("+" regrefitem)* ;` + +`regrefitem : (register "*" num_lit | num_lit "*" register | register | expr) ;` + +`labelref : (">" ident | "<" ident | "->" ident | "=>" expr) ;` + +`typemap : register "=>" expr_path ("." ident | "[" register "]" ("." ident)?) ;` + +`register = static_reg | dynamic_reg ;` + +`dynamic_reg = dynamic_reg_family "(" expr ")" ;` + +# Reference + +## Directives + +Dynasm-rs currently supports the following directives: + + +Table 1: dynasm-rs directives + +Name | Argument format | Description +----------|-----------------|------------ +`.align` | An expression of type usize | Pushes NOPs until the assembling head has reached the desired alignment. +`.byte` | One or more expressions of the type `i8` | Pushes the values into the assembling buffer. +`.word` | One or more expressions of the type `i16` | Pushes the values into the assembling buffer. +`.dword` | One or more expressions of the type `i32` | Pushes the values into the assembling buffer. +`.qword` | One or more expressions of the type `i64` | Pushes the values into the assembling buffer. +`.bytes` | An expression of that implements `IntoIterator` or `IntoIterator` | extends the assembling buffer with the iterator. + +## Labels + +In order to describe flow control effectively, dynasm-rs supports labels. However, since the assembly templates can be combined in a variety of ways at the mercy of the program using dynasm-rs, the semantics of these labels are somewhat different from how labels work in a static assembler. + +Dynasm-rs distinguishes between three different types of labels: global, local and dynamic labels. Their syntax is as follows: + +Table 2: dynasm-rs label types + +Type | Definition | Reference +--------|--------------|----------- +Local | `label:` | `>label` or `label:` | `->label` +Dynamic | `=>expr` | `=>expr` + +### Local labels + +On first sight, local label definitions are similar to how labels are normally used in static assemblers. The trick with local labels is however in how they can be referenced. Local labels referenced with the `>label` syntax will be resolved to the first definition of this label after this piece of code, while local labels referenced with the `label]` | Label references can also be dereferenced. This goes for all label types. + +#### Type mapped references + +To ease interoperation with rust structures, dynasm-rs supports the following syntax for accessing members of pointers to structs and struct arrays. In this syntax, the scale and displacement in a normal memory reference are derived from the size of the type and the offset of the member in the type. Due to the limitations of procedural macros, invalid scales will unfortunately only panic at runtime. Note that dynasm-rs is unable to infer the size of the attribute and it should therefore be determined by a size prefix. + +The syntax for type maps is as follows + +Table 5: dynasm-rs type map formats + +Syntax | Equivalent expression +:------|:----------- +`rax => Type.attr` | `(rax as *mut Type).attr` +`rax => Type[rbx]` | `(rax as *mut [Type])[rbx]` +`rax => Type[rbx].attr` | `(rax as *mut [Type])[rbx].attr ` + +#### Immediates + +Any operand which does not match the previously discussed forms will be interpreted as an immediate argument. This operand will be evaluated as an expression at runtime and the resulting value will be encoded. The size of the encoded value can be determined by a size prefix. diff --git a/doc/post.html b/doc/post.html new file mode 100644 index 0000000000..c63a94a2b8 --- /dev/null +++ b/doc/post.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/doc/pre.html b/doc/pre.html new file mode 100644 index 0000000000..b4c8e4858a --- /dev/null +++ b/doc/pre.html @@ -0,0 +1,37 @@ + +
\ No newline at end of file diff --git a/doc/tutorial.md b/doc/tutorial.md new file mode 100644 index 0000000000..9245fa1a4b --- /dev/null +++ b/doc/tutorial.md @@ -0,0 +1,3 @@ +% Tutorial + +Coming soon. \ No newline at end of file diff --git a/plugin/src/lib.rs b/plugin/src/lib.rs index c09a666025..9278e3a535 100644 --- a/plugin/src/lib.rs +++ b/plugin/src/lib.rs @@ -17,11 +17,11 @@ use syntax::util::small_vector::SmallVector; use syntax::parse::token::intern; use syntax::tokenstream::TokenTree; -mod parser; -mod compiler; -mod x64data; -mod serialize; -mod debug; +pub mod parser; +pub mod compiler; +pub mod x64data; +pub mod serialize; +pub mod debug; #[plugin_registrar]