bcl

package
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package bcl implements the partial Base Class Library (System.*) vmnet ships natively in Go: types and methods that are not interpreted from IL but registered as native implementations (e.g. System.Math, System.String, System.Collections.Generic.List[T]). Coverage grows by profile — see docs/en/ROADMAP.md Fase 1-3 and docs/en/spec.md section 16.

Index

Constants

View Source
const (
	ExprTypeEqual               = exprTypeEqual
	ExprTypeNotEqual            = exprTypeNotEqual
	ExprTypePreIncrementAssign  = exprTypePreIncrementAssign
	ExprTypePreDecrementAssign  = exprTypePreDecrementAssign
	ExprTypePostIncrementAssign = exprTypePostIncrementAssign
	ExprTypePostDecrementAssign = exprTypePostDecrementAssign
)

Exported mirrors of the exprTypeXxx values above, needed by internal/interpreter/exprcompile.go to tell which real increment/decrement/reference-compare variant an IncDecExpressionParts/BinaryCompareExpressionParts opType holds — everything else about a node's shape is already exposed through its own typed accessor, but opType itself is a bare int since it doubles as the real NodeType value returned by expressionGetNodeType.

Variables

This section is empty.

Functions

func ArrayIndexExpressionParts added in v0.9.0

func ArrayIndexExpressionParts(v runtime.Value) (array, index runtime.Value, ok bool)

ArrayIndexExpressionParts exposes array/index to exprcompile.go's own evaluator, mirroring BinaryCompareExpressionParts/CoalesceExpressionParts.

func AssignExpressionParts

func AssignExpressionParts(v runtime.Value) (left, right runtime.Value, ok bool)

func BinaryCompareExpressionParts

func BinaryCompareExpressionParts(v runtime.Value) (opType int, left, right runtime.Value, ok bool)

BinaryCompareExpressionParts exposes opType/left/right to internal/interpreter/exprcompile.go, mirroring IncDecExpressionParts.

func BlockExpressionParts

func BlockExpressionParts(v runtime.Value) (variables, body []runtime.Value, ok bool)

func CallExpressionParts

func CallExpressionParts(v runtime.Value) (instance runtime.Value, typeName, methodName string, args []runtime.Value, ok bool)

func CatchBlockParts

func CatchBlockParts(v runtime.Value) (testType string, variable, body runtime.Value, ok bool)

CatchBlockParts exposes a CatchBlock's own test type, bound exception variable (KindNull if none), and handler body to exprcompile.go's own Try evaluator.

func ClosedGenericArgs

func ClosedGenericArgs(fullName string) []string

ClosedGenericArgs returns fullName's own closed generic type argument names — e.g. "List`1[[System.String]]" -> ["System.String"] — nil for a non-generic or still-open name. Exported for internal/interpreter/reflection.go's own typeGetBaseType (Fase 3.66), which needs to resolve a "!N" class-generic-parameter-forwarding sentinel in a base type's own BaseTypeFullName (see resolveTypeTokenName's own doc comment, assembly.go) against the RECEIVER type's own closed args — the same splitGenericArgs parsing this package's own typeGetGenericArguments already uses internally.

func CoalesceExpressionParts

func CoalesceExpressionParts(v runtime.Value) (left, right runtime.Value, ok bool)

CoalesceExpressionParts exposes left/right to exprcompile.go's own evaluator and exprvisitor.go's own rebuild logic.

func CompareOrdinaryValues

func CompareOrdinaryValues(a, b runtime.Value) (int, error)

CompareOrdinaryValues implements Comparer<T>.Default's natural ordering for the primitive/string kinds real callers in this loop's target packages actually sort by — vmnet's Value has no generic IComparable dispatch, so this switches on Kind directly (same posture linqCompare, internal/interpreter/linq.go, takes for LINQ's own OrderBy — kept as a separate copy here rather than shared, since interpreter already imports bcl and a reverse import would cycle).

func ConcurrentDictGetOrAdd

func ConcurrentDictGetOrAdd(recv runtime.Value, key runtime.Value, compute func() (runtime.Value, error)) (runtime.Value, error)

ConcurrentDictGetOrAdd looks up key, computing and storing it via compute while holding the dictionary's own lock for the whole operation if it's missing — mirrors LazyGetOrCompute's single-lock-for-the-whole-compute approach (system_lazy.go, Fase 3.17) so two concurrent misses on the same key can't both run the factory. Exported for the Machine-aware GetOrAdd native (internal/interpreter/concurrentdict.go), which supplies compute as either "return the literal value" or "invoke the factory delegate" depending on the real overload called.

func ConditionalExpressionParts

func ConditionalExpressionParts(v runtime.Value) (test, ifTrue, ifFalse runtime.Value, ok bool)

func ConstantExpressionValue

func ConstantExpressionValue(v runtime.Value) (runtime.Value, bool)

func ConstructorInfoConstructTypeFullName added in v0.9.0

