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.