Started to update the closure extractor to work with Rhino 1.7.3.

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4438 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
msridhar1 2012-02-08 15:32:15 +00:00
parent 1e0ad9dbc6
commit 174a30454c
2 changed files with 43 additions and 13 deletions

View File

@ -172,6 +172,8 @@ import com.ibm.wala.util.debug.UnimplementedError;
* *
*/ */
public class ClosureExtractor extends CAstRewriterExt { public class ClosureExtractor extends CAstRewriterExt {
private static final boolean RHINO_1_7_2 = false;
private LinkedList<ExtractionPolicy> policies = new LinkedList<ExtractionPolicy>(); private LinkedList<ExtractionPolicy> policies = new LinkedList<ExtractionPolicy>();
private final ExtractionPolicyFactory policyFactory; private final ExtractionPolicyFactory policyFactory;
@ -388,6 +390,8 @@ public class ClosureExtractor extends CAstRewriterExt {
} }
private int anonymous_counter = 0; private int anonymous_counter = 0;
@SuppressWarnings("unused")
private List<CAstNode> extractRegion(CAstNode root, CAstControlFlowMap cfg, ExtractionPos context, Map<Pair<CAstNode, NoKey>, CAstNode> nodeMap) { private List<CAstNode> extractRegion(CAstNode root, CAstControlFlowMap cfg, ExtractionPos context, Map<Pair<CAstNode, NoKey>, CAstNode> nodeMap) {
CAstEntity entity = getCurrentEntity(); CAstEntity entity = getCurrentEntity();
@ -412,26 +416,28 @@ public class ClosureExtractor extends CAstRewriterExt {
*/ */
ArrayList<CAstNode> prologue = new ArrayList<CAstNode>(); ArrayList<CAstNode> prologue = new ArrayList<CAstNode>();
ArrayList<CAstNode> fun_body_stmts = new ArrayList<CAstNode>(); ArrayList<CAstNode> fun_body_stmts = new ArrayList<CAstNode>();
if(RHINO_1_7_2) {
CAstNode self_ref = makeVarRef(name); CAstNode self_ref = makeVarRef(name);
CAstNode self_assign = Ast.makeNode(ASSIGN, self_ref, makeVarRef(name)); CAstNode self_assign = Ast.makeNode(ASSIGN, self_ref, makeVarRef(name));
addFlow(self_ref, JavaScriptTypes.ReferenceError, CAstControlFlowMap.EXCEPTION_TO_EXIT, entity.getControlFlow()); addFlow(self_ref, JavaScriptTypes.ReferenceError, CAstControlFlowMap.EXCEPTION_TO_EXIT, entity.getControlFlow());
fun_body_stmts.add(self_assign); fun_body_stmts.add(self_assign);
}
// if we are extracting a block, unwrap it // if we are extracting a block, unwrap it
if(extractingBlock) { if(extractingBlock) {
CAstNode block = root.getChild(context.getStart()); CAstNode block = root.getChild(context.getStart());
for(int i=0;i<block.getChildCount();++i) for(int i=0;i<block.getChildCount();++i)
fun_body_stmts.add(block.getChild(i)); fun_body_stmts.add(block.getChild(i));
if(mayCompleteNormally(block)) if(RHINO_1_7_2 && mayCompleteNormally(block))
fun_body_stmts.add(markSynthetic(Ast.makeNode(RETURN))); fun_body_stmts.add(markSynthetic(Ast.makeNode(RETURN)));
} else { } else {
if(context.getRegion() instanceof TwoLevelExtractionRegion) { if(context.getRegion() instanceof TwoLevelExtractionRegion) {
CAstNode start = root.getChild(context.getStart()); CAstNode start = root.getChild(context.getStart());
TwoLevelExtractionRegion tler = (TwoLevelExtractionRegion)context.getRegion(); TwoLevelExtractionRegion tler = (TwoLevelExtractionRegion)context.getRegion();
if(start.getKind() != CAstNode.BLOCK_EXPR)
throw new IllegalArgumentException("Invalid two-level extraction region.");
if(tler.getEndInner() != -1) if(tler.getEndInner() != -1)
throw new UnimplementedError("Two-level extraction not fully implemented."); throw new UnimplementedError("Two-level extraction not fully implemented.");
if(start.getKind() != CAstNode.BLOCK_EXPR)
throw new IllegalArgumentException("Invalid two-level extraction region.");
int i; int i;
for(i=0;i<tler.getStartInner();++i) for(i=0;i<tler.getStartInner();++i)
prologue.add(copyNodes(start.getChild(i), cfg, context, nodeMap)); prologue.add(copyNodes(start.getChild(i), cfg, context, nodeMap));
@ -449,11 +455,11 @@ public class ClosureExtractor extends CAstRewriterExt {
fun_body_stmts.add(root.getChild(context.getStart())); fun_body_stmts.add(root.getChild(context.getStart()));
} }
} }
if(mayCompleteNormally(root.getChild(context.getEnd()-1))) if(RHINO_1_7_2 && mayCompleteNormally(root.getChild(context.getEnd()-1)))
fun_body_stmts.add(markSynthetic(Ast.makeNode(RETURN))); fun_body_stmts.add(markSynthetic(Ast.makeNode(RETURN)));
} }
CAstNode inner_block = Ast.makeNode(BLOCK_STMT, fun_body_stmts.toArray(new CAstNode[0])); CAstNode inner_block = Ast.makeNode(BLOCK_STMT, fun_body_stmts.toArray(new CAstNode[0]));
CAstNode fun_body = Ast.makeNode(BLOCK_STMT, inner_block); CAstNode fun_body = RHINO_1_7_2 ? Ast.makeNode(BLOCK_STMT, inner_block) : inner_block;
/* /*
* Now we rewrite the body and construct a Rewrite object. * Now we rewrite the body and construct a Rewrite object.

View File

@ -13,7 +13,9 @@ package com.ibm.wala.cast.js.ipa.callgraph.correlations.extraction;
import static com.ibm.wala.cast.tree.CAstNode.ASSIGN; import static com.ibm.wala.cast.tree.CAstNode.ASSIGN;
import static com.ibm.wala.cast.tree.CAstNode.BLOCK_STMT; import static com.ibm.wala.cast.tree.CAstNode.BLOCK_STMT;
import static com.ibm.wala.cast.tree.CAstNode.DECL_STMT;
import static com.ibm.wala.cast.tree.CAstNode.EACH_ELEMENT_GET; import static com.ibm.wala.cast.tree.CAstNode.EACH_ELEMENT_GET;
import static com.ibm.wala.cast.tree.CAstNode.LABEL_STMT;
import static com.ibm.wala.cast.tree.CAstNode.VAR; import static com.ibm.wala.cast.tree.CAstNode.VAR;
import java.util.Collections; import java.util.Collections;
@ -21,7 +23,11 @@ import java.util.List;
import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.CAstNode; import com.ibm.wala.cast.tree.CAstNode;
import com.ibm.wala.cast.tree.pattern.*; import com.ibm.wala.cast.tree.pattern.Alt;
import com.ibm.wala.cast.tree.pattern.AnyNode;
import com.ibm.wala.cast.tree.pattern.NodeOfKind;
import com.ibm.wala.cast.tree.pattern.SomeConstant;
import com.ibm.wala.cast.tree.pattern.SubtreeOfKind;
/** /**
* A policy telling a {@link ClosureExtractor} to extract the body of every for-in loop. * A policy telling a {@link ClosureExtractor} to extract the body of every for-in loop.
@ -47,7 +53,27 @@ public class ForInBodyExtractionPolicy extends ExtractionPolicy {
@Override @Override
public List<ExtractionRegion> extract(CAstNode node) { public List<ExtractionRegion> extract(CAstNode node) {
SomeConstant loopVar = new SomeConstant(); SomeConstant loopVar = new SomeConstant();
/* matches the following pattern:
/*
* matches Rhino 1.7.3 encoding of for-in loop bodies:
*
* BLOCK_STMT
* decl/assign of loop variable
* <loopBody>
*/
if(new NodeOfKind(BLOCK_STMT,
new Alt(new NodeOfKind(DECL_STMT,
loopVar,
new SubtreeOfKind(EACH_ELEMENT_GET)),
new NodeOfKind(ASSIGN,
new NodeOfKind(VAR, loopVar),
new SubtreeOfKind(EACH_ELEMENT_GET))),
new AnyNode(),
new SubtreeOfKind(LABEL_STMT)).matches(node)) {
return Collections.singletonList(new ExtractionRegion(1, 2, Collections.singletonList((String)loopVar.getLastMatch())));
}
/* matches Rhino < 1.7.3 encoding of for-in loop bodies:
* *
* BLOCK_STMT * BLOCK_STMT
* ASSIGN * ASSIGN
@ -55,8 +81,6 @@ public class ForInBodyExtractionPolicy extends ExtractionPolicy {
* EACH_ELEMENT_GET * EACH_ELEMENT_GET
* VAR <forin_tmp> * VAR <forin_tmp>
* <loopBody> * <loopBody>
*
* TODO: this is too brittle; what if future versions of Rhino encode for-in loops differently?
*/ */
if(new NodeOfKind(BLOCK_STMT, if(new NodeOfKind(BLOCK_STMT,
new NodeOfKind(ASSIGN, new NodeOfKind(ASSIGN,