Skip to content

Commit

Permalink
Torque - modules are now namespaces (#67)
Browse files Browse the repository at this point in the history
* Update torque.md

* getting closer

* More renaming
  • Loading branch information
ripsawridge committed Nov 13, 2018
1 parent ae877e9 commit 51e1298
Showing 1 changed file with 23 additions and 23 deletions.
46 changes: 23 additions & 23 deletions src/docs/torque.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Hello world!

The Torque compiler doesn’t create machine code directly, but rather generates C++ code that calls V8’s existing `CodeStubAssembler` interface. The `CodeStubAssembler` uses the TurboFan compiler’s backend to generate efficient code. Torque compilation therefore requires multiple steps:

1. The `gn` build first runs the Torque compiler. It processes all `*.tq` files, outputting corresponding `*-gen.cc` files (one `.cc` file per Torque module). The `.cc` files that are generated use TurboFan’s `CodeStubAssembler` interface for generating code.
1. The `gn` build first runs the Torque compiler. It processes all `*.tq` files, outputting corresponding `*-gen.cc` files (one `.cc` file per Torque namespace). The `.cc` files that are generated use TurboFan’s `CodeStubAssembler` interface for generating code.
1. The `gn` build then compiles the generated `.cc` files from step 1 into the `mksnapshot` executable.
1. When `mksnapshot` runs, all of V8’s builtins are generated and packaged in to the snapshot file, including those that are defined in Torque and any other builtins that use Torque-defined functionality.
1. The rest of V8 is built. All of Torque-authored builtins are made accessible via the snapshot file which is linked into V8. They can be called like any other builtin. In the final packaging, no direct traces of Torque remain (except for debug information): neither the Torque source code (`.tq` files) nor Torque-generated `.cc` files are included in the the `d8` or `chrome` executable.
Expand Down Expand Up @@ -89,7 +89,7 @@ In combination with generics, `constexpr` is a powerful Torque tool that can be

## Files

Torque code is packaged in individual source files. Each source file consists of a series of declarations, which themselves can optionally wrapped in a module declaration to separate the namespaces of declarations. The grammar for a `.tq` file is as follows:
Torque code is packaged in individual source files. Each source file consists of a series of declarations, which themselves can optionally wrapped in a namespace declaration to separate the namespaces of declarations. The grammar for a `.tq` file is as follows:

<pre><code class="language-grammar">Declaration :
AbstractTypeDeclaration
Expand All @@ -98,55 +98,55 @@ Torque code is packaged in individual source files. Each source file consists of
ConstDeclaration
GenericSpecialization

ModuleDeclaration :
<b>module</b> IdentifierName <b>{</b> Declaration* <b>}</b>
NamespaceDeclaration :
<b>namespace</b> IdentifierName <b>{</b> Declaration* <b>}</b>

FileDeclaration :
ModuleDeclaration
NamespaceDeclaration
Declaration</code></pre>

## Modules
## Namespaces

Torque modules allow declarations to be independent namespaces and they bear a similarity to C++ namespaces. They allow you to create declarations that are not automatically visible in other modules. Modules can be nested, and declarations inside a nested module can access the declarations in the module that contains them without qualification. Declarations that are not explicitly in a module declaration are put in a shared global default module that is visible to all modules. Modules can be reopened, allowing them to be defined over multiple files.
Torque namespaces allow declarations to be independent namespaces. They are similar to C++ namespaces. They allow you to create declarations that are not automatically visible in other namespaces. They can be nested, and declarations inside a nested namespace can access the declarations in the namespace that contains them without qualification. Declarations that are not explicitly in a namespace declaration are put in a shared global default namespace that is visible to all namespaces. Namespaces can be reopened, allowing them to be defined over multiple files.

For example:

```torque
macro IsJSObject(o: Object): bool { … } // In default module
macro IsJSObject(o: Object): bool { … } // In default namespace
module array {
macro IsJSArray(o: Object): bool { … } // In array module
namespace array {
macro IsJSArray(o: Object): bool { … } // In array namespace
};
module string {
namespace string {
// …
macro TestVisibility() {
IsJsObject(o); // OK, global module visible here
IsJSArray(o); // ERROR, not visible in this module
IsJsObject(o); // OK, global namespace visible here
IsJSArray(o); // ERROR, not visible in this namespace
}
// …
}
module array {
// OK, module has been re-opened.
namespace array {
// OK, namespace has been re-opened.
macro EnsureWriteableFastElements(array: JSArray){ … }
};
```

Conceptually, a Torque module maps to a specific subclass of `CodeStubAssembler`, and most Torque module declarations map to C++ declarations in that subclass. When the Torque compiler process all of the `.tq` files in V8, all of the declarations in a module are collected and written out together into a predictably-named `CodeStubAssembler` subclass that’s generated at compile-time.
Conceptually, a Torque namespace maps to a specific subclass of `CodeStubAssembler`, and most Torque namespace declarations map to C++ declarations in that subclass. When the Torque compiler process all of the `.tq` files in V8, all of the declarations in a namespace are collected and written out together into a predictably-named `CodeStubAssembler` subclass that’s generated at compile-time.

For example, the following module declaration specifies two Torque `macro`s in the `foo` module. (`macro`s are a Torque primitive that specifies how to generate a bunch of CSA code and they are discussed in more detail below, but for this example it suffices to know that they produce CSA-generating C++ code that would have been hand-written in a method of a `CodeStubAssembler` class in a pre-Torque world.)
For example, the following namespace declaration specifies two Torque `macro`s in the `foo` namespace. (`macro`s are a Torque primitive that specifies how to generate a bunch of CSA code and they are discussed in more detail below, but for this example it suffices to know that they produce CSA-generating C++ code that would have been hand-written in a method of a `CodeStubAssembler` class in a pre-Torque world.)

```torque
module foo {
namespace foo {
extern macro Bar();
macro Baz() {}
};
```

This module declaration would result in two generated files in the build directory called `builtins-foo-gen-from-idl.h` and `builtins-foo-gen-from-idl.cc`. These files contain the declaration and definition of a `CodeStubAssembler`-derivative class containing the C++ that implements the Torque code in the `foo` namespace.
This namespace declaration would result in two generated files in the build directory called `builtins-foo-gen-from-idl.h` and `builtins-foo-gen-from-idl.cc`. These files contain the declaration and definition of a `CodeStubAssembler`-derivative class containing the C++ that implements the Torque code in the `foo` namespace.

In this example, `builtins-foo-gen-from-idl.h` declares `FooBuiltinsFromDSLAssembler`, a subclass of a similarly-named `FooBuiltinsAssembler`. Both class names are mechanically generated by converting the module name to a CamelCase identifier:
In this example, `builtins-foo-gen-from-idl.h` declares `FooBuiltinsFromDSLAssembler`, a subclass of a similarly-named `FooBuiltinsAssembler`. Both class names are mechanically generated by converting the namespace name to a CamelCase identifier:

```cpp
class FooBuiltinsFromDSLAssembler: public FooBuiltinsAssembler {
Expand All @@ -158,9 +158,9 @@ class FooBuiltinsFromDSLAssembler: public FooBuiltinsAssembler {
`FooBuiltinsFromDSLAssembler` contains all of the Torque-implemented declarations for the `foo` namespace. In this case it only contains the method `Baz`, a C++ method that uses the CSA interface to generate code for `Baz`’s Torque implementation.
Note that module classes do not directly derive from the class of their parent module, but rather provide a level of indirection between themselves and their parent module’s superclass that allows direct CSA-based functionality to be added to the module. In this case, `FooBuiltinsFromDSLAssembler` subclasses `FooBuiltinsAssembler`, which must be provided as a pure-CSA implementation. It provides an intermediary place to put non-Torque implemented (i.e. hand-written CSA) functionality that also belongs to the module. In this example, `FooBuiltinsAssembler` must implement `Bar`, since it is declared in a Torque as an `external macro`, i.e. it is not implemented in Torque code but provided through a hand-written CSA implementation in C++.
Note that namespace classes do not directly derive from the class of their parent namespace, but rather provide a level of indirection between themselves and their parent namespace’s superclass that allows direct CSA-based functionality to be added to the namespace. In this case, `FooBuiltinsFromDSLAssembler` subclasses `FooBuiltinsAssembler`, which must be provided as a pure-CSA implementation. It provides an intermediary place to put non-Torque implemented (i.e. hand-written CSA) functionality that also belongs to the namespace. In this example, `FooBuiltinsAssembler` must implement `Bar`, since it is declared in a Torque as an `external macro`, i.e. it is not implemented in Torque code but provided through a hand-written CSA implementation in C++.
New modules must be added to the `BUILD.gn` file in the `torque_modules` variable.
New namespaces must be added to the `BUILD.gn` file in the `torque_namespaces` variable.
## Declarations
Expand Down Expand Up @@ -249,7 +249,7 @@ Macros are a callable that correspond to a chunk of generated CSA-producing C++.
<b>extern macro</b> IdentifierName ImplicitParameters<sub>opt</sub> ExplicitTypes ReturnType<sub>opt</sub> LabelsDeclaration<sub>opt</sub> <b>;</b>
</code></pre>

Every non-`extern` Torque `macro` uses the `StatementBlock` body of the `macro` to create a CSA-generating function in its module’s generated `Assembler` class. This code looks just like other code that you might find in `code-stub-assembler.cc`, albeit a bit less readable because it’s machine-generated. `macro`s that are marked `extern` have no body written in Torque and simply provide the interface to hand-written C++ CSA code so that it’s usable from Torque.
Every non-`extern` Torque `macro` uses the `StatementBlock` body of the `macro` to create a CSA-generating function in its namespace’s generated `Assembler` class. This code looks just like other code that you might find in `code-stub-assembler.cc`, albeit a bit less readable because it’s machine-generated. `macro`s that are marked `extern` have no body written in Torque and simply provide the interface to hand-written C++ CSA code so that it’s usable from Torque.

`macro` definitions specify implicit and explict parameters, an optional return type and optoinal labels. Parameters and return types will be discussed in more detail below, but for now it suffices to know that they work somewhat like TypeScript parameters, which as discussed in the Function Types section of the TypeScript documentation [here](https://www.typescriptlang.org/docs/handbook/functions.html).

Expand Down

0 comments on commit 51e1298

Please sign in to comment.