/// <summary> /// The method implements <c>...</c> unpack operator. /// Unpacks <paramref name="array"/> into <paramref name="stack"/>. /// </summary> /// <param name="stack">The list with unpacked arguments.</param> /// <param name="array">Value to be unpacked.</param> /// <param name="byrefs">Bit mask of parameters that are passed by reference. Arguments corresponding to <c>1</c>-bit are aliased.</param> static void Unpack(List <PhpValue> stack, Array array, ulong byrefs) { for (int i = 0; i < array.Length; i++) { stack.Add(PhpValue.FromClr(array.GetValue(i))); } }
protected override void FetchCurrent(ref PhpValue key, ref PhpValue value) { var entry = _enumerator.Entry; key = PhpValue.FromClr(entry.Key); value = PhpValue.FromClr(entry.Value); }
protected override void FetchCurrent(ref PhpValue key, ref PhpValue value) { var entry = _enumerator.Current; key = PhpValue.FromClr(entry.Item1); value = PhpValue.FromClr(entry.Item2); }
static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } // remember the assembly for class map: s_assClassMap.AddPhpAssemblyNoLock(assembly); // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { Context.AddScriptReference(r.ScriptType); } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { // TODO: remember the container, do not reflect repetitiously foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsPhpHidden()) { RoutinesTable.DeclareAppRoutine(m.Name, m); } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { // TODO: remember the container, do not reflect repetitiously foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null))); } else { ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null)))); } }
///// <summary> ///// Initializes a new instance of the <see cref="PhpArray"/> class filled by values from specified array. ///// </summary> ///// <param name="values">An array of values to be added to the table.</param> ///// <param name="start">An index of the first item from <paramref name="values"/> to add.</param> ///// <param name="length">A number of items to add.</param> ///// <param name="value">A value to be filtered.</param> ///// <param name="doFilter">Wheter to add all items but <paramref name="value"/> (<b>true</b>) or ///// all items with the value <paramref name="value"/> (<b>false</b>).</param> //public PhpArray(int[] values, int start, int length, int value, bool doFilter) // : base(values, start, length, value, doFilter) { } /// <summary> /// Creates a new instance of <see cref="PhpArray"/> filled by data from an enumerator. /// </summary> /// <param name="data">The enumerator containing values added to the new instance.</param> public PhpArray(IEnumerable data) : base((data is ICollection) ? ((ICollection)data).Count : 0) { if (data != null) { foreach (object value in data) { AddToEnd(PhpValue.FromClr(value)); } } }
public PhpValue GetItemValue(IntStringKey key) { if (key.IsInteger) { return(PhpValue.FromClr(_array[key.Integer])); } else { throw new ArgumentException(nameof(key)); } }
public override PhpValue GetArrayItem(ref PhpValue me, PhpValue index, bool quiet) { // IPhpArray.GetItemValue if (me.Object is IPhpArray arr) { return(arr.GetItemValue(index)); // , quiet); } // ArrayAccess.offsetGet() if (me.Object is ArrayAccess arracces) { return(arracces.offsetGet(index)); } // IList[] if (me.Object is System.Collections.IList list) { var key = index.ToIntStringKey(); if (key.IsInteger) { if (key.Integer >= 0 && key.Integer < list.Count) { return(PhpValue.FromClr(list[index.ToIntStringKey().Integer])); } else if (!quiet) { PhpException.Throw(PhpError.Error, Resources.ErrResources.undefined_offset, key.Integer.ToString()); } } else if (!quiet) { PhpException.Throw(PhpError.Warning, Resources.ErrResources.illegal_offset_type); } return(PhpValue.Void); } // if (!quiet) { PhpException.Throw(PhpError.Error, Resources.ErrResources.object_used_as_array, me.Object.GetPhpTypeInfo().Name); } // return(PhpValue.Void); }
/// <summary> /// Reflects given assembly for PeachPie compiler specifics - compiled scripts, references to other assemblies, declared functions and classes. /// Scripts and declarations are loaded into application context (static). /// </summary> /// <param name="assembly">PeachPie compiler generated assembly.</param> /// <remarks>Not thread safe.</remarks> public static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (assembly.GetType(ScriptInfo.ScriptTypeName) == null || !TryAddAssembly(assembly)) { // nothing to reflect return; } // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { AddPhpPackageReference(r.ScriptType); } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { if (ExtensionsAppContext.ExtensionsTable.VisitFunctionsContainer(t.ContainerType, out var attr)) { foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsSpecialName && !m.IsPhpHidden()) { ExtensionsAppContext.ExtensionsTable.AddRoutine(attr, RoutinesTable.DeclareAppRoutine(m.Name, m)); } } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { if (!s_processedConstantsContainers.Add(t.ContainerType)) { // already visited before continue; } // var extensionName = t.ContainerType.GetCustomAttribute <PhpExtensionAttribute>(false)?.FirstExtensionOrDefault; // reflect constants defined in the container foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { // constant ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null)), false, extensionName); } else { // static field ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null))), false, extensionName); } }
/// <summary> /// Reflects given assembly for PeachPie compiler specifics - compiled scripts, references to other assemblies, declared functions and classes. /// Scripts and declarations are loaded into application context (static). /// </summary> /// <param name="assembly">PeachPie compiler generated assembly.</param> /// <remarks>Not thread safe.</remarks> public static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (assembly.GetType(ScriptInfo.ScriptTypeName) == null || !s_processedAssemblies.Add(assembly)) { // nothing to reflect return; } s_processedAssembliesArr = ArrayUtils.AppendRange(assembly, s_processedAssembliesArr); // TODO: ImmutableArray<T> // remember the assembly for class map: s_assClassMap.AddPhpAssemblyNoLock(assembly); // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { if (r.ScriptType != null) // always true { AddScriptReference(r.ScriptType.Assembly); } } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { if (ExtensionsAppContext.ExtensionsTable.VisitFunctionsContainer(t.ContainerType, out var attr)) { foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsPhpHidden()) { ExtensionsAppContext.ExtensionsTable.AddRoutine(attr, RoutinesTable.DeclareAppRoutine(m.Name, m)); } } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { if (!s_processedConstantsContainers.Add(t.ContainerType)) { // already visited before continue; } // reflect constants defined in the container foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null))); } else { ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null)))); } }
/// <summary> /// Creates an instance of a type dynamically with constructor overload resolution. /// </summary> /// <param name="classname">Full name of the class to instantiate. The name uses PHP syntax of name separators (<c>\</c>) and is case insensitive.</param> /// <param name="arguments">Arguments to be passed to the constructor.</param> /// <returns>Object instance or <c>null</c> if class is not declared.</returns> public object Create(string classname, params object[] arguments) => Create(classname, PhpValue.FromClr(arguments));
/// <summary> /// Call a function by its name dynamically. /// </summary> /// <param name="function">Function name valid within current runtime context.</param> /// <param name="arguments">Arguments to be passed to the function call.</param> /// <returns>Returns value given from the function call.</returns> public PhpValue Call(string function, params object[] arguments) => PhpCallback.Create(function, default(RuntimeTypeHandle)).Invoke(this, PhpValue.FromClr(arguments));
public PhpValue Call(string function, params object[] arguments) => PhpCallback.Create(function).Invoke(this, PhpValue.FromClr(arguments));
protected override void FetchCurrent(ref PhpValue key, ref PhpValue value) { key = (PhpValue)(key.IsSet ? key.ToLong() + 1L : 0L); value = PhpValue.FromClr(_enumerator.Current); }