コード例 #1
0
ファイル: JSAstTranslator.java プロジェクト: sonatype/WALA
 protected void doFieldWrite(
     WalkContext context, int receiver, CAstNode elt, CAstNode parent, int rval) {
   this.visit(elt, context, this);
   if (elt.getKind() == CAstNode.CONSTANT && elt.getValue() instanceof String) {
     String field = (String) elt.getValue();
     if (isPrologueScript(context) && "__proto__".equals(field)) {
       context.cfg().addInstruction(((JSInstructionFactory) insts).SetPrototype(receiver, rval));
       return;
     }
   }
   /*
     } else {
       context.currentScope().getConstantValue(field);
       SSAPutInstruction put = ((JSInstructionFactory) insts).PutInstruction(receiver, rval, field);
       try {
         assert field.equals(put.getDeclaredField().getName().toUnicodeString());
       } catch (UTFDataFormatException e) {
         Assertions.UNREACHABLE();
       }
       context.cfg().addInstruction(put);
     }
   } else {
   */
   context
       .cfg()
       .addInstruction(
           ((JSInstructionFactory) insts).PropertyWrite(receiver, context.getValue(elt), rval));
   // }
 }
コード例 #2
0
ファイル: JSAstTranslator.java プロジェクト: sonatype/WALA
  protected boolean doVisit(CAstNode n, WalkContext cntxt, CAstVisitor<WalkContext> visitor) {
    WalkContext context = (WalkContext) cntxt;
    switch (n.getKind()) {
      case CAstNode.TYPE_OF:
        {
          int result = context.currentScope().allocateTempValue();

          this.visit(n.getChild(0), context, this);
          int ref = context.getValue(n.getChild(0));

          context
              .cfg()
              .addInstruction(((JSInstructionFactory) insts).TypeOfInstruction(result, ref));

          context.setValue(n, result);
          return true;
        }

      case JavaScriptCAstNode.ENTER_WITH:
      case JavaScriptCAstNode.EXIT_WITH:
        {
          this.visit(n.getChild(0), context, this);
          int ref = context.getValue(n.getChild(0));

          context
              .cfg()
              .addInstruction(
                  ((JSInstructionFactory) insts)
                      .WithRegion(ref, n.getKind() == JavaScriptCAstNode.ENTER_WITH));

          return true;
        }
      default:
        {
          return false;
        }
    }
  }
コード例 #3
0
ファイル: JSAstTranslator.java プロジェクト: sonatype/WALA
  protected void doFieldRead(
      WalkContext context, int result, int receiver, CAstNode elt, CAstNode readNode) {
    this.visit(elt, context, this);
    int x = context.currentScope().allocateTempValue();

    context.cfg().addInstruction(((JSInstructionFactory) insts).AssignInstruction(x, receiver));

    context.cfg().addInstruction(((JSInstructionFactory) insts).PrototypeLookup(x, x));

    if (elt.getKind() == CAstNode.CONSTANT && elt.getValue() instanceof String) {
      String field = (String) elt.getValue();
      // symtab needs to have this value
      context.currentScope().getConstantValue(field);
      context.cfg().addInstruction(((JSInstructionFactory) insts).GetInstruction(result, x, field));
    } else {
      context
          .cfg()
          .addInstruction(
              ((JSInstructionFactory) insts).PropertyRead(result, x, context.getValue(elt)));
    }

    // generate code to handle read of non-existent property
    if (context.getControlFlow().getMappedNodes().contains(readNode)) {
      context.cfg().addPreNode(readNode, context.getUnwindState());

      context.cfg().newBlock(true);

      if (context.getControlFlow().getTarget(readNode, JavaScriptTypes.TypeError) != null)
        context
            .cfg()
            .addPreEdge(
                readNode,
                context.getControlFlow().getTarget(readNode, JavaScriptTypes.TypeError),
                true);
      else context.cfg().addPreEdgeToExit(readNode, true);
    }
  }
コード例 #4
0
ファイル: JSAstTranslator.java プロジェクト: sonatype/WALA
  protected void doIsFieldDefined(WalkContext context, int result, int ref, CAstNode f) {
    if (f.getKind() == CAstNode.CONSTANT && f.getValue() instanceof String) {
      String field = (String) f.getValue();

      FieldReference fieldRef =
          FieldReference.findOrCreate(
              JavaScriptTypes.Root,
              Atom.findOrCreateUnicodeAtom((String) field),
              JavaScriptTypes.Root);

      context
          .cfg()
          .addInstruction(
              ((JSInstructionFactory) insts).IsDefinedInstruction(result, ref, fieldRef));

    } else {

      context
          .cfg()
          .addInstruction(
              ((JSInstructionFactory) insts)
                  .IsDefinedInstruction(result, ref, context.getValue(f)));
    }
  }