func ConstructorInfoConstructTypeFullName(v runtime.Value) (string, bool)

ConstructorInfoConstructTypeFullName returns the type name to use when actually CONSTRUCTING an instance through this ConstructorInfo (Fase 3.81, e.g. ConstructorInfo.Invoke or the compiled Expression.New(ctor) pattern) — the original, possibly-closed-generic name Type. GetConstructor(s) was called on, not the open name ConstructorInfoTypeFullName/ConstructorInfoParts still (correctly) return for Machine.ResolveMember/ResolveMemberParams lookups. Falls back to the open name when no closed name was ever captured (a non-generic type, or a reflection call site that only ever had the open name to begin with) — see nativeConstructorInfo. closedTypeFullName's own doc comment for the real CsvHelper AutoMap()/DefaultClassMap<T> bug this exists to fix.

func ConstructorInfoParts

func ConstructorInfoParts(v runtime.Value) (typeFullName string, overloadIndex int, ok bool)

ConstructorInfoParts is ConstructorInfoTypeFullName plus overloadIndex (Fase 3.52) — used by internal/interpreter/reflection.go's methodBaseGetParameters to find the exact overload this wrapper names among Type.GetConstructors()'s possibly-several real .ctor overloads.

func ConstructorInfoTypeFullName

func ConstructorInfoTypeFullName(v runtime.Value) (string, bool)

ConstructorInfoTypeFullName/MethodInfoParts/FieldInfoParts unwrap the wrapper values back to their plain data — exported so internal/interpreter/reflection.go's Invoke/GetValue natives (which need Machine access the bcl package itself doesn't have) can read them without reaching into bcl's own unexported types.

func ConvertExpressionParts

func ConvertExpressionParts(v runtime.Value) (operand runtime.Value, typeName string, ok bool)

func CustomAttributeDataParts

func CustomAttributeDataParts(v runtime.Value) (typeFullName string, ctorArgs []runtime.Value, ok bool)

CustomAttributeDataParts exposes a CustomAttributeData value's own decoded (typeFullName, ctorArgs) — used by internal/interpreter/ customattributes.go to actually CONSTRUCT a real attribute instance (CustomAttributeExtensions.GetCustomAttribute<T>, Attribute. GetCustomAttribute), which needs Machine.New/newObj access this package doesn't have.

func DBNullValue

func DBNullValue() runtime.Value

DBNullValue exports dbNullValue for other packages' natives (only internal/interpreter's ADO.NET glue today, if any) that need to report a SQL NULL as a boxed `object` using this exact same shared instance.

func DefaultExpressionTypeName

func DefaultExpressionTypeName(v runtime.Value) (string, bool)

func DisplayString added in v0.9.0

func DisplayString(v runtime.Value) string

DisplayString exports displayString (Fase 3.81) for internal/interpreter's own Machine-aware System.String::Join override (System_string_join.go — needs this package's own formatting rules for each already-resolved element, after driving a real plugin IEnumerable <string>'s own iteration protocol, something a plain bcl.Native can't do at all — see that override's own doc comment).

func ExprNodeIdentity

func ExprNodeIdentity(v runtime.Value) (*runtime.Object, bool)

ExprNodeIdentity returns v's own *runtime.Object pointer as an opaque comparable key — used by exprcompile.go's own environment map to give every distinct ParameterExpression/variable a stable slot regardless of how many times it's referenced across a tree.

func FieldInfoParts

func FieldInfoParts(v runtime.Value) (typeFullName, fieldName string, ok bool)

func GenericOpenName

func GenericOpenName(fullName string) string

genericOpenName strips a closed generic instantiation's "[[Arg1], [Arg2]]" suffix, if present, leaving the open generic type's own name (e.g. "System.Collections.Generic.List`1[[System.Int32]]" -> "System.Collections.Generic.List`1"). Exported for internal/interpreter/reflection.go, which needs it to classify a closed generic instantiation's IsValueType/IsEnum/IsInterface/BaseType against the SAME open name a plugin's TypeDef or a hardcoded BCL entry is registered under.

func IncDecExpressionParts

func IncDecExpressionParts(v runtime.Value) (opType int, operand runtime.Value, ok bool)

IncDecExpressionParts exposes opType/operand to internal/interpreter/exprcompile.go — opType is one of the real exprTypeXxx ExpressionType values above, letting the evaluator pick increment vs. decrement and pre- vs. post- semantics.

func InvokeExpressionParts

func InvokeExpressionParts(v runtime.Value) (expr runtime.Value, args []runtime.Value, ok bool)

func IsParameterExpression

func IsParameterExpression(v runtime.Value) bool

func LambdaExpressionBody

func LambdaExpressionBody(v runtime.Value) (runtime.Value, bool)

func LambdaExpressionParameters

func LambdaExpressionParameters(v runtime.Value) ([]runtime.Value, bool)

func LazyFactory

func LazyFactory(native any) (runtime.Value, bool)

