diff --git a/mozilla/js2/src/js2date.cpp b/mozilla/js2/src/js2date.cpp index f1223ba60b3..2118b182d54 100644 --- a/mozilla/js2/src/js2date.cpp +++ b/mozilla/js2/src/js2date.cpp @@ -1481,7 +1481,9 @@ void initDateObject(JS2Metadata *meta) LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond); meta->initBuiltinClass(meta->dateClass, &staticFunctions[0], Date_Constructor, Date_Call); - meta->dateClass->prototype = OBJECT_TO_JS2VAL(new DateInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->dateClass)); + DateInstance *ur = new DateInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->dateClass); + meta->dateClass->prototype = OBJECT_TO_JS2VAL(ur); + ur->ms = 0; meta->initBuiltinClassPrototype(meta->dateClass, &prototypeFunctions[0]); } diff --git a/mozilla/js2/src/js2error.cpp b/mozilla/js2/src/js2error.cpp index e7ea4d46547..aba01bede7d 100644 --- a/mozilla/js2/src/js2error.cpp +++ b/mozilla/js2/src/js2error.cpp @@ -113,18 +113,19 @@ js2val UriError_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2va js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc) { js2val thatValue = thisValue; - js2val result; - Multiname mn(&meta->world.identifiers["message"], meta->publicNamespace); + js2val nameVal; + js2val messageVal; + String s; JS2Class *c = meta->objectType(thatValue); - if (c->ReadPublic(meta, &thatValue, &meta->world.identifiers["message"], RunPhase, &result)) { - if (JS2VAL_IS_STRING(result)) - return result; - else - return meta->engine->allocString(meta->toString(result)); + if (c->ReadPublic(meta, &thatValue, &meta->world.identifiers["name"], RunPhase, &nameVal)) { + s = *meta->toString(nameVal); + if (c->ReadPublic(meta, &thatValue, &meta->world.identifiers["message"], RunPhase, &messageVal)) { + s += widenCString(":"); + s += *meta->toString(messageVal); + } } - else - return JS2VAL_UNDEFINED; + return meta->engine->allocString(s); } static void initErrorClass(JS2Metadata *meta, JS2Class *c, Constructor *constructor) diff --git a/mozilla/js2/src/js2eval.cpp b/mozilla/js2/src/js2eval.cpp index 43376cbc6d1..9fbd5f5657f 100644 --- a/mozilla/js2/src/js2eval.cpp +++ b/mozilla/js2/src/js2eval.cpp @@ -724,6 +724,16 @@ namespace MetaData { return Read(meta, base, mn, NULL, phase, rval); } + bool isValidIndex(const String *name, uint32 &index) + { + const char16 *numEnd; + float64 f = stringToDouble(name->data(), name->data() + name->length(), numEnd); + index = JS2Engine::float64toUInt32(f); + char buf[dtosStandardBufferSize]; + const char *chrp = doubleToStr(buf, dtosStandardBufferSize, index, dtosStandard, 0); + return (widenCString(chrp) == *name); + } + bool JS2ArrayClass::Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { ASSERT(JS2VAL_IS_OBJECT(base)); @@ -737,32 +747,67 @@ namespace MetaData { else { result = JS2Class::Write(meta, base, multiname, env, createIfMissing, newValue, false); if (result && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { - const char16 *numEnd; - float64 f = stringToDouble(multiname->name->data(), multiname->name->data() + multiname->name->length(), numEnd); - uint32 index = JS2Engine::float64toUInt32(f); - - char buf[dtosStandardBufferSize]; - const char *chrp = doubleToStr(buf, dtosStandardBufferSize, index, dtosStandard, 0); - - if (widenCString(chrp) == *multiname->name) { + uint32 index; + if (isValidIndex(multiname->name, index)) { uint32 length = getLength(meta, obj); if (index >= length) setLength(meta, obj, index + 1); } - } } return result; } - bool JS2ArrayClass::WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue) - { - DEFINE_ROOTKEEPER(rk1, name); - // XXX could speed up by pushing knowledge of single namespace? - Multiname *mn = new Multiname(name, meta->publicNamespace); - DEFINE_ROOTKEEPER(rk, mn); - return Write(meta, base, mn, meta->env, createIfMissing, newValue, false); - } + bool JS2ArrayClass::BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *rval) + { + const String *indexStr = meta->toString(indexVal); + DEFINE_ROOTKEEPER(rk, indexStr); + Multiname *mn = new Multiname(indexStr, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk1, mn); + return Read(meta, base, mn, NULL, phase, rval); + } + + bool JS2ArrayClass::BracketWrite(JS2Metadata *meta, js2val base, js2val indexVal, js2val newValue) + { + const String *indexStr = meta->toString(indexVal); + DEFINE_ROOTKEEPER(rk, indexStr); + Multiname *mn = new Multiname(indexStr, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk1, mn); + + ASSERT(JS2VAL_IS_OBJECT(base)); + JS2Object *obj = JS2VAL_TO_OBJECT(base); + + bool result; + if (!JS2VAL_IS_INT(indexVal)) { + if (*mn->name == *meta->engine->length_StringAtom) { + Array_lengthSet(meta, base, &newValue, 1); + return true; + } + } + result = JS2Class::Write(meta, base, mn, NULL, true, newValue, false); + uint32 index; + if (result) { + if (JS2VAL_IS_INT(indexVal)) + index = JS2VAL_TO_INT(indexVal); + else { + if (!isValidIndex(mn->name, index)) + return true; // not a valid index, don't need to set length + } + } + uint32 length = getLength(meta, obj); + if (index >= length) + setLength(meta, obj, index + 1); + return result; + } + + bool JS2ArrayClass::BracketDelete(JS2Metadata *meta, js2val base, js2val indexVal, bool *result) + { + const String *indexStr = meta->toString(indexVal); + DEFINE_ROOTKEEPER(rk, indexStr); + Multiname *mn = new Multiname(indexStr, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk1, mn); + return Delete(meta, base, mn, NULL, result); + } bool JS2Class::Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { diff --git a/mozilla/js2/src/js2function.cpp b/mozilla/js2/src/js2function.cpp index 02728e5ee83..5a5633d5369 100644 --- a/mozilla/js2/src/js2function.cpp +++ b/mozilla/js2/src/js2function.cpp @@ -125,15 +125,26 @@ namespace MetaData { return STRING_TO_JS2VAL(meta->engine->Function_StringAtom); } - static js2val Function_call(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/) + static js2val Function_call(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc) { if (!JS2VAL_IS_OBJECT(thisValue) || (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind) || ((checked_cast(JS2VAL_TO_OBJECT(thisValue)))->type != meta->functionClass)) meta->reportError(Exception::typeError, "Function.call called on something other than a function thing", meta->engine->errorPos()); -// FunctionInstance *fnInst = checked_cast(JS2VAL_TO_OBJECT(thisValue)); - return STRING_TO_JS2VAL(meta->engine->Function_StringAtom); - } + FunctionInstance *fnInst = checked_cast(JS2VAL_TO_OBJECT(thisValue)); + + js2val callThis = argv[0]; + DEFINE_ROOTKEEPER(rk0, callThis); + if (JS2VAL_IS_NULL(argv[0]) || JS2VAL_IS_UNDEFINED(argv[0])) + callThis = OBJECT_TO_JS2VAL(meta->glob); + else + callThis = meta->toObject(callThis); + + if (argc > 1) + return meta->invokeFunction(fnInst, callThis, &argv[1], argc - 1, NULL); + else + return meta->invokeFunction(fnInst, callThis, NULL, 0, NULL); + } static js2val Function_apply(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc) { @@ -143,28 +154,28 @@ namespace MetaData { meta->reportError(Exception::typeError, "Function.apply called on something other than a function thing", meta->engine->errorPos()); FunctionInstance *fnInst = checked_cast(JS2VAL_TO_OBJECT(thisValue)); js2val callThis = argv[0]; + DEFINE_ROOTKEEPER(rk0, callThis); if (JS2VAL_IS_NULL(argv[0]) || JS2VAL_IS_UNDEFINED(argv[0])) callThis = OBJECT_TO_JS2VAL(meta->glob); else callThis = meta->toObject(callThis); - js2val *argArray = NULL; - uint32 length = 0; if ((argc > 1) && !JS2VAL_IS_NULL(argv[1]) && !JS2VAL_IS_UNDEFINED(argv[1])) { if (!JS2VAL_IS_OBJECT(argv[1]) || (JS2VAL_TO_OBJECT(argv[1])->kind != SimpleInstanceKind) || ((checked_cast(JS2VAL_TO_OBJECT(argv[1])))->type != meta->arrayClass)) meta->reportError(Exception::typeError, "Function.apply passed a non-array argument list", meta->engine->errorPos()); - ArrayInstance *arrInst = checked_cast(JS2VAL_TO_OBJECT(argv[1])); uint32 length = getLength(meta, arrInst); - argArray = new js2val[length]; + js2val *argArray = new js2val[length]; DEFINE_ARRAYROOTKEEPER(rk, argArray, length); for (uint32 i = 0; i < length; i++) meta->arrayClass->ReadPublic(meta, &argv[1], meta->engine->numberToString(i), RunPhase, &argArray[i]); + return meta->invokeFunction(fnInst, callThis, argArray, length, NULL); } + else + return meta->invokeFunction(fnInst, callThis, NULL, 0, NULL); - return meta->invokeFunction(fnInst, callThis, argArray, 0, NULL); } void initFunctionObject(JS2Metadata *meta) diff --git a/mozilla/js2/src/js2metadata.cpp b/mozilla/js2/src/js2metadata.cpp index 4e2d763a0a3..cc0de338dfa 100644 --- a/mozilla/js2/src/js2metadata.cpp +++ b/mozilla/js2/src/js2metadata.cpp @@ -123,11 +123,17 @@ namespace MetaData { } pb = fnDef->parameters; while (pb) { - FrameVariable *v = new FrameVariable(result->fWrap->compileFrame->allocateSlot(), FrameVariable::Parameter); if (pb->type) ValidateTypeExpression(cxt, env, pb->type); - pb->member = v; - pb->mn = defineLocalMember(env, pb->name, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos, true); + if (unchecked) { + pb->member = NULL; + defineHoistedVar(env, pb->name, JS2VAL_UNDEFINED, true, pos); + } + else { + FrameVariable *v = new FrameVariable(result->fWrap->compileFrame->allocateSlot(), FrameVariable::Parameter); + pb->member = v; + defineLocalMember(env, pb->name, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos, true); + } pb = pb->next; } } @@ -1332,11 +1338,13 @@ namespace MetaData { bCon->fName = *f->function.name; VariableBinding *pb = f->function.parameters; while (pb) { - FrameVariable *v = checked_cast(pb->member); - if (pb->type) - v->type = EvalTypeExpression(env, CompilePhase, pb->type); - else - v->type = objectClass; + if (pb->member) { + FrameVariable *v = checked_cast(pb->member); + if (pb->type) + v->type = EvalTypeExpression(env, CompilePhase, pb->type); + else + v->type = objectClass; + } pb = pb->next; } if (f->function.resultType) @@ -2435,7 +2443,8 @@ doUnary: break; case ParameterFrameKind: { - LocalMember *m = findLocalMember(pf, multiname, ReadAccess); + bool isEnumerable; + LocalMember *m = findLocalMember(pf, multiname, ReadAccess, isEnumerable); if (m) { switch (checked_cast(m)->memberKind) { case LocalMember::VariableMember: @@ -2452,7 +2461,8 @@ doUnary: break; case BlockFrameKind: { - LocalMember *m = findLocalMember(pf, multiname, ReadAccess); + bool isEnumerable; + LocalMember *m = findLocalMember(pf, multiname, ReadAccess, isEnumerable); if (m) { switch (checked_cast(m)->memberKind) { case LocalMember::VariableMember: @@ -2920,7 +2930,8 @@ doUnary: case ParameterFrameKind: case BlockFrameKind: { - LocalMember *m = meta->findLocalMember(f, multiname, ReadAccess); + bool isEnumerable; + LocalMember *m = meta->findLocalMember(f, multiname, ReadAccess, isEnumerable); if (m) result = meta->readLocalMember(m, phase, rval, f); } @@ -2964,7 +2975,8 @@ doUnary: case ParameterFrameKind: case BlockFrameKind: { - LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess); + bool isEnumerable; + LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess, isEnumerable); if (m) { meta->writeLocalMember(m, newValue, false, f); result = true; @@ -3016,7 +3028,8 @@ doUnary: case ParameterFrameKind: case BlockFrameKind: { - LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess); + bool isEnumerable; + LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess, isEnumerable); if (m) { meta->writeLocalMember(m, newValue, true, f); result = true; @@ -3066,7 +3079,8 @@ doUnary: case ParameterFrameKind: case BlockFrameKind: { - LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess); + bool isEnumerable; + LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess, isEnumerable); if (m) return false; } @@ -3596,8 +3610,8 @@ rescan: newchars[ni++] = ch; } newchars[ni] = 0; - - return STRING_TO_JS2VAL(meta->engine->allocStringPtr(&meta->world.identifiers[newchars])); + String s(newchars, ni); + return meta->engine->allocString(s); } // Taken from jsstr.c... @@ -3693,8 +3707,8 @@ static const uint8 urlCharType[256] = } ASSERT(ni == newlength); newchars[newlength] = 0; - - return STRING_TO_JS2VAL(meta->engine->allocStringPtr(&meta->world.identifiers[newchars])); + String s(newchars, newlength); + return meta->engine->allocString(s); } static js2val GlobalObject_parseInt(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint32 argc) @@ -3848,6 +3862,47 @@ static const uint8 urlCharType[256] = return JS2VAL_UNDEFINED; } + static js2val Object_hasOwnProperty(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc) + { + ASSERT(JS2VAL_IS_OBJECT(thisValue)); + JS2Object *obj = JS2VAL_TO_OBJECT(thisValue); + Multiname mn(meta->toString(argv[0])); + bool isEnumerable; + if (!meta->findLocalMember(obj, &mn, ReadAccess, isEnumerable)) + return JS2VAL_FALSE; + return JS2VAL_TRUE; + } + + static js2val Object_isPropertyOf(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc) + { + ASSERT(JS2VAL_IS_OBJECT(thisValue)); + js2val v = argv[0]; + while (JS2VAL_IS_OBJECT(v)) { + JS2Object *v_obj = JS2VAL_TO_OBJECT(v); + if (v_obj->kind != SimpleInstanceKind) + break; + v = checked_cast(v_obj)->super; + if (JS2VAL_IS_NULL(v)) + break; + if (v == thisValue) + return JS2VAL_TRUE; + } + return JS2VAL_FALSE; + } + + static js2val Object_propertyIsEnumerble(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc) + { + ASSERT(JS2VAL_IS_OBJECT(thisValue)); + JS2Object *obj = JS2VAL_TO_OBJECT(thisValue); + Multiname mn(meta->toString(argv[0])); + bool isEnumerable; + LocalMember *m = meta->findLocalMember(obj, &mn, ReadAccess, isEnumerable); + if ((m == NULL) || !isEnumerable) + return JS2VAL_FALSE; + return JS2VAL_TRUE; + } + + static js2val class_underbarProtoGet(JS2Metadata *meta, const js2val thisValue, js2val /* argv */ [], uint32 /* argc */) { ASSERT(JS2VAL_IS_OBJECT(thisValue)); @@ -3876,8 +3931,11 @@ static const uint8 urlCharType[256] = if (newLength < arrInst->length) { // need to delete all the elements above the new length bool deleteResult; - for (uint32 i = newLength; i < arrInst->length; i++) { - meta->arrayClass->DeletePublic(meta, thisValue, meta->engine->numberToString(i), &deleteResult); + Multiname *mn = new Multiname(NULL, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk, mn); + for (uint32 i = newLength; i < arrInst->length; i++) { + mn->name = meta->engine->numberToString(i); + meta->arrayClass->Delete(meta, thisValue, mn, NULL, &deleteResult); } } arrInst->length = newLength; @@ -4207,7 +4265,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... return getDerivedInstanceMember(c->super, mBase, access); } - LocalMember *JS2Metadata::findLocalMember(JS2Object *container, Multiname *multiname, Access access) + LocalMember *JS2Metadata::findLocalMember(JS2Object *container, Multiname *multiname, Access access, bool &enumerable) { LocalMember *found = NULL; LocalBindingMap *lMap; @@ -4225,6 +4283,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... reportError(Exception::propertyAccessError, "Ambiguous reference to {0}", engine->errorPos(), multiname->name); else { found = ns.second->content; + enumerable = ns.second->enumerable; } } } @@ -4250,6 +4309,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... Member *JS2Metadata::findCommonMember(js2val *base, Multiname *multiname, Access access, bool flat) { + bool isEnumerable; Member *m = NULL; if (JS2VAL_IS_PRIMITIVE(*base) && cxt.E3compatibility) { *base = toObject(*base); // XXX E3 compatibility... @@ -4257,13 +4317,13 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... JS2Object *baseObj = JS2VAL_TO_OBJECT(*base); switch (baseObj->kind) { case SimpleInstanceKind: - m = findLocalMember(baseObj, multiname, access); + m = findLocalMember(baseObj, multiname, access, isEnumerable); break; case PackageKind: - m = findLocalMember(baseObj, multiname, access); + m = findLocalMember(baseObj, multiname, access, isEnumerable); break; case ClassKind: - m = findLocalMember(baseObj, multiname, access); + m = findLocalMember(baseObj, multiname, access, isEnumerable); if (m == NULL) m = findLocalInstanceMember(checked_cast(baseObj), multiname, access); break; @@ -4633,10 +4693,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... env->removeTopFrame(); // Add "constructor" as a dynamic property of the prototype +/* FunctionInstance *fInst = createFunctionInstance(env, true, true, builtinClass->construct, 0, NULL); ASSERT(JS2VAL_IS_OBJECT(builtinClass->prototype)); createDynamicProperty(JS2VAL_TO_OBJECT(builtinClass->prototype), &world.identifiers["constructor"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); - +*/ + // XXX Set the class object itself as the value of 'constructor' + ASSERT(JS2VAL_IS_OBJECT(builtinClass->prototype)); + createDynamicProperty(JS2VAL_TO_OBJECT(builtinClass->prototype), &world.identifiers["constructor"], OBJECT_TO_JS2VAL(builtinClass), ReadWriteAccess, false, false); + FunctionData *pf = protoFunctions; if (pf) { while (pf->name) { diff --git a/mozilla/js2/src/js2metadata.h b/mozilla/js2/src/js2metadata.h index fa162dd245e..66bb2656c12 100644 --- a/mozilla/js2/src/js2metadata.h +++ b/mozilla/js2/src/js2metadata.h @@ -818,7 +818,9 @@ public: : JS2Class(super, proto, privateNamespace, dynamic, final, name) { } virtual bool Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag); - virtual bool WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue); + virtual bool BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *rval); + virtual bool BracketWrite(JS2Metadata *meta, js2val base, js2val indexVal, js2val newValue); + virtual bool BracketDelete(JS2Metadata *meta, js2val base, js2val indexVal, bool *result); }; class JS2IntegerClass : public JS2Class { @@ -1470,7 +1472,7 @@ public: InstanceMember *searchForOverrides(JS2Class *c, Multiname *multiname, Access access, size_t pos); InstanceMember *findInstanceMember(JS2Class *c, QualifiedName *qname, Access access); Slot *findSlot(js2val thisObjVal, InstanceVariable *id); - LocalMember *findLocalMember(JS2Object *container, Multiname *multiname, Access access); + LocalMember *findLocalMember(JS2Object *container, Multiname *multiname, Access access, bool &enumerable); js2val getSuperObject(JS2Object *obj); JS2Class *getVariableType(Variable *v, Phase phase, size_t pos); InstanceMember *getDerivedInstanceMember(JS2Class *c, InstanceMember *mBase, Access access); diff --git a/mozilla/js2/src/js2op_invocation.cpp b/mozilla/js2/src/js2op_invocation.cpp index 3660b24f772..53a3ca3f5e0 100644 --- a/mozilla/js2/src/js2op_invocation.cpp +++ b/mozilla/js2/src/js2op_invocation.cpp @@ -310,24 +310,28 @@ doCall: if (!JS2VAL_IS_OBJECT(b)) meta->reportError(Exception::typeError, "Object expected for instanceof", errorPos()); JS2Object *obj = JS2VAL_TO_OBJECT(b); + js2val a_protoVal; + js2val b_protoVal; + JS2Object *aObj = NULL; if ((obj->kind == SimpleInstanceKind) && (checked_cast(obj)->type == meta->functionClass)) { // XXX this is [[hasInstance]] from ECMA3 if (!JS2VAL_IS_OBJECT(a)) push(JS2VAL_FALSE); else { - JS2Object *aObj = JS2VAL_TO_OBJECT(a); + aObj = JS2VAL_TO_OBJECT(a); if (aObj->kind != SimpleInstanceKind) meta->reportError(Exception::typeError, "Prototype instance expected for instanceof", errorPos()); - js2val a_protoVal = checked_cast(aObj)->super; - - js2val b_protoVal; - Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere - JS2Class *limit = meta->objectType(b); - if (limit->Read(meta, &b, &mn, meta->env, RunPhase, &b_protoVal)) { - if (!JS2VAL_IS_OBJECT(b_protoVal)) - meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos()); - } + a_protoVal = checked_cast(aObj)->super; + { + Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere + JS2Class *limit = meta->objectType(b); + if (limit->Read(meta, &b, &mn, meta->env, RunPhase, &b_protoVal)) { + if (!JS2VAL_IS_OBJECT(b_protoVal)) + meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos()); + } + } +doInstanceOfLoop: bool result = false; while (!JS2VAL_IS_NULL(a_protoVal) && !JS2VAL_IS_UNDEFINED(a_protoVal)) { if (b_protoVal == a_protoVal) { @@ -350,13 +354,13 @@ doCall: if (!JS2VAL_IS_OBJECT(a)) push(JS2VAL_FALSE); else { - JS2Object *aObj = JS2VAL_TO_OBJECT(a); + aObj = JS2VAL_TO_OBJECT(a); if (aObj->kind != SimpleInstanceKind) meta->reportError(Exception::typeError, "Prototype instance expected for instanceof", errorPos()); - js2val a_protoVal = checked_cast(aObj)->super; - - js2val b_protoVal = checked_cast(obj)->prototype; - + a_protoVal = checked_cast(aObj)->super; + b_protoVal = checked_cast(obj)->prototype; + goto doInstanceOfLoop; +/* bool result = false; while (!JS2VAL_IS_NULL(a_protoVal) && !JS2VAL_IS_UNDEFINED(a_protoVal)) { if (b_protoVal == a_protoVal) { @@ -371,6 +375,7 @@ doCall: a_protoVal = checked_cast(aObj)->super; } push(BOOLEAN_TO_JS2VAL(result)); +*/ } } else diff --git a/mozilla/js2/src/lexer.cpp b/mozilla/js2/src/lexer.cpp index fe1871df5b0..1ae59c23d4b 100644 --- a/mozilla/js2/src/lexer.cpp +++ b/mozilla/js2/src/lexer.cpp @@ -290,8 +290,15 @@ char16 JS::Lexer::lexEscape(bool unicodeOnly) while (nDigits--) { ch = getChar(); uint digit; - if (!isASCIIHexDigit(ch, digit)) - goto error; + if (!isASCIIHexDigit(ch, digit)) { + /* E3 compatibility, back off */ + // goto error; + do { + reader.unget(); + ch = peekChar(); + } while (ch != '\\'); + return getChar(); + } n = (n << 4) | digit; } return static_cast(n); @@ -306,7 +313,7 @@ char16 JS::Lexer::lexEscape(bool unicodeOnly) */ return ch; } - error: +// error: syntaxError("Bad escape code"); return 0; } @@ -726,7 +733,11 @@ void JS::Lexer::lexToken(bool preferRegExp) reader.unget(); // Number number: kind = Token::number; - lexingUnit = lexNumeral(); +#ifdef PARSE_UNIT + lexingUnit = +#else + lexNumeral(); +#endif break; default: diff --git a/mozilla/js2/src/parser.cpp b/mozilla/js2/src/parser.cpp index 14f018f2764..47a0b29604a 100644 --- a/mozilla/js2/src/parser.cpp +++ b/mozilla/js2/src/parser.cpp @@ -374,12 +374,14 @@ JS::ExprNode *JS::Parser::parsePrimaryExpression(SuperState superState) case Token::number: { +#ifdef PARSE_UNITS const Token &tUnit = lexer.peek(false); if (!lineBreakBefore(tUnit) && (tUnit.hasKind(Token::unit) || tUnit.hasKind(Token::string))) { lexer.skip(); e = parseUnitSuffixes(new(arena) NumUnitExprNode(t.getPos(), ExprNode::numUnit, copyTokenChars(t), t.getValue(), copyTokenChars(tUnit))); } else +#endif e = new(arena) NumberExprNode(t); } break; diff --git a/mozilla/js2/src/parser.h b/mozilla/js2/src/parser.h index a83efb75874..ad2cc137045 100644 --- a/mozilla/js2/src/parser.h +++ b/mozilla/js2/src/parser.h @@ -149,9 +149,9 @@ namespace JavaScript { JS2Runtime::JSObject *scope; // ditto #endif #ifdef EPIMETHEUS - MetaData::Member *member; // the associated definition, - MetaData::InstanceMember *overridden; // overridden member... - MetaData::Multiname *mn; // ...and name constructed by the semantics phase + MetaData::Member *member; // the associated definition, [used to resolve eventual type] + MetaData::InstanceMember *overridden; // overridden member... [used for resolving override legality] + MetaData::Multiname *mn; // ...and name constructed by the semantics phase. [used for emitting initialization sequence] #endif VariableBinding(size_t pos, const StringAtom *name, ExprNode *type, ExprNode *initializer, bool constant):