/* * Copyright 2010 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.dev.js; import com.google.gwt.core.ext.BadPropertyValueException; import com.google.gwt.core.ext.PropertyOracle; import com.google.gwt.core.ext.SelectionProperty; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.dev.jjs.SourceInfo; import com.google.gwt.dev.js.ast.JsBinaryOperation; import com.google.gwt.dev.js.ast.JsBinaryOperator; import com.google.gwt.dev.js.ast.JsContext; import com.google.gwt.dev.js.ast.JsExpression; import com.google.gwt.dev.js.ast.JsModVisitor; import com.google.gwt.dev.js.ast.JsPrefixOperation; import com.google.gwt.dev.js.ast.JsProgram; import com.google.gwt.dev.js.ast.JsUnaryOperator; /** * Coerces lhs of right shift operations to int. Necessary for Safari 5 bug * https://bugs.webkit.org/show_bug.cgi?id=40367 fixed in * http://trac.webkit.org/changeset/60990 -- this should be removed once that * fix has been pushed. */ public class JsCoerceIntShift { // TODO(jat): remove this once Safari 5 has the update /** * Rewrite a >> b as (~~a) >> b. */ private static class MyVisitor extends JsModVisitor { @Override public void endVisit(JsBinaryOperation x, JsContext ctx) { JsBinaryOperator op = x.getOperator(); if (op != JsBinaryOperator.SHR && op != JsBinaryOperator.SHRU) { return; } SourceInfo sourceInfo = x.getSourceInfo(); JsExpression lhs = x.getArg1(); JsExpression rhs = x.getArg2(); JsExpression newNode = new JsBinaryOperation(sourceInfo, op, new JsPrefixOperation(sourceInfo, JsUnaryOperator.BIT_NOT, new JsPrefixOperation(sourceInfo, JsUnaryOperator.BIT_NOT, lhs)), rhs); ctx.replaceMe(newNode); } } /** * If this permutation may be executed on WebKit, rewrite a >> b as ~~a >> b. * * @param program * @param logger * @param propertyOracles * @return true if any changes were made */ public static boolean exec(JsProgram program, TreeLogger logger, PropertyOracle[] propertyOracles) { boolean seenWebKit = false; for (PropertyOracle oracle : propertyOracles) { try { SelectionProperty prop = oracle.getSelectionProperty(logger, "user.agent"); // TODO(jat): more checks if we split up the safari permutation if ("safari".equals(prop.getCurrentValue())) { seenWebKit = true; break; } } catch (BadPropertyValueException e) { // if we couldn't get the property, assume this might be used on WebKit. seenWebKit = true; break; } } if (!seenWebKit) { return false; } MyVisitor v = new MyVisitor(); v.accept(program); return v.didChange(); } }