Methods are similar to C functions, but also have an implicit (invisible) parameter which allows them to refer to the current device instance, i.e., the Simics configuration object representing the device. Methods also support exception handling in DML, using try and throw. The body of the method is a compound statement in an extended subset of C; see also Section 4.10. It is an error to have more than one method declaration using the same name within the same scope.
In addition to the input parameters, a DML method can have any number of output parameters, in contrast to C functions which have at most one return value. DML methods do not use the keyword void - an empty pair of parentheses always means "zero parameters", and can even be omitted. Apart from this, the parameter declarations of a method are ordinary C-style declarations.
For example,
method m1 {...}
and
method m1() {...}
are equivalent, and define a method that takes no input parameters and
returns nothing.
method m2(int a) -> () {...}
defines a method that takes a single input parameter, and also returns
nothing.
method m3(int a, int b) -> (int c) {
...;
c = ...;
}
defines a method with two input parameters and a single output
parameter. Output parameters must be explicitly assigned before the
method returns.
method m4() -> (int c, int d) {
...;
c = ...;
d = ...;
return;
}
has no input parameters, but two output parameters. Ending the method
body with a return statement is optional.
In DML, a method call is performed with one of the call and inline keywords. (In DML 1.0, method calls can only be statements, not expressions; this limitation may be removed in later versions of DML.) For instance,
call $access(...) -> (a, b)
will call the method 'access' in the same object, assigning the values
of the output parameters to variables a and b. (Note
the '$' character which is necessary for referring to the
method.) The call might be inline expanded depending on the C compiler
used to compile the generated code, but there is no guarantee.
On the other hand,
inline $access(...) -> (a, b)
has the same semantics as the call, but will always inline
expand the called method.
Methods can also be used as macros, by omitting the types on one or more of the input parameters. A method defined this way can only be called through an inline statement; see Section 4.11.5.
For example,
method twice(x) -> (y) { y = x + x; }
could be used to double any numeric value without forcing the result to
be of any particular type, as in
int32_t x;
int64_t y;
inline twice(x) -> (x);
inline twice(y) -> (y);
This is sometimes referred to as a polymorphic method.
This form of macros is particularly useful when writing templates (see Section 4.9.2). Note that the name scoping rules and the semantics of calls are the same as for normal methods; in other words, it is a form of "hygienic macros".
A method can be declared external, which means that a C function corresponding to the method is guaranteed to be generated, and will have external linkage. This is done by prefixing the name of the method with the keyword extern; e.g.:
method extern my_method(int x) { ... }
An external method must have a proper signature, i.e., the types of all
its input and output parameters must be specified.
External methods are rarely used, since most of the needs for making DML methods accessible from outside the device model itself are covered by the implement, event, and attribute type objects.