コード例 #5
0
  @Override
  protected CAstNode copyNodes(
      CAstNode root,
      final CAstControlFlowMap cfg,
      RewriteContext context,
      Map<Pair<CAstNode, ExpanderKey>, CAstNode> nodeMap) {
    int kind = root.getKind();

    if (kind == CAstNode.OBJECT_REF && context.inRead()) {
      // if we see a property access (OBJECT_REF) in a read context, transform
      // to a loop traversing the prototype chain
      CAstNode readLoop;
      CAstNode receiver = copyNodes(root.getChild(0), cfg, READ, nodeMap);
      CAstNode element = copyNodes(root.getChild(1), cfg, READ, nodeMap);
      if (element.getKind() == CAstNode.CONSTANT && element.getValue() instanceof String) {
        readLoop = makeConstRead(root, receiver, element, context, nodeMap);
      } else {
        readLoop = makeVarRead(root, receiver, element, context, nodeMap);
      }
      return readLoop;

    } else if (kind == CAstNode.ASSIGN_PRE_OP || kind == CAstNode.ASSIGN_POST_OP) {
      // handle cases like x.f++, represented as ASSIGN_POST_OP(x.f,1,+)
      AssignPreOrPostOpContext ctxt = new AssignPreOrPostOpContext();
      // generate loop for the first child (x.f for example), keeping the loop var and element var
      // in ctxt
      CAstNode lval = copyNodes(root.getChild(0), cfg, ctxt, nodeMap);
      CAstNode rval = copyNodes(root.getChild(1), cfg, READ, nodeMap);
      CAstNode op = copyNodes(root.getChild(2), cfg, READ, nodeMap);
      if (ctxt.receiverTemp != null) { // if we found a nested property access
        String temp1 = TEMP_NAME + (readTempCounter++);
        String temp2 = TEMP_NAME + (readTempCounter++);
        CAstNode copy =
            Ast.makeNode(
                CAstNode.BLOCK_EXPR,
                // assign lval to temp1 (where lval is a block that includes the prototype chain
                // loop)
                Ast.makeNode(
                    CAstNode.DECL_STMT,
                    Ast.makeConstant(new InternalCAstSymbol(temp1, true, false)),
                    lval),
                // ? --MS
                // rval,
                // assign temp2 the new value to be assigned
                Ast.makeNode(
                    CAstNode.DECL_STMT,
                    Ast.makeConstant(new InternalCAstSymbol(temp2, true, false)),
                    Ast.makeNode(
                        CAstNode.BINARY_EXPR,
                        op,
                        Ast.makeNode(CAstNode.VAR, Ast.makeConstant(temp1)),
                        rval)),
                // write temp2 into the property
                Ast.makeNode(
                    CAstNode.ASSIGN,
                    Ast.makeNode(CAstNode.OBJECT_REF, ctxt.receiverTemp, ctxt.elementTemp),
                    Ast.makeNode(CAstNode.VAR, Ast.makeConstant(temp2))),
                // final value depends on whether we had a pre op or post op
                Ast.makeNode(
                    CAstNode.VAR,
                    Ast.makeConstant((kind == CAstNode.ASSIGN_PRE_OP) ? temp2 : temp1)));
        nodeMap.put(Pair.make(root, context.key()), copy);
        return copy;
      } else {
        CAstNode copy = Ast.makeNode(kind, lval, rval, op);
        nodeMap.put(Pair.make(root, context.key()), copy);
        return copy;
      }

    } else if (kind == CAstNode.ASSIGN) {
      // use ASSIGN context for LHS so we don't translate property accesses there
      CAstNode copy =
          Ast.makeNode(
              CAstNode.ASSIGN,
              copyNodes(root.getChild(0), cfg, ASSIGN, nodeMap),
              copyNodes(root.getChild(1), cfg, READ, nodeMap));
      nodeMap.put(Pair.make(root, context.key()), copy);
      return copy;

    } else if (kind == CAstNode.BLOCK_EXPR) {
      CAstNode children[] = new CAstNode[root.getChildCount()];
      int last = (children.length - 1);
      for (int i = 0; i < last; i++) {
        children[i] = copyNodes(root.getChild(i), cfg, READ, nodeMap);
      }
      children[last] = copyNodes(root.getChild(last), cfg, context, nodeMap);

      CAstNode copy = Ast.makeNode(CAstNode.BLOCK_EXPR, children);
      nodeMap.put(Pair.make(root, context.key()), copy);
      return copy;

    } else if (root.getKind() == CAstNode.CONSTANT) {
      CAstNode copy = Ast.makeConstant(root.getValue());
      nodeMap.put(Pair.make(root, context.key()), copy);
      return copy;

    } else if (root.getKind() == CAstNode.OPERATOR) {
      nodeMap.put(Pair.make(root, context.key()), root);
      return root;

    } else {
      CAstNode children[] = new CAstNode[root.getChildCount()];
      for (int i = 0; i < children.length; i++) {
        children[i] = copyNodes(root.getChild(i), cfg, READ, nodeMap);
      }
      for (Object label : cfg.getTargetLabels(root)) {
        if (label instanceof CAstNode) {
          copyNodes((CAstNode) label, cfg, READ, nodeMap);
        }
      }
      CAstNode copy = Ast.makeNode(kind, children);
      nodeMap.put(Pair.make(root, context.key()), copy);
      return copy;
    }
  }