RegExpObject * RegExpObjectBuilder::clone(RegExpObject *other, RegExpObject *proto) { if (!getOrCreateClone(proto)) return NULL; /* * Check that the RegExpPrivate for the original is okay to use in * the clone -- if the |RegExpStatics| provides more flags we'll * need a different |RegExpPrivate|. */ RegExpStatics *res = cx->regExpStatics(); RegExpFlag origFlags = other->getFlags(); RegExpFlag staticsFlags = res->getFlags(); if ((origFlags & staticsFlags) != staticsFlags) { RegExpFlag newFlags = RegExpFlag(origFlags | staticsFlags); return build(other->getSource(), newFlags); } RegExpPrivate *toShare = other->getOrCreatePrivate(cx); if (!toShare) return NULL; toShare->incref(cx); return build(AlreadyIncRefed<RegExpPrivate>(toShare)); }
RegExpObject * RegExpObjectBuilder::build(RegExpObject *other) { RegExpPrivate *rep = other->getOrCreatePrivate(cx); if (!rep) return NULL; /* Now, incref it for the RegExpObject being built. */ rep->incref(cx); return build(AlreadyIncRefed<RegExpPrivate>(rep)); }
/* * Compile a new |RegExpPrivate| for the |RegExpObject|. * * Per ECMAv5 15.10.4.1, we act on combinations of (pattern, flags) as * arguments: * * RegExp, undefined => flags := pattern.flags * RegExp, _ => throw TypeError * _ => pattern := ToString(pattern) if defined(pattern) else '' * flags := ToString(flags) if defined(flags) else '' */ static bool CompileRegExpObject(JSContext *cx, RegExpObject *obj, uintN argc, Value *argv, Value *rval) { if (argc == 0) { if (!ResetRegExpObjectWithStatics(cx, obj, cx->runtime->emptyString)) return false; *rval = ObjectValue(*obj); return true; } Value sourceValue = argv[0]; if (ValueIsRegExp(sourceValue)) { /* * If we get passed in a |RegExpObject| source we return a new * object with the same |RegExpPrivate|. * * Note: the regexp static flags are not taken into consideration here. */ JSObject &sourceObj = sourceValue.toObject(); if (argc >= 2 && !argv[1].isUndefined()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEWREGEXP_FLAGGED); return false; } RegExpPrivate *rep = sourceObj.asRegExp()->getPrivate(); if (!rep) return false; rep->incref(cx); if (!ResetRegExpObject(cx, obj, AlreadyIncRefed<RegExpPrivate>(rep))) return false; *rval = ObjectValue(*obj); return true; } JSString *sourceStr; if (sourceValue.isUndefined()) { sourceStr = cx->runtime->emptyString; } else { /* Coerce to string and compile. */ sourceStr = js_ValueToString(cx, sourceValue); if (!sourceStr) return false; } RegExpFlag flags = RegExpFlag(0); if (argc > 1 && !argv[1].isUndefined()) { JSString *flagStr = js_ValueToString(cx, argv[1]); if (!flagStr) return false; argv[1].setString(flagStr); if (!ParseRegExpFlags(cx, flagStr, &flags)) return false; } JSString *escapedSourceStr = EscapeNakedForwardSlashes(cx, sourceStr); if (!escapedSourceStr) return false; if (!ResetRegExpObjectWithStatics(cx, obj, escapedSourceStr, flags)) return false; *rval = ObjectValue(*obj); return true; }