/** 11.13 and 7.8 assignment with literal. */ @Override public void visit(ConstantNode n, State state) { Value v; switch (n.getType()) { case NULL: v = Value.makeNull(); break; case UNDEFINED: v = Value.makeUndef(); break; case BOOLEAN: v = Value.makeBool(n.getBoolean()); break; case NUMBER: v = Value.makeNum(n.getNumber()); break; case STRING: v = Value.makeStr(n.getString()); break; default: throw new AnalysisException(); } if (n.getResultRegister() != AbstractNode.NO_VALUE) state.writeRegister(n.getResultRegister(), v); }
/** 12.6.4 begin 'for-in' statement. */ @Override public void visit(BeginForInNode n, State state) { if (!Options.get().isForInSpecializationDisabled()) { // 1. Find properties to iterate through Value v1 = state.readRegister(n.getObjectRegister()); state.writeRegister( n.getObjectRegister(), v1.makeExtendedScope()); // preserve the register value v1 = UnknownValueResolver.getRealValue(v1, state); Set<ObjectLabel> objs = Conversion.toObjectLabels(state, n, v1, c); State.Properties p = state.getEnumProperties(objs); Collection<Value> propertyNameValues = newList(p.toValues()); // Add the no-iteration case propertyNameValues.add(Value.makeNull().makeExtendedScope()); // 2. Make specialized context for each iteration int it = n.getPropertyListRegister(); // List<Context> specialized_contexts = newList(); BasicBlock successor = n.getBlock().getSingleSuccessor(); for (Value k : propertyNameValues) { m.visitPropertyRead(n, objs, k, state, true); if (!c.isScanning()) { // 2.1 Make specialized context State specialized_state = state.clone(); specialized_state.writeRegister(it, k); Context specialized_context = c.getAnalysis() .getContextSensitivityStrategy() .makeForInEntryContext(state.getContext(), n, k); // specialized_contexts.add(specialized_context); specialized_state.setContext(specialized_context); specialized_state.setBasicBlock(successor); // 2.2 Propagate specialized context c.propagateToFunctionEntry( n, state.getContext(), specialized_state, specialized_context, successor); } } if (!c.isScanning()) { // TODO: could kill flow to specializations if covered by other context // List<Context> previousSpecializations = c.getAnalysis().getForInSpecializations(n, // s.getContext()); // if (previousSpecializations != null && (p.isArray() || p.isNonArray())) { // previousSpecializations.forEach(c -> { // // covered.setToNone(); // }); // } // TODO: could kill null flow unless all iterations has reached at least one EndForInNode } state.setToNone(); } else { // fall back to simple mode without context specialization Value v1 = state.readRegister(n.getObjectRegister()); state.writeRegister( n.getObjectRegister(), v1.makeExtendedScope()); // preserve the register value v1 = UnknownValueResolver.getRealValue(v1, state); Set<ObjectLabel> objs = Conversion.toObjectLabels(state, n, v1, c); Properties p = state.getEnumProperties(objs); Value proplist = p.toValue().joinNull(); m.visitPropertyRead(n, objs, proplist, state, true); state.writeRegister(n.getPropertyListRegister(), proplist); } }