-
Notifications
You must be signed in to change notification settings - Fork 242
Meta Attributes
The assembly JSIL.Meta contains various attributes you can use to control the behavior of JSILc when it translates your managed code to JavaScript. These attributes can either be applied directly, or applied indirectly using Proxies.
Proxy Attributes lists attributes specific to authoring proxies. Those ones can only be used when writing a proxy.
Static Analysis Attributes lists attributes specific to optimization. You can use those to control the static analyzer and resulting optimizations JSILc applies to your code.
Ignore any references to the attributed type or member. Attempts to use it will produce errors at runtime. Anything defined by the ignored type or member will be ignored automatically (i.e. ignoring a class ignores its methods).
Renames the type or member at runtime. This allows you to work around members having a reserved name in JavaScript, and similar problems (for example, we use this to rename .NET's ToString to match JS's toString.)
Replaces references to the attributed type or member with a JavaScript Expression. Replacement expressions support special variable tokens. Variable tokens are prefixed with $ to mark them as a string to be replaced. If you want to insert an actual $, write $$.
Token | Description |
---|---|
argumentName | Inserts the value of the named argument. |
typeof(argumentName) | Inserts the type of the named argument. Note that this is using compile-time information. |
etypeof(argumentName) | Inserts the element type of the named argument. Note that this is using compile-time information. For an array T[], the element type will be T. |
this | Inserts the this-reference for the method being called. |
typeof(this) | Inserts the type of the this-reference for the method being called (compile-time information). For static methods, this is the type that declared the method. |
etypeof(this) | See etypeof(argumentName) and typeof(this) above; I'm lazy. |
assemblyof(executing) |
Assembly.GetExecutingAssembly and company can't be trivially implemented in JS, since they rely on stack-walking and method handles and stuff. This expression is replaced with the assembly that defined the executing code (i.e. the code CALLING the function that was replaced by this expression). We use this to implement GetExecutingAssembly and make all your grandest dreams come true*. * Not really |
For methods and properties, only generate method information, not a method body. This lets you implement them in JS. For types, this applies the same behavior to all their methods and properties. I'm not really sure what this does for fields. (:
For fields, tells JSILc to treat the field as if it is immutable - you're promising that it won't get modified, and the optimizer assumes as much. For types, all the type's fields (and instances of the type itself) are treated as immutable by the optimizer. This can have devastating code correctness consequences if used improperly.
Only generate a stub for this type instead of a full definition. The stub will provide the shape of the type (as if the whole containing assembly were stubbed) so that you can provide implementations with externals. Similar to JSExternal, but easier to use for types.
Overload resolution and other invocation machinery is entirely deferred until runtime. Normally, JSILc does some work to figure out what method you're calling at compile time and generates JS accordingly. This attribute is designed for scenarios where you want to use a single JS function to implement many overloads (and check argument types at runtime).
This tags the attributed method as an 'extra' static constructor that JSIL will invoke at runtime (after the normal static constructor). You can use this for dark, terrible magic. Please don't.
Replaces invocations of this constructor with invocations of a static method. (You provide the name of the method.)
In many cases JSILc will attempt to invoke property accessors directly (instance.get_X()); this suppresses that optimization so that instance.X is always generated.
Tag a field containing an array with this, and the compiler will try to create dense Typed Array storage for it in JS. This eliminates the heap instance for each element, reduces memory usage for the array, and lets you use the array in unsafe code (pinning, etc).
The downside is that this makes everything a total nightmare, because you're messing with type information. :) The following attributes let you control the type information for methods so that they can handle packed arrays correctly.
Tag a method with this to indicate that the array it returns is a packed array.
Tag a method with this to indicate that the named arguments are always packed arrays.
Tag a method with this to indicate that the named arguments may be packed arrays but are not required to be.