/// <summary> /// Returns a handle to a helper function for creating a new Array instance from the /// arguments on the stack. This is used for the newarray ABC instruction. The arguments /// on the stack must be of the "any" type. /// </summary> /// <param name="size">The size argument to the newarray instruction, i.e. the number of /// arguments on the stack.</param> /// <param name="handle">If a helper function is available or can be emitted, a handle to /// the function is set to this argument.</param> /// <returns>True if a helper function is available or can be created, otherwise false.</returns> public bool tryGetNewArrayHelper(int size, out EntityHandle handle) { handle = default; if (size > newArrayHelperMaxSize) { return(false); } if (m_newArrayHelperMethods[size] != null) { handle = m_newArrayHelperMethods[size].handle; return(true); } _createContainerTypeIfNotCreated(); TypeSignature[] parameterTypes = new TypeSignature[size]; parameterTypes.AsSpan().Fill(m_assemblyBuilder.metadataContext.getTypeSignature(typeof(ASAny))); string methodName = "newarray" + size.ToString(CultureInfo.InvariantCulture); var methodBuilder = m_containerType !.defineMethod( methodName, MethodAttributes.Public | MethodAttributes.Static, m_assemblyBuilder.metadataContext.getTypeSignature(typeof(ASArray)), parameterTypes ); m_ilBuilder.reset(); var tempVar = m_ilBuilder.declareLocal(typeof(ASArray)); m_ilBuilder.emit(ILOp.ldc_i4, size); m_ilBuilder.emit(ILOp.newobj, KnownMembers.arrayCtorWithLength); m_ilBuilder.emit(ILOp.stloc, tempVar); for (int i = 0; i < size; i++) { m_ilBuilder.emit(ILOp.ldloc, tempVar); m_ilBuilder.emit(ILOp.ldc_i4, i); m_ilBuilder.emit(ILOp.ldarg, i); m_ilBuilder.emit(ILOp.call, KnownMembers.arraySetUintIndex, -3); } m_ilBuilder.emit(ILOp.ldloc, tempVar); m_ilBuilder.emit(ILOp.ret); methodBuilder.setMethodBody(m_ilBuilder.createMethodBody()); m_newArrayHelperMethods[size] = methodBuilder; handle = methodBuilder.handle; return(true); }