зеркало из https://github.com/mozilla/gecko-dev.git
RegExp fixes.
This commit is contained in:
Родитель
0b305af30a
Коммит
724858322b
|
@ -822,6 +822,7 @@ namespace MetaData {
|
|||
case StmtNode::label:
|
||||
{
|
||||
LabelStmtNode *l = checked_cast<LabelStmtNode *>(p);
|
||||
bCon->setLabel(l->labelID);
|
||||
SetupStmt(env, phase, l->stmt);
|
||||
}
|
||||
break;
|
||||
|
@ -4858,6 +4859,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
|
||||
void InstanceVariable::mark()
|
||||
{
|
||||
InstanceMember::mark();
|
||||
if (type != FUTURE_TYPE)
|
||||
GCMARKOBJECT(type);
|
||||
}
|
||||
|
@ -4873,6 +4875,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
// gc-mark all contained JS2Objects and visit contained structures to do likewise
|
||||
void InstanceMethod::mark()
|
||||
{
|
||||
InstanceMember::mark();
|
||||
GCMARKOBJECT(fInst);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,30 +62,30 @@ namespace MetaData {
|
|||
|
||||
void RegExpInstance::setLastIndex(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["lastIndex"], true, a);
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("lastIndex"), true, a);
|
||||
}
|
||||
void RegExpInstance::setGlobal(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["global"], true, a);
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("global"), true, a);
|
||||
}
|
||||
void RegExpInstance::setMultiline(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["multiline"], true, a);
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("multiline"), true, a);
|
||||
}
|
||||
void RegExpInstance::setIgnoreCase(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["ignoreCase"], true, a);
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("ignoreCase"), true, a);
|
||||
}
|
||||
void RegExpInstance::setSource(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["source"], true, a);
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("source"), true, a);
|
||||
}
|
||||
|
||||
js2val RegExpInstance::getLastIndex(JS2Metadata *meta)
|
||||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, &meta->world.identifiers["lastIndex"], RunPhase, &r))
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("lastIndex"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace MetaData {
|
|||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, &meta->world.identifiers["global"], RunPhase, &r))
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("global"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ namespace MetaData {
|
|||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, &meta->world.identifiers["multiline"], RunPhase, &r))
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("multiline"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ namespace MetaData {
|
|||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, &meta->world.identifiers["ignoreCase"], RunPhase, &r))
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("ignoreCase"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
|
@ -117,11 +117,36 @@ namespace MetaData {
|
|||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, &meta->world.identifiers["source"], RunPhase, &r))
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("source"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
js2val RegExp_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
|
||||
{
|
||||
if (meta->objectType(thisValue) != meta->regexpClass)
|
||||
meta->reportError(Exception::typeError, "RegExp.toString can only be applied to RegExp objects", meta->engine->errorPos());
|
||||
RegExpInstance *thisInst = checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
js2val srcval = thisInst->getSource(meta);
|
||||
ASSERT(JS2VAL_IS_STRING(srcval));
|
||||
const String *s = JS2VAL_TO_STRING(srcval);
|
||||
String result = "/" + *s + "/";
|
||||
js2val flagVal = thisInst->getGlobal(meta);
|
||||
ASSERT(JS2VAL_IS_BOOLEAN(flagVal));
|
||||
if (JS2VAL_TO_BOOLEAN(flagVal))
|
||||
result += "g";
|
||||
flagVal = thisInst->getIgnoreCase(meta);
|
||||
ASSERT(JS2VAL_IS_BOOLEAN(flagVal));
|
||||
if (JS2VAL_TO_BOOLEAN(flagVal))
|
||||
result += "i";
|
||||
flagVal = thisInst->getMultiline(meta);
|
||||
ASSERT(JS2VAL_IS_BOOLEAN(flagVal));
|
||||
if (JS2VAL_TO_BOOLEAN(flagVal))
|
||||
result += "m";
|
||||
return meta->engine->allocString(result);
|
||||
}
|
||||
|
||||
js2val RegExp_exec(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
|
||||
{
|
||||
if (meta->objectType(thisValue) != meta->regexpClass)
|
||||
|
@ -135,7 +160,7 @@ namespace MetaData {
|
|||
const String *str = meta->toString(argv[0]);
|
||||
js2val globalMultiline = thisInst->getMultiline(meta);
|
||||
|
||||
if (thisInst->getGlobal(meta)) {
|
||||
if (meta->toBoolean(thisInst->getGlobal(meta))) {
|
||||
js2val lastIndex = thisInst->getLastIndex(meta);
|
||||
index = meta->toInteger(lastIndex);
|
||||
}
|
||||
|
@ -143,17 +168,24 @@ namespace MetaData {
|
|||
REMatchState *match = REExecute(thisInst->mRegExp, str->begin(), index, toInt32(str->length()), meta->toBoolean(globalMultiline));
|
||||
if (match) {
|
||||
ArrayInstance *A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
|
||||
DEFINE_ROOTKEEPER(rk, A);
|
||||
result = OBJECT_TO_JS2VAL(A);
|
||||
js2val matchStr = meta->engine->allocString(str->substr((uint32)match->startIndex, (uint32)match->endIndex - match->startIndex));
|
||||
meta->createDynamicProperty(A, &meta->world.identifiers[*meta->toString((long)0)], matchStr, ReadWriteAccess, false, true);
|
||||
meta->createDynamicProperty(A, meta->engine->numberToString((long)0), matchStr, ReadWriteAccess, false, true);
|
||||
for (int32 i = 0; i < match->parenCount; i++) {
|
||||
if (match->parens[i].index != -1) {
|
||||
js2val parenStr = meta->engine->allocString(str->substr((uint32)(match->parens[i].index), (uint32)(match->parens[i].length)));
|
||||
meta->createDynamicProperty(A, &meta->world.identifiers[*meta->toString(i + 1)], parenStr, ReadWriteAccess, false, true);
|
||||
meta->createDynamicProperty(A, meta->engine->numberToString(i + 1), parenStr, ReadWriteAccess, false, true);
|
||||
}
|
||||
else
|
||||
meta->createDynamicProperty(A, &meta->world.identifiers[*meta->toString(i + 1)], JS2VAL_UNDEFINED, ReadWriteAccess, false, true);
|
||||
meta->createDynamicProperty(A, meta->engine->numberToString(i + 1), JS2VAL_UNDEFINED, ReadWriteAccess, false, true);
|
||||
}
|
||||
setLength(meta, A, match->parenCount + 1);
|
||||
|
||||
meta->createDynamicProperty(A, meta->engine->allocStringPtr("index"), meta->engine->allocNumber((float64)(match->startIndex)), ReadWriteAccess, false, true);
|
||||
meta->createDynamicProperty(A, meta->engine->allocStringPtr("input"), meta->engine->allocString(str), ReadWriteAccess, false, true);
|
||||
|
||||
|
||||
/*
|
||||
// XXX SpiderMonkey also adds 'index' and 'input' properties to the result
|
||||
JSValue::instance(result)->setProperty(cx, cx->Index_StringAtom, CURRENT_ATTR, JSValue::newNumber((float64)(match->startIndex)));
|
||||
|
@ -167,7 +199,7 @@ namespace MetaData {
|
|||
contextStr = new String(str->substr((uint32)match->endIndex, (uint32)str->length() - match->endIndex));
|
||||
RegExp_Type->setProperty(cx, cx->RightContext_StringAtom, CURRENT_ATTR, JSValue::newString(contextStr));
|
||||
*/
|
||||
if (thisInst->getGlobal(meta)) {
|
||||
if (meta->toBoolean(thisInst->getGlobal(meta))) {
|
||||
index = match->endIndex;
|
||||
thisInst->setLastIndex(meta, meta->engine->allocNumber((float64)index));
|
||||
}
|
||||
|
@ -226,7 +258,18 @@ namespace MetaData {
|
|||
|
||||
void initRegExpObject(JS2Metadata *meta)
|
||||
{
|
||||
meta->regexpClass->construct = RegExp_Constructor;
|
||||
meta->regexpClass->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->dateClass));
|
||||
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "toString", 0, RegExp_toString },
|
||||
{ "exec", 0, RegExp_exec },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
meta->initBuiltinClass(meta->regexpClass, &prototypeFunctions[0], NULL, RegExp_Constructor, RegExp_Constructor);
|
||||
|
||||
|
||||
|
||||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
@ -247,11 +290,12 @@ namespace MetaData {
|
|||
|
||||
for (uint32 i = 0; i < INSTANCE_VAR_COUNT; i++)
|
||||
{
|
||||
Multiname *mn = new Multiname(&meta->world.identifiers[RegExpInstanceVars[i].name], &publicNamespaceList);
|
||||
InstanceMember *m = new InstanceVariable(mn, RegExpInstanceVars[i].type, true, true, true, meta->regexpClass->slotCount++);
|
||||
Multiname *mn = new Multiname(meta->engine->allocStringPtr(RegExpInstanceVars[i].name), &publicNamespaceList);
|
||||
InstanceMember *m = new InstanceVariable(mn, RegExpInstanceVars[i].type, false, true, true, meta->regexpClass->slotCount++);
|
||||
meta->defineInstanceMember(meta->regexpClass, &meta->cxt, mn->name, *mn->nsList, Attribute::NoOverride, false, m, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -166,6 +166,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
|||
}
|
||||
|
||||
RegExpInstance *thisInst = checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(regexp));
|
||||
DEFINE_ROOTKEEPER(rk1, thisInst);
|
||||
REState *pState = thisInst->mRegExp;
|
||||
if ((pState->flags & RE_GLOBAL) == 0) {
|
||||
return RegExp_exec(meta, regexp, &S, 1);
|
||||
|
|
Загрузка…
Ссылка в новой задаче