CTS, CLI, VES

 


CLI - The Common Language Infrastructure (CLI) provides a specification for executable code and the execution environment (the Virtual Execution System) in which it runs. Executable code is presented to the VES as modules. A module is a single file containing executable content.

CTS -  The Common Type System (CTS)—The CTS provides a rich type system that supports the types and operations found in many programming languages. 

VES - The Virtual Execution System (VES)—The VES implements and enforces the CTS model. The VES is responsible for loading and running programs written for the CLI. It provides the services needed to execute managed code and data, using the metadata to connect separately generated modules together at runtime (late binding).

CLS - The Common Language Specification (CLS)—The CLS is an agreement between language designers and framework (that is, class library) designers. It specifies a subset of the CTS and a set of usage conventions. 

Metadata—The CLI uses metadata to describe and reference the types defined by the CTS. Metadata is stored (that is, persisted) in a way that is independent of any particular programming language. Thus, metadata provides a common interchange mechanism for use between tools (such as compilers and debuggers) that manipulate programs, as well as between these tools and the VES

CTS :

Types describe values. Any value described by a type is called an instance of that type. Any use of a value—storing it, passing it as an argument, operating on it—requires a type. This applies in particular to all variables, arguments, evaluation stack locations, and method results. The type defines the allowable values and the allowable operations supported by the values of the type. All operators and functions have expected types for each of the values accessed or used. Every value has an exact type that fully describes its type properties. Every value is an instance of its exact type, and can be an instance of other types as well. In particular, if a value is an instance of a type that inherits from another type, it is also an instance of that other type.

Value types and reference types 

There are two kinds of types: value types and reference types

Value types – The values described by a value type are self-contained (each can be understood without reference to other values

Reference types –A value described by a reference type denotes the location of another value. There are four kinds of reference type:

  1. An object type is a reference type of a self-describing value .Some object types (e.g., abstract classes) are only a partial description of a value
  2. An interface type is always a partial description of a value, potentially supported by many object types.
  3. A pointer type is a compile-time description of a value whose representation is a machine address of a location. Pointers are divided into managed and unmanaged
  4. Built-in reference types. 

Boxing and unboxing of values 

For every value type, the CTS defines a corresponding reference type called the boxed type. The reverse is not true: In general, reference types do not have a corresponding value type. The representation of a value of a boxed type (a boxed value) is a location where a value of the value type can be stored. A boxed type is an object type and a boxed value is an object.

 All value types have an operation called box. Boxing a value of any value type produces its boxed value; -  a value of the corresponding boxed type containing a bitwise copy of the original value. If the value type is a nullable type—defined as an instantiation of the value type System.Nullable—the result is a null reference or bitwise copy of its Value property of type T, depending on its HasValue property (false and true, respectively). All boxed types have an operation called unbox, which results in a managed pointer to the bit representation of the value. 

(bitwise copy is a copy of a block of memory. by performing a bitwise copy, you're only gonna copy the address of memory it points to.)

Accessibility of members and nested types
- compiler-controlled – accessible only through the use of a definition, not a reference, hence only accessible from within a single compilation unit and under the control of the compiler. 

- private – accessible only to referents in the implementation of the exact type that defines the member

- family – accessible to referents that support the same type (i.e., an exact type and all of the types that inherit from it). For verifiable code , there is an additional requirement that can require a runtime check: the reference shall be made through an item whose exact type supports the exact type of the referent. That is, the item whose member is being accessed shall inherit from the type performing the access
assembly – accessible only to referents in the same assembly that contains the implementation of the type
-family-and-assembly – accessible only to referents that qualify for both family and assembly access
- family-and-assembly – accessible only to referents that qualify for both family and assembly access
- public – accessible to all referents.

Contracts
Contracts are named. They are the shared assumptions on a set of signatures between all implementers and all users of the contract. The signatures are the part of the contract that can be checked and enforced. Contracts are not types; rather they specify requirements on the implementation of types. Types state which contracts they abide by.
 - Class contract– A class contract is specified with a class definition. Hence, a class definition defines both the class contract and the class type.

- Interface contract – An interface contract is specified with an interface definition. Hence, an interface definition defines both the interface contract and the interface type

 - Method contract – A method contract is specified with a method definition. A method contract is a named operation that specifies the contract between the implementation(s) of the method and the callers of the method. A method contract is always part of a type contract (class, value type, or interface), and describes how a particular named operation is implemented

-Property contract – A property contract is specified with a property definition. There is an extensible set of operations for handling a named value, which includes a standard pair for reading the value and changing the value.
  - Event contract – An event contract is specified with an event definition. There is an extensible set of operations for managing a named event, which includes three standard methods :
  1. register interest in an event, 
  2. revoke interest in an event, 
  3. fire the event
Signatures 
Signatures are the part of a contract that can be checked and automatically enforced. Signatures are formed by adding constraints to types and other signatures. A constraint is a limitation on the use of or allowed operations on a value or location. Example constraints would be whether a location can be overwritten with a different value or whether a value can ever be changed. 
All locations have signatures, as do all values
There are four fundamental kinds of signatures:
  • type signatures 
  • location signatures 

- init-only constraint requires that once the location has been initialized, its contents never change. 

 - literal constraint promises that the value of the location is actually a fixed value of a built-in type

  • parameter signatures 
  • method signatures
Type safety and verification 
Since types specify contracts, it is important to know whether a given implementation lives up to these contracts. An implementation that lives up to the enforceable part of the contract (the named signatures) is said to be type-safe. An important part of the contract deals with restrictions on the visibility and accessibility  of named items as well as the mapping of names to implementations and locations in memory.

Verification is a mechanical process of examining an implementation and asserting that it is type-safe. Verification is said to succeed if the process proves that an implementation is typesafe. Verification is said to fail if that process does not prove the type safety of an implementation.

Array types 
An array type shall be defined by specifying the element type of the array, the rank (number of dimensions) of the array, and the upper and lower bounds of each dimension of the array. Hence, no separate definition of the array type is needed. The bounds (as well as indices into the array) shall be signed integers. While the actual bounds for each dimension are known only at runtime, the signature can specify the information that is known at compile time (e.g., no bounds, a lower bound, or both an upper and a lower bound).