public void VisitNode(JSBinaryOperatorExpression boe) { var leftType = boe.Left.GetActualType(TypeSystem); var leftIsEnum = IsEnumOrNullableEnum(leftType); var rightType = boe.Right.GetActualType(TypeSystem); var rightIsEnum = IsEnumOrNullableEnum(rightType); var resultType = boe.GetActualType(TypeSystem); var resultIsEnum = IsEnumOrNullableEnum(resultType); if ((leftIsEnum || rightIsEnum) && LogicalOperators.Contains(boe.Operator)) { if (leftIsEnum) { var cast = JSInvocationExpression.InvokeStatic( JS.Number(TypeSystem.Int32), new[] { boe.Left }, true ); boe.ReplaceChild(boe.Left, cast); } if (rightIsEnum) { var cast = JSInvocationExpression.InvokeStatic( JS.Number(TypeSystem.Int32), new[] { boe.Right }, true ); boe.ReplaceChild(boe.Right, cast); } } VisitChildren(boe); }
public JSInvocationExpression GetTypeFromAssembly(JSExpression assembly, JSExpression typeName, JSExpression throwOnFail) { return(JSInvocationExpression.InvokeStatic( Dot("GetTypeFromAssembly", TypeSystem.SystemType()), new[] { assembly, typeName, new JSNullLiteral(TypeSystem.Object), throwOnFail }, true )); }
public JSInvocationExpression GetTypeOf(JSExpression expression) { return(JSInvocationExpression.InvokeStatic( Dot("GetType", TypeSystem.SystemType()), new[] { expression }, true )); }
public JSInvocationExpression GetTypeFromAssembly(JSExpression assembly, JSExpression typeName, JSExpression throwOnFail) { return(JSInvocationExpression.InvokeStatic( Dot("GetTypeFromAssembly", new TypeReference("System", "Type", TypeSystem.Object.Module, TypeSystem.Object.Scope)), new[] { assembly, typeName, new JSNullLiteral(TypeSystem.Object), throwOnFail }, true )); }
public JSInvocationExpression CreateInstanceOfType(TypeReference type) { return(JSInvocationExpression.InvokeStatic( Dot(new JSFakeMethod("CreateInstanceOfType", type, new[] { TypeSystem.Object }, MethodTypes)), new[] { new JSTypeOfExpression(type) } )); }
public JSInvocationExpression CheckType(JSExpression expression, TypeReference targetType) { return(JSInvocationExpression.InvokeStatic( Dot("CheckType", TypeSystem.Boolean), new[] { expression, new JSTypeOfExpression(targetType) }, true )); }
public JSInvocationExpression ThrowNullReferenceException() { return(JSInvocationExpression.InvokeStatic( Dot(new JSFakeMethod("ThrowNullReferenceException", TypeSystem.Void, new TypeReference[0], MethodTypes)), new JSExpression[0] )); }
public JSInvocationExpression StructEquals(JSExpression left, JSExpression right) { return(JSInvocationExpression.InvokeStatic( Dot("StructEquals", TypeSystem.Boolean), new[] { left, right }, true )); }
public JSInvocationExpression GetTypeOf(JSExpression expression) { return(JSInvocationExpression.InvokeStatic( Dot("GetType", new TypeReference("System", "Type", TypeSystem.Object.Module, TypeSystem.Object.Scope)), new[] { expression }, true )); }
public JSInvocationExpression Coalesce(JSExpression left, JSExpression right, TypeReference expectedType) { return(JSInvocationExpression.InvokeStatic( Dot("Coalesce", expectedType), new[] { left, right }, true )); }
public JSInvocationExpression FreezeImmutableObject(JSExpression @object) { return(JSInvocationExpression.InvokeStatic( Dot(new JSFakeMethod("FreezeImmutableObject", TypeSystem.Void, new[] { TypeSystem.Object }, MethodTypes)), new[] { @object } )); }
public void VisitNode(JSUnaryOperatorExpression uoe) { var exType = uoe.Expression.GetActualType(TypeSystem); var opType = uoe.ActualType; if (IsLongOrULong(exType) && IsLongOrULong(opType)) //exType == TypeSystem.Int64 && opType == TypeSystem.Int64) { string verb; switch (uoe.Operator.Token) { case "-": verb = "op_UnaryNegation"; break; case "~": verb = "op_OnesComplement"; break; default: throw new NotSupportedException(); } var method = new JSFakeMethod(verb, TypeSystem.Int64, new[] { TypeSystem.Int64 }, MethodTypeFactory); var replacement = JSInvocationExpression.InvokeStatic(exType, method, new[] { uoe.Expression }, true); ParentNode.ReplaceChild(uoe, replacement); VisitReplacement(replacement); return; } VisitChildren(uoe); }
public JSExpression Cast(JSExpression expression, TypeReference targetType) { return(JSInvocationExpression.InvokeStatic( Dot("Cast", targetType), new[] { expression, new JSTypeOfExpression(targetType) }, true )); }
public JSInvocationExpression ShallowCopy(JSExpression array, JSExpression initializer, TypeReference arrayType) { return(JSInvocationExpression.InvokeStatic( new JSDotExpression( Dot("Array", TypeSystem.Object), new JSFakeMethod("ShallowCopy", TypeSystem.Void, new[] { arrayType, arrayType }, MethodTypes) ), new[] { array, initializer } )); }
public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod) { return(JSInvocationExpression.InvokeStatic( new JSDotExpression( new JSType(delegateType), new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes) ), new [] { thisReference, targetMethod }, true )); }
public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod) { var targetDotExpression = targetMethod as JSDotExpressionBase; var jsMethod = targetDotExpression != null ? targetDotExpression.Member as JSMethod : null; JSExpression[] invocationExpressionArguments; if (jsMethod == null) { // Not sure if it is possible. invocationExpressionArguments = new[] { thisReference, targetMethod }; } else { var jsMethodAccess = targetMethod as JSMethodAccess; var arguments = jsMethod == null ? null : jsMethod.Reference.Parameters.Select( (parameter, index) => (JSExpression) new JSRawOutputIdentifier(parameter.ParameterType, "arguments[{0}]", index)) .ToArray(); bool isFromDelegate = jsMethod.Reference.Name == "Invoke" && TypeUtil.IsDelegateType(jsMethod.Reference.DeclaringType); JSExpression methodInvocation; if (isFromDelegate) { methodInvocation = targetMethod; } else if (jsMethod.Method.IsStatic) { methodInvocation = new JSDeferredExpression(JSInvocationExpression.InvokeStatic(jsMethod.Reference.DeclaringType, jsMethod, arguments)); } else if (jsMethodAccess == null || jsMethodAccess.IsVirtual) { methodInvocation = new JSDeferredExpression(JSInvocationExpression.InvokeMethod(jsMethod.Reference.DeclaringType, jsMethod, thisReference, arguments)); } else { methodInvocation = new JSDeferredExpression(JSInvocationExpression.InvokeBaseMethod(jsMethod.Reference.DeclaringType, jsMethod, thisReference, arguments)); } invocationExpressionArguments = new[] { thisReference, methodInvocation, new JSDeferredExpression(new JSMethodOfExpression(jsMethod.Reference, jsMethod.Method, jsMethod.MethodTypes, jsMethod.GenericArguments)) }; } return(JSInvocationExpression.InvokeStatic( new JSDotExpression( new JSType(delegateType), new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes)), invocationExpressionArguments, true)); }
public JSInvocationExpression ValueOfNullable(JSExpression nullableExpression) { var valueType = nullableExpression.GetActualType(TypeSystem); valueType = TypeUtil.StripNullable(valueType); return(JSInvocationExpression.InvokeStatic( Dot("ValueOfNullable", valueType), new[] { nullableExpression }, true )); }
public JSExpression ValueOfNullableOrDefault(JSExpression nullableExpression, JSExpression defaultValue) { var valueType = nullableExpression.GetActualType(TypeSystem); valueType = TypeUtil.StripNullable(valueType); return(JSInvocationExpression.InvokeStatic( Dot("Nullable_ValueOrDefault", valueType), new[] { nullableExpression, defaultValue }, true )); }
public JSInvocationExpression NewArray(TypeReference elementType, JSExpression sizeOrArrayInitializer) { var arrayType = new ArrayType(elementType); return(JSInvocationExpression.InvokeStatic( new JSDotExpression( Dot("Array", TypeSystem.Object), new JSFakeMethod("New", arrayType, new[] { arrayType }, MethodTypes) ), new [] { new JSType(elementType), sizeOrArrayInitializer }, true )); }
public JSInvocationExpression StackAlloc(JSExpression sizeInBytes, TypeReference pointerType) { if (!pointerType.IsPointer) { throw new InvalidOperationException("Type being stack-allocated must be a pointer"); } return(JSInvocationExpression.InvokeStatic( Dot(new JSFakeMethod("StackAlloc", pointerType, new[] { TypeSystem.Int32, TypeSystem.Object }, MethodTypes)), new[] { sizeInBytes, new JSType(TypeUtil.GetElementType(pointerType, true)) } )); }
public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod, JSMethod method) { return(JSInvocationExpression.InvokeStatic( new JSDotExpression( new JSType(delegateType), new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes) ), method == null ? new [] { thisReference, targetMethod } : new [] { thisReference, targetMethod, new JSDefferedExpression(new JSMethodOfExpression(method.Reference, method.Method, method.MethodTypes, method.GenericArguments)), }, true )); }
public JSInvocationExpression GetLongLiteralExpression(long number, bool unsigned = false) { var type = unsigned ? TypeSystem.UInt64 : TypeSystem.Int64; uint a = (uint)(number & 0xffffff); uint b = (uint)((number >> 24) & 0xffffff); uint c = (uint)((number >> 48) & 0xffff); return(JSInvocationExpression .InvokeStatic( new JSType(type), new JSFakeMethod("Create", type, new[] { TypeSystem.UInt32, TypeSystem.UInt32, TypeSystem.UInt32 }, MethodTypeFactory), new JSExpression[] { new JSIntegerLiteral((long)a, typeof(uint)), new JSIntegerLiteral((long)b, typeof(uint)), new JSIntegerLiteral((long)c, typeof(uint)) })); }
public JSInvocationExpression NewMultidimensionalArray(TypeReference elementType, JSExpression[] dimensions, JSExpression initializer = null) { var arrayType = new ArrayType(elementType, dimensions.Length); var arguments = new JSExpression[] { new JSType(elementType) }.Concat(dimensions); if (initializer != null) { arguments = arguments.Concat(new[] { initializer }); } return(JSInvocationExpression.InvokeStatic( new JSDotExpression( Dot("MultidimensionalArray", TypeSystem.Object), new JSFakeMethod("New", arrayType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes) ), arguments.ToArray(), true )); }
public void VisitNode(JSIndexerExpression ie) { var indexType = ie.Index.GetActualType(TypeSystem); if ( !TypeUtil.IsIntegral(indexType) && IsEnumOrNullableEnum(indexType) ) { var cast = JSInvocationExpression.InvokeStatic( JS.Number(TypeSystem.Int32), new[] { ie.Index }, true ); ie.ReplaceChild(ie.Index, cast); } VisitChildren(ie); }
public void VisitNode(JSSwitchStatement ss) { var conditionType = ss.Condition.GetActualType(TypeSystem); if ( !TypeUtil.IsIntegral(conditionType) && IsEnumOrNullableEnum(conditionType) ) { var cast = JSInvocationExpression.InvokeStatic( JS.Number(TypeSystem.Int32), new[] { ss.Condition }, true ); ss.ReplaceChild(ss.Condition, cast); } VisitChildren(ss); }
public JSInvocationExpression NewDelegate(TypeReference delegateType, JSExpression thisReference, JSExpression targetMethod) { var targetDotExpression = targetMethod as JSDotExpressionBase; var jsMethod = targetDotExpression != null ? targetDotExpression.Member as JSMethod : null; JSExpression[] invocationExpressionArguments; if (jsMethod == null) { // Not sure if it is possible. invocationExpressionArguments = new[] { thisReference, targetMethod }; } else { var useRuntimeDispatch = jsMethod.Method != null && jsMethod.Method.Metadata.HasAttribute("JSIL.Meta.JSRuntimeDispatch"); var jsMethodAccess = targetMethod as JSMethodAccess; invocationExpressionArguments = new[] { thisReference, useRuntimeDispatch ? targetMethod : new JSNullLiteral(TypeSystem.Object), new JSMethodPointerInfoExpression( jsMethod.Reference, jsMethod.Method, jsMethod.MethodTypes, jsMethodAccess != null && jsMethodAccess.IsVirtual, jsMethod.GenericArguments), }; } return(JSInvocationExpression.InvokeStatic( new JSDotExpression( new JSType(delegateType), new JSFakeMethod("New", delegateType, new[] { TypeSystem.Object, TypeSystem.Object }, MethodTypes)), invocationExpressionArguments, true)); }
public void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isEnum = IsEnumOrNullableEnum(type); if (isEnum) { var cast = JSInvocationExpression.InvokeStatic( JS.Number(TypeSystem.Int32), new[] { uoe.Expression }, true ); if (LogicalOperators.Contains(uoe.Operator)) { uoe.ReplaceChild(uoe.Expression, cast); } else if (uoe.Operator == JSOperator.Negation) { uoe.ReplaceChild(uoe.Expression, cast); } } VisitChildren(uoe); }
public JSInvocationExpression CreateNamedFunction(TypeReference resultType, JSExpression name, JSExpression argumentNames, JSExpression body, JSExpression closure = null) { var nae = argumentNames as JSNewArrayExpression; if (nae != null) { argumentNames = nae.SizeOrArrayInitializer; } // FIXME: We should do a cast of the result to ensure it's actually the requested result type instead of just a raw JS function return(JSInvocationExpression.InvokeStatic( Dot( new JSFakeMethod( "CreateNamedFunction", resultType, new[] { TypeSystem.String, new ArrayType(TypeSystem.String), TypeSystem.String, TypeSystem.Object }, MethodTypes ) ), new[] { name, argumentNames, body, closure } )); }
protected JSInvocationExpression CastToChar(JSExpression integerExpression) { return(JSInvocationExpression.InvokeStatic( JS.fromCharCode, new[] { integerExpression }, true )); }
private void EmitCctors() { // HACK var identifier = (MemberIdentifier)Activator.CreateInstance( typeof(MemberIdentifier), System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, null, new object[] { true, MemberIdentifier.MemberType.Method, ".cctor", EntryPointAstEmitter.TypeSystem.Void, null, 0 }, null ); // Find types we emitted that have static constructors var cctors = ( from t in TypesToStaticInitialize let ti = Translator.TypeInfoProvider.GetExisting(t) where ti.Members.ContainsKey(identifier) let mi = ti.Members[identifier] select(MethodInfo) mi ).ToList(); if (cctors.Count == 0) { return; } NeedStaticInit = true; Formatter.NewLine(); Formatter.WriteRaw(";; Compiler-generated static constructor dispatcher"); Formatter.NewLine(); // If we found any, we need to generate a special function that invokes all the cctors Formatter.WriteRaw("(func $__static_init (block "); Formatter.Indent(); Formatter.NewLine(); // FIXME: Walk cctor dependencies and invoke in correct order foreach (var cctor in cctors) { // Synthesize a regular static method call var jsm = new JSMethod( cctor.Member, cctor, Translator.FunctionCache.MethodTypes ); var call = JSInvocationExpression.InvokeStatic(jsm, new JSExpression[0], false); // HACK EntryPointAstEmitter.Emit(call); Formatter.ConditionalNewLine(); } Formatter.Unindent(); Formatter.ConditionalNewLine(); Formatter.WriteRaw(") )"); Formatter.NewLine(); Formatter.NewLine(); Formatter.WriteRaw("(export \"__static_init\" $__static_init)"); Formatter.NewLine(); }