public static void trace(RestParam args = default) { switch (args.length) { case 0: Console.WriteLine(); break; case 1: Console.WriteLine(ASAny.AS_convertString(args[0])); break; default: for (int i = 0, n = args.length; i < n; i++) { if (i != 0) { Console.Write(' '); } Console.Write(ASAny.AS_convertString(args[i])); } Console.WriteLine(); break; } }
protected private override void convertSpanImpl(ReadOnlySpan <ASAny> src, Span <T?> dst) { for (int i = 0; i < src.Length; i++) { dst[i] = ASAny.AS_cast <T>(src[i]); } }
/// <summary> /// Creates a new instance of <see cref="MockCallRecord"/>. /// </summary> /// <param name="receiver">The "this" argument of the function call, or null for a /// constructor call.</param> /// <param name="args">The arguments passed to the function call.</param> /// <param name="retval">The return value of the function call.</param> /// <param name="isConstruct">True if the function was called as a constructor, otherwise false.</param> public MockCallRecord(ASObject receiver, ReadOnlySpan <ASAny> args, ASAny retval, bool isConstruct) { m_receiver = receiver; m_args = args.ToArray(); m_retval = retval; m_isConstruct = isConstruct; }
protected private override void convertSpanImpl(ReadOnlySpan <T?> src, Span <ASAny> dst) { for (int i = 0; i < src.Length; i++) { dst[i] = new ASAny((ASObject?)(object?)src[i]); } }
public ASError([ParamDefaultValue("")] ASAny message, int id = 0) { this.m_errorID = id; this.message = message; this.name = "Error"; this.m_stackTrace = new StackTrace(1, fNeedFileInfo: false); this.m_lazyStackTraceString = new LazyInitObject <string>(_initStackTrace); }
internal MethodTraitParameter(string?name, Class?type, bool isOptional, bool hasDefault, ASAny defaultValue) { m_name = name; m_type = type; m_isOptional = isOptional; m_hasDefault = hasDefault; m_defaultValue = defaultValue; }
private static ASAny[] makeValues(int domainSize) { var array = new ASAny[domainSize]; // Leave the first element as undefined. for (int i = 1; i < domainSize; i++) { array[i] = new ASObject(); } return(array); }
/// <summary> /// Emits IL instructions to push a constant value onto the stack. /// </summary> /// <param name="builder">The <see cref="ILBuilder"/> instance in which to emit the /// code.</param> /// <param name="value">The constant. This must be of one of the following types: int, uint, /// Number, String, Boolean or Namespace, or the value null or undefined.</param> public static void emitPushConstant(ILBuilder builder, ASAny value) { if (value.isUndefined) { builder.emit(ILOp.ldsfld, KnownMembers.undefinedField); return; } if (value.isNull) { builder.emit(ILOp.ldnull); return; } switch (value.AS_class !.tag) {
/// <summary> /// Asserts that two instances of the <see cref="ASAny"/> type are both undefined, both null /// or both containing the same object. /// </summary> /// <param name="expected">The expected <see cref="ASAny"/> instance.</param> /// <param name="actual">The actual instance to check against <see cref="expected"/>.</param> public static void identical(ASAny expected, ASAny actual) { if (expected.isUndefined) { Assert.True(actual.isUndefined, $"Expected {actual} to be undefined."); } else if (expected.isNull) { Assert.True(actual.isNull, $"Expected {actual} to be null."); } else { Assert.IsType(expected.value.GetType(), actual.value); Assert.Same(expected.value, actual.value); } }
/// <summary> /// Asserts that two instances of the <see cref="ASAny"/> type are equal, using value equality /// for primitive types and reference equality for object types. This considers NaNs to be equal /// to each other, and the +0 and -0 floating-point values to be not equal. /// </summary> /// <param name="expected">The expected <see cref="ASAny"/> instance.</param> /// <param name="actual">The actual instance to check against <see cref="expected"/>.</param> public static void valueIdentical(ASAny expected, ASAny actual) { if (ASObject.AS_isNumeric(expected.value) && ASObject.AS_isNumeric(actual.value)) { floatIdentical((double)expected, (double)actual); } else if (expected.value is ASString && actual.value is ASString) { Assert.Equal((string)expected, (string)actual); } else if (expected.value is ASBoolean && actual.value is ASBoolean) { Assert.Equal((bool)expected, (bool)actual); } else { identical(expected, actual); } }
public ASRegExp(RestParam rest) { if (rest.length >= 1 && rest[0].value is ASRegExp otherRegExp) { if (rest.length >= 2 && !rest[1].isUndefined) { throw ErrorHelper.createError(ErrorCode.REGEXP_CONSTRUCT_COPY_FLAGS); } m_internalRegex = otherRegExp.m_internalRegex; m_auxFlags = otherRegExp.m_auxFlags; m_groupNames = otherRegExp.m_groupNames; m_groupCount = otherRegExp.m_groupCount; m_source = otherRegExp.m_source; } else { string pattern = (rest.length >= 1 && !rest[0].isUndefined) ? ASAny.AS_convertString(rest[0]) : ""; string flags = (rest.length >= 2 && !rest[1].isUndefined) ? ASAny.AS_convertString(rest[1]) : ""; _init(pattern, flags); } }
/// <summary> /// Attempts to unwrap a caught exception and retrieve the thrown object if it should be /// handled by AS3 code. /// </summary> /// <param name="exception">The caught exception.</param> /// <param name="thrownValue">An output parameter where the object thrown will be written, /// if the exception should be handled by compiled ActionScript code.</param> /// <returns>True if the exception should be handled, false otherwise.</returns> /// <remarks> /// Calls to this method are inserted into code generated by the IL compiler; this method /// should not be used in .NET code. /// </remarks> public static bool tryUnwrapCaughtException(Exception exception, out ASAny thrownValue) { thrownValue = default; // Unwrap inner exceptions from TypeInitializationException and TargetInvocationException. while (exception is TypeInitializationException || exception is TargetInvocationException) { exception = exception.InnerException; } if (exception is AVM2Exception avm2Exception) { thrownValue = avm2Exception.thrownValue; return(true); } if (exception is NullReferenceException) { thrownValue = ErrorHelper.createErrorObject(ErrorCode.NULL_REFERENCE_ERROR); return(true); } return(false); }
/// <summary> /// Creates a new <see cref="AVM2Exception"/> instance. /// </summary> /// <param name="thrownValue">The error object to be thrown. This is usually an instance of /// the Error class (or a subclass of it), but any AS3 object is allowed to be thrown as an /// error.</param> public AVM2Exception(ASAny thrownValue) { m_thrownValue = thrownValue; }
public ASEvalError([ParamDefaultValue("")] ASAny message, int id = 0) : base(message, id) { name = "EvalError"; }
public ASArgumentError([ParamDefaultValue("")] ASAny message, int id = 0) : base(message, id) { name = "ArgumentError"; }
public ASSecurityError([ParamDefaultValue("")] ASAny message, int id = 0) : base(message, id) { name = "SecurityError"; }
private ABCTraitInfo[] _readTraitInfo(int count) { const ABCTraitFlags validTraitAttrs = ABCTraitFlags.ATTR_Final | ABCTraitFlags.ATTR_Metadata | ABCTraitFlags.ATTR_Override; if (count == 0) { return(Array.Empty <ABCTraitInfo>()); } var traits = new ABCTraitInfo[count]; for (int i = 0; i < traits.Length; i++) { ABCMultiname traitName = m_abcFile.resolveMultiname(_readU30()); if (traitName.kind != ABCConstKind.QName) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NOT_QNAME); } QName traitQualifiedName = new QName( m_abcFile.resolveNamespace(traitName.namespaceIndex), m_abcFile.resolveString(traitName.localNameIndex) ); if (traitQualifiedName.ns.kind == NamespaceKind.ANY || traitQualifiedName.localName == null) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NULL); } ABCTraitFlags flags = (ABCTraitFlags)_readU8(); if ((flags & ~ABCTraitFlags.KIND_MASK & ~validTraitAttrs) != 0) { throw ErrorHelper.createError(ErrorCode.INVALID_TRAIT_KIND, (int)flags); } ABCTraitFlags kind = flags & ABCTraitFlags.KIND_MASK; ABCTraitInfo traitInfo; if (kind == ABCTraitFlags.Slot || kind == ABCTraitFlags.Const) { int slotId = _readU30(); ABCMultiname typeName = m_abcFile.resolveMultiname(_readU30()); ASAny defaultVal = ASAny.undefined; int defaultValIndex = _readU30(); if (defaultValIndex != 0) { defaultVal = m_abcFile.resolveConstant((ABCConstKind)_readU8(), defaultValIndex); } traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotId, typeName, defaultValIndex != 0, defaultVal); } else if (kind == ABCTraitFlags.Class) { int slotId = _readU30(); ABCClassInfo classInfo = m_abcFile.resolveClassInfo(_readU30()); traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotId, classInfo); } else if (kind >= ABCTraitFlags.Method && kind <= ABCTraitFlags.Function) { int slotOrDispId = _readU30(); ABCMethodInfo methodInfo = m_abcFile.resolveMethodInfo(_readU30()); traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotOrDispId, methodInfo); } else { throw ErrorHelper.createError(ErrorCode.INVALID_TRAIT_KIND, (int)flags); } if ((flags & ABCTraitFlags.ATTR_Metadata) != 0) { int metadataCount = _readU30(); if (metadataCount != 0) { MetadataTag[] metadata = new MetadataTag[metadataCount]; for (int j = 0; j < metadata.Length; j++) { metadata[j] = m_abcFile.resolveMetadata(_readU30()); } traitInfo.setMetadata(new MetadataTagCollection(metadata)); } } traits[i] = traitInfo; } return(traits); }
private void _readMethodInfo() { const ABCMethodFlags validMethodFlags = ABCMethodFlags.NEED_REST | ABCMethodFlags.HAS_OPTIONAL | ABCMethodFlags.NEED_ACTIVATION | ABCMethodFlags.NEED_ARGUMENTS | ABCMethodFlags.SET_DXNS | ABCMethodFlags.HAS_PARAM_NAMES; int methodCount = _readU30(); var methodInfoArr = new ABCMethodInfo[methodCount]; for (int i = 0; i < methodCount; i++) { int paramCount = _readU30(); ABCMultiname retTypeName = m_abcFile.resolveMultiname(_readU30()); ABCMultiname[] paramTypeNames = Array.Empty <ABCMultiname>(); ASAny[]? defaultValues = null; string?[]? paramNames = null; if (paramCount != 0) { paramTypeNames = new ABCMultiname[paramCount]; for (int j = 0; j < paramCount; j++) { paramTypeNames[j] = m_abcFile.resolveMultiname(_readU30()); } } string methodName = m_abcFile.resolveString(_readU30()) ?? ""; ABCMethodFlags methodFlags = (ABCMethodFlags)_readU8(); if ((methodFlags & ~validMethodFlags) != 0) { throw ErrorHelper.createError(ErrorCode.METHOD_INFO_INVALID_FLAGS, i, (int)methodFlags); } // NEED_ARGUMENTS and NEED_REST cannot be set together. const ABCMethodFlags needArgumentsOrRest = ABCMethodFlags.NEED_ARGUMENTS | ABCMethodFlags.NEED_REST; if ((methodFlags & needArgumentsOrRest) == needArgumentsOrRest) { throw ErrorHelper.createError(ErrorCode.METHOD_INFO_INVALID_FLAGS, i, (int)methodFlags); } if ((methodFlags & ABCMethodFlags.HAS_OPTIONAL) != 0) { int optionCount = _readU30(); if (optionCount > paramCount) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_METHOD_INFO_OPTIONAL_EXCEEDS_PARAM, i); } defaultValues = new ASAny[optionCount]; for (int j = 0; j < optionCount; j++) { int val = _readU30(); var kind = (ABCConstKind)_readU8(); defaultValues[j] = m_abcFile.resolveConstant(kind, val); } } if ((methodFlags & ABCMethodFlags.HAS_PARAM_NAMES) != 0) { paramNames = new string?[paramCount]; for (int j = 0; j < paramNames.Length; j++) { paramNames[j] = m_abcFile.resolveString(_readU30()); } } methodInfoArr[i] = new ABCMethodInfo( i, retTypeName, methodName, methodFlags, paramTypeNames, paramNames, defaultValues); } m_abcFile.setMethodInfo(methodInfoArr); }
/// <summary> /// Asserts that two instances of the <see cref="ASAny"/> type are equal when compared /// using the strict equality operator. /// </summary> /// <param name="expected">The expected <see cref="ASAny"/> instance.</param> /// <param name="actual">The actual instance to check against <see cref="expected"/>.</param> public static void strictEqual(ASAny expected, ASAny actual) { Assert.True(ASAny.AS_strictEq(expected, actual), $"Expected {actual} to be strictly equal to {expected}."); }
public ASDefinitionError([ParamDefaultValue("")] ASAny message, int id = 0) : base(message, id) { name = "DefinitionError"; }
public void prefixPropertyTest(ASNamespace ns) { ASAny expected = (ns.prefix == null) ? ASAny.undefined : ns.prefix; Assert.Equal(expected, ns.AS_prefix); }
public NativeClassLoadError([ParamDefaultValue("")] ASAny message, int id = 0) : base(message, id) { }
public ASReferenceError([ParamDefaultValue("")] ASAny message, int id = 0) : base(message, id) { name = "ReferenceError"; }
public override T?convert(ASAny value) => ASAny.AS_cast <T>(value);