+ node->setCanExit(node->op() == IsUndefined && m_codeBlock->globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
+ JSValue child = forNode(node->child1()).value();
+ if (child) {
+ bool constantWasSet;
+ switch (node->op()) {
+ case IsUndefined:
+ if (m_codeBlock->globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ constantWasSet = trySetConstant(node, jsBoolean(
+ child.isCell()
+ ? false
+ : child.isUndefined()));
+ } else {
+ constantWasSet = trySetConstant(node, jsBoolean(
+ child.isCell()
+ ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->codeOrigin))
+ : child.isUndefined()));
+ }
+ break;
+ case IsBoolean:
+ constantWasSet = trySetConstant(node, jsBoolean(child.isBoolean()));
+ break;
+ case IsNumber:
+ constantWasSet = trySetConstant(node, jsBoolean(child.isNumber()));
+ break;
+ case IsString:
+ constantWasSet = trySetConstant(node, jsBoolean(isJSString(child)));
+ break;
+ case IsObject:
+ if (child.isNull() || !child.isObject()) {
+ constantWasSet = trySetConstant(node, jsBoolean(child.isNull()));
+ break;
+ }
+ default:
+ constantWasSet = false;
+ break;
+ }
+ if (constantWasSet) {
+ m_foundConstants = true;
+ break;
+ }
+ }
+
+ forNode(node).set(SpecBoolean);
+ break;
+ }
+
+ case TypeOf: {
+ VM* vm = m_codeBlock->vm();
+ JSValue child = forNode(node->child1()).value();
+ AbstractValue& abstractChild = forNode(node->child1());
+ if (child) {
+ JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->codeOrigin), child);
+ if (trySetConstant(node, typeString)) {
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isNumberSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.numberString())) {
+ forNode(node->child1()).filter(SpecNumber);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isStringSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.stringString())) {
+ forNode(node->child1()).filter(SpecString);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.objectString())) {
+ forNode(node->child1()).filter(SpecFinalObject | SpecArray | SpecArguments);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isFunctionSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.functionString())) {
+ forNode(node->child1()).filter(SpecFunction);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isBooleanSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.booleanString())) {
+ forNode(node->child1()).filter(SpecBoolean);
+ m_foundConstants = true;
+ break;
+ }
+ }
+
+ switch (node->child1().useKind()) {
+ case StringUse:
+ case CellUse:
+ node->setCanExit(true);
+ break;
+ case UntypedUse:
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ forNode(node).set(m_graph.m_vm.stringStructure.get());