зеркало из https://github.com/mozilla/pjs.git
New implementation of read/write handling, fixed gc bugs etc.
This commit is contained in:
Родитель
08874ced8a
Коммит
dfc97970bc
|
@ -84,8 +84,7 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
|
|||
}
|
||||
Multiname *mn = new Multiname(meta->engine->length_StringAtom, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, &lookup, true, result, false);
|
||||
defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, meta->env, true, result, false);
|
||||
}
|
||||
else {
|
||||
JS2Class *c = meta->objectType(obj);
|
||||
|
@ -227,6 +226,7 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin
|
|||
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
|
||||
DEFINE_ROOTKEEPER(rk, A);
|
||||
uint32 n = 0;
|
||||
uint32 i = 0;
|
||||
|
||||
|
@ -383,6 +383,7 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg
|
|||
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
|
||||
DEFINE_ROOTKEEPER(rk, A);
|
||||
|
||||
uint32 length = getLength(meta, thisObj);
|
||||
|
||||
|
@ -583,25 +584,22 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv
|
|||
JS2Object *thisObj = JS2VAL_TO_OBJECT(thatValue);
|
||||
uint32 length = getLength(meta, thisObj);
|
||||
|
||||
if (length > 0) {
|
||||
uint32 i;
|
||||
js2val *vec = new js2val[length];
|
||||
uint32 i;
|
||||
// XXX bogus! new[] was supposed to behave itself, not just assert fail or crash
|
||||
if (length > 0x1000000)
|
||||
meta->reportError(Exception::internalError, "out of memory", meta->engine->errorPos());
|
||||
|
||||
JS2Class *c = meta->objectType(thisObj);
|
||||
// XXX Need to root the Strings somewhere, this'll do for now..
|
||||
Multiname *mn1 = new Multiname(meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk1, mn1);
|
||||
for (i = 0; i < length; i++) {
|
||||
mn1->name = meta->engine->numberToString(i);
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &vec[i]);
|
||||
}
|
||||
js2val *vec = new js2val[length];
|
||||
|
||||
js_qsort(vec, length, &ca);
|
||||
JS2Class *c = meta->objectType(thisObj);
|
||||
for (i = 0; i < length; i++) {
|
||||
c->readPublic(meta, &thatValue, c, meta->engine->numberToString(i), RunPhase, &vec[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
mn1->name = meta->engine->numberToString(i);
|
||||
c->writePublic(meta, thatValue, c, mn1->name, true, vec[i]);
|
||||
}
|
||||
js_qsort(vec, length, &ca);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
c->writePublic(meta, thatValue, c, meta->engine->numberToString(i), true, vec[i]);
|
||||
}
|
||||
return thatValue;
|
||||
}
|
||||
|
@ -618,6 +616,7 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
|||
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
|
||||
DEFINE_ROOTKEEPER(rk, A);
|
||||
|
||||
int32 arg0 = meta->toInteger(argv[0]);
|
||||
uint32 start;
|
||||
|
|
|
@ -97,6 +97,11 @@ namespace MetaData {
|
|||
DEFINE_ROOTKEEPER(rk2, astr);
|
||||
DEFINE_ROOTKEEPER(rk3, bstr);
|
||||
|
||||
DEFINE_ROOTKEEPER(rk4, a);
|
||||
DEFINE_ROOTKEEPER(rk5, b);
|
||||
DEFINE_ROOTKEEPER(rk6, baseVal);
|
||||
DEFINE_ROOTKEEPER(rk7, indexVal);
|
||||
|
||||
retval = JS2VAL_VOID;
|
||||
while (true) {
|
||||
try {
|
||||
|
@ -125,6 +130,7 @@ namespace MetaData {
|
|||
// one that matches the handler's. The bytecode container, pc and
|
||||
// sp are all reset appropriately, and execution continues.
|
||||
HandlerData *hndlr = (HandlerData *)mTryStack.top();
|
||||
// mTryStack.pop();
|
||||
ActivationFrame *curAct = (activationStackEmpty()) ? NULL : (activationStackTop - 1);
|
||||
|
||||
js2val x = JS2VAL_UNDEFINED;
|
||||
|
@ -247,6 +253,13 @@ namespace MetaData {
|
|||
return result;
|
||||
}
|
||||
|
||||
String *JS2Engine::allocStringPtr(const char16 *s, uint32 length)
|
||||
{
|
||||
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
|
||||
String *result = new (p) String(s, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
String *JS2Engine::allocStringPtr(const String *s)
|
||||
{
|
||||
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
|
||||
|
@ -977,7 +990,8 @@ namespace MetaData {
|
|||
// jump to start of new bytecodeContainer
|
||||
void JS2Engine::jsr(Phase execPhase, BytecodeContainer *new_bCon, uint32 stackBase, js2val returnVal, Environment *env)
|
||||
{
|
||||
ASSERT(activationStackTop < (activationStack + MAX_ACTIVATION_STACK));
|
||||
if (activationStackTop >= (activationStack + MAX_ACTIVATION_STACK))
|
||||
meta->reportError(Exception::internalError, "out of activation stack", meta->engine->errorPos());
|
||||
activationStackTop->bCon = bCon;
|
||||
activationStackTop->pc = pc;
|
||||
activationStackTop->phase = phase;
|
||||
|
|
|
@ -238,12 +238,14 @@ public:
|
|||
js2val posInfValue;
|
||||
js2val negInfValue;
|
||||
|
||||
js2val allocString(const String *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
|
||||
js2val allocString(const String &s) { return allocString(&s); }
|
||||
js2val allocString(const char *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
|
||||
js2val allocString(const String *s, uint32 index, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, index, length)); }
|
||||
js2val allocString(const String *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
|
||||
js2val allocString(const String &s) { return allocString(&s); }
|
||||
js2val allocString(const char *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
|
||||
js2val allocString(const char16 *s, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, length)); }
|
||||
js2val allocString(const String *s, uint32 index, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, index, length)); }
|
||||
String *allocStringPtr(const String *s);
|
||||
String *allocStringPtr(const char *s);
|
||||
String *allocStringPtr(const char16 *s, uint32 length);
|
||||
String *allocStringPtr(const String *s, uint32 index, uint32 length);
|
||||
String *concatStrings(const String *s1, const String *s2);
|
||||
|
||||
|
|
|
@ -108,7 +108,6 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u
|
|||
{
|
||||
js2val thatValue = thisValue;
|
||||
js2val result;
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname mn(&meta->world.identifiers["message"], meta->publicNamespace);
|
||||
|
||||
JS2Class *c = meta->objectType(thatValue);
|
||||
|
|
|
@ -625,7 +625,7 @@ namespace MetaData {
|
|||
}
|
||||
|
||||
|
||||
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval)
|
||||
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval)
|
||||
{
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, ReadAccess);
|
||||
if (mBase)
|
||||
|
@ -635,9 +635,10 @@ namespace MetaData {
|
|||
|
||||
Member *m = meta->findCommonMember(base, multiname, ReadAccess, false);
|
||||
if (m == NULL) {
|
||||
if (lookupKind->isPropertyLookup() && JS2VAL_IS_OBJECT(*base)
|
||||
&& ( (JS2VAL_TO_OBJECT(*base)->kind == SimpleInstanceKind) && !checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(*base))->sealed)
|
||||
|| ( (JS2VAL_TO_OBJECT(*base)->kind == PackageKind) && !checked_cast<Package *>(JS2VAL_TO_OBJECT(*base))->sealed) ) {
|
||||
if ((env == NULL)
|
||||
&& JS2VAL_IS_OBJECT(*base)
|
||||
&& (( (JS2VAL_TO_OBJECT(*base)->kind == SimpleInstanceKind) && !checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(*base))->sealed)
|
||||
|| ( (JS2VAL_TO_OBJECT(*base)->kind == PackageKind) && !checked_cast<Package *>(JS2VAL_TO_OBJECT(*base))->sealed) ) ) {
|
||||
if (phase == CompilePhase)
|
||||
meta->reportError(Exception::compileExpressionError, "Inappropriate compile time expression", meta->engine->errorPos());
|
||||
else {
|
||||
|
@ -661,14 +662,12 @@ namespace MetaData {
|
|||
case Member::InstanceMethodMember:
|
||||
case Member::InstanceGetterMember:
|
||||
case Member::InstanceSetterMember:
|
||||
if ( (JS2VAL_IS_OBJECT(*base) && (JS2VAL_TO_OBJECT(*base)->kind != ClassKind))
|
||||
|| lookupKind->isPropertyLookup())
|
||||
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
|
||||
if (JS2VAL_IS_VOID(lookupKind->thisObject))
|
||||
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
|
||||
if (JS2VAL_IS_UNINITIALIZED(lookupKind->thisObject))
|
||||
meta->reportError(Exception::compileExpressionError, "Inappropriate compile time expression", meta->engine->errorPos());
|
||||
return meta->readInstanceMember(lookupKind->thisObject, meta->objectType(lookupKind->thisObject), checked_cast<InstanceMember *>(m), phase, rval);
|
||||
{
|
||||
if (!JS2VAL_IS_OBJECT(*base) || (JS2VAL_TO_OBJECT(*base)->kind != ClassKind) || (env == NULL))
|
||||
meta->reportError(Exception::referenceError, "Can't read an instance member without supplying an instance", meta->engine->errorPos());
|
||||
js2val thisVal = env->readImplicitThis(meta);
|
||||
return meta->readInstanceMember(thisVal, meta->objectType(thisVal), checked_cast<InstanceMember *>(m), phase, rval);
|
||||
}
|
||||
default:
|
||||
NOT_REACHED("bad member kind");
|
||||
return false;
|
||||
|
@ -679,44 +678,44 @@ namespace MetaData {
|
|||
{
|
||||
// XXX could speed up by pushing knowledge of single namespace?
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = new Multiname(name, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
return defaultReadProperty(meta, base, limit, mn, &lookup, phase, rval);
|
||||
return defaultReadProperty(meta, base, limit, mn, NULL, phase, rval);
|
||||
}
|
||||
|
||||
bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result)
|
||||
{
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
// XXX could speed up by pushing knowledge of single namespace & lookup?
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
// XXX could speed up by pushing knowledge of single namespace?
|
||||
Multiname *mn = new Multiname(name, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
return defaultDeleteProperty(meta, base, limit, mn, &lookup, result);
|
||||
return defaultDeleteProperty(meta, base, limit, mn, NULL, result);
|
||||
}
|
||||
|
||||
bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
|
||||
{
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
// XXX could speed up by pushing knowledge of single namespace?
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = new Multiname(name, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
return defaultWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue, false);
|
||||
return defaultWriteProperty(meta, base, limit, mn, NULL, createIfMissing, newValue, false);
|
||||
}
|
||||
|
||||
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval)
|
||||
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval)
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
return limit->read(meta, base, limit, multiname, &lookup, phase, rval);
|
||||
const String *indexStr = meta->toString(indexVal);
|
||||
DEFINE_ROOTKEEPER(rk, indexStr);
|
||||
Multiname *mn = new Multiname(indexStr, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk1, mn);
|
||||
return limit->read(meta, base, limit, mn, NULL, phase, rval);
|
||||
}
|
||||
|
||||
bool arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag)
|
||||
bool arrayClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag)
|
||||
{
|
||||
ASSERT(JS2VAL_IS_OBJECT(base));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(base);
|
||||
|
||||
bool result = defaultWriteProperty(meta, base, limit, multiname, lookupKind, createIfMissing, newValue, false);
|
||||
bool result = defaultWriteProperty(meta, base, limit, 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);
|
||||
|
@ -735,17 +734,16 @@ namespace MetaData {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
|
||||
bool arrayClass_WritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
|
||||
{
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
// XXX could speed up by pushing knowledge of single namespace?
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = new Multiname(name, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
return arrayWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue, false);
|
||||
return arrayClass_WriteProperty(meta, base, limit, mn, meta->env, createIfMissing, newValue, false);
|
||||
}
|
||||
|
||||
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag)
|
||||
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag)
|
||||
{
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess);
|
||||
if (mBase) {
|
||||
|
@ -794,26 +792,29 @@ namespace MetaData {
|
|||
case Member::InstanceMethodMember:
|
||||
case Member::InstanceGetterMember:
|
||||
case Member::InstanceSetterMember:
|
||||
if ( (JS2VAL_IS_OBJECT(base) && (JS2VAL_TO_OBJECT(base)->kind != ClassKind))
|
||||
|| lookupKind->isPropertyLookup())
|
||||
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
|
||||
if (JS2VAL_IS_VOID(lookupKind->thisObject))
|
||||
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
|
||||
meta->writeInstanceMember(lookupKind->thisObject, meta->objectType(lookupKind->thisObject), checked_cast<InstanceMember *>(m), newValue);
|
||||
return true;
|
||||
{
|
||||
if ( !JS2VAL_IS_OBJECT(base) || (JS2VAL_TO_OBJECT(base)->kind != ClassKind) || (env == NULL))
|
||||
meta->reportError(Exception::referenceError, "Can't write an instance member withoutsupplying an instance", meta->engine->errorPos());
|
||||
js2val thisVal = env->readImplicitThis(meta);
|
||||
meta->writeInstanceMember(thisVal, meta->objectType(thisVal), checked_cast<InstanceMember *>(m), newValue);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
NOT_REACHED("bad member kind");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue)
|
||||
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue)
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
return limit->write(meta, base, limit, multiname, &lookup, true, newValue, false);
|
||||
const String *indexStr = meta->toString(indexVal);
|
||||
DEFINE_ROOTKEEPER(rk, indexStr);
|
||||
Multiname *mn = new Multiname(indexStr, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk1, mn);
|
||||
return limit->write(meta, base, limit, mn, NULL, true, newValue, false);
|
||||
}
|
||||
|
||||
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result)
|
||||
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result)
|
||||
{
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess);
|
||||
if (mBase) {
|
||||
|
@ -882,12 +883,11 @@ VariableMemberCommon:
|
|||
case Member::InstanceMethodMember:
|
||||
case Member::InstanceGetterMember:
|
||||
case Member::InstanceSetterMember:
|
||||
if ( (JS2VAL_IS_OBJECT(base) && (JS2VAL_TO_OBJECT(base)->kind != ClassKind)) || lookupKind->isPropertyLookup()) {
|
||||
if ( (!JS2VAL_IS_OBJECT(base) || (JS2VAL_TO_OBJECT(base)->kind != ClassKind)) || (env == NULL)) {
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
if (JS2VAL_IS_VOID(lookupKind->thisObject))
|
||||
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
|
||||
env->readImplicitThis(meta);
|
||||
*result = false;
|
||||
return true;
|
||||
default:
|
||||
|
@ -896,10 +896,13 @@ VariableMemberCommon:
|
|||
}
|
||||
}
|
||||
|
||||
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result)
|
||||
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result)
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
return limit->deleteProperty(meta, base, limit, multiname, &lookup, result);
|
||||
const String *indexStr = meta->toString(indexVal);
|
||||
DEFINE_ROOTKEEPER(rk, indexStr);
|
||||
Multiname *mn = new Multiname(indexStr, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk1, mn);
|
||||
return limit->deleteProperty(meta, base, limit, mn, NULL, result);
|
||||
}
|
||||
|
||||
js2val defaultImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass)
|
||||
|
@ -943,6 +946,32 @@ VariableMemberCommon:
|
|||
return BOOLEAN_TO_JS2VAL(result);
|
||||
}
|
||||
|
||||
bool stringClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval)
|
||||
{
|
||||
if (JS2VAL_IS_INT(indexVal)) {
|
||||
const String *str = NULL;
|
||||
if (JS2VAL_IS_STRING(*base)) {
|
||||
str = JS2VAL_TO_STRING(*base);
|
||||
}
|
||||
else {
|
||||
ASSERT(JS2VAL_IS_OBJECT(*base));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(*base);
|
||||
ASSERT((obj->kind == SimpleInstanceKind) && (checked_cast<SimpleInstance *>(obj)->type == meta->stringClass));
|
||||
StringInstance *a = checked_cast<StringInstance *>(obj);
|
||||
str = a->mValue;
|
||||
}
|
||||
int32 i = JS2VAL_TO_INT(indexVal);
|
||||
if ((i >= 0) && (i < str->length()))
|
||||
*rval = meta->engine->allocString(&(*str)[i], 1);
|
||||
else
|
||||
*rval = JS2VAL_UNDEFINED;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return defaultBracketRead(meta, base, limit, indexVal, phase, rval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}; // namespace MetaData
|
||||
}; // namespace Javascript
|
||||
|
|
|
@ -2813,6 +2813,20 @@ doUnary:
|
|||
return false;
|
||||
}
|
||||
|
||||
js2val Environment::readImplicitThis(JS2Metadata *meta)
|
||||
{
|
||||
ParameterFrame *pFrame = getEnclosingParameterFrame();
|
||||
if (pFrame == NULL)
|
||||
meta->reportError(Exception::referenceError, "Can't access instance members outside an instance method without supplying an instance object", meta->engine->errorPos());
|
||||
js2val thisVal = pFrame->thisObject;
|
||||
if ((!JS2VAL_IS_OBJECT(thisVal) || JS2VAL_IS_NULL(thisVal)) || !pFrame->isInstance || !pFrame->isConstructor)
|
||||
meta->reportError(Exception::referenceError, "Can't access instance members inside a non-instance method without supplying an instance object", meta->engine->errorPos());
|
||||
if (!pFrame->superConstructorCalled)
|
||||
meta->reportError(Exception::uninitializedError, "Can't access instance members from within a constructor before the superconstructor has been called", meta->engine->errorPos());
|
||||
return thisVal;
|
||||
}
|
||||
|
||||
|
||||
// Read the value of a lexical reference - it's an error if that reference
|
||||
// doesn't have a binding somewhere.
|
||||
// Attempt the read in each frame in the current environment, stopping at the
|
||||
|
@ -2822,7 +2836,6 @@ doUnary:
|
|||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
LookupKind lookup(true, a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
|
@ -2832,7 +2845,7 @@ doUnary:
|
|||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
js2val frame = OBJECT_TO_JS2VAL(*fi);
|
||||
result = limit->read(meta, &frame, limit, multiname, &lookup, phase, rval);
|
||||
result = limit->read(meta, &frame, limit, multiname, this, phase, rval);
|
||||
}
|
||||
break;
|
||||
case SystemKind:
|
||||
|
@ -2850,7 +2863,7 @@ doUnary:
|
|||
// XXX uninitialized 'with' object?
|
||||
js2val withVal = OBJECT_TO_JS2VAL(wf->obj);
|
||||
JS2Class *limit = meta->objectType(withVal);
|
||||
result = limit->read(meta, &withVal, limit, multiname, &lookup, phase, rval);
|
||||
result = limit->read(meta, &withVal, limit, multiname, this, phase, rval);
|
||||
if (result && base)
|
||||
*base = withVal;
|
||||
}
|
||||
|
@ -2869,7 +2882,6 @@ doUnary:
|
|||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
LookupKind lookup(true, a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
|
@ -2878,7 +2890,7 @@ doUnary:
|
|||
case PackageKind:
|
||||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, false, newValue, false);
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, false);
|
||||
}
|
||||
break;
|
||||
case SystemKind:
|
||||
|
@ -2897,7 +2909,7 @@ doUnary:
|
|||
WithFrame *wf = checked_cast<WithFrame *>(*fi);
|
||||
// XXX uninitialized 'with' object?
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, false, newValue, false);
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2908,7 +2920,7 @@ doUnary:
|
|||
if (createIfMissing) {
|
||||
Package *pkg = getPackageFrame();
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(pkg));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, &lookup, true, newValue, false);
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, this, true, newValue, false);
|
||||
if (result)
|
||||
return;
|
||||
}
|
||||
|
@ -2923,7 +2935,6 @@ doUnary:
|
|||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
LookupKind lookup(true, a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
|
@ -2932,7 +2943,7 @@ doUnary:
|
|||
case PackageKind:
|
||||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, false, newValue, true);
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, true);
|
||||
}
|
||||
break;
|
||||
case SystemKind:
|
||||
|
@ -2951,7 +2962,7 @@ doUnary:
|
|||
WithFrame *wf = checked_cast<WithFrame *>(*fi);
|
||||
// XXX uninitialized 'with' object?
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, false, newValue, true);
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2963,7 +2974,7 @@ doUnary:
|
|||
ASSERT(false);
|
||||
Package *pkg = getPackageFrame();
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(pkg));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, &lookup, true, newValue, true);
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, this, true, newValue, true);
|
||||
if (result)
|
||||
return;
|
||||
}
|
||||
|
@ -2974,7 +2985,6 @@ doUnary:
|
|||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
LookupKind lookup(true, a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
|
@ -2983,7 +2993,7 @@ doUnary:
|
|||
case PackageKind:
|
||||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, &result))
|
||||
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, &result))
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
@ -3001,7 +3011,7 @@ doUnary:
|
|||
WithFrame *wf = checked_cast<WithFrame *>(*fi);
|
||||
// XXX uninitialized 'with' object?
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
|
||||
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, &result))
|
||||
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, &result))
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
@ -3773,16 +3783,16 @@ static const uint8 urlCharType[256] =
|
|||
return thisValue;
|
||||
}
|
||||
|
||||
bool nullClass_ReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval) { return false; }
|
||||
bool nullClass_ReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval) { return false; }
|
||||
bool nullClass_ReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval) { return false; }
|
||||
bool nullClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval) { return false; }
|
||||
bool nullClass_arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue) { return false; }
|
||||
bool nullClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag) { return false; }
|
||||
bool nullClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval) { return false; }
|
||||
bool nullClass_arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue) { return false; }
|
||||
bool nullClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { return false; }
|
||||
bool nullClass_WritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) { return false; }
|
||||
bool nullClass_BracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue) { return false; }
|
||||
bool nullClass_DeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result) { return false; }
|
||||
bool nullClass_BracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue) { return false; }
|
||||
bool nullClass_DeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result) { return false; }
|
||||
bool nullClass_DeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result) { return false; }
|
||||
bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result) { return false; }
|
||||
bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result) { return false; }
|
||||
|
||||
#define MAKEBUILTINCLASS(c, super, dynamic, final, name, defaultVal) c = new JS2Class(super, NULL, new Namespace(engine->private_StringAtom), dynamic, final, name); c->complete = true; c->defaultValue = defaultVal;
|
||||
|
||||
|
@ -3823,6 +3833,8 @@ bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Mu
|
|||
integerClass->is = integerIs;
|
||||
MAKEBUILTINCLASS(characterClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Character"]), JS2VAL_ZERO);
|
||||
MAKEBUILTINCLASS(stringClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["String"]), JS2VAL_NULL);
|
||||
stringClass->bracketRead = stringClass_BracketRead;
|
||||
|
||||
MAKEBUILTINCLASS(namespaceClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["namespace"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(attributeClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["attribute"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(classClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Class"]), JS2VAL_NULL);
|
||||
|
@ -3955,8 +3967,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
|
||||
/*** ECMA 3 Array Class ***/
|
||||
MAKEBUILTINCLASS(arrayClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Array"]), JS2VAL_NULL);
|
||||
arrayClass->write = arrayWriteProperty;
|
||||
arrayClass->writePublic = arrayWritePublic;
|
||||
arrayClass->write = arrayClass_WriteProperty;
|
||||
arrayClass->writePublic = arrayClass_WritePublic;
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(arrayClass), true);
|
||||
defineLocalMember(env, &world.identifiers["Array"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
initArrayObject(this);
|
||||
|
@ -4852,10 +4864,11 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
JS2Object *result = this;
|
||||
DEFINE_ROOTKEEPER(rk1, result);
|
||||
|
||||
JS2Object *obj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass);
|
||||
DEFINE_ROOTKEEPER(rk2, obj);
|
||||
JS2Object *protoObj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass);
|
||||
DEFINE_ROOTKEEPER(rk2, protoObj);
|
||||
|
||||
meta->createDynamicProperty(this, meta->engine->prototype_StringAtom, OBJECT_TO_JS2VAL(obj), ReadWriteAccess, true, false);
|
||||
meta->createDynamicProperty(this, meta->engine->prototype_StringAtom, OBJECT_TO_JS2VAL(protoObj), ReadWriteAccess, true, false);
|
||||
meta->createDynamicProperty(protoObj, &meta->world.identifiers["constructor"], OBJECT_TO_JS2VAL(this), ReadWriteAccess, true, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5106,28 +5119,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
************************************************************************************/
|
||||
|
||||
Pond JS2Object::pond(POND_SIZE, NULL);
|
||||
#ifdef DEBUG
|
||||
std::list<RootKeeper *> JS2Object::rootList;
|
||||
#else
|
||||
std::list<PondScum **> JS2Object::rootList;
|
||||
#endif
|
||||
|
||||
// Add a pointer to the (address of a) gc-allocated object to the root list
|
||||
// (Note - we hand out an iterator, so it's essential to
|
||||
// use something like std::list that doesn't mess with locations)
|
||||
#ifdef DEBUG
|
||||
JS2Object::RootIterator JS2Object::addRoot(RootKeeper *t)
|
||||
{
|
||||
return rootList.insert(rootList.end(), t);
|
||||
}
|
||||
#else
|
||||
JS2Object::RootIterator JS2Object::addRoot(void *t)
|
||||
{
|
||||
PondScum **p = (PondScum **)t;
|
||||
ASSERT(p);
|
||||
return rootList.insert(rootList.end(), p);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Remove a root pointer
|
||||
void JS2Object::removeRoot(RootIterator ri)
|
||||
|
@ -5152,22 +5152,20 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
PondScum *scum = NULL;
|
||||
if (r->is_js2val) {
|
||||
js2val *valp = (js2val *)(r->p);
|
||||
if (JS2VAL_IS_OBJECT(*valp))
|
||||
scum = ((PondScum *)(JS2VAL_TO_OBJECT(*valp))) - 1;
|
||||
markJS2Value(*valp);
|
||||
}
|
||||
else {
|
||||
JS2Object *objp = (JS2Object *)(r->p);
|
||||
if (objp)
|
||||
scum = ((PondScum *)objp - 1);
|
||||
}
|
||||
if (scum) {
|
||||
ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY));
|
||||
if (scum->isJS2Object()) {
|
||||
JS2Object *obj = (JS2Object *)(scum + 1);
|
||||
GCMARKOBJECT(obj)
|
||||
JS2Object **objp = (JS2Object **)(r->p);
|
||||
if (*objp) {
|
||||
scum = ((PondScum *)(*objp) - 1);
|
||||
ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY));
|
||||
if (scum->isJS2Object()) {
|
||||
JS2Object *obj = (JS2Object *)(scum + 1);
|
||||
GCMARKOBJECT(obj)
|
||||
}
|
||||
else
|
||||
mark(scum + 1);
|
||||
}
|
||||
else
|
||||
mark(scum + 1);
|
||||
}
|
||||
}
|
||||
return pond.moveUnmarkedToFreeList();
|
||||
|
|
|
@ -56,7 +56,6 @@ class StringInstance;
|
|||
class FunctionInstance;
|
||||
class ArrayInstance;
|
||||
class RegExpInstance;
|
||||
class LookupKind;
|
||||
class Package;
|
||||
|
||||
typedef void (Invokable)();
|
||||
|
@ -64,35 +63,37 @@ typedef js2val (Callor)(JS2Metadata *meta, const js2val thisValue, js2val *argv,
|
|||
typedef js2val (Constructor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
|
||||
typedef js2val (NativeCode)(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc);
|
||||
|
||||
typedef bool (Read)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
typedef bool (Read)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval);
|
||||
typedef bool (ReadPublic)(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval);
|
||||
typedef bool (Write)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
typedef bool (Write)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
typedef bool (WritePublic)(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
|
||||
typedef bool (DeleteProperty)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result);
|
||||
typedef bool (DeleteProperty)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result);
|
||||
typedef bool (DeletePublic)(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result);
|
||||
typedef bool (BracketRead)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval);
|
||||
typedef bool (BracketWrite)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue);
|
||||
typedef bool (BracketDelete)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result);
|
||||
typedef bool (BracketRead)(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval);
|
||||
typedef bool (BracketWrite)(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue);
|
||||
typedef bool (BracketDelete)(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result);
|
||||
typedef js2val (ImplicitCoerce)(JS2Metadata *meta, js2val newValue, JS2Class *toClass);
|
||||
typedef js2val (Is)(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
|
||||
|
||||
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval);
|
||||
bool defaultReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval);
|
||||
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval);
|
||||
bool arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval);
|
||||
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
|
||||
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue);
|
||||
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result);
|
||||
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue);
|
||||
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result);
|
||||
bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result);
|
||||
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result);
|
||||
bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
|
||||
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result);
|
||||
|
||||
bool arrayClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
bool arrayClass_WritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
|
||||
|
||||
js2val defaultImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
|
||||
js2val defaultIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
|
||||
js2val integerImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
|
||||
js2val integerIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
|
||||
|
||||
|
||||
bool stringClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval);
|
||||
|
||||
extern void initDateObject(JS2Metadata *meta);
|
||||
extern void initStringObject(JS2Metadata *meta);
|
||||
|
@ -253,10 +254,16 @@ public:
|
|||
static void markJS2Value(js2val v);
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p, int line, char *pfile) : is_js2val(false), p(p) { init(line, pfile); }
|
||||
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__);
|
||||
#else
|
||||
#define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p) : is_js2val(false), p(p) { ri = JS2Object::addRoot(this); }
|
||||
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj);
|
||||
#endif
|
||||
|
||||
class RootKeeper {
|
||||
public:
|
||||
#ifdef DEBUG
|
||||
|
||||
ROOTKEEPER_CONSTRUCTOR(JS2Object)
|
||||
ROOTKEEPER_CONSTRUCTOR(RegExpInstance)
|
||||
|
@ -274,22 +281,18 @@ public:
|
|||
ROOTKEEPER_CONSTRUCTOR(FunctionInstance)
|
||||
ROOTKEEPER_CONSTRUCTOR(DateInstance)
|
||||
|
||||
RootKeeper(js2val *p, int line, char *pfile) : is_js2val(true), p(p)
|
||||
{
|
||||
init(line, pfile);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
RootKeeper(js2val *p, int line, char *pfile) : is_js2val(true), p(p) { init(line, pfile); }
|
||||
~RootKeeper() { JS2Object::removeRoot(ri); delete file; }
|
||||
|
||||
void RootKeeper::init(int line, char *pfile)
|
||||
void RootKeeper::init(int ln, char *pfile)
|
||||
{
|
||||
line = line;
|
||||
line = ln;
|
||||
file = new char[strlen(pfile) + 1];
|
||||
strcpy(file, pfile);
|
||||
ri = JS2Object::addRoot(this);
|
||||
}
|
||||
#else
|
||||
RootKeeper(JS2Object **p) : is_js2val(false), p(p), { ri = JS2Object::addRoot(p); }
|
||||
RootKeeper(js2val *p) : is_js2val(true), p(p) { ri = JS2Object::addRoot(p); }
|
||||
RootKeeper(js2val *p) : is_js2val(true), p(p) { ri = JS2Object::addRoot(this); }
|
||||
~RootKeeper() { JS2Object::removeRoot(ri); }
|
||||
#endif
|
||||
|
||||
|
@ -303,11 +306,6 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__);
|
||||
#else
|
||||
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj);
|
||||
#endif
|
||||
|
||||
class Attribute : public JS2Object {
|
||||
public:
|
||||
|
@ -740,6 +738,7 @@ public:
|
|||
void removeTopFrame() { frameList.pop_front(); }
|
||||
|
||||
bool findThis(JS2Metadata *meta, bool allowPrototypeThis, js2val *result);
|
||||
js2val readImplicitThis(JS2Metadata *meta);
|
||||
void lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase, js2val *rval, js2val *base);
|
||||
void lexicalWrite(JS2Metadata *meta, Multiname *multiname, js2val newValue, bool createIfMissing);
|
||||
void lexicalInit(JS2Metadata *meta, Multiname *multiname, js2val newValue);
|
||||
|
@ -1240,6 +1239,7 @@ public:
|
|||
prototype(prototype),
|
||||
buildArguments(false),
|
||||
isConstructor(false),
|
||||
isInstance(false),
|
||||
callsSuperConstructor(false),
|
||||
superConstructorCalled(true)
|
||||
{ }
|
||||
|
@ -1249,6 +1249,7 @@ public:
|
|||
prototype(pluralFrame->prototype),
|
||||
buildArguments(pluralFrame->buildArguments),
|
||||
isConstructor(pluralFrame->isConstructor),
|
||||
isInstance(pluralFrame->isInstance),
|
||||
callsSuperConstructor(pluralFrame->callsSuperConstructor),
|
||||
superConstructorCalled(false) // initialized to false for each construction of a singular frame
|
||||
// and then set true when/if the call occurs
|
||||
|
@ -1262,6 +1263,7 @@ public:
|
|||
bool prototype; // true if this function is not an instance method but defines this anyway
|
||||
bool buildArguments;
|
||||
bool isConstructor;
|
||||
bool isInstance;
|
||||
bool callsSuperConstructor;
|
||||
bool superConstructorCalled;
|
||||
|
||||
|
@ -1286,17 +1288,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class LookupKind {
|
||||
public:
|
||||
LookupKind(bool isLexical, js2val thisObject) : isLexical(isLexical), thisObject(thisObject) { }
|
||||
|
||||
bool isPropertyLookup() { return !isLexical; }
|
||||
|
||||
bool isLexical; // if isLexical, use the 'this' below. Otherwise it's a propertyLookup
|
||||
js2val thisObject;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<Namespace *> NamespaceList;
|
||||
typedef NamespaceList::iterator NamespaceListIterator;
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
// Read a multiname property from a base object, push the value onto the stack
|
||||
case eDotRead:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
|
@ -43,12 +42,12 @@
|
|||
if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) {
|
||||
LimitedInstance *li = checked_cast<LimitedInstance *>(JS2VAL_TO_OBJECT(b));
|
||||
b = OBJECT_TO_JS2VAL(li->instance);
|
||||
if (!li->limit->read(meta, &b, li->limit, mn, &lookup, RunPhase, &a))
|
||||
if (!li->limit->read(meta, &b, li->limit, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
}
|
||||
else {
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->read(meta, &b, limit, mn, &lookup, RunPhase, &a))
|
||||
if (!limit->read(meta, &b, limit, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
}
|
||||
push(a);
|
||||
|
@ -57,13 +56,12 @@
|
|||
|
||||
case eDotDelete:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
bool result;
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->deleteProperty(meta, b, limit, mn, &lookup, &result))
|
||||
if (!limit->deleteProperty(meta, b, limit, mn, NULL, &result))
|
||||
push(JS2VAL_FALSE);
|
||||
else
|
||||
push(BOOLEAN_TO_JS2VAL(result));
|
||||
|
@ -75,7 +73,6 @@
|
|||
case eDotWrite:
|
||||
{
|
||||
a = pop();
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
|
@ -84,14 +81,14 @@
|
|||
if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) {
|
||||
LimitedInstance *li = checked_cast<LimitedInstance *>(JS2VAL_TO_OBJECT(b));
|
||||
b = OBJECT_TO_JS2VAL(li->instance);
|
||||
if (!li->limit->write(meta, b, li->limit, mn, &lookup, true, a, false)) {
|
||||
if (!li->limit->write(meta, b, li->limit, mn, NULL, true, a, false)) {
|
||||
if (!meta->cxt.E3compatibility)
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->write(meta, b, limit, mn, &lookup, true, a, false)) {
|
||||
if (!limit->write(meta, b, limit, mn, NULL, true, a, false)) {
|
||||
if (!meta->cxt.E3compatibility)
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
}
|
||||
|
@ -103,12 +100,11 @@
|
|||
// Read the multiname property, but leave the base and the value on the stack
|
||||
case eDotRef:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->read(meta, &b, limit, mn, &lookup, RunPhase, &a))
|
||||
if (!limit->read(meta, &b, limit, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
push(b);
|
||||
push(a);
|
||||
|
@ -175,32 +171,25 @@
|
|||
{
|
||||
indexVal = pop();
|
||||
b = pop();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case eBracketDelete:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
indexVal = pop();
|
||||
b = pop();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
bool result;
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketDelete(meta, b, limit, &mn, &result))
|
||||
if (!limit->bracketDelete(meta, b, limit, indexVal, &result))
|
||||
push(JS2VAL_FALSE);
|
||||
else
|
||||
push(BOOLEAN_TO_JS2VAL(result));
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -211,48 +200,40 @@
|
|||
a = pop();
|
||||
indexVal = pop();
|
||||
b = pop();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketWrite(meta, b, limit, &mn, a)) {
|
||||
if (!limit->bracketWrite(meta, b, limit, indexVal, a)) {
|
||||
if (!meta->cxt.E3compatibility)
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
}
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
// Leave the base object on the stack and push the property value
|
||||
case eBracketRef:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
indexVal = pop();
|
||||
b = top();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
// Leave the base object and index value, push the value
|
||||
case eBracketReadForRef:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
indexVal = pop();
|
||||
b = top();
|
||||
astr = meta->toString(indexVal);
|
||||
push(STRING_TO_JS2VAL(astr));
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
indexVal = STRING_TO_JS2VAL(astr);
|
||||
push(indexVal);
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), astr);
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
|
@ -262,16 +243,14 @@
|
|||
// Beneath the value is a reference pair (base and index), write to that location but leave just the value
|
||||
case eBracketWriteRef:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
a = pop();
|
||||
indexVal = pop();
|
||||
ASSERT(JS2VAL_IS_STRING(indexVal));
|
||||
ASSERT(JS2VAL_IS_STRING(indexVal)); // because the readForRef above will have executed first
|
||||
b = pop();
|
||||
Multiname mn(&meta->world.identifiers[*JS2VAL_TO_STRING(indexVal)], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketWrite(meta, b, limit, &mn, a)) {
|
||||
if (!limit->bracketWrite(meta, b, limit, indexVal, a)) {
|
||||
if (!meta->cxt.E3compatibility)
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), JS2VAL_TO_STRING(indexVal));
|
||||
}
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
|
|
|
@ -964,15 +964,14 @@
|
|||
|
||||
case eDotPostInc:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
float64 num = meta->toFloat64(a);
|
||||
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num + 1.0), false))
|
||||
if (!limit->write(meta, baseVal, limit, mn, NULL, true, allocNumber(num + 1.0), false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
|
@ -980,15 +979,14 @@
|
|||
break;
|
||||
case eDotPostDec:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
float64 num = meta->toFloat64(a);
|
||||
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num - 1.0), false))
|
||||
if (!limit->write(meta, baseVal, limit, mn, NULL, true, allocNumber(num - 1.0), false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
|
@ -996,32 +994,30 @@
|
|||
break;
|
||||
case eDotPreInc:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num + 1.0);
|
||||
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a, false))
|
||||
if (!limit->write(meta, baseVal, limit, mn, NULL, true, a, false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
break;
|
||||
case eDotPreDec:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num - 1.0);
|
||||
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a, false))
|
||||
if (!limit->write(meta, baseVal, limit, mn, NULL, true, a, false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
|
@ -1029,36 +1025,29 @@
|
|||
|
||||
case eBracketPostInc:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
float64 num = meta->toFloat64(a);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num + 1.0)))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, allocNumber(num + 1.0)))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
}
|
||||
break;
|
||||
case eBracketPostDec:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
float64 num = meta->toFloat64(a);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num - 1.0)))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, allocNumber(num - 1.0)))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
indexVal = JS2VAL_VOID;
|
||||
|
@ -1067,18 +1056,15 @@
|
|||
break;
|
||||
case eBracketPreInc:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num + 1.0);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, &mn, a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
baseVal = JS2VAL_VOID;
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
|
@ -1086,18 +1072,15 @@
|
|||
break;
|
||||
case eBracketPreDec:
|
||||
{
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
astr = meta->toString(indexVal);
|
||||
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num - 1.0);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, &mn, a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
|
||||
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
baseVal = JS2VAL_VOID;
|
||||
indexVal = JS2VAL_VOID;
|
||||
astr = NULL;
|
||||
|
|
|
@ -65,11 +65,8 @@
|
|||
// stack is out of balance anyway...
|
||||
js2val protoVal = OBJECT_TO_JS2VAL(meta->objectClass->prototype);
|
||||
Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere
|
||||
LookupKind lookup(true, JS2VAL_NULL); // make it a lexical lookup since we want it to
|
||||
// fail if 'prototype' hasn't been defined
|
||||
// XXX (prototype should always exist for functions)
|
||||
JS2Class *limit = meta->objectType(a);
|
||||
if (limit->read(meta, &a, limit, &mn, &lookup, RunPhase, &protoVal)) {
|
||||
if (limit->read(meta, &a, limit, &mn, meta->env, RunPhase, &protoVal)) {
|
||||
if (!JS2VAL_IS_OBJECT(protoVal))
|
||||
meta->reportError(Exception::badValueError, "Non-object prototype value", errorPos());
|
||||
}
|
||||
|
@ -291,11 +288,8 @@
|
|||
|
||||
js2val b_protoVal;
|
||||
Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere
|
||||
LookupKind lookup(true, JS2VAL_NULL); // make it a lexical lookup since we want it to
|
||||
// fail if 'prototype' hasn't been defined
|
||||
// XXX (prototype should always exist for functions)
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (limit->read(meta, &b, limit, &mn, &lookup, RunPhase, &b_protoVal)) {
|
||||
if (limit->read(meta, &b, limit, &mn, meta->env, RunPhase, &b_protoVal)) {
|
||||
if (!JS2VAL_IS_OBJECT(b_protoVal))
|
||||
meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos());
|
||||
}
|
||||
|
|
|
@ -41,14 +41,8 @@
|
|||
*/
|
||||
|
||||
|
||||
typedef uint32 jsint;
|
||||
typedef char16 jschar;
|
||||
typedef bool JSBool;
|
||||
typedef uint32 uintN;
|
||||
typedef int32 intN;
|
||||
typedef uint8 jsbytecode;
|
||||
typedef char16 JSString;
|
||||
typedef char16 JSSubString;
|
||||
|
||||
|
||||
typedef struct RECharSet {
|
||||
|
|
|
@ -42,7 +42,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\js\src" /I "../../RegExp" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "EPIMETHEUS" /D "IS_LITTLE_ENDIAN" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /Zi /O2 /I "..\..\..\js\src" /I "../../RegExp" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "EPIMETHEUS" /D "IS_LITTLE_ENDIAN" /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
@ -50,7 +50,7 @@ BSC32=bscmake.exe
|
|||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\..\js\src\release"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\..\..\..\js\src\release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "Epimetheus - Win32 Debug"
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче