/** * Converts the given value to the given NativeObject (optionally following the prototype chains). * * @param nativeObject target NativeObject * @param value Value to convert * @param prototype use the prototype chain? */ public static Value toNativeObject( HostObject nativeObject, Value value, boolean prototype, Solver.SolverInterface solverInterface) { State state = solverInterface.getState(); boolean bad = false; Set<ObjectLabel> matches = Collections.newSet(); if (prototype) { // Make lookup using prototype chains Set<ObjectLabel> objectLabels = Collections.newSet(value.getObjectLabels()); Set<ObjectLabel> visited = Collections.newSet(); while (!objectLabels.isEmpty()) { Set<ObjectLabel> temp = Collections.newSet(); for (ObjectLabel objectLabel : objectLabels) { if (!visited.contains(objectLabel)) { visited.add(objectLabel); Value prototypeValue = state.readInternalPrototype(java.util.Collections.singleton(objectLabel)); prototypeValue = UnknownValueResolver.getRealValue(prototypeValue, state); // FIXME: Needs code review. Looks fishy to compare objects with toString(). String nativeObjectPrototype = nativeObject.toString(); String objectLabelPrototype = ""; if (objectLabel.getHostObject() != null) { objectLabelPrototype = objectLabel.getHostObject().toString(); } if (nativeObject == objectLabel.getHostObject() || nativeObjectPrototype.equals(objectLabelPrototype)) { matches.add(objectLabel); } else if (prototypeValue.getObjectLabels().isEmpty()) { bad = true; } else { temp.addAll(prototypeValue.getObjectLabels()); } } } objectLabels = temp; } } else { // Make lookup ignoring prototype chains // TODO: Verify this for (ObjectLabel objectLabel : value.getObjectLabels()) { if (objectLabel.getHostObject() == nativeObject || (objectLabel.getHostObject() != null && objectLabel.getHostObject().toString().equals(nativeObject + ".prototype"))) { matches.add(objectLabel); } else { bad = true; } } } // Message.Status status; // if (good && bad) { // status = Message.Status.MAYBE; // } else if (!good && bad) { // status = Message.Status.CERTAIN; // } else if (good && !bad) { // status = Message.Status.NONE; // } else if (!good && !bad) { // equivalent to Value of Undef / a null argument // // Considered a certain type error. // status = Message.Status.CERTAIN; // } else { // throw new AnalysisException("toNativeObject: fell through cases - should not // happen."); // } if (bad) { String message = "TypeError, argument is not of expected type: " + nativeObject; solverInterface .getMonitoring() .addMessage(solverInterface.getNode(), Message.Severity.HIGH, message); } return Value.makeObject(matches); }
/** End of loop. */ @Override public void visit(EndLoopNode n, State state) { // TODO: do nothing if loop unrolling is disabled or in scanning mode // branch condition is determinate, switch context and propagate only to generalized successor Context generalizedContext = c.getAnalysis().getContextSensitivityStrategy().makeLoopExitContext(state.getContext(), n); BasicBlock successor = state.getBasicBlock().getSingleSuccessor(); State specializedState = state.clone(); specializedState.setContext(generalizedContext); specializedState.setBasicBlock(successor); c.propagateToBasicBlock(specializedState, successor, generalizedContext); state.setToNone(); }
/** 11.1.2 assignment with right-hand-side identifier reference. */ @Override public void visit(ReadVariableNode n, State state) { String varname = n.getVariableName(); Value v; if (varname.equals("this")) { // 11.1.1 read 'this' from the execution context v = state.readThis(); m.visitReadThis(n, v, state, InitialStateBuilder.GLOBAL); } else { // ordinary variable int result_base_reg = n.getResultBaseRegister(); Set<ObjectLabel> base_objs = null; if (c.isScanning() || result_base_reg != AbstractNode.NO_VALUE) base_objs = newSet(); v = state.readVariable(varname, base_objs); m.visitPropertyRead(n, base_objs, Value.makeTemporaryStr(varname), state, true); m.visitVariableAsRead(n, v, state); m.visitVariableOrProperty(varname, n.getSourceLocation(), v, state.getContext(), state); m.visitReadNonThisVariable(n, v); if (v.isMaybeAbsent()) Exceptions.throwReferenceError(state, c); if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) { state.setToNone(); return; } if (result_base_reg != AbstractNode.NO_VALUE) state.writeRegister(result_base_reg, Value.makeObject(base_objs)); // see 10.1.4 m.visitRead(n, v, state); m.visitReadVariable(n, v, state); // TODO: combine some of these m.visitXYZ methods? } if (v.isNotPresent() && !Options.get().isPropagateDeadFlow()) { state.setToNone(); return; } if (n.getResultRegister() != AbstractNode.NO_VALUE) state.writeRegister(n.getResultRegister(), v.restrictToNotAbsent()); }
public static void build(Solver.SolverInterface c) { State s = c.getState(); PropVarOperations pv = c.getAnalysis().getPropVarOperations(); CONSTRUCTOR = new ObjectLabel(DOMObjects.HTMLBODYELEMENT_CONSTRUCTOR, ObjectLabel.Kind.FUNCTION); PROTOTYPE = new ObjectLabel(DOMObjects.HTMLBODYELEMENT_PROTOTYPE, ObjectLabel.Kind.OBJECT); INSTANCES = new ObjectLabel(DOMObjects.HTMLBODYELEMENT_INSTANCES, ObjectLabel.Kind.OBJECT); // Constructor Object s.newObject(CONSTRUCTOR); pv.writePropertyWithAttributes( CONSTRUCTOR, "length", Value.makeNum(0).setAttributes(true, true, true)); pv.writePropertyWithAttributes( CONSTRUCTOR, "prototype", Value.makeObject(PROTOTYPE).setAttributes(true, true, true)); s.writeInternalPrototype(CONSTRUCTOR, Value.makeObject(InitialStateBuilder.FUNCTION_PROTOTYPE)); pv.writeProperty(DOMWindow.WINDOW, "HTMLBodyElement", Value.makeObject(CONSTRUCTOR)); // Prototype Object s.newObject(PROTOTYPE); s.writeInternalPrototype(PROTOTYPE, Value.makeObject(HTMLElement.ELEMENT_PROTOTYPE)); // Multiplied Object s.newObject(INSTANCES); s.writeInternalPrototype(INSTANCES, Value.makeObject(PROTOTYPE)); /* * Properties. */ // DOM LEVEL 1 createDOMProperty(INSTANCES, "aLink", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "background", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "bgColor", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "link", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "text", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "vLink", Value.makeAnyStr(), c); s.multiplyObject(INSTANCES); INSTANCES = INSTANCES.makeSingleton().makeSummary(); /* * Functions. */ // No functions. createDOMProperty(HTMLDocument.INSTANCES, "body", Value.makeObject(INSTANCES), c); }
/** 12.6.4 end of loop of 'for-in' statement. */ @Override public void visit(EndForInNode n, State state) { if (!Options.get().isForInSpecializationDisabled()) { if (!c.isScanning()) { // 1. Find successor block, context and base-state BasicBlock successor = state.getBasicBlock().getSingleSuccessor(); for (Pair<NodeAndContext<Context>, Context> ncc : c.getAnalysisLatticeElement() .getCallGraph() .getSources(BlockAndContext.makeEntry(n.getBlock(), state.getContext()))) { State nonSpecializedMergeState = state.clone(); Context nonSpecializedContext = ncc.getFirst().getContext(); // 2. Use State.mergeFunctionReturn to do the merge State forInBeginState = c.getAnalysisLatticeElement() .getState( n.getBlock().getEntryBlock().getEntryPredecessorBlock(), nonSpecializedContext); State forInEntryState = c.getAnalysisLatticeElement() .getState(n.getBlock().getEntryBlock(), state.getContext()); Value returnValue = nonSpecializedMergeState.mergeFunctionReturn( forInBeginState, forInBeginState, forInEntryState, nonSpecializedMergeState.getSummarized(), nonSpecializedMergeState.readRegister(AbstractNode.RETURN_REG)); nonSpecializedMergeState.setContext(nonSpecializedContext); nonSpecializedMergeState.writeRegister(AbstractNode.RETURN_REG, returnValue); if (state.hasExceptionRegisterValue()) { nonSpecializedMergeState.writeRegister( AbstractNode.EXCEPTION_REG, state.readRegister(AbstractNode.EXCEPTION_REG)); } // 3. Propagate only to the non-specialized successor nonSpecializedMergeState.setBasicBlock(n.getBlock().getSingleSuccessor()); c.propagateToBasicBlock(nonSpecializedMergeState, successor, nonSpecializedContext); } state.setToNone(); } } }
/** 11.1.5 object initializer. */ @Override public void visit(NewObjectNode n, State state) { HeapContext heapContext = c.getAnalysis().getContextSensitivityStrategy().makeObjectLiteralHeapContext(n, state); ObjectLabel objlabel = new ObjectLabel(n, Kind.OBJECT, heapContext); state.newObject(objlabel); state.writeInternalPrototype(objlabel, Value.makeObject(InitialStateBuilder.OBJECT_PROTOTYPE)); if (n.getResultRegister() != AbstractNode.NO_VALUE) state.writeRegister(n.getResultRegister(), Value.makeObject(objlabel)); }
/** Transfer ordinary and exceptional return for the given call node and callee entry. */ public void transferReturn( AbstractNode call_node, BasicBlock callee_entry, Context caller_context, Context callee_context, Context edge_context) { if (call_node instanceof BeginForInNode) { for (EndForInNode endNode : ((BeginForInNode) call_node).getEndNodes()) { BasicBlock end_block = endNode.getBlock(); if (c.getAnalysisLatticeElement().getState(end_block, callee_context) != null) // (EndForInNode uses same context as corresponding BeginForInNode) c.addToWorklist(end_block, callee_context); } } else { // call_node is an ordinary call node Function callee = callee_entry.getFunction(); BasicBlock ordinary_exit = callee.getOrdinaryExit(); BasicBlock exceptional_exit = callee.getExceptionalExit(); State ordinary_exit_state = c.getAnalysisLatticeElement() .getState( ordinary_exit, callee_context); // (ReturnNode uses same context as corresponding function entry // node) State exceptional_exit_state = c.getAnalysisLatticeElement().getState(exceptional_exit, callee_context); NodeAndContext<Context> caller = new NodeAndContext<>(call_node, caller_context); if (ordinary_exit_state != null) { if (ordinary_exit.getFirstNode() instanceof ReturnNode) { ReturnNode returnNode = (ReturnNode) ordinary_exit.getFirstNode(); transferReturn( returnNode.getReturnValueRegister(), ordinary_exit, ordinary_exit_state.clone(), caller, edge_context); } else throw new AnalysisException("ReturnNode expected"); } if (exceptional_exit_state != null) { transferExceptionalReturn( exceptional_exit, exceptional_exit_state.clone(), caller, edge_context); } } }
/** Beginning of loop. */ @Override public void visit(BeginLoopNode n, State state) { // TODO: do nothing if loop unrolling is disabled or in scanning mode Value v = state.readRegister(n.getIfNode().getConditionRegister()); v = Conversion.toBoolean(UnknownValueResolver.getRealValue(v, state)); if (v.isMaybeTrueButNotFalse() || v.isMaybeFalseButNotTrue()) { // branch condition is determinate, switch context and propagate only to specialized successor Context specializedContext = c.getAnalysis() .getContextSensitivityStrategy() .makeNextLoopUnrollingContext(state.getContext(), n); BasicBlock successor = state.getBasicBlock().getSingleSuccessor(); State specializedState = state.clone(); specializedState.setContext(specializedContext); specializedState.setBasicBlock(successor); c.propagateToBasicBlock(specializedState, successor, specializedContext); state.setToNone(); } // otherwise, just ordinary propagation like no-op }
public static void build(Solver.SolverInterface c) { State s = c.getState(); PropVarOperations pv = c.getAnalysis().getPropVarOperations(); CONSTRUCTOR = new ObjectLabel(DOMObjects.COMMENT_CONSTRUCTOR, ObjectLabel.Kind.FUNCTION); PROTOTYPE = new ObjectLabel(DOMObjects.COMMENT_PROTOTYPE, ObjectLabel.Kind.OBJECT); INSTANCES = new ObjectLabel(DOMObjects.COMMENT_INSTANCES, ObjectLabel.Kind.OBJECT); // Constructor Object s.newObject(CONSTRUCTOR); pv.writePropertyWithAttributes( CONSTRUCTOR, "length", Value.makeNum(0).setAttributes(true, true, true)); pv.writePropertyWithAttributes( CONSTRUCTOR, "prototype", Value.makeObject(PROTOTYPE).setAttributes(true, true, true)); s.writeInternalPrototype(CONSTRUCTOR, Value.makeObject(InitialStateBuilder.OBJECT_PROTOTYPE)); pv.writeProperty(DOMWindow.WINDOW, "Comment", Value.makeObject(CONSTRUCTOR)); // Prototype object. s.newObject(PROTOTYPE); s.writeInternalPrototype(PROTOTYPE, Value.makeObject(DOMCharacterData.PROTOTYPE)); // Multiplied object. s.newObject(INSTANCES); s.writeInternalPrototype(INSTANCES, Value.makeObject(PROTOTYPE)); s.multiplyObject(INSTANCES); INSTANCES = INSTANCES.makeSingleton().makeSummary(); /* * Properties. */ // No properties. /* * Functions. */ // No functions. }
public static void build(Solver.SolverInterface c) { State s = c.getState(); PropVarOperations pv = c.getAnalysis().getPropVarOperations(); CONSTRUCTOR = new ObjectLabel(DOMObjects.HTMLOBJECTELEMENT_CONSTRUCTOR, ObjectLabel.Kind.FUNCTION); PROTOTYPE = new ObjectLabel(DOMObjects.HTMLOBJECTELEMENT_PROTOTYPE, ObjectLabel.Kind.OBJECT); INSTANCES = new ObjectLabel(DOMObjects.HTMLOBJECTELEMENT_INSTANCES, ObjectLabel.Kind.OBJECT); // Constructor Object s.newObject(CONSTRUCTOR); pv.writePropertyWithAttributes( CONSTRUCTOR, "length", Value.makeNum(0).setAttributes(true, true, true)); pv.writePropertyWithAttributes( CONSTRUCTOR, "prototype", Value.makeObject(PROTOTYPE).setAttributes(true, true, true)); s.writeInternalPrototype(CONSTRUCTOR, Value.makeObject(InitialStateBuilder.FUNCTION_PROTOTYPE)); pv.writeProperty(DOMWindow.WINDOW, "HTMLObjectElement", Value.makeObject(CONSTRUCTOR)); // Prototype Object s.newObject(PROTOTYPE); s.writeInternalPrototype(PROTOTYPE, Value.makeObject(HTMLElement.ELEMENT_PROTOTYPE)); // Multiplied Object s.newObject(INSTANCES); s.writeInternalPrototype(INSTANCES, Value.makeObject(PROTOTYPE)); /* * Properties. */ // DOM Level 1 createDOMProperty( INSTANCES, "form", Value.makeObject(HTMLFormElement.INSTANCES).setReadOnly(), c); createDOMProperty(INSTANCES, "code", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "align", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "archive", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "border", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "codeBase", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "codeType", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "data", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "declare", Value.makeAnyBool(), c); createDOMProperty(INSTANCES, "height", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "hspace", Value.makeAnyNum(), c); createDOMProperty(INSTANCES, "name", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "standby", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "tabIndex", Value.makeAnyNum(), c); createDOMProperty( INSTANCES, "type", Value.makeAnyStr().restrictToNotStrIdentifierParts() /* mime-type */, c); createDOMProperty(INSTANCES, "useMap", Value.makeAnyStr(), c); createDOMProperty(INSTANCES, "vspace", Value.makeAnyNum(), c); createDOMProperty(INSTANCES, "width", Value.makeAnyStr(), c); // DOM Level 2 createDOMProperty( INSTANCES, "contentDocument", Value.makeObject(DOMDocument.INSTANCES).setReadOnly(), c); s.multiplyObject(INSTANCES); INSTANCES = INSTANCES.makeSingleton().makeSummary(); /* * Functions. */ // No functions. }
/** 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); } }
/** Initializes the connection to the solver. */ public void setSolverInterface(Solver.SolverInterface c) { this.c = c; m = c.getMonitoring(); }
public static void build(Solver.SolverInterface c) { State s = c.getState(); PropVarOperations pv = c.getAnalysis().getPropVarOperations(); CONSTRUCTOR = new ObjectLabel(DOMObjects.ELEMENT_CONSTRUCTOR, ObjectLabel.Kind.FUNCTION); PROTOTYPE = new ObjectLabel(DOMObjects.ELEMENT_PROTOTYPE, ObjectLabel.Kind.OBJECT); INSTANCES = new ObjectLabel(DOMObjects.ELEMENT_INSTANCES, ObjectLabel.Kind.OBJECT); // Constructor Object s.newObject(CONSTRUCTOR); pv.writePropertyWithAttributes( CONSTRUCTOR, "length", Value.makeNum(0).setAttributes(true, true, true)); pv.writePropertyWithAttributes( CONSTRUCTOR, "prototype", Value.makeObject(PROTOTYPE).setAttributes(true, true, true)); s.writeInternalPrototype(CONSTRUCTOR, Value.makeObject(InitialStateBuilder.OBJECT_PROTOTYPE)); pv.writeProperty(DOMWindow.WINDOW, "Element", Value.makeObject(CONSTRUCTOR)); // Prototype s.newObject(PROTOTYPE); s.writeInternalPrototype(PROTOTYPE, Value.makeObject(DOMNode.PROTOTYPE)); // Multiplied object s.newObject(INSTANCES); s.writeInternalPrototype(INSTANCES, Value.makeObject(PROTOTYPE)); /* * Properties. */ // DOM Level 1 createDOMProperty(INSTANCES, "tagName", Value.makeAnyStr(), c); s.multiplyObject(INSTANCES); INSTANCES = INSTANCES.makeSingleton().makeSummary(); /* * Functions. */ // Unknown createDOMFunction( PROTOTYPE, DOMObjects.ELEMENT_GET_BOUNDING_CLIENT_RECT, "getBoundingClientRect", 0, c); // DOM Level 1 createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_GET_ATTRIBUTE, "getAttribute", 1, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_SET_ATTRIBUTE, "setAttribute", 2, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_REMOVE_ATTRIBUTE, "removeAttribute", 1, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_GET_ATTRIBUTE_NODE, "getAttributeNode", 1, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_SET_ATTRIBUTE_NODE, "setAttributeNode", 2, c); createDOMFunction( PROTOTYPE, DOMObjects.ELEMENT_REMOVE_ATTRIBUTE_NODE, "removeAttributeNode", 1, c); createDOMFunction( PROTOTYPE, DOMObjects.ELEMENT_GET_ELEMENTS_BY_TAGNAME, "getElementsByTagName", 1, c); // DOM Level 2 createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_GET_ATTRIBUTE_NS, "getAttributeNS", 2, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_SET_ATTRIBUTE_NS, "setAttributeNS", 3, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_REMOVE_ATTRIBUTE_NS, "removeAttributeNS", 2, c); createDOMFunction( PROTOTYPE, DOMObjects.ELEMENT_GET_ATTRIBUTE_NODE_NS, "getAttributeNodeNS", 2, c); createDOMFunction( PROTOTYPE, DOMObjects.ELEMENT_SET_ATTRIBUTE_NODE_NS, "setAttributeNodeNS", 3, c); createDOMFunction( PROTOTYPE, DOMObjects.ELEMENT_GET_ELEMENTS_BY_TAGNAME_NS, "getElementsByTagNameNS", 2, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_HAS_ATTRIBUTE, "hasAttribute", 1, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_HAS_ATTRIBUTE_NS, "hasAttributeNS", 2, c); // DOM Level 3 createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_SET_ID_ATTRIBUTE, "setIdAttribute", 2, c); createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_SET_ID_ATTRIBUTE_NS, "setIdAttributeNS", 3, c); createDOMFunction( PROTOTYPE, DOMObjects.ELEMENT_SET_ID_ATTRIBUTE_NODE, "setIdAttributeNode", 2, c); // DOM Level 2 createDOMProperty( DOMAttr.INSTANCES, "ownerElement", Value.makeObject(INSTANCES).setReadOnly(), c); // semistandard createDOMFunction(PROTOTYPE, DOMObjects.ELEMENT_QUERY_SELECTOR_ALL, "querySelectorAll", 1, c); }
/** Transfer Functions. */ public static Value evaluate(DOMObjects nativeObject, CallInfo call, Solver.SolverInterface c) { State s = c.getState(); switch (nativeObject) { case ELEMENT_GET_ATTRIBUTE: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); return Value.makeAnyStr(); } case ELEMENT_SET_ATTRIBUTE: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); /* Value value =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); return Value.makeUndef(); } case ELEMENT_REMOVE_ATTRIBUTE: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); return Value.makeUndef(); } case ELEMENT_GET_ATTRIBUTE_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); return Value.makeAnyStr(); } case ELEMENT_GET_ATTRIBUTE_NODE: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); return Value.makeObject(DOMAttr.INSTANCES); } case ELEMENT_GET_ATTRIBUTE_NODE_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); return Value.makeObject(DOMAttr.INSTANCES); } case ELEMENT_GET_BOUNDING_CLIENT_RECT: { NativeFunctions.expectParameters(nativeObject, call, c, 0, 0); return Value.makeObject(ClientBoundingRect.INSTANCES); } case ELEMENT_GET_ELEMENTS_BY_TAGNAME: { // TODO: needs precision, but cannot do like document.getElementsByTagName() bc. State is // for everything NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); return Value.makeObject(DOMNodeList.INSTANCES); } case ELEMENT_GET_ELEMENTS_BY_TAGNAME_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); return Value.makeObject(DOMNodeList.INSTANCES); } case ELEMENT_HAS_ATTRIBUTE: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); return Value.makeAnyBool(); } case ELEMENT_HAS_ATTRIBUTE_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); return Value.makeAnyBool(); } case ELEMENT_REMOVE_ATTRIBUTE_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value namespaceURI =*/ Conversion.toString( NativeFunctions.readParameter(call, s, 0), c); /* Value localName =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); return Value.makeUndef(); } case ELEMENT_REMOVE_ATTRIBUTE_NODE: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); return DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c); } case ELEMENT_SET_ATTRIBUTE_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 3, 3); /* Value namespace =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c) .joinNull(); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); /* Value value =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 2), c); return Value.makeUndef(); } case ELEMENT_SET_ATTRIBUTE_NODE: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); /* Value newAttr =*/ DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c); return Value.makeObject(DOMAttr.INSTANCES).joinNull(); } case ELEMENT_SET_ATTRIBUTE_NODE_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); /* Value newAttr =*/ DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c); return Value.makeObject(DOMAttr.INSTANCES).joinNull(); } case ELEMENT_SET_ID_ATTRIBUTE: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value name =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 0), c); /* Value isId =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 1)); return Value.makeUndef(); } case ELEMENT_SET_ID_ATTRIBUTE_NS: { NativeFunctions.expectParameters(nativeObject, call, c, 3, 3); /* Value namespaceURI =*/ Conversion.toString( NativeFunctions.readParameter(call, s, 0), c); /* Value localName =*/ Conversion.toString(NativeFunctions.readParameter(call, s, 1), c); /* Value isId =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 2)); return Value.makeUndef(); } case ELEMENT_SET_ID_ATTRIBUTE_NODE: { NativeFunctions.expectParameters(nativeObject, call, c, 2, 2); /* Value idAttr =*/ DOMConversion.toAttr(NativeFunctions.readParameter(call, s, 0), c); /* Value isId =*/ Conversion.toBoolean(NativeFunctions.readParameter(call, s, 1)); return Value.makeUndef(); } case ELEMENT_QUERY_SELECTOR_ALL: { NativeFunctions.expectParameters(nativeObject, call, c, 1, 1); return Value.makeObject(DOMNodeList.INSTANCES); } default: { throw new AnalysisException("Unknown Native Object: " + nativeObject); } } }