Object binaryOp()

in debugger/src/main/java/flash/tools/debugger/expression/AS3DebuggerReducer.java [190:494]


	Object binaryOp(IASNode iNode, Object l, Object r, int opcode) {
		if (hookallreducercalls)
			hookforreducercalls("binaryOp");
		// REFER : ASC : public Value evaluate(macromedia.asc.util.Context cx,
		// BinaryExpressionNode node)
		switch (opcode) {
		case ABCConstants.OP_add:
			break;
		}

		DebuggerValue lhs = (DebuggerValue) l;
		DebuggerValue rhs = (DebuggerValue) r;

		Context eeContext = contextStack.scope();
		Session session = eeContext.getSession();
		switch (opcode) {
		case ABCConstants.OP_multiply: {
			// ECMA 11.5
			double d1 = ECMA.toNumber(session,
					eeContext.toValue(lhs.debuggerValue));
			double d2 = ECMA.toNumber(session,
					eeContext.toValue(rhs.debuggerValue));
			return new DebuggerValue(Double.valueOf(d1 * d2));
		}
		case ABCConstants.OP_divide: {
			// ECMA 11.5
			double d1 = ECMA.toNumber(session,
					eeContext.toValue(lhs.debuggerValue));
			double d2 = ECMA.toNumber(session,
					eeContext.toValue(rhs.debuggerValue));
			return new DebuggerValue(Double.valueOf(d1 / d2));
		}
		case ABCConstants.OP_modulo: {
			// ECMA 11.5
			double d1 = ECMA.toNumber(session,
					eeContext.toValue(lhs.debuggerValue));
			double d2 = ECMA.toNumber(session,
					eeContext.toValue(rhs.debuggerValue));
			return new DebuggerValue(Double.valueOf(d1 % d2));
		}
		case ABCConstants.OP_add: {
			// E4X 11.4.1 and ECMA 11.6.1
			flash.tools.debugger.Value v1 = eeContext
					.toValue(lhs.debuggerValue);
			flash.tools.debugger.Value v2 = eeContext
					.toValue(rhs.debuggerValue);

			boolean isXMLConcat = false;

			if (v1.getType() == VariableType.OBJECT
					&& v2.getType() == VariableType.OBJECT) {
				String type1 = v1.getTypeName();
				String type2 = v2.getTypeName();
				int at;
				at = type1.indexOf('@');
				if (at != -1)
					type1 = type1.substring(0, at);
				at = type2.indexOf('@');
				if (at != -1)
					type2 = type2.substring(0, at);

				if (type1.equals("XML") || type1.equals("XMLList")) //$NON-NLS-1$ //$NON-NLS-2$
					if (type2.equals("XML") || type2.equals("XMLList")) //$NON-NLS-1$ //$NON-NLS-2$
						isXMLConcat = true;
			}

			if (isXMLConcat) {
				try {
					IsolateSession workerSession = session.getWorkerSession(v1
							.getIsolateId());
					flash.tools.debugger.Value xml1 = workerSession
							.callFunction(
									v1,
									"toXMLString", new flash.tools.debugger.Value[0]); //$NON-NLS-1$
					flash.tools.debugger.Value xml2 = session.getWorkerSession(
							v2.getIsolateId()).callFunction(v2,
							"toXMLString", new flash.tools.debugger.Value[0]); //$NON-NLS-1$
					String allXML = xml1.getValueAsString()
							+ xml2.getValueAsString();
					flash.tools.debugger.Value allXMLValue = DValue
							.forPrimitive(allXML, v1.getIsolateId());
					flash.tools.debugger.Value retval = workerSession
							.callConstructor(
									"XMLList", new flash.tools.debugger.Value[] { allXMLValue }); //$NON-NLS-1$
					return new DebuggerValue(retval);
				} catch (PlayerDebugException e) {
					throw new ExpressionEvaluatorException(e);
				}
			} else {
				v1 = ECMA.toPrimitive(session, v1, null,
						eeContext.getIsolateId());
				v2 = ECMA.toPrimitive(session, v2, null,
						eeContext.getIsolateId());
				if (v1.getType() == VariableType.STRING
						|| v2.getType() == VariableType.STRING) {
					return new DebuggerValue(ECMA.toString(session, v1)
							+ ECMA.toString(session, v2));
				} else {
					return new DebuggerValue(Double.valueOf(ECMA.toNumber(session,
							v1) + ECMA.toNumber(session, v2)));
				}
			}
		}
		case ABCConstants.OP_subtract: {
			// ECMA 11.6.2
			double d1 = ECMA.toNumber(session,
					eeContext.toValue(lhs.debuggerValue));
			double d2 = ECMA.toNumber(session,
					eeContext.toValue(rhs.debuggerValue));
			return new DebuggerValue(Double.valueOf(d1 - d2));
		}
		case ABCConstants.OP_lshift: {
			// ECMA 11.7.1
			int n1 = ECMA
					.toInt32(session, eeContext.toValue(lhs.debuggerValue));
			int n2 = (int) (ECMA.toUint32(session,
					eeContext.toValue(rhs.debuggerValue)) & 0x1F);
			return new DebuggerValue(Double.valueOf(n1 << n2));
		}
		case ABCConstants.OP_rshift: {
			// ECMA 11.7.1
			int n1 = ECMA
					.toInt32(session, eeContext.toValue(lhs.debuggerValue));
			int n2 = (int) (ECMA.toUint32(session,
					eeContext.toValue(rhs.debuggerValue)) & 0x1F);
			return new DebuggerValue(Double.valueOf(n1 >> n2));
		}
		case ABCConstants.OP_urshift: {
			// ECMA 11.7.1
			long n1 = ECMA.toUint32(session,
					eeContext.toValue(lhs.debuggerValue));
			long n2 = (ECMA.toUint32(session,
					eeContext.toValue(rhs.debuggerValue)) & 0x1F);
			return new DebuggerValue(Double.valueOf(n1 >>> n2));
		}
		case ABCConstants.OP_lessthan: {
			// ECMA 11.8.1
			flash.tools.debugger.Value lessThan = ECMA.lessThan(session,
					eeContext.toValue(lhs.debuggerValue),
					eeContext.toValue(rhs.debuggerValue));
			boolean result;
			if (lessThan.getType() == VariableType.UNDEFINED) {
				result = false;
			} else {
				result = ECMA.toBoolean(lessThan);
			}
			return new DebuggerValue(result);
		}
		case ABCConstants.OP_greaterthan: {
			// ECMA 11.8.2
			flash.tools.debugger.Value greaterThan = ECMA.lessThan(session,
					eeContext.toValue(rhs.debuggerValue),
					eeContext.toValue(lhs.debuggerValue));
			boolean result;
			if (greaterThan.getType() == VariableType.UNDEFINED) {
				result = false;
			} else {
				result = ECMA.toBoolean(greaterThan);
			}
			return new DebuggerValue(result);
		}
		case ABCConstants.OP_lessequals: {
			// ECMA 11.8.3
			flash.tools.debugger.Value lessThan = ECMA.lessThan(session,
					eeContext.toValue(rhs.debuggerValue),
					eeContext.toValue(lhs.debuggerValue));
			boolean result;
			if (lessThan.getType() == VariableType.UNDEFINED) {
				result = false;
			} else {
				result = !ECMA.toBoolean(lessThan);
			}
			return new DebuggerValue(result);
		}
		case ABCConstants.OP_greaterequals: {
			// ECMA 11.8.4
			flash.tools.debugger.Value lessThan = ECMA.lessThan(session,
					eeContext.toValue(lhs.debuggerValue),
					eeContext.toValue(rhs.debuggerValue));
			boolean result;
			if (lessThan.getType() == VariableType.UNDEFINED) {
				result = false;
			} else {
				result = !ECMA.toBoolean(lessThan);
			}
			return new DebuggerValue(result);
		}
		case ABCConstants.OP_instanceof: {
			try {
				return new DebuggerValue(session.getWorkerSession(
						eeContext.getIsolateId()).evalInstanceof(
						eeContext.toValue(lhs.debuggerValue),
						eeContext.toValue(rhs.debuggerValue)));
			} catch (PlayerDebugException e) {
				throw new ExpressionEvaluatorException(e);
			} catch (PlayerFaultException e) {
				throw new ExpressionEvaluatorException(e);
			}
		}
		case ABCConstants.OP_in: {
			try {
				return new DebuggerValue(session.getWorkerSession(
						eeContext.getIsolateId()).evalIn(
						eeContext.toValue(lhs.debuggerValue),
						eeContext.toValue(rhs.debuggerValue)));
			} catch (PlayerDebugException e) {
				throw new ExpressionEvaluatorException(e);
			} catch (PlayerFaultException e) {
				throw new ExpressionEvaluatorException(e);
			}
		}
		case ABCConstants.OP_istypelate: {
			try {
				return new DebuggerValue(session.getWorkerSession(
						eeContext.getIsolateId()).evalIs(
						eeContext.toValue(lhs.debuggerValue),
						eeContext.toValue(rhs.debuggerValue)));
			} catch (PlayerDebugException e) {
				throw new ExpressionEvaluatorException(e);
			} catch (PlayerFaultException e) {
				throw new ExpressionEvaluatorException(e);
			}
		}
		case ABCConstants.OP_astypelate: {
			try {
				return new DebuggerValue(session.getWorkerSession(
						eeContext.getIsolateId()).evalAs(
						eeContext.toValue(lhs.debuggerValue),
						eeContext.toValue(rhs.debuggerValue)));
			} catch (PlayerDebugException e) {
				throw new ExpressionEvaluatorException(e);
			} catch (PlayerFaultException e) {
				throw new ExpressionEvaluatorException(e);
			}
		}
		case ABCConstants.OP_equals: {
			// ECMA 11.9.1
			return new DebuggerValue(Boolean.valueOf(ECMA.equals(session,
					eeContext.toValue(lhs.debuggerValue),
					eeContext.toValue(rhs.debuggerValue))));
		}
		// ASC3 notequals is a sepearate reducer nequals
		// case ABCConstants.op_Tokens.NOTEQUALS_TOKEN:
		// {
		// // ECMA 11.9.2
		// return new DebuggerValue(Boolean.valueOf(!ECMA.equals(session,
		// eeContext.toValue(lhs.debuggerValue), eeContext
		// .toValue(rhs.debuggerValue))));
		// }
		case ABCConstants.OP_strictequals: {
			// ECMA 11.9.4
			return new DebuggerValue(Boolean.valueOf(ECMA.strictEquals(
					eeContext.toValue(lhs.debuggerValue),
					eeContext.toValue(rhs.debuggerValue))));
		}
		// ASC3 notequals is a sepearate reducer nequals
		/*
		 * case Tokens.STRICTNOTEQUALS_TOKEN: { // ECMA 11.9.5 return new
		 * DebuggerValue(new
		 * Boolean(!ECMA.strictEquals(eeContext.toValue(lhs.debuggerValue),
		 * eeContext .toValue(rhs.debuggerValue)))); }
		 */
		case ABCConstants.OP_bitand: {
			// ECMA 11.10
			return new DebuggerValue(Double.valueOf(ECMA.toInt32(session,
					eeContext.toValue(lhs.debuggerValue))
					& ECMA.toInt32(session,
							eeContext.toValue(rhs.debuggerValue))));
		}
		case ABCConstants.OP_bitxor: {
			// ECMA 11.10
			return new DebuggerValue(Double.valueOf(ECMA.toInt32(session,
					eeContext.toValue(lhs.debuggerValue))
					^ ECMA.toInt32(session,
							eeContext.toValue(rhs.debuggerValue))));
		}
		case ABCConstants.OP_bitor: {
			// ECMA 11.10
			return new DebuggerValue(Double.valueOf(ECMA.toInt32(session,
					eeContext.toValue(lhs.debuggerValue))
					| ECMA.toInt32(session,
							eeContext.toValue(rhs.debuggerValue))));
		}
		/*
		 * ASC3 reduce_logicalAndExpr & reduce_logicalOrExpr sepearate reducers
		 * case Tokens.LOGICALAND_TOKEN: { // ECMA 11.11
		 * flash.tools.debugger.Value result =
		 * eeContext.toValue(lhs.debuggerValue); if (ECMA.toBoolean(result)) {
		 * rhs = (DebuggerValue) node.rhs.evaluate(cx, this); result =
		 * eeContext.toValue(rhs.debuggerValue); } return new
		 * DebuggerValue(result); } case Tokens.LOGICALOR_TOKEN: { // ECMA 11.11
		 * flash.tools.debugger.Value result =
		 * eeContext.toValue(lhs.debuggerValue); if (!ECMA.toBoolean(result)) {
		 * rhs = (DebuggerValue) node.rhs.evaluate(cx, this); result =
		 * eeContext.toValue(rhs.debuggerValue); } return new
		 * DebuggerValue(result); }
		 */
		// case Tokens.EMPTY_TOKEN:
		// // do nothing, already been folded
		// return new DebuggerValue(null);
		default:
			//cx.internalError(ASTBuilder.getLocalizationManager().getLocalizedTextString("unrecognizedBinaryOperator")); //$NON-NLS-1$
			return new DebuggerValue(null);
		}
	}