LazyFactory returns a Lazy<T> instance's factory delegate — used by internal/interpreter/lazy.go's Machine-aware get_Value (invoking the factory needs m.invokeFunc, unavailable to a plain bcl.Native). Safe to read without locking: factory is set once at construction and never mutated afterward.

func LazyGetOrCompute

func LazyGetOrCompute(native any, compute func() (runtime.Value, error)) (runtime.Value, error)

LazyGetOrCompute returns a Lazy<T> instance's cached value, or calls compute (with the instance's own lock held for the whole call, not just around the check) to produce and cache it. Holding the lock across compute — rather than releasing it, computing, then re-acquiring to store — is what makes two goroutines racing to read the same Lazy<T>.Value for the first time serialize into "one computes, the other blocks and then observes the same cached result" instead of "both compute, one cached value silently wins" (a real bug class, not hypothetical: static Lazy<T> fields are Lazy<T>'s primary real-world use, and Assembly.Call is documented safe for concurrent goroutines).

func LookupStaticFieldHost

func LookupStaticFieldHost(typeFullName string) (*runtime.Type, bool)

LookupStaticFieldHost returns the synthetic Type descriptor for a BCL type's static-field storage (ldsfld/stsfld), if any — a narrower sibling of LookupValueType for reference-shaped BCL types (Fase 3.27, e.g. System.String::Empty).

func LookupValueType

func LookupValueType(typeFullName string) (*runtime.Type, bool)

LookupValueType returns the synthetic Type descriptor for a native BCL value type by full name ("Namespace.Type"), if any — used by interpreter.Machine's initobj handling (internal/interpreter/structs.go).

func MemberExpressionParts

func MemberExpressionParts(v runtime.Value) (propertyName string, inner runtime.Value, ok bool)

MemberExpressionParts returns a MemberExpression node's own property name and the Expression it was accessed off of (Expression.Property's own first argument — see nativeMemberExpression's own doc comment).

func MemberExpressionTypeName

func MemberExpressionTypeName(v runtime.Value) (string, bool)

MemberExpressionTypeName exposes a MemberExpression's own declared .Type name — separate from MemberExpressionParts (whose two return values are already used positionally by several call sites) since only exprvisitor.go's own VisitMember rebuild actually needs it.

func MemoryStreamBytesFromCurrentPosition added in v0.9.1

func MemoryStreamBytesFromCurrentPosition(v runtime.Value) ([]byte, bool)

MemoryStreamBytesFromCurrentPosition returns ms's own remaining bytes (from its current read position onward) if v is a native MemoryStream/ FileStream (system_io.go) — the fast path internal/interpreter/calls.go's own StreamReader construction special case tries first, before falling back to driving a real Stream.Read loop for anything else.

func MethodInfoGenericArgs

func MethodInfoGenericArgs(v runtime.Value) []string

MethodInfoGenericArgs returns a MethodInfo wrapper's own MakeGenericMethod type arguments, if any were ever attached — exported so internal/ interpreter/reflection.go's methodInfoInvoke (which needs Machine access to actually call the target, unlike MakeGenericMethod itself) can pass them through to Machine.call as its real methodGenericArgs.

func MethodInfoParts

func MethodInfoParts(v runtime.Value) (typeFullName, methodName string, ok bool)

func NativeBaseTypeName

func NativeBaseTypeName(typeName string) (string, bool)

NativeBaseTypeName returns typeName's immediate base type per nativeBaseTypeNames, if any — chain it (repeatedly looking up the result) to walk further than one level.

func NativeListItems

func NativeListItems(native any) ([]runtime.Value, bool)

NativeListItems returns a native-backed List<T>'s items, if native is one — used by LINQ's enumerateAll (internal/interpreter/linq.go) as a direct fast path (skip driving a real GetEnumerator/MoveNext/ get_Current loop when the elements are already a Go slice), and by every other plain bcl.Native that special-cases "an IEnumerable argument might really already be a Go slice" the same way (String.Join, List<T>.AddRange/Contains, ...). A *NativeOrdered (a pending LINQ OrderBy/ThenBy chain, system_linq_native.go) answers here too, via its own already-sorted Items, and a *NativeGrouping (one GroupBy result group) recurses into its own already-List-shaped Items — found via a real, hand-written probe: `string.Join("/", someGroup)` (iterating an IGrouping<K,V> directly, a very ordinary GroupBy consumption pattern) printed the group's own placeholder ToString() instead of its elements before this case existed, the exact same class of bug NativeOrdered's own case just below already fixed for OrderBy/ThenBy. Both types' own doc comments explain why this is load-bearing, not just a convenience: those plain natives have no Machine access to fall back to a real GetEnumerator/MoveNext loop if this returns false.

func NativeTypeName

func NativeTypeName(native any) (string, bool)

NativeTypeName returns the BCL full type name of a native-backed Object (List<T>, Dictionary<K,V>, StringBuilder, ...) — vmnet gives these no *runtime.Type (they're backed by a plain Go struct in Native, not fields), so unlike a plugin object or a synthetic value type there is normally nothing to ask "what is your real type" at runtime. This exists for exactly one caller: the interpreter's interface-call fallback (Fase 3.13), which redirects a call site declared against an interface (e.g. IEnumerable`1::GetEnumerator) to the receiver's actual concrete type when the interface name itself has no native registered — the names returned here must match the strings register() calls use in system_collections.go/system_stringbuilder.go exactly.

func NewArrayExpressionParts

func NewArrayExpressionParts(v runtime.Value) (elemTypeName string, elements []runtime.Value, ok bool)

func NewAssignExpressionValue

func NewAssignExpressionValue(left, right runtime.Value) runtime.Value

func NewBinaryCompareExpressionValue

func NewBinaryCompareExpressionValue(opType int, left, right runtime.Value) runtime.Value

func NewBlockExpressionValue

func NewBlockExpressionValue(variables, body []runtime.Value) runtime.Value

func NewCallExpressionValue

func NewCallExpressionValue(instance runtime.Value, typeName, methodName string, args []runtime.Value) runtime.Value

func NewCatchBlockValue

func NewCatchBlockValue(testType string, variable, body runtime.Value) runtime.Value

func NewCoalesceExpressionValue

func NewCoalesceExpressionValue(left, right runtime.Value) runtime.Value

func NewCompletedTask

func NewCompletedTask(value runtime.Value, hasValue bool) runtime.Value

NewCompletedTask/NewFaultedTask are exported for internal/interpreter/async.go's Task.Run (needs Machine access to invoke the delegate argument, unavailable to a plain bcl.Native).

func NewConditionalExpressionValue

func NewConditionalExpressionValue(test, ifTrue, ifFalse runtime.Value) runtime.Value

func NewConstructorInfoValue

func NewConstructorInfoValue(typeFullName, closedTypeFullName string) runtime.Value

NewConstructorInfoValue/NewMethodInfoValue/NewFieldInfoValue build the respective System.Reflection wrapper values — called from internal/interpreter/reflection.go's Machine-aware GetConstructor/GetMethod/GetField natives.

func NewConstructorInfoValueAt

func NewConstructorInfoValueAt(typeFullName, closedTypeFullName string, overloadIndex int) runtime.Value

NewConstructorInfoValueAt builds a ConstructorInfo tagged with WHICH real .ctor overload it names (Fase 3.52, Type.GetConstructors — see nativeConstructorInfo.overloadIndex's own doc comment).

func NewConvertExpressionValue

func NewConvertExpressionValue(operand runtime.Value, typeName string) runtime.Value

func NewCustomAttributeDataValue

func NewCustomAttributeDataValue(typeFullName string, ctorArgs []runtime.Value) runtime.Value

NewCustomAttributeDataValue wraps a fully-decoded attribute application as a real CustomAttributeData value — used by internal/interpreter/ customattributes.go's own Machine-aware GetCustomAttributesData/ GetCustomAttribute<T>, which resolve the real data via Machine.ResolveCustomAttributes and hand it back through this unexported wrapper.

func NewDictValue

func NewDictValue(pairs map[string]runtime.Value) runtime.Value

NewDictValue wraps pairs (string keys, LINQ's ToDictionary own scope) as a real Dictionary<string,V>-shaped value — used by LINQ's ToDictionary (internal/interpreter/linq.go, Fase 3.32), which needs to build a real Dictionary instance without importing bcl's own unexported nativeDict/dictEntry types.

func NewExpressionParts

func NewExpressionParts(v runtime.Value) (typeName string, args []runtime.Value, ok bool)

func NewFaultedTask

func NewFaultedTask(err *runtime.ManagedException) runtime.Value

func NewFieldInfoValue

func NewFieldInfoValue(typeFullName, fieldName, fieldTypeFullName string) runtime.Value

NewFieldInfoValue builds a FieldInfo wrapper carrying its own real declared type (Fase 3.53, FieldInfo.FieldType) — fieldTypeFullName is "" for the handful of call sites that don't have a real resolved type name to hand (a BCL type vmnet has no TypeDef/FieldsResolver data for at all), which fieldInfoGetFieldType above then answers with null, matching PropertyInfo.PropertyType's own "" -> null convention.

func NewGroupingValue

func NewGroupingValue(key, items runtime.Value) runtime.Value

NewGroupingValue wraps one GroupBy result group as a real IGrouping<TKey,TElement>-shaped value. items must already be a native List value (e.g. built via NewListValue).

func NewHashSetValue

func NewHashSetValue(items []runtime.Value) runtime.Value

NewHashSetValue wraps items (already deduplicated by the caller — LINQ's own ToHashSet, internal/interpreter/linq.go) as a real HashSet<T>-shaped value, the same way NewListValue backs every other LINQ terminal method.

func NewIncDecExpressionValue

func NewIncDecExpressionValue(opType int, operand runtime.Value) runtime.Value

func NewIndexerPropertyInfoValue

func NewIndexerPropertyInfoValue(typeFullName, propertyName string, canRead, canWrite bool, propertyTypeFullName string, indexParamTypes []string) runtime.Value

NewIndexerPropertyInfoValue is NewPropertyInfoValue plus indexParamTypes — called only from the narrow well-known-BCL-property fallback (internal/interpreter/reflection.go's wellKnownBclProperties) for a real framework indexer (e.g. DbDataReader's `this[int]`) vmnet has no TypeDef to read a real Property row's accessor signature from.

func NewInvokeExpressionValue

func NewInvokeExpressionValue(expr runtime.Value, args []runtime.Value) runtime.Value

func NewLambdaExpressionValue

func NewLambdaExpressionValue(body runtime.Value, parameters []runtime.Value) runtime.Value

func NewListValue

func NewListValue(items []runtime.Value) runtime.Value

NewListValue wraps items as a real List<T>-shaped value — the same native backing `new List<T>()` produces, so the result is a valid source for another foreach/LINQ call/List<T> method. Used by LINQ (internal/interpreter/linq.go, Fase 3.14) to materialize eager results (Select/Where/ToList/...) as something the rest of the program can keep treating as a normal collection.

func NewListValueTyped added in v0.9.1

func NewListValueTyped(items []runtime.Value, typeName string) runtime.Value

NewListValueTyped is NewListValue with an explicit typeName (Fase 3.83) — for the one other real caller that needs a nativeList-backed value NOT tagged as List`1: System.Collections.ArrayList shares this exact same struct (see nativeList's own doc comment) but must keep reporting its own real type name to NativeTypeName/receiverTypeName's virtual-dispatch chain walk, the same reasoning typeName exists on nativeList at all for.

func NewMatchValueFromLoc

func NewMatchValueFromLoc(loc []int, input string) runtime.Value

NewMatchValueFromLoc wraps one FindStringSubmatchIndex-shaped result as a real Match value — exported (Fase 3.64) for internal/interpreter/ regexreplace.go's own MatchEvaluator-invoking Regex.Replace, which needs one real Match per occurrence to pass to the delegate.

func NewMemberExpressionValue

func NewMemberExpressionValue(propertyName string, inner runtime.Value, typeName string) runtime.Value

Rebuild constructors (Fase 3.65, ExpressionVisitor support) — exported so internal/interpreter/exprvisitor.go's own default Visit/VisitXxx implementations can build a NEW node of the same shape after recursively visiting its children, exactly like real .NET's own default ExpressionVisitor behavior (Update-if-changed). Unlike real .NET, these always allocate a fresh node rather than returning the original when nothing changed — object-identity preservation is a real-.NET optimization this subsystem's own evaluator never depends on, so it isn't reproduced here.

func NewMemoryStreamValue

func NewMemoryStreamValue(data []byte) runtime.Value

NewMemoryStreamValue wraps data as a real MemoryStream-shaped value — the same native backing `new MemoryStream(bytes)` produces, so the result is a valid source for any other MemoryStream/Stream method (Read/Seek/CopyTo/...). Used by Assembly.GetManifestResourceStream (Fase 3.40, internal/interpreter/reflection.go), which needs to hand back a real stream without importing bcl's own unexported nativeMemoryStream type.

func NewMethodInfoValue

func NewMethodInfoValue(typeFullName, methodName string) runtime.Value

func NewNewArrayExpressionValue

func NewNewArrayExpressionValue(elemTypeName string, elements []runtime.Value) runtime.Value

func NewNewExpressionValue

func NewNewExpressionValue(typeName string, args []runtime.Value) runtime.Value

func NewOrderedValue

func NewOrderedValue(items, source []runtime.Value, keys []OrderKey) runtime.Value

NewOrderedValue wraps an already-sorted items/source/keys triple (interpreter/linq_orderby.go computes the sort itself, since only it has the Machine access needed to invoke key selectors/comparers) as a real IOrderedEnumerable<T>-shaped value.

func NewParameterInfoValue

func NewParameterInfoValue(paramTypeFullName, name string, position int) runtime.Value

NewParameterInfoValue builds a System.Reflection.ParameterInfo wrapper — called from internal/interpreter/reflection.go's Machine-aware methodBaseGetParameters.

func NewPropertyInfoValue

func NewPropertyInfoValue(typeFullName, propertyName string, canRead, canWrite bool, propertyTypeFullName string) runtime.Value

NewPropertyInfoValue builds a System.Reflection.PropertyInfo wrapper — called from internal/interpreter/reflection.go's Machine-aware GetProperties/GetProperty natives.

func NewStreamReaderFromBytes added in v0.9.1

func NewStreamReaderFromBytes(data []byte) runtime.Value

NewStreamReaderFromBytes decodes data as UTF-8 (stripping a leading BOM if present, matching real StreamReader's own default encoding-detection behavior for the common case — a real Encoding argument, if the caller passed a non-default one, is otherwise ignored, same posture StringReader's own doc comment documents for TextReader more broadly) and wraps the result exactly the way StringReader's own constructor does — every read method the two share afterward is the identical nativeStringReader-backed native.

func NewStringFromCtor

func NewStringFromCtor(args []runtime.Value) (runtime.Value, error)

NewStringFromCtor backs `new string(...)` — called directly from internal/interpreter/calls.go's newObj (not through the normal bcl.LookupCtor/registerCtor path, which always wraps its result as a KindObject; a vmnet string is a plain KindString value, never an Object). Covers the char[]-based overloads (char[], char[] with start+length, and char*repeated-count) — the overwhelming majority of real `new string(...)` call sites; the ReadOnlySpan<char>-based .NET Core-only overload isn't covered (netstandard2.0 target, spec's own certified-package scope).

func NewThrowExpressionValue

func NewThrowExpressionValue(value runtime.Value, typeName string) runtime.Value

func NewTryExpressionValue

func NewTryExpressionValue(body runtime.Value, catches []runtime.Value, finallyExpr runtime.Value) runtime.Value

func NewTypeValue

func NewTypeValue(fullName string) runtime.Value

NewTypeValue builds a System.Type value for fullName — the runtime counterpart of ir.LoadTypeToken (typeof(T)), called directly from internal/interpreter/eval.go rather than through the normal bcl.Lookup/native-call path, since ldtoken isn't a call at all. Always returns the same *runtime.Object for the same fullName (see typeValueCache's own doc comment).

func ObjectArrayToValues

func ObjectArrayToValues(v runtime.Value) ([]runtime.Value, error)

ObjectArrayToValues unwraps an object[] argument (a real KindArray — every element already a plain runtime.Value regardless of its original declared/boxed type, vmnet's Value model doesn't box separately) into a plain slice — used by ConstructorInfo.Invoke/ MethodInfo.Invoke's own args parameter.

func ParameterExpressionTypeName

func ParameterExpressionTypeName(v runtime.Value) (string, bool)

func PropertyInfoParts

func PropertyInfoParts(v runtime.Value) (typeFullName, propertyName string, canRead, canWrite bool, ok bool)

PropertyInfoParts unwraps a PropertyInfo wrapper value back to its plain data — same rationale as ConstructorInfoTypeFullName/ MethodInfoParts/FieldInfoParts above.

func RegexReplaceString

func RegexReplaceString(args []runtime.Value) (runtime.Value, error)

RegexReplaceString backs the plain string-replacement Regex.Replace overloads — exported (Fase 3.64) for internal/interpreter/ regexreplace.go's own Machine-aware Replace to delegate to when the 3rd argument is a plain string rather than a MatchEvaluator delegate (invoking a real delegate needs Machine access this package doesn't have, so both overloads are now dispatched from that one call site).

func ResolveRegexReplaceEvaluatorTarget

func ResolveRegexReplaceEvaluatorTarget(args []runtime.Value) (re *regexp.Regexp, input string, ok bool)

ResolveRegexReplaceEvaluatorTarget resolves the (compiled regex, input) pair for the real Regex.Replace(string, MatchEvaluator) overloads — instance (receiver, input, evaluator) and static (input, pattern, evaluator) — the same instance-vs-static shape resolveRegexAndInput already disambiguates for the 2-argument IsMatch/Match/plain-string- Replace shapes, just with a 3rd (evaluator) argument along for the ride this function itself never inspects.

func SetNativeListItems

func SetNativeListItems(native any, items []runtime.Value) bool

SetNativeListItems overwrites a native-backed List<T>'s items in place, reporting whether native really was one — used by List<T>.Sort (internal/interpreter/array_sort.go's machineRegistry entry, which needs Machine access to invoke a Comparison<T>/IComparer<T> argument, unlike every other plain List method in this file): real List<T>.Sort mutates the same list instance every other outstanding reference sees, not a copy, so this must write back through the existing *nativeList rather than have the caller build and return a brand new one.

func SpanBacking

func SpanBacking(v runtime.Value) (backing runtime.Value, start, length int, ok bool)

SpanBacking exposes a Span<T>/ReadOnlySpan<T>/Memory<T>/ReadOnlyMemory<T> value's own (backing, start, length) triple to internal/interpreter (Fase 3.41, MemoryMarshal.Read<T>/Write<T> — see that package's own memorymarshal.go) without needing its own copy of this package's private field-index convention.

func ThrowExpressionParts

func ThrowExpressionParts(v runtime.Value) (value runtime.Value, typeName string, ok bool)

ThrowExpressionParts exposes the thrown value expression and the node's own declared .Type to exprcompile.go's own evaluator and exprvisitor.go's own rebuild logic.

func TryExpressionParts

func TryExpressionParts(v runtime.Value) (body runtime.Value, catches []runtime.Value, finallyExpr runtime.Value, ok bool)

TryExpressionParts exposes body/catches/finally to exprcompile.go's own evaluator and exprvisitor.go's own rebuild logic.

func TypeArrayToFullNames

func TypeArrayToFullNames(v runtime.Value) ([]string, error)

TypeArrayToFullNames unwraps a Type[] argument (Type.GetConstructor/ GetMethod's own parameterTypes argument) into full type name strings.

func TypeFullNameOf

func TypeFullNameOf(v runtime.Value) (string, bool)

TypeFullNameOf returns a System.Type value's FullName — used by internal/interpreter/reflection.go (Fase 3.16), which needs it outside this package to implement Type::IsAssignableFrom (a Machine-aware native: walking the real type hierarchy needs Machine.ResolveType, unavailable to a plain bcl.Native).

func UnwrapNullable

func UnwrapNullable(v runtime.Value) runtime.Value

UnwrapNullable collapses a Nullable<T> struct Value (system_nullable.go) into either its underlying T (HasValue == true) or a plain KindNull (HasValue == false) — v unchanged for every other Kind. A LINQ key/ aggregation callback typed to return `int?`/`double?`/etc. (e.g. `xs.OrderBy(x => x.NullableAge)`, `xs.Sum(x => x.NullableScore)`) hands back exactly this struct shape verbatim; the CLR only ever unboxes it to a bare value or a real null reference at a `box`/pattern-match site, neither of which a plain delegate return passes through. Comparison (interpreter/comparer.go) and the numeric LINQ aggregates (Sum/ Average/Min/Max, interpreter/linq.go) both need the T underneath (or "no value, sorts/counts as null") rather than an opaque two-field struct they have no other reason to know about.

func ValueBoxFactory

func ValueBoxFactory(native any) (runtime.Value, bool)

ValueBoxFactory returns a ThreadLocal<T> instance's own valueFactory delegate, if any — used by internal/interpreter/threadlocal.go's Machine-aware get_Value (invoking it needs m.invokeFunc, unavailable to a plain bcl.Native). Mirrors bcl.LazyFactory exactly.

func ValueBoxGetOrCompute

func ValueBoxGetOrCompute(native any, compute func() (runtime.Value, error)) (runtime.Value, error)

ValueBoxGetOrCompute mirrors bcl.LazyGetOrCompute exactly (same hold-the-lock-across-compute rationale — a static ThreadLocal<T> field is a real, common use, and Assembly.Call is documented safe for concurrent goroutines).

func ValuesEqual

func ValuesEqual(a, b runtime.Value) bool

ValuesEqual exports valuesEqual (Fase 3.50) for internal/interpreter/collection_objectmodel.go's collectionRemove, which needs the exact same "find this item's index" equality List<T>. Remove/ArrayList.Remove already use (listRemove, below) — real Collection<T>.Remove(T item) is spec'd as `int index = IndexOf(item); if index<0 return false; RemoveItem(index); return true;`, the same notion of equality as every other Remove overload in this package.

Types

type ExprNodeKind

type ExprNodeKind int

LambdaExpressionBody/IsParameterExpression/MemberExpressionParts and the rest of this section expose this file's own unexported native shapes to internal/interpreter/exprcompile.go (Fase 3.64/3.65), which needs to walk a real expression tree node by node to actually EVALUATE it. ExprNodeKind identifies which one a given Value holds, so the evaluator can dispatch with one type switch on the exported kind rather than needing a type assertion against each unexported Go type individually from outside this package.

const (
	ExprNodeNone ExprNodeKind = iota
	ExprNodeLambda
	ExprNodeParameter
	ExprNodeMember
	ExprNodeConstant
	ExprNodeCall
	ExprNodeNew
	ExprNodeNewArrayInit
	ExprNodeConvert
	ExprNodeAssign
	ExprNodeBlock
	ExprNodeDefault
	ExprNodeConditional
	ExprNodeInvoke
	ExprNodeIncDec
	ExprNodeBinaryCompare
	ExprNodeThrow
	ExprNodeCoalesce
	ExprNodeTry
	ExprNodeArrayIndex
)

func KindOfExprNode

func KindOfExprNode(v runtime.Value) ExprNodeKind

KindOfExprNode identifies v's own real Expression node kind, or ExprNodeNone if v isn't one of this subsystem's own native shapes at all.

type Native

type Native func(args []runtime.Value) (runtime.Value, error)

Native is a BCL method implemented directly in Go. args holds exactly the arguments the IL call site pushed (including an implicit `this` as args[0] for instance calls) — the interpreter does the popping.

func Lookup

func Lookup(fullName string) (fn Native, hasReturn bool, ok bool)

Lookup returns the native registered for fullName ("Namespace.Type::Method").

type NativeCtor

type NativeCtor func(args []runtime.Value) (*runtime.Object, error)

NativeCtor is a BCL constructor implemented directly in Go: it allocates and returns the new object rather than mutating one handed to it, since (unlike a normal call) there's no `this` yet when newobj runs.

func LookupCtor

func LookupCtor(typeFullName string) (fn NativeCtor, ok bool)

LookupCtor returns the native constructor registered for a type's full name ("Namespace.Type"), if any.

type NativeGrouping

type NativeGrouping struct {
	Key   runtime.Value
	Items runtime.Value // Always an already-built native List value.
}

NativeGrouping backs one IGrouping<TKey,TElement> LINQ GroupBy result group (internal/interpreter/linq_groupby.go constructs these via NewGroupingValue — GroupBy itself needs Machine access to invoke the caller's keySelector/elementSelector/IEqualityComparer<TKey>, so the actual grouping algorithm stays in that package; only the result TYPE lives here). Defined in bcl (not interpreter, where it used to live before this hardening pass) for the same reason NativeOrdered is: so NativeListItems, just below, and NativeTypeName (system_object.go) can both recognize it without either needing Machine access — a interpreter-package-local type is invisible to bcl's own plain natives (String.Join, List<T>.AddRange/Contains, ...), which have no way to import a package that itself imports bcl.

func AsNativeGrouping

func AsNativeGrouping(v runtime.Value) (*NativeGrouping, bool)

AsNativeGrouping extracts v's own *NativeGrouping, if it wraps one — linq_groupby.go's groupingGetKey/groupingGetEnumerator need this the same way AsNativeOrdered serves ThenBy.

type NativeOrdered

type NativeOrdered struct {
	Items  []runtime.Value
	Source []runtime.Value
	// Keys is the applied ordering, most significant first: index 0 is
	// the original OrderBy/OrderByDescending call, each later entry one
	// more ThenBy/ThenByDescending appended after it.
	Keys []OrderKey
}

NativeOrdered backs a LINQ OrderBy/OrderByDescending/ThenBy/ ThenByDescending chain's result (a real IOrderedEnumerable<T>) — defined here (not in internal/interpreter, where the actual sorting logic lives) so NativeTypeName, just below, can recognize it: without that, `foreach (var x in xs.OrderBy(...))` or any further LINQ call reached through the declared IEnumerable<T>/IOrderedEnumerable<T> interface type (rather than already-materialized via ToList/ToArray) has no way to redirect back to this receiver's real concrete type (see receiverTypeName's own doc comment, internal/interpreter/ typecheck.go).

Items is always kept fully sorted by every key applied SO FAR (Machine access is available at both OrderBy's and ThenBy's own call sites, so there's no need to defer) — this is the field NativeListItems, just below, exposes: a plain bcl.Native with no Machine access at all (String.Join, List<T>.Contains, ...) that already special-cases "an IEnumerable source might really be a native List" must keep working unchanged for an OrderBy/ThenBy result exactly like it does for one from Select/Where/any other LINQ terminal — this was a real, probed regression found the hard way: routing OrderBy through a DIFFERENT, deferred-sort shape broke `string.Join(",", xs.OrderBy(...))` outright (silently printed the receiver's own placeholder ToString() instead of its elements) the moment NativeListItems stopped recognizing it.

Source/Keys are kept alongside Items purely so ThenBy/ThenByDescending can recompute the FULL multi-key sort from the original, pre-sort order plus every key applied so far (its own key appended to Keys) — re-sorting from Source on each ThenBy, rather than re-sorting the already-sorted Items in place, is what makes a later ThenBy able to use a DIFFERENT, less significant tie-breaking rule than a naive "stable-sort the current Items by just the new key" would (which would wrongly make the new key primary for any earlier tie).

func AsNativeOrdered

func AsNativeOrdered(v runtime.Value) (*NativeOrdered, bool)

AsNativeOrdered extracts v's own *NativeOrdered, if it wraps one — ThenBy/ThenByDescending need this to append one more key onto an existing chain rather than starting a brand new one (interpreter/ linq_orderby.go).

type NativeValueTypeCtor

type NativeValueTypeCtor func(args []runtime.Value) (*runtime.Struct, error)

NativeValueTypeCtor is a BCL value-type constructor: unlike NativeCtor (always builds a *runtime.Object), it builds a *runtime.Struct directly, since `newobj` on a value type pushes the value itself rather than a heap reference (spec §III.4.21).

func LookupValueTypeCtor

func LookupValueTypeCtor(typeFullName string) (fn NativeValueTypeCtor, ok bool)

LookupValueTypeCtor returns the native constructor registered for a BCL value type's full name, if any.

type OrderKey

type OrderKey struct {
	Selector   runtime.Value // Func<TSource,TKey> — always KindFunc.
	Descending bool
	// Comparer is an explicit IComparer<TKey> argument, or KindNull for
	// natural ordering (interpreter's compareFunc/compareNatural).
	Comparer runtime.Value
}

OrderKey is one key selector in an OrderBy/ThenBy chain.

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL