/** 11.2.1 assignment with left-hand-side property accessor. */ @Override public void visit(WritePropertyNode n, State state) { // get the base value, coerce with ToObject Value baseval = state.readRegister(n.getBaseRegister()); baseval = UnknownValueResolver.getRealValue(baseval, state); m.visitPropertyAccess(n, baseval); Set<ObjectLabel> objlabels = Conversion.toObjectLabels(state, n, baseval, c); if (objlabels.isEmpty() && !Options.get().isPropagateDeadFlow()) { state.setToNone(); return; } state.writeRegister( n.getBaseRegister(), Value.makeObject(objlabels)); // if null/undefined, an exception would have been thrown via // toObjectLabels // get the property name value, separate the undefined/null/NaN components, coerce with ToString Value propertyval; int propertyreg; if (n.isPropertyFixed()) { propertyreg = AbstractNode.NO_VALUE; propertyval = Value.makeStr(n.getPropertyString()); } else { propertyreg = n.getPropertyRegister(); propertyval = state.readRegister(propertyreg); propertyval = UnknownValueResolver.getRealValue(propertyval, state); } boolean maybe_undef = propertyval.isMaybeUndef(); boolean maybe_null = propertyval.isMaybeNull(); boolean maybe_nan = propertyval.isMaybeNaN(); propertyval = propertyval.restrictToNotNullNotUndef().restrictToNotNaN(); Str propertystr = Conversion.toString(propertyval, propertyreg, c); // get the value to be written Value v = state.readRegister(n.getValueRegister()); NativeFunctions.updateArrayLength(n, state, objlabels, propertystr, v, n.getValueRegister(), c); // write the object property value, as fixed property name or unknown property name, and // separately for "undefined"/"null"/"NaN" state.writeProperty(objlabels, propertystr, v, true, maybe_undef || maybe_null || maybe_nan); if (maybe_undef && !propertystr.isMaybeStr("undefined")) state.writeProperty( objlabels, Value.makeTemporaryStr("undefined"), v, true, !propertystr.isNotStr()); if (maybe_null && !propertystr.isMaybeStr("null")) state.writeProperty( objlabels, Value.makeTemporaryStr("null"), v, true, !propertystr.isNotStr()); if (maybe_nan && !propertystr.isMaybeStr("NaN")) state.writeProperty( objlabels, Value.makeTemporaryStr("NaN"), v, true, !propertystr.isNotStr()); m.visitPropertyWrite(n, objlabels, propertystr); // TODO: more monitoring around here? if (Options.get().isEvalStatistics() && propertystr.getStr() != null && propertystr.getStr().equals("innerHTML")) { m.visitInnerHTMLWrite(n, v); } m.visitVariableOrProperty( n.getPropertyString(), n.getSourceLocation(), v, state.getContext(), state); }
/** 11.13 and 11.1.2 assignment with left-hand-side identifier reference. */ @Override public void visit(WriteVariableNode n, State state) { Value v = state.readRegister(n.getValueRegister()); m.visitWriteVariable(n, v, state); Set<ObjectLabel> objs = state.writeVariable(n.getVariableName(), v, true); Function f = n.getBlock().getFunction(); if (f.getParameterNames().contains(n.getVariableName())) { // TODO: review ObjectLabel arguments_obj = new ObjectLabel(f.getEntry().getFirstNode(), Kind.ARGUMENTS); state.writeProperty( arguments_obj, Integer.toString(f.getParameterNames().indexOf(n.getVariableName())), v); } m.visitPropertyWrite(n, objs, Value.makeTemporaryStr(n.getVariableName())); m.visitVariableOrProperty( n.getVariableName(), n.getSourceLocation(), v, state.getContext(), state); }