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 void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isIntegral = TypeUtil.Is32BitIntegral(type); if (isIntegral && (uoe.Operator is JSUnaryMutationOperator)) { if ( (uoe.Operator == JSOperator.PreIncrement) || (uoe.Operator == JSOperator.PreDecrement) ) { var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PreDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); ParentNode.ReplaceChild(uoe, assignment); VisitReplacement(assignment); return; } else if ( (uoe.Operator == JSOperator.PostIncrement) || (uoe.Operator == JSOperator.PostDecrement) ) { // FIXME: Terrible hack var tempVariable = TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ); var makeTempCopy = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVariable, uoe.Expression, type ); var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PostDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); var comma = new JSCommaExpression( makeTempCopy, assignment, tempVariable ); ParentNode.ReplaceChild(uoe, comma); VisitReplacement(comma); return; } else { throw new NotImplementedException("Unary mutation not supported: " + uoe.ToString()); } } VisitChildren(uoe); }
public static bool ExtractOffsetFromPointerExpression(JSExpression pointer, TypeSystem typeSystem, out JSExpression newPointer, out JSExpression offset) { pointer = JSPointerExpressionUtil.UnwrapExpression(pointer); offset = null; newPointer = pointer; var boe = pointer as JSBinaryOperatorExpression; if (boe == null) { return(false); } if (boe.Right.IsNull) { return(false); } var right = JSPointerExpressionUtil.UnwrapExpression(boe.Right); var rightType = right.GetActualType(typeSystem); var resultType = boe.GetActualType(typeSystem); if (!resultType.IsPointer) { return(false); } if ( !TypeUtil.IsIntegral(rightType) && // Adding pointers together shouldn't be valid but ILSpy generates it. Pfft. !TypeUtil.IsPointer(rightType) ) { return(false); } if (boe.Operator == JSOperator.Subtract) { newPointer = boe.Left; offset = new JSUnaryOperatorExpression(JSOperator.Negation, right, rightType); return(true); } else if (boe.Operator == JSOperator.Add) { newPointer = boe.Left; offset = right; return(true); } else { return(false); } }
public void VisitNode(JSUnaryOperatorExpression uoe) { var isBoolean = TypeUtil.IsBoolean(uoe.GetActualType(TypeSystem)); if (isBoolean) { if (uoe.Operator == JSOperator.IsTrue) { ParentNode.ReplaceChild( uoe, uoe.Expression ); VisitReplacement(uoe.Expression); return; } else if (uoe.Operator == JSOperator.LogicalNot) { var nestedUoe = uoe.Expression as JSUnaryOperatorExpression; var boe = uoe.Expression as JSBinaryOperatorExpression; JSBinaryOperator newOperator; if ((boe != null) && InvertedOperators.TryGetValue(boe.Operator, out newOperator) ) { var newBoe = new JSBinaryOperatorExpression( newOperator, boe.Left, boe.Right, boe.ActualType ); ParentNode.ReplaceChild(uoe, newBoe); VisitReplacement(newBoe); return; } else if ( (nestedUoe != null) && (nestedUoe.Operator == JSOperator.LogicalNot) ) { var nestedExpression = nestedUoe.Expression; ParentNode.ReplaceChild(uoe, nestedExpression); VisitReplacement(nestedExpression); return; } } } VisitChildren(uoe); }
public void VisitNode(JSUnaryOperatorExpression uop) { if (!uop.IsPostfix) { Output.WriteRaw(uop.Operator.Token); } Visit(uop.Expression); if (uop.IsPostfix) { Output.WriteRaw(uop.Operator.Token); } }
public static JSExpression DecomposeUnaryMutation( JSUnaryOperatorExpression uoe, Func <JSRawOutputIdentifier> makeTemporaryVariable, TypeReference type, TypeSystem typeSystem ) { if ( (uoe.Operator == JSOperator.PreIncrement) || (uoe.Operator == JSOperator.PreDecrement) ) { var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PreDecrement) ? JSOperator.Subtract : JSOperator.Add, type, typeSystem ); return(assignment); } else if ( (uoe.Operator == JSOperator.PostIncrement) || (uoe.Operator == JSOperator.PostDecrement) ) { // FIXME: Terrible hack var tempVariable = makeTemporaryVariable(); var makeTempCopy = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVariable, uoe.Expression, type ); var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PostDecrement) ? JSOperator.Subtract : JSOperator.Add, type, typeSystem ); var comma = new JSCommaExpression( makeTempCopy, assignment, tempVariable ); return(comma); } else { throw new NotImplementedException("Unary mutation not supported: " + uoe); } }
public void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetExpectedType(TypeSystem); var isEnum = ILBlockTranslator.IsEnum(type); if (isEnum) { var cast = JSInvocationExpression.InvokeMethod( new JSFakeMethod("valueOf", TypeSystem.Int32, type), uoe.Expression, null, 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 void VisitNode(JSUnaryOperatorExpression uoe) { JSUnaryMutationOperator op; JSExpression target; TypeReference type; if (UnpackUnaryMutation(uoe, out op, out target, out type)) { var tempVar = TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ); var store = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVar, target, type ); var delta = ( (op == JSOperator.PostIncrement) || (op == JSOperator.PreIncrement) ) ? 1 : -1; JSExpression replacement; if ( (op == JSOperator.PostIncrement) || (op == JSOperator.PostDecrement) ) { var mutated = new JSPointerAddExpression(target, JSLiteral.New(delta), false); replacement = new JSCommaExpression(store, mutated, tempVar); } else { replacement = new JSPointerAddExpression(target, JSLiteral.New(delta), true); } ParentNode.ReplaceChild(uoe, replacement); VisitReplacement(replacement); return; } VisitChildren(uoe); }
public void VisitNode(JSUnaryOperatorExpression uoe) { JSExpression expr; if (!JSReferenceExpression.TryDereference(JSIL, uoe.Expression, out expr)) { expr = uoe.Expression; } var eVar = expr as JSVariable; var eChangeType = expr as JSChangeTypeExpression; if (eChangeType != null) { eVar = eChangeType.Expression as JSVariable; } var type = uoe.Expression.GetActualType(TypeSystem); if ( (eVar != null) && (eVar.Identifier == Variable.Identifier) && (uoe.Operator is JSUnaryMutationOperator) ) { var newValue = DecomposeMutationOperators.DecomposeUnaryMutation( uoe, () => TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ), type, TypeSystem ); var replacement = new JSWriteThroughReferenceExpression( Variable, newValue ); ParentNode.ReplaceChild(uoe, replacement); VisitReplacement(replacement); } else { VisitChildren(uoe); } }
public void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isIntegral = TypeUtil.Is32BitIntegral(type); if (isIntegral && (uoe.Operator is JSUnaryMutationOperator)) { var replacement = DecomposeUnaryMutation( uoe, () => TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ), type, TypeSystem ); ParentNode.ReplaceChild(uoe, replacement); VisitReplacement(replacement); return; } VisitChildren(uoe); }
public void VisitNode(JSUnaryOperatorExpression uoe) { var variable = ExtractAffectedVariable(uoe.Expression); var isMutator = uoe.Operator is JSUnaryMutationOperator; VisitChildren(uoe); if (isMutator) { if (variable != null) { State.Assignments.Add( new FunctionAnalysis1stPass.Assignment( GetParentNodeIndices(), StatementIndex, NodeIndex, variable, uoe, uoe.Operator, variable.GetActualType(TypeSystem), uoe.GetActualType(TypeSystem) ) ); ModifiedVariable(variable); } } }
private bool UnpackUnaryMutation( JSUnaryOperatorExpression uoe, out JSUnaryMutationOperator op, out JSExpression target, out TypeReference type ) { type = uoe.Expression.GetActualType(TypeSystem); if ( TypeUtil.IsPointer(type) && (uoe.Operator is JSUnaryMutationOperator) ) { target = uoe.Expression; op = (JSUnaryMutationOperator)uoe.Operator; return(true); } target = null; op = null; return(false); }
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 void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isEnum = IsEnumOrNullableEnum(type); if (isEnum) { var cast = JSInvocationExpression.InvokeMethod( JS.valueOf(TypeSystem.Int32), uoe.Expression, null, true ); if (LogicalOperators.Contains(uoe.Operator)) { uoe.ReplaceChild(uoe.Expression, cast); } else if (uoe.Operator == JSOperator.Negation) { uoe.ReplaceChild(uoe.Expression, cast); } } VisitChildren(uoe); }
private bool UnpackUnaryMutation ( JSUnaryOperatorExpression uoe, out JSUnaryMutationOperator op, out JSExpression target, out TypeReference type ) { type = uoe.Expression.GetActualType(TypeSystem); if ( TypeUtil.IsPointer(type) && (uoe.Operator is JSUnaryMutationOperator) ) { target = uoe.Expression; op = (JSUnaryMutationOperator)uoe.Operator; return true; } target = null; op = null; return false; }
public void VisitNode (JSBinaryOperatorExpression boe) { if (!boe.CanSimplify) { VisitChildren(boe); return; } JSExpression left, right, nestedLeft; if (!JSReferenceExpression.TryDereference(JSIL, boe.Left, out left)) left = boe.Left; if (!JSReferenceExpression.TryDereference(JSIL, boe.Right, out right)) right = boe.Right; var nestedBoe = right as JSBinaryOperatorExpression; var isAssignment = (boe.Operator == JSOperator.Assignment); var leftNew = left as JSNewExpression; var rightNew = right as JSNewExpression; var leftVar = left as JSVariable; if ( isAssignment && (nestedBoe != null) && (left.IsConstant || (leftVar != null) || left is JSDotExpressionBase) && !(ParentNode is JSVariableDeclarationStatement) ) { if (!nestedBoe.CanSimplify) { VisitChildren(boe); return; } JSUnaryOperator prefixOperator; JSAssignmentOperator compoundOperator; if (!JSReferenceExpression.TryDereference(JSIL, nestedBoe.Left, out nestedLeft)) nestedLeft = nestedBoe.Left; var rightLiteral = nestedBoe.Right as JSIntegerLiteral; var areEqual = left.Equals(nestedLeft); if ( areEqual && PrefixOperators.TryGetValue(nestedBoe.Operator, out prefixOperator) && (rightLiteral != null) && (rightLiteral.Value == 1) ) { var newUoe = new JSUnaryOperatorExpression( prefixOperator, boe.Left, boe.GetActualType(TypeSystem) ); ParentNode.ReplaceChild(boe, newUoe); VisitReplacement(newUoe); return; } else if ( areEqual && CompoundAssignments.TryGetValue(nestedBoe.Operator, out compoundOperator) ) { var newBoe = new JSBinaryOperatorExpression( compoundOperator, boe.Left, nestedBoe.Right, boe.GetActualType(TypeSystem) ); ParentNode.ReplaceChild(boe, newBoe); VisitReplacement(newBoe); return; } } else if ( isAssignment && (leftNew != null) && (rightNew != null) ) { // FIXME /* var rightType = rightNew.Type as JSDotExpressionBase; if ( (rightType != null) && (rightType.Member.Identifier == "CollectionInitializer") ) { var newInitializer = new JSInitializerApplicationExpression( boe.Left, new JSArrayExpression( TypeSystem.Object, rightNew.Arguments.ToArray() ) ); ParentNode.ReplaceChild(boe, newInitializer); VisitReplacement(newInitializer); return; } */ } else if ( isAssignment && (leftVar != null) && leftVar.IsThis ) { var leftType = leftVar.GetActualType(TypeSystem); if (!TypeUtil.IsStruct(leftType)) { ParentNode.ReplaceChild(boe, new JSUntranslatableExpression(boe)); return; } else { var newInvocation = JSInvocationExpression.InvokeStatic( JSIL.CopyMembers, new[] { boe.Right, leftVar } ); ParentNode.ReplaceChild(boe, newInvocation); VisitReplacement(newInvocation); return; } } VisitChildren(boe); }
public void VisitNode (JSUnaryOperatorExpression uoe) { JSUnaryMutationOperator op; JSExpression target; TypeReference type; if (UnpackUnaryMutation(uoe, out op, out target, out type)) { var tempVar = TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ); var store = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVar, target, type ); var delta = ( (op == JSOperator.PostIncrement) || (op == JSOperator.PreIncrement) ) ? 1 : -1; JSExpression replacement; if ( (op == JSOperator.PostIncrement) || (op == JSOperator.PostDecrement) ) { var mutated = new JSPointerAddExpression(target, JSLiteral.New(delta), false); replacement = new JSCommaExpression(store, mutated, tempVar); } else { replacement = new JSPointerAddExpression(target, JSLiteral.New(delta), true); } ParentNode.ReplaceChild(uoe, replacement); VisitReplacement(replacement); return; } VisitChildren(uoe); }
public void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isEnum = IsEnumOrNullableEnum(type); if (isEnum) { var castToInt = JSInvocationExpression.InvokeMethod( JS.valueOf(TypeSystem.Int32), uoe.Expression, null, true ); if (LogicalOperators.Contains(uoe.Operator)) { uoe.ReplaceChild(uoe.Expression, castToInt); } else if (uoe.Operator == JSOperator.Negation) { uoe.ReplaceChild(uoe.Expression, castToInt); } else if (uoe.Operator is JSUnaryMutationOperator) { if ( (uoe.Operator == JSOperator.PreIncrement) || (uoe.Operator == JSOperator.PreDecrement) ) { var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PreDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); ParentNode.ReplaceChild(uoe, assignment); VisitReplacement(assignment); return; } else if ( (uoe.Operator == JSOperator.PostIncrement) || (uoe.Operator == JSOperator.PostDecrement) ) { // FIXME: Terrible hack oh god (also not strict mode safe) var tempVariable = new JSRawOutputIdentifier( (output) => output.WriteRaw("$temp"), type ); var makeTempCopy = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVariable, uoe.Expression, type ); var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PostDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); var comma = new JSCommaExpression( makeTempCopy, assignment, tempVariable ); ParentNode.ReplaceChild(uoe, comma); VisitReplacement(comma); return; } else { throw new NotImplementedException("Unary mutation of enum not supported: " + uoe.ToString()); } } } VisitChildren(uoe); }
public void VisitNode (JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isIntegral = TypeUtil.Is32BitIntegral(type); if (isIntegral && (uoe.Operator is JSUnaryMutationOperator)) { var replacement = DecomposeUnaryMutation( uoe, () => TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ), type, TypeSystem ); ParentNode.ReplaceChild(uoe, replacement); VisitReplacement(replacement); return; } VisitChildren(uoe); }
public void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isIntegral = TypeUtil.Is32BitIntegral(type); if (isIntegral && (uoe.Operator is JSUnaryMutationOperator)) { if ( (uoe.Operator == JSOperator.PreIncrement) || (uoe.Operator == JSOperator.PreDecrement) ) { var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PreDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); ParentNode.ReplaceChild(uoe, assignment); VisitReplacement(assignment); return; } else if ( (uoe.Operator == JSOperator.PostIncrement) || (uoe.Operator == JSOperator.PostDecrement) ) { // FIXME: Terrible hack var tempVariable = TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ); var makeTempCopy = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVariable, uoe.Expression, type ); var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PostDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); var comma = new JSCommaExpression( makeTempCopy, assignment, tempVariable ); ParentNode.ReplaceChild(uoe, comma); VisitReplacement(comma); return; } else { throw new NotImplementedException("Unary mutation not supported: " + uoe); } } VisitChildren(uoe); }
public static JSExpression DecomposeUnaryMutation ( JSUnaryOperatorExpression uoe, Func<JSRawOutputIdentifier> makeTemporaryVariable, TypeReference type, TypeSystem typeSystem ) { if ( (uoe.Operator == JSOperator.PreIncrement) || (uoe.Operator == JSOperator.PreDecrement) ) { var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PreDecrement) ? JSOperator.Subtract : JSOperator.Add, type, typeSystem ); return assignment; } else if ( (uoe.Operator == JSOperator.PostIncrement) || (uoe.Operator == JSOperator.PostDecrement) ) { // FIXME: Terrible hack var tempVariable = makeTemporaryVariable(); var makeTempCopy = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVariable, uoe.Expression, type ); var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PostDecrement) ? JSOperator.Subtract : JSOperator.Add, type, typeSystem ); var comma = new JSCommaExpression( makeTempCopy, assignment, tempVariable ); return comma; } else { throw new NotImplementedException("Unary mutation not supported: " + uoe); } }
public void VisitNode(JSBinaryOperatorExpression boe) { JSExpression left, right, nestedLeft; if (!JSReferenceExpression.TryDereference(JSIL, boe.Left, out left)) { left = boe.Left; } if (!JSReferenceExpression.TryDereference(JSIL, boe.Right, out right)) { right = boe.Right; } var nestedBoe = right as JSBinaryOperatorExpression; var isAssignment = (boe.Operator == JSOperator.Assignment); var leftNew = left as JSNewExpression; var rightNew = right as JSNewExpression; var leftVar = left as JSVariable; if ( isAssignment && (nestedBoe != null) && (left.IsConstant || (leftVar != null) || left is JSDotExpressionBase) && !(ParentNode is JSVariableDeclarationStatement) ) { JSUnaryOperator prefixOperator; JSAssignmentOperator compoundOperator; if (!JSReferenceExpression.TryDereference(JSIL, nestedBoe.Left, out nestedLeft)) { nestedLeft = nestedBoe.Left; } var rightLiteral = nestedBoe.Right as JSIntegerLiteral; var areEqual = left.Equals(nestedLeft); if ( areEqual && PrefixOperators.TryGetValue(nestedBoe.Operator, out prefixOperator) && (rightLiteral != null) && (rightLiteral.Value == 1) ) { var newUoe = new JSUnaryOperatorExpression( prefixOperator, boe.Left, boe.GetActualType(TypeSystem) ); ParentNode.ReplaceChild(boe, newUoe); VisitReplacement(newUoe); return; } else if ( areEqual && CompoundAssignments.TryGetValue(nestedBoe.Operator, out compoundOperator) ) { var newBoe = new JSBinaryOperatorExpression( compoundOperator, boe.Left, nestedBoe.Right, boe.GetActualType(TypeSystem) ); ParentNode.ReplaceChild(boe, newBoe); VisitReplacement(newBoe); return; } } else if ( isAssignment && (leftNew != null) && (rightNew != null) ) { var rightType = rightNew.Type as JSDotExpressionBase; if ( (rightType != null) && (rightType.Member.Identifier == "CollectionInitializer") ) { var newInitializer = new JSInitializerApplicationExpression( boe.Left, new JSArrayExpression( TypeSystem.Object, rightNew.Arguments.ToArray() ) ); ParentNode.ReplaceChild(boe, newInitializer); VisitReplacement(newInitializer); return; } } else if ( isAssignment && (leftVar != null) && leftVar.IsThis ) { var leftType = leftVar.GetActualType(TypeSystem); if (!TypeUtil.IsStruct(leftType)) { ParentNode.ReplaceChild(boe, new JSUntranslatableExpression(boe)); return; } else { var newInvocation = JSInvocationExpression.InvokeStatic( JSIL.CopyMembers, new[] { boe.Right, leftVar } ); ParentNode.ReplaceChild(boe, newInvocation); VisitReplacement(newInvocation); return; } } VisitChildren(boe); }
private JSForLoop ReplaceWhileLoopAndEnumerator(JSWhileLoop wl, JSExpression backingStore, JSExpression enumerator, TypeInfo enumeratorType, string arrayMember, string lengthMember) { var loopId = _NextLoopId++; var arrayVariableName = String.Format("a${0:x}", loopId); var indexVariableName = String.Format("i${0:x}", loopId); var lengthVariableName = String.Format("l${0:x}", loopId); var currentPropertyReference = enumeratorType.Definition.Properties.First((p) => p.Name == "Current"); var currentPropertyInfo = enumeratorType.Source.GetProperty(currentPropertyReference); var itemType = currentPropertyInfo.ReturnType; var arrayType = new ArrayType(itemType); var arrayVariable = new JSVariable( arrayVariableName, arrayType, Function.Method.Reference, JSDotExpression.New(backingStore, new JSStringIdentifier(arrayMember, arrayType)) ); var indexVariable = new JSVariable( indexVariableName, TypeSystem.Int32, Function.Method.Reference, JSLiteral.New(0) ); var lengthVariable = new JSVariable( lengthVariableName, TypeSystem.Int32, Function.Method.Reference, JSDotExpression.New(backingStore, new JSStringIdentifier(lengthMember, TypeSystem.Int32)) ); var initializer = new JSVariableDeclarationStatement( new JSBinaryOperatorExpression( JSOperator.Assignment, arrayVariable, arrayVariable.DefaultValue, arrayVariable.IdentifierType ), new JSBinaryOperatorExpression( JSOperator.Assignment, indexVariable, indexVariable.DefaultValue, indexVariable.IdentifierType ), new JSBinaryOperatorExpression( JSOperator.Assignment, lengthVariable, lengthVariable.DefaultValue, lengthVariable.IdentifierType ) ); var condition = new JSBinaryOperatorExpression( JSBinaryOperator.LessThan, indexVariable, lengthVariable, TypeSystem.Boolean ); var increment = new JSUnaryOperatorExpression( JSUnaryOperator.PostIncrement, indexVariable, TypeSystem.Int32 ); var result = new JSForLoop( initializer, condition, new JSExpressionStatement(increment), wl.Statements.ToArray() ); result.Index = wl.Index; new PropertyAccessReplacer( enumerator, new JSProperty(currentPropertyReference, currentPropertyInfo), new JSIndexerExpression( arrayVariable, indexVariable, itemType ) ).Visit(result); return result; }
private JSForLoop ReplaceWhileLoopAndEnumerator(JSWhileLoop wl, JSExpression backingStore, JSExpression enumerator, TypeInfo enumeratorType, string arrayMember, string lengthMember) { var loopId = _NextLoopId++; var arrayVariableName = String.Format("a${0:x}", loopId); var indexVariableName = String.Format("i${0:x}", loopId); var lengthVariableName = String.Format("l${0:x}", loopId); var currentPropertyReference = enumeratorType.Definition.Properties.First((p) => p.Name == "Current"); var currentPropertyInfo = enumeratorType.Source.GetProperty(currentPropertyReference); var itemType = currentPropertyInfo.ReturnType; var arrayType = new ArrayType(itemType); var arrayVariable = new JSVariable( arrayVariableName, arrayType, Function.Method.Reference, JSDotExpression.New(backingStore, new JSStringIdentifier(arrayMember, arrayType)) ); var indexVariable = new JSVariable( indexVariableName, TypeSystem.Int32, Function.Method.Reference, JSLiteral.New(0) ); var lengthVariable = new JSVariable( lengthVariableName, TypeSystem.Int32, Function.Method.Reference, JSDotExpression.New(backingStore, new JSStringIdentifier(lengthMember, TypeSystem.Int32)) ); var initializer = new JSVariableDeclarationStatement( new JSBinaryOperatorExpression( JSOperator.Assignment, arrayVariable, arrayVariable.DefaultValue, arrayVariable.IdentifierType ), new JSBinaryOperatorExpression( JSOperator.Assignment, indexVariable, indexVariable.DefaultValue, indexVariable.IdentifierType ), new JSBinaryOperatorExpression( JSOperator.Assignment, lengthVariable, lengthVariable.DefaultValue, lengthVariable.IdentifierType ) ); var condition = new JSBinaryOperatorExpression( JSOperator.LessThan, indexVariable, lengthVariable, TypeSystem.Boolean ); var increment = new JSUnaryOperatorExpression( JSOperator.PostIncrement, indexVariable, TypeSystem.Int32 ); var result = new JSForLoop( initializer, condition, new JSExpressionStatement(increment), wl.Statements.ToArray() ); result.Index = wl.Index; new PropertyAccessReplacer( enumerator, new JSProperty(currentPropertyReference, currentPropertyInfo), new JSIndexerExpression( arrayVariable, indexVariable, itemType ) ).Visit(result); return(result); }
public void VisitNode (JSUnaryOperatorExpression uoe) { JSExpression expr; if (!JSReferenceExpression.TryDereference(JSIL, uoe.Expression, out expr)) expr = uoe.Expression; var eVar = expr as JSVariable; var eChangeType = expr as JSChangeTypeExpression; if (eChangeType != null) eVar = eChangeType.Expression as JSVariable; var type = uoe.Expression.GetActualType(TypeSystem); if ( (eVar != null) && (eVar.Identifier == Variable.Identifier) && (uoe.Operator is JSUnaryMutationOperator) ) { var newValue = DecomposeMutationOperators.DecomposeUnaryMutation( uoe, () => TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type, FunctionSource ), type, TypeSystem ); var replacement = new JSWriteThroughReferenceExpression( Variable, newValue ); ParentNode.ReplaceChild(uoe, replacement); VisitReplacement(replacement); } else { VisitChildren(uoe); } }
public static bool ExtractOffsetFromPointerExpression (JSExpression pointer, TypeSystem typeSystem, out JSExpression newPointer, out JSExpression offset) { pointer = JSPointerExpressionUtil.UnwrapExpression(pointer); offset = null; newPointer = pointer; var boe = pointer as JSBinaryOperatorExpression; if (boe == null) return false; if (boe.Right.IsNull) return false; var right = JSPointerExpressionUtil.UnwrapExpression(boe.Right); var rightType = right.GetActualType(typeSystem); var resultType = boe.GetActualType(typeSystem); if (!resultType.IsPointer) return false; if ( !TypeUtil.IsIntegral(rightType) && // Adding pointers together shouldn't be valid but ILSpy generates it. Pfft. !TypeUtil.IsPointer(rightType) ) return false; if (boe.Operator == JSOperator.Subtract) { newPointer = boe.Left; offset = new JSUnaryOperatorExpression(JSOperator.Negation, right, rightType); return true; } else if (boe.Operator == JSOperator.Add) { newPointer = boe.Left; offset = right; return true; } else { return false; } }
public void VisitNode(JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isEnum = IsEnumOrNullableEnum(type); if (isEnum) { var castToInt = JSInvocationExpression.InvokeMethod( JS.valueOf(TypeSystem.Int32), uoe.Expression, null, true ); if (LogicalOperators.Contains(uoe.Operator)) { uoe.ReplaceChild(uoe.Expression, castToInt); } else if (uoe.Operator == JSOperator.Negation) { uoe.ReplaceChild(uoe.Expression, castToInt); } else if (uoe.Operator is JSUnaryMutationOperator) { if ( (uoe.Operator == JSOperator.PreIncrement) || (uoe.Operator == JSOperator.PreDecrement) ) { var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PreDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); ParentNode.ReplaceChild(uoe, assignment); VisitReplacement(assignment); return; } else if ( (uoe.Operator == JSOperator.PostIncrement) || (uoe.Operator == JSOperator.PostDecrement) ) { // FIXME: Terrible hack var tempVariable = TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type ); var makeTempCopy = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVariable, uoe.Expression, type ); var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PostDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); var comma = new JSCommaExpression( makeTempCopy, assignment, tempVariable ); ParentNode.ReplaceChild(uoe, comma); VisitReplacement(comma); return; } else { throw new NotImplementedException("Unary mutation of enum not supported: " + uoe.ToString()); } } } VisitChildren(uoe); }
public void VisitNode(JSUnaryOperatorExpression uoe) { var resultType = uoe.GetActualType(TypeSystem); var typeToken = WasmUtil.PickTypeKeyword(resultType); if (typeToken == null) { Console.WriteLine("Unhandled unary operator type {0}", resultType); return; } if (uoe.Operator == JSOperator.LogicalNot) { Formatter.WriteRaw("({0}.xor ", typeToken); Visit(uoe.Expression); Formatter.WriteRaw(" ({0}.const 1))", typeToken); return; } else if (uoe.Operator == JSOperator.Negation) { Formatter.WriteRaw("({0}.sub ({0}.const 0) ", typeToken); Visit(uoe.Expression); Formatter.WriteRaw(")", typeToken); return; } string keyword; if (!OperatorTable.TryGetValue(uoe.Operator, out keyword)) { Console.WriteLine("Unimplemented operator {0}", uoe.Operator); return; } var operandType = uoe.Expression.GetActualType(TypeSystem); var sign = TypeUtil.IsSigned(operandType); var signSuffix = ""; if ( (sign.HasValue && TypeUtil.IsIntegral(operandType)) || // HACK (operandType.FullName == "System.Char") ) { signSuffix = sign.GetValueOrDefault(true) ? "_s" : "_u"; } var actualKeyword = string.Format( typeToken + "." + keyword, signSuffix ); Formatter.WriteSExpr( actualKeyword, (_) => EmitArgumentList(_, new[] { uoe.Expression }, true), true, false ); }
public void VisitNode (JSUnaryOperatorExpression uoe) { var type = uoe.Expression.GetActualType(TypeSystem); var isEnum = IsEnumOrNullableEnum(type); if (isEnum) { var castToInt = JSInvocationExpression.InvokeMethod( JS.valueOf(TypeSystem.Int32), uoe.Expression, null, true ); if (LogicalOperators.Contains(uoe.Operator)) { uoe.ReplaceChild(uoe.Expression, castToInt); } else if (uoe.Operator == JSOperator.Negation) { uoe.ReplaceChild(uoe.Expression, castToInt); } else if (uoe.Operator is JSUnaryMutationOperator) { if ( (uoe.Operator == JSOperator.PreIncrement) || (uoe.Operator == JSOperator.PreDecrement) ) { var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PreDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); ParentNode.ReplaceChild(uoe, assignment); VisitReplacement(assignment); return; } else if ( (uoe.Operator == JSOperator.PostIncrement) || (uoe.Operator == JSOperator.PostDecrement) ) { // FIXME: Terrible hack var tempVariable = TemporaryVariable.ForFunction( Stack.Last() as JSFunctionExpression, type, FunctionSource ); var makeTempCopy = new JSBinaryOperatorExpression( JSOperator.Assignment, tempVariable, uoe.Expression, type ); var assignment = MakeUnaryMutation( uoe.Expression, (uoe.Operator == JSOperator.PostDecrement) ? JSOperator.Subtract : JSOperator.Add, type ); var comma = new JSCommaExpression( makeTempCopy, assignment, tempVariable ); ParentNode.ReplaceChild(uoe, comma); VisitReplacement(comma); return; } else { throw new NotImplementedException("Unary mutation of enum not supported: " + uoe); } } } VisitChildren(uoe); }