/****************************************************************************** * Copyright (c) 2009 - 2015 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *****************************************************************************/ package com.ibm.wala.memsat.frontEnd.types; import java.util.Iterator; import com.ibm.wala.cast.js.types.JavaScriptTypes; import com.ibm.wala.ipa.callgraph.CGNode; import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey; import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; import com.ibm.wala.ipa.callgraph.propagation.PointerKey; import com.ibm.wala.memsat.frontEnd.IRType; import com.ibm.wala.ssa.IR; import com.ibm.wala.ssa.SymbolTable; import com.ibm.wala.types.TypeReference; import com.ibm.wala.util.intset.OrdinalSet; class MiniaturJavaScriptTypeData implements MiniaturTypeData { private final CGNode node; private final PointerAnalysis<InstanceKey> PA; MiniaturJavaScriptTypeData(CGNode node, PointerAnalysis<InstanceKey> PA) { this.node = node; this.PA = PA; } public String toString() { StringBuffer buf = new StringBuffer("types for " + node + "\n"); IR ir = node.getIR(); SymbolTable st = ir.getSymbolTable(); for(int vn = 1; vn <= st.getMaxValueNumber(); vn++) { if (st.isNullConstant(vn)) { buf.append(vn + " --> <null constant>\n"); } PointerKey pk = new LocalPointerKey(node, vn); OrdinalSet<? extends InstanceKey> types = PA.getPointsToSet( pk ); buf.append(vn + " --> " + types + "\n"); } return buf.toString(); } private boolean isTypeValue(int valueNumber, TypeReference type) { IR ir = node.getIR(); if (ir.getSymbolTable().isNullConstant(valueNumber)) { return false; } PointerKey pk = new LocalPointerKey(node, valueNumber); OrdinalSet<? extends InstanceKey> types = PA.getPointsToSet( pk ); if (types.isEmpty()) { assert !types.isEmpty() : "no types for " + valueNumber + " of " + node; } boolean result = true; for(Iterator<? extends InstanceKey> ts = types.iterator(); ts.hasNext(); ) { InstanceKey t = ts.next(); if (! t.getConcreteType().getReference().equals(type)) { result = false; } } return result; } public IRType typeOf(int valueNumber) { if (isTypeValue(valueNumber, JavaScriptTypes.Boolean)) { return IRType.BOOLEAN; } else if (isTypeValue(valueNumber, JavaScriptTypes.Number)) { // TODO: need to distinguish real/integer somehow return IRType.INTEGER; } else { return IRType.OBJECT; } } }