Skip to content
This repository has been archived by the owner on Aug 24, 2022. It is now read-only.

Meta Attributes

K. Gadd edited this page Apr 25, 2014 · 13 revisions

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.

Universal Attributes

JSIgnore

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).

JSChangeName

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.)

JSReplacement

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

JSExternal

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. (:

JSImmutable

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.

Type Attributes

JSStubOnly

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.

Method or Constructor Attributes

JSRuntimeDispatch

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).

Method Attributes

JSExtraStaticConstructor

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.

Constructor Attributes

JSChangeToStaticMethod

Replaces invocations of this constructor with invocations of a static method. (You provide the name of the method.)

Property Attributes

JSAlwaysAccessAsProperty

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.

Packed Arrays

JSPackedArray

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.

JSPackedArrayReturnValue

Tag a method with this to indicate that the array it returns is a packed array.

JSPackedArrayArguments

Tag a method with this to indicate that the named arguments are always packed arrays.

JSAllowPackedArrayArguments

Tag a method with this to indicate that the named arguments may be packed arrays but are not required to be.