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); } }
protected void doCall( WalkContext context, CAstNode call, int result, int exception, CAstNode name, int receiver, int[] arguments) { MethodReference ref = name.getValue().equals("ctor") ? JavaScriptMethods.ctorReference : name.getValue().equals("dispatch") ? JavaScriptMethods.dispatchReference : AstMethodReference.fnReference(JavaScriptTypes.CodeBody); context .cfg() .addInstruction( ((JSInstructionFactory) insts) .Invoke( receiver, result, arguments, exception, new JSCallSiteReference(ref, context.cfg().getCurrentInstruction()))); context.cfg().addPreNode(call, context.getUnwindState()); // this new block is for the normal termination case context.cfg().newBlock(true); // exceptional case: flow to target given in CAst, or if null, the exit node if (context.getControlFlow().getTarget(call, null) != null) context.cfg().addPreEdge(call, context.getControlFlow().getTarget(call, null), true); else context.cfg().addPreEdgeToExit(call, true); }