This commit is contained in:
rogerl%netscape.com 2003-03-31 02:09:03 +00:00
Родитель 0dcb8105ec
Коммит e15c203bcb
15 изменённых файлов: 436 добавлений и 531 удалений

Просмотреть файл

@ -134,7 +134,7 @@ static js2val Array_toString(JS2Metadata *meta, const js2val thisValue, js2val *
js2val result;
String *s = new String();
for (uint32 i = 0; i < length; i++) {
if (meta->arrayClass->readPublic(meta, thisValue, meta->arrayClass, meta->engine->numberToString(i), RunPhase, &result))
if (meta->arrayClass->readPublic(meta, thisValue, meta->arrayClass, meta->engine->numberToString(i), RunPhase, &result)
&& !JS2VAL_IS_UNDEFINED(result)
&& !JS2VAL_IS_NULL(result) )
s->append(*meta->toString(result));
@ -165,7 +165,7 @@ static js2val Array_toSource(JS2Metadata *meta, const js2val thisValue, js2val *
js2val result;
String *s = new String();
for (uint32 i = 0; i < length; i++) {
if (meta->arrayClass->readPublic(meta, thisValue, meta->arrayClass, meta->engine->numberToString(i), RunPhase, &result))
if (meta->arrayClass->readPublic(meta, thisValue, meta->arrayClass, meta->engine->numberToString(i), RunPhase, &result)
&& !JS2VAL_IS_UNDEFINED(result))
s->append(*meta->toString(result));
if (i < (length - 1))
@ -185,9 +185,9 @@ static js2val Array_push(JS2Metadata *meta, const js2val thisValue, js2val *argv
JS2Object *thisObj = JS2VAL_TO_OBJECT(thisValue);
uint32 length = getLength(meta, thisObj);
JS2Class *c = meta->objectType(thisObj);
for (uint32 i = 0; i < argc; i++) {
meta->mn1->name = meta->engine->numberToString(i + length);
meta->writeDynamicProperty(thisObj, meta->mn1, true, argv[i], RunPhase);
c->writePublic(meta, thisValue, c, meta->engine->numberToString(i + length), true, argv[i]);
}
return setLength(meta, thisObj, length + argc);
}
@ -199,12 +199,11 @@ static js2val Array_pop(JS2Metadata *meta, const js2val thisValue, js2val * /*ar
uint32 length = getLength(meta, thisObj);
if (length > 0) {
meta->mn1->name = meta->engine->numberToString(length - 1);
LookupKind lookup(false, JS2VAL_NULL);
js2val result = JS2VAL_UNDEFINED;
bool deleteResult;
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &result);
meta->deleteProperty(thisValue, meta->mn1, &lookup, RunPhase, &deleteResult);
JS2Class *c = meta->objectType(thisObj);
c->readPublic(meta, thisValue, c, meta->engine->numberToString(length - 1), RunPhase, &result);
c->deletePublic(meta, thisValue, c, meta->engine->numberToString(length - 1), &deleteResult);
setLength(meta, thisObj, length - 1);
return result;
}
@ -220,23 +219,20 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
uint32 n = 0;
uint32 i = 0;
LookupKind lookup(false, JS2VAL_NULL);
do {
if (meta->objectType(E) != meta->arrayClass) {
meta->mn1->name = meta->engine->numberToString(n++);
meta->writeDynamicProperty(A, meta->mn1, true, E, RunPhase);
meta->arrayClass->writePublic(meta, result, meta->arrayClass, meta->engine->numberToString(n++), true, E);
}
else {
ASSERT(JS2VAL_IS_OBJECT(thisValue));
JS2Object *arrObj = JS2VAL_TO_OBJECT(E);
uint32 length = getLength(meta, arrObj);
JS2Class *c = meta->objectType(arrObj);
for (uint32 k = 0; k < length; k++) {
meta->mn1->name = meta->engine->numberToString(k);
js2val rval = JS2VAL_UNDEFINED;
meta->readDynamicProperty(arrObj, meta->mn1, &lookup, RunPhase, &rval);
meta->mn1->name = meta->engine->numberToString(n++);
meta->writeDynamicProperty(A, meta->mn1, true, rval, RunPhase);
c->readPublic(meta, E, c, meta->engine->numberToString(k), RunPhase, &rval);
meta->arrayClass->writePublic(meta, result, meta->arrayClass, meta->engine->numberToString(n++), true, rval);
}
}
E = argv[i++];
@ -258,12 +254,11 @@ static js2val Array_join(JS2Metadata *meta, const js2val thisValue, js2val *argv
separator = meta->toString(argv[0]);
String *S = new String();
LookupKind lookup(false, JS2VAL_NULL);
JS2Class *c = meta->objectType(thisObj);
for (uint32 k = 0; k < length; k++) {
js2val result = JS2VAL_UNDEFINED;
meta->mn1->name = meta->engine->numberToString(k);
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &result);
c->readPublic(meta, thisValue, c, meta->engine->numberToString(k), RunPhase, &result);
if (!JS2VAL_IS_UNDEFINED(result) && !JS2VAL_IS_NULL(result))
*S += *meta->toString(result);
@ -279,45 +274,47 @@ static js2val Array_reverse(JS2Metadata *meta, const js2val thisValue, js2val *
ASSERT(JS2VAL_IS_OBJECT(thisValue));
JS2Object *thisObj = JS2VAL_TO_OBJECT(thisValue);
uint32 length = getLength(meta, thisObj);
LookupKind lookup(false, JS2VAL_NULL);
uint32 halfway = length / 2;
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
RootKeeper rk1(&mn1);
RootKeeper rk2(&mn2);
for (uint32 k = 0; k < halfway; k++) {
bool deleteResult;
js2val result1 = JS2VAL_UNDEFINED;
js2val result2 = JS2VAL_UNDEFINED;
meta->mn1->name = meta->engine->numberToString(k);
meta->mn2->name = meta->engine->numberToString(length - k - 1);
mn1->name = meta->engine->numberToString(k);
mn2->name = meta->engine->numberToString(length - k - 1);
if (meta->hasOwnProperty(thisObj, meta->mn1->name)) {
if (meta->hasOwnProperty(thisObj, meta->mn2->name)) {
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &result1);
meta->readDynamicProperty(thisObj, meta->mn2, &lookup, RunPhase, &result2);
meta->writeDynamicProperty(thisObj, meta->mn1, true, result2, RunPhase);
meta->writeDynamicProperty(thisObj, meta->mn2, true, result1, RunPhase);
if (meta->hasOwnProperty(thisObj, mn1->name)) {
if (meta->hasOwnProperty(thisObj, mn2->name)) {
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &result1);
c->readPublic(meta, thisValue, c, mn2->name, RunPhase, &result2);
c->writePublic(meta, thisValue, c, mn1->name, true, result2);
c->writePublic(meta, thisValue, c, mn2->name, true, result1);
}
else {
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &result1);
meta->writeDynamicProperty(thisObj, meta->mn2, true, result1, RunPhase);
meta->deleteProperty(thisValue, meta->mn1, &lookup, RunPhase, &deleteResult);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &result1);
c->writePublic(meta, thisValue, c, mn2->name, true, result1);
c->deletePublic(meta, thisValue, c, mn1->name, &deleteResult);
}
}
else {
if (meta->hasOwnProperty(thisObj, meta->mn2->name)) {
meta->readDynamicProperty(thisObj, meta->mn2, &lookup, RunPhase, &result2);
meta->writeDynamicProperty(thisObj, meta->mn1, true, result2, RunPhase);
meta->deleteProperty(thisValue, meta->mn2, &lookup, RunPhase, &deleteResult);
if (meta->hasOwnProperty(thisObj, mn2->name)) {
c->readPublic(meta, thisValue, c, mn2->name, RunPhase, &result2);
c->writePublic(meta, thisValue, c, mn1->name, true, result2);
c->deletePublic(meta, thisValue, c, mn2->name, &deleteResult);
}
else {
meta->deleteProperty(thisValue, meta->mn1, &lookup, RunPhase, &deleteResult);
meta->deleteProperty(thisValue, meta->mn2, &lookup, RunPhase, &deleteResult);
c->deletePublic(meta, thisValue, c, mn1->name, &deleteResult);
c->deletePublic(meta, thisValue, c, mn2->name, &deleteResult);
}
}
// XXX would this help?
// delete meta->mn1->name; meta->mn1->name = NULL;
// delete meta->mn2->name; meta->mn2->name = NULL;
}
return thisValue;
@ -334,26 +331,32 @@ static js2val Array_shift(JS2Metadata *meta, const js2val thisValue, js2val * /*
return JS2VAL_UNDEFINED;
}
LookupKind lookup(false, JS2VAL_NULL);
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
RootKeeper rk1(&mn1);
RootKeeper rk2(&mn2);
js2val result;
bool deleteResult;
meta->mn1->name = meta->engine->numberToString((int32)0);
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &result);
mn1->name = meta->engine->numberToString((int32)0);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &result);
for (uint32 k = 1; k < length; k++) {
meta->mn1->name = meta->engine->numberToString(k);
meta->mn2->name = meta->engine->numberToString(k - 1);
mn1->name = meta->engine->numberToString(k);
mn2->name = meta->engine->numberToString(k - 1);
if (meta->hasOwnProperty(thisObj, meta->mn1->name)) {
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &result);
meta->writeDynamicProperty(thisObj, meta->mn2, true, result, RunPhase);
if (meta->hasOwnProperty(thisObj, mn1->name)) {
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &result);
c->writePublic(meta, thisValue, c, mn2->name, true, result);
}
else
meta->deleteProperty(thisValue, meta->mn2, &lookup, RunPhase, &deleteResult);
c->deletePublic(meta, thisValue, c, mn2->name, &deleteResult);
}
meta->mn2->name = meta->engine->numberToString(length - 1);
meta->deleteProperty(thisValue, meta->mn2, &lookup, RunPhase, &deleteResult);
mn2->name = meta->engine->numberToString(length - 1);
c->deletePublic(meta, thisValue, c, mn2->name, &deleteResult);
setLength(meta, thisObj, length - 1);
return result;
}
@ -407,15 +410,20 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg
}
}
LookupKind lookup(false, JS2VAL_NULL);
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
RootKeeper rk1(&mn1);
RootKeeper rk2(&mn2);
uint32 n = 0;
while (start < end) {
meta->mn1->name = meta->engine->numberToString(start);
if (meta->hasOwnProperty(thisObj, meta->mn1->name)) {
mn1->name = meta->engine->numberToString(start);
if (meta->hasOwnProperty(thisObj, mn1->name)) {
js2val rval;
meta->mn2->name = meta->engine->numberToString(n);
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &rval);
meta->writeDynamicProperty(A, meta->mn2, true, rval, RunPhase);
mn2->name = meta->engine->numberToString(n);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &rval);
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
}
n++;
start++;
@ -561,17 +569,20 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv
uint32 i;
js2val *vec = new js2val[length];
LookupKind lookup(false, JS2VAL_NULL);
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
RootKeeper rk1(&mn1);
for (i = 0; i < length; i++) {
meta->mn1->name = meta->engine->numberToString(i);
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &vec[i]);
mn1->name = meta->engine->numberToString(i);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &vec[i]);
}
js_qsort(vec, length, &ca);
for (i = 0; i < length; i++) {
meta->mn1->name = meta->engine->numberToString(i);
meta->writeDynamicProperty(thisObj, meta->mn1, true, vec[i], RunPhase);
mn1->name = meta->engine->numberToString(i);
c->writePublic(meta, thisValue, c, mn1->name, true, vec[i]);
}
}
return thisValue;
@ -615,14 +626,20 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
else
deleteCount = toUInt32(arg1);
LookupKind lookup(false, JS2VAL_NULL);
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
RootKeeper rk1(&mn1);
RootKeeper rk2(&mn2);
for (k = 0; k < deleteCount; k++) {
meta->mn1->name = meta->engine->numberToString(start + k);
if (meta->hasOwnProperty(thisObj, meta->mn1->name)) {
mn1->name = meta->engine->numberToString(start + k);
if (meta->hasOwnProperty(thisObj, mn1->name)) {
js2val rval;
meta->mn2->name = meta->engine->numberToString(k);
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &rval);
meta->writeDynamicProperty(A, meta->mn2, true, rval, RunPhase);
mn2->name = meta->engine->numberToString(k);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &rval);
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
}
}
setLength(meta, A, deleteCount);
@ -631,41 +648,41 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
if (newItemCount < deleteCount) {
bool deleteResult;
for (k = start; k < (length - deleteCount); k++) {
meta->mn1->name = meta->engine->numberToString(k + deleteCount);
meta->mn2->name = meta->engine->numberToString(k + newItemCount);
if (meta->hasOwnProperty(thisObj, meta->mn1->name)) {
mn1->name = meta->engine->numberToString(k + deleteCount);
mn2->name = meta->engine->numberToString(k + newItemCount);
if (meta->hasOwnProperty(thisObj, mn1->name)) {
js2val rval;
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &rval);
meta->writeDynamicProperty(A, meta->mn2, true, rval, RunPhase);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &rval);
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
}
else
meta->deleteProperty(thisValue, meta->mn2, &lookup, RunPhase, &deleteResult);
c->deletePublic(meta, thisValue, c, mn2->name, &deleteResult);
}
for (k = length; k > (length - deleteCount + newItemCount); k--) {
meta->mn1->name = meta->engine->numberToString(k - 1);
meta->deleteProperty(thisValue, meta->mn1, &lookup, RunPhase, &deleteResult);
mn1->name = meta->engine->numberToString(k - 1);
c->deletePublic(meta, thisValue, c, mn1->name, &deleteResult);
}
}
else {
if (newItemCount > deleteCount) {
for (k = length - deleteCount; k > start; k--) {
bool deleteResult;
meta->mn1->name = meta->engine->numberToString(k + deleteCount - 1);
meta->mn2->name = meta->engine->numberToString(k + newItemCount - 1);
mn1->name = meta->engine->numberToString(k + deleteCount - 1);
mn2->name = meta->engine->numberToString(k + newItemCount - 1);
if (meta->hasOwnProperty(thisObj, meta->mn1->name)) {
js2val rval;
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &rval);
meta->writeDynamicProperty(A, meta->mn2, true, rval, RunPhase);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &rval);
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
}
else
meta->deleteProperty(thisValue, meta->mn2, &lookup, RunPhase, &deleteResult);
c->deletePublic(meta, thisValue, c, mn2->name, &deleteResult);
}
}
}
k = start;
for (uint32 i = 2; i < argc; i++) {
meta->mn2->name = meta->engine->numberToString(k++);
meta->writeDynamicProperty(A, meta->mn2, true, argv[i], RunPhase);
mn2->name = meta->engine->numberToString(k++);
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, argv[i]);
}
setLength(meta, thisObj, (length - deleteCount + newItemCount));
return result;
@ -681,96 +698,35 @@ static js2val Array_unshift(JS2Metadata *meta, const js2val thisValue, js2val *a
uint32 length = getLength(meta, thisObj);
uint32 k;
LookupKind lookup(false, JS2VAL_NULL);
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
RootKeeper rk1(&mn1);
RootKeeper rk2(&mn2);
for (k = length; k > 0; k--) {
bool deleteResult;
meta->mn1->name = meta->engine->numberToString(k - 1);
meta->mn2->name = meta->engine->numberToString(k + argc - 1);
if (meta->hasOwnProperty(thisObj, meta->mn1->name)) {
mn1->name = meta->engine->numberToString(k - 1);
mn2->name = meta->engine->numberToString(k + argc - 1);
if (meta->hasOwnProperty(thisObj, mn1->name)) {
js2val rval;
meta->readDynamicProperty(thisObj, meta->mn1, &lookup, RunPhase, &rval);
meta->writeDynamicProperty(thisObj, meta->mn2, true, rval, RunPhase);
c->readPublic(meta, thisValue, c, mn1->name, RunPhase, &rval);
c->writePublic(meta, thisValue, c, mn2->name, true, rval);
}
else
meta->deleteProperty(thisValue, meta->mn2, &lookup, RunPhase, &deleteResult);
c->deletePublic(meta, thisValue, c, mn2->name, &deleteResult);
}
for (k = 0; k < argc; k++) {
meta->mn1->name = meta->engine->numberToString(k);
meta->writeDynamicProperty(thisObj, meta->mn1, true, argv[k], RunPhase);
mn1->name = meta->engine->numberToString(k);
c->writePublic(meta, thisValue, c, mn1->name, true, argv[k]);
}
setLength(meta, thisObj, (length + argc));
return thisValue;
}
#if 0
// An index has to pass the test that :
// toString(ToUint32(toString(index))) == toString(index)
//
// the 'toString(index)' operation is the default behaviour of '[]'
//
// isArrayIndex() is called when we know that index is a Number
//
static bool isArrayIndex(JS2Metadata *meta, js2val index, uint32 &intIndex)
{
ASSERT(JS2VAL_IS_NUMBER(index));
js2val v = JSValue::toUInt32(cx, index);
if ((JSValue::f64(v) == JSValue::f64(index)) && (JSValue::f64(v) < two32minus1)) {
intIndex = (uint32)JSValue::f64(v);
return true;
}
return false;
}
js2val Array_GetElement(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
// the 'this' value is the first argument, then the index
if (argc != 2)
cx->reportError(Exception::referenceError, "[] only supports single dimension");
JSArrayInstance *arrInst = checked_cast<JSArrayInstance *>(JSValue::instance(thisValue));
js2val index = argv[1];
const String *name = JSValue::string(JSValue::meta->toString(cx, index));
arrInst->getProperty(cx, *name, NULL);
return cx->popValue();
}
js2val Array_SetElement(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
// the 'this' value is the first argument, then the rValue, and finally the index
if (argc != 3)
cx->reportError(Exception::referenceError, "[]= only supports single dimension");
JSArrayInstance *arrInst = checked_cast<JSArrayInstance *>(JSValue::instance(thisValue));
js2val index = argv[2];
const String *name = JSValue::string(JSValue::meta->toString(cx, index));
if (JS2VAL_IS_NUMBER(index)) {
uint32 intIndex;
if (isArrayIndex(cx, index, intIndex)) {
PropertyIterator it = arrInst->findNamespacedProperty(*name, NULL);
if (it == arrInst->mProperties.end())
arrInst->insertNewProperty(*name, NULL, Property::Enumerable, Object_Type, argv[1]);
else {
Property *prop = PROPERTY(it);
ASSERT(prop->mFlag == ValuePointer);
prop->mData.vp = argv[1];
}
if (intIndex >= arrInst->mLength)
arrInst->mLength = intIndex + 1;
}
}
else {
arrInst->setProperty(cx, *name, NULL, argv[1]);
}
return argv[0];
}
#endif
void initArrayObject(JS2Metadata *meta)

Просмотреть файл

@ -1070,6 +1070,7 @@ namespace MetaData {
return (it != length);
}
else {
/*
if (originalObj != obj) {
while (it != length)
if (engine->meta->lookupDynamicProperty(originalObj, nameList[it]) != obj)
@ -1078,6 +1079,7 @@ namespace MetaData {
else
break;
}
*/
if (it == length) {
if (obj->kind == SimpleInstanceKind) {
js2val protoval = (checked_cast<SimpleInstance *>(obj))->super;

Просмотреть файл

@ -61,8 +61,7 @@ js2val error_ConstructorCore(JS2Metadata *meta, JS2Class *errorClass, js2val arg
js2val thatValue = OBJECT_TO_JS2VAL(obj);
if (!JS2VAL_IS_VOID(arg)) {
Multiname mn(&meta->world.identifiers["message"], meta->publicNamespace);
meta->writeDynamicProperty(obj, &mn, true, meta->engine->allocString(meta->toString(arg)), RunPhase);
errorClass->writePublic(meta, thatValue, errorClass, &meta->world.identifiers["message"], true, meta->engine->allocString(meta->toString(arg)));
}
return thatValue;
@ -110,9 +109,9 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u
js2val result;
LookupKind lookup(false, JS2VAL_NULL);
Multiname mn(&meta->world.identifiers["message"], meta->publicNamespace);
js2val a = thisValue;
if (meta->readProperty(&a, &mn, &lookup, RunPhase, &result)) {
JS2Class *c = meta->objectType(thisValue);
if (c->readPublic(meta, thisValue, c, &meta->world.identifiers["message"], RunPhase, &result)) {
if (JS2VAL_IS_STRING(result))
return result;
else
@ -126,10 +125,10 @@ static void initErrorClass(JS2Metadata *meta, JS2Class *c, Constructor *construc
{
// XXX Or make 'name' a static class member?
c->construct = constructor;
c->prototype = new SimpleInstance(meta, JS2VAL_NULL, c);
js2val nameVal = meta->engine->allocString(c->name);
QualifiedName qName(meta->publicNamespace, &meta->world.identifiers["name"])
meta->createDynamicProperty(c->prototype, &qName, nameVal, true, true);
c->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(meta, JS2VAL_NULL, c));
js2val nameVal = meta->engine->allocString(c->getName());
QualifiedName qName(meta->publicNamespace, &meta->world.identifiers["name"]);
meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &qName, nameVal, ReadAccess, true, true);
}
void initErrorObject(JS2Metadata *meta)
@ -153,11 +152,12 @@ void initErrorObject(JS2Metadata *meta)
PrototypeFunction *pf = &errorProtos[0];
while (pf->name) {
SimpleInstance *fInst = new SimpleInstance(meta->functionClass);
SimpleInstance *fInst = new SimpleInstance(meta, meta->functionClass->prototype, meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, meta->env);
InstanceMember *m = new InstanceMethod(fInst);
meta->defineInstanceMember(meta->errorClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
Multiname *mn = new Multiname(&meta->world.identifiers[pf->name], &publicNamespaceList);
InstanceMember *m = new InstanceMethod(mn, fInst, true, false);
meta->defineInstanceMember(meta->errorClass, &meta->cxt, mn->name, mn->nsList, Attribute::NoOverride, false, m, 0);
pf++;
}

Просмотреть файл

@ -200,12 +200,10 @@ namespace MetaData {
// function result value.
bool JS2Metadata::invokeFunctionOnObject(js2val thisValue, const String *fnName, js2val &result)
{
Multiname mn(fnName, publicNamespace);
LookupKind lookup(true, JS2VAL_NULL); // XXX using lexical lookup since we want readProperty to fail
// if the function isn't defined
js2val fnVal;
if (readProperty(&thisValue, &mn, &lookup, RunPhase, &fnVal)) {
JS2Class *limit = objectType(thisValue);
if (limit->readPublic(this, thisValue, limit, fnName, RunPhase, &fnVal)) {
if (JS2VAL_IS_OBJECT(fnVal)) {
JS2Object *fnObj = JS2VAL_TO_OBJECT(fnVal);
result = invokeFunction(fnObj, thisValue, NULL, 0);

Просмотреть файл

@ -89,7 +89,7 @@ namespace MetaData {
FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thatValue));
fnInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), meta->env);
fnInst->fWrap->bCon->emitOp(eReturnVoid, meta->engine->errorPos());
fnInst->writeProperty(meta, meta->engine->length_StringAtom, INT_TO_JS2VAL(0), DynamicPropertyValue::READONLY);
meta->createDynamicProperty(fnInst, meta->engine->length_StringAtom, INT_TO_JS2VAL(0), ReadAccess, true, false);
return thatValue;
}
}
@ -97,8 +97,8 @@ namespace MetaData {
static js2val Function_toString(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (!JS2VAL_IS_OBJECT(thisValue)
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->functionClass))
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->functionClass))
meta->reportError(Exception::typeError, "Function.toString called on something other than a function thing", meta->engine->errorPos());
// FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thisValue));
return STRING_TO_JS2VAL(meta->engine->Function_StringAtom);
@ -107,8 +107,8 @@ namespace MetaData {
static js2val Function_valueOf(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (!JS2VAL_IS_OBJECT(thisValue)
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->functionClass))
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->functionClass))
meta->reportError(Exception::typeError, "Function.valueOf called on something other than a function thing", meta->engine->errorPos());
// FunctionInstance *nfInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thisValue));
return STRING_TO_JS2VAL(meta->engine->Function_StringAtom);
@ -123,7 +123,7 @@ namespace MetaData {
{ NULL }
};
meta->functionClass->prototype = new FunctionInstance(meta, meta->objectClass->prototype, meta->functionClass);
meta->functionClass->prototype = OBJECT_TO_JS2VAL(new FunctionInstance(meta, meta->objectClass->prototype, meta->functionClass));
meta->initBuiltinClass(meta->functionClass, &prototypeFunctions[0], NULL, Function_Constructor, Function_Constructor);
}

Просмотреть файл

@ -340,13 +340,13 @@ void initMathObject(JS2Metadata *meta)
meta->env->addFrame(meta->mathClass);
FunctionData *pf = &prototypeFunctions[0];
while (pf->name) {
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
SimpleInstance *callInst = new SimpleInstance(meta, meta->functionClass->prototype, meta->functionClass);
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, meta->env);
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
meta->defineLocalMember(meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
// XXX add 'length' as a dynamic property of the method
meta->writeDynamicProperty(callInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase);
meta->createDynamicProperty(callInst, meta->engine->length_StringAtom, INT_TO_JS2VAL(pf->length), ReadAccess, true, false);
pf++;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -52,7 +52,7 @@ class BytecodeContainer;
class Pond;
class SimpleInstance;
class LookupKind;
class Package;
typedef void (Invokable)();
typedef js2val (Callor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
@ -263,9 +263,13 @@ typedef NamespaceList::iterator NamespaceListIterator;
class Multiname : public JS2Object {
public:
Multiname() : JS2Object(MultinameKind), name(NULL), nsList(new NamespaceList) { }
Multiname(Namespace *ns) : JS2Object(MultinameKind), name(NULL), nsList(new NamespaceList) { nsList->push_back(ns); }
Multiname(const String *name) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList) { }
Multiname(const String *name, Namespace *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList) { addNamespace(ns); }
Multiname(QualifiedName& q) : JS2Object(MultinameKind), name(q.name), nsList(new NamespaceList) { nsList->push_back(q.nameSpace); }
Multiname(const String *name, NamespaceList *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList) { addNamespace(ns); }
Multiname(const String *name, Context *cxt) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList) { addNamespace(*cxt); }
Multiname(const Multiname& m) : JS2Object(MultinameKind), name(m.name), nsList(m.nsList) { }
@ -286,7 +290,6 @@ public:
virtual ~Multiname() { }
};
class NamedParameter {
public:
const String *name; // This parameter's name
@ -584,7 +587,7 @@ public:
Frame *getTopFrame() { return frameList.front(); }
FrameListIterator getBegin() { return frameList.begin(); }
FrameListIterator getEnd() { return frameList.end(); }
Frame *getPackageFrame();
Package *getPackageFrame();
SystemFrame *getSystemFrame() { return checked_cast<SystemFrame *>(frameList.back()); }
void setTopFrame(Frame *f) { while (frameList.front() != f) frameList.pop_front(); }
@ -1129,7 +1132,7 @@ public:
void ValidateStmt(Context *cxt, Environment *env, Plurality pl, StmtNode *p);
void ValidateExpression(Context *cxt, Environment *env, ExprNode *p);
void ValidateAttributeExpression(Context *cxt, Environment *env, ExprNode *p);
JS2Object *validateStaticFunction(FunctionDefinition *fnDef, js2val compileThis, bool prototype, bool unchecked, Context *cxt, Environment *env);
FunctionInstance *validateStaticFunction(FunctionDefinition *fnDef, js2val compileThis, bool prototype, bool unchecked, Context *cxt, Environment *env);
js2val ExecuteStmtList(Phase phase, StmtNode *p);
js2val EvalExpression(Environment *env, Phase phase, ExprNode *p);
@ -1142,7 +1145,6 @@ public:
JS2Class *objectType(js2val obj);
JS2Class *objectType(JS2Object *obj);
bool hasType(js2val objVal, JS2Class *c);
bool relaxedHasType(js2val objVal, JS2Class *c);
LocalMember *findFlatMember(NonWithFrame *container, Multiname *multiname, Access access, Phase phase);
InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase, QualifiedName *qname);
@ -1158,9 +1160,10 @@ public:
LocalMember *findLocalMember(JS2Object *container, Multiname *multiname, Access access);
js2val getSuperObject(JS2Object *obj);
JS2Class *getVariableType(Variable *v, Phase phase, size_t pos);
InstanceMember *getDerivedInstanceMember(JS2Class *c, InstanceMember *mBase, Multiname *multiname, Access access);
InstanceMember *getDerivedInstanceMember(JS2Class *c, InstanceMember *mBase, Access access);
InstanceMember *findBaseInstanceMember(JS2Class *limit, Multiname *multiname, Access access);
InstanceBinding *findLocalInstanceMember(JS2Class *limit, Multiname *multiname, Access access);
InstanceMember *findLocalInstanceMember(JS2Class *limit, Multiname *multiname, Access access);
Member *findCommonMember(js2val base, Multiname *multiname, Access access, bool flat);
js2val invokeFunction(const char *fname);
bool invokeFunctionOnObject(js2val thisValue, const String *fnName, js2val &result);
@ -1176,15 +1179,15 @@ public:
// bool readProperty(Frame *pf, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
// bool readDynamicProperty(JS2Object *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
bool readLocalMember(LocalMember *m, Phase phase, js2val *rval);
bool readInstanceMember(js2val containerVal, JS2Class *c, QualifiedName *qname, Phase phase, js2val *rval);
JS2Object *lookupDynamicProperty(JS2Object *obj, const String *name);
bool readInstanceMember(js2val containerVal, JS2Class *c, InstanceMember *mBase, Phase phase, js2val *rval);
// JS2Object *lookupDynamicProperty(JS2Object *obj, const String *name);
bool JS2Metadata::hasOwnProperty(JS2Object *obj, const String *name);
// bool writeProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, Phase phase);
// bool writeProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, Phase phase, bool initFlag);
// bool writeDynamicProperty(JS2Object *container, Multiname *multiname, bool createIfMissing, js2val newValue, Phase phase);
bool writeLocalMember(LocalMember *m, js2val newValue, Phase phase, bool initFlag);
bool writeInstanceMember(js2val containerVal, JS2Class *c, QualifiedName *qname, js2val newValue, Phase phase);
bool writeLocalMember(LocalMember *m, js2val newValue, bool initFlag);
bool writeInstanceMember(js2val containerVal, JS2Class *c, InstanceMember *mBase, js2val newValue);
// bool deleteProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, bool *result);
// bool deleteProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, Phase phase, bool *result);

Просмотреть файл

@ -78,8 +78,8 @@ namespace MetaData {
static js2val Number_toString(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (!JS2VAL_IS_OBJECT(thisValue)
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->numberClass))
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->numberClass))
meta->reportError(Exception::typeError, "Number.toString called on something other than a number thing", meta->engine->errorPos());
NumberInstance *numInst = checked_cast<NumberInstance *>(JS2VAL_TO_OBJECT(thisValue));
return STRING_TO_JS2VAL(meta->engine->numberToString(&numInst->mValue));
@ -88,8 +88,8 @@ namespace MetaData {
static js2val Number_valueOf(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (!JS2VAL_IS_OBJECT(thisValue)
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->numberClass))
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->numberClass))
meta->reportError(Exception::typeError, "Number.valueOf called on something other than a number thing", meta->engine->errorPos());
NumberInstance *numInst = checked_cast<NumberInstance *>(JS2VAL_TO_OBJECT(thisValue));
return meta->engine->allocNumber(numInst->mValue);
@ -133,7 +133,7 @@ namespace MetaData {
{ NULL }
};
meta->numberClass->prototype = new NumberInstance(meta, meta->objectClass->prototype, meta->numberClass);
meta->numberClass->prototype = OBJECT_TO_JS2VAL(new NumberInstance(meta, meta->objectClass->prototype, meta->numberClass));
meta->initBuiltinClass(meta->numberClass, &prototypeFunctions[0], NULL, Number_Constructor, Number_Call);
}

Просмотреть файл

@ -951,10 +951,12 @@
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
if (!meta->readProperty(&baseVal, mn, &lookup, RunPhase, &a))
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, baseVal, limit, mn, &lookup, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
meta->writeProperty(baseVal, mn, &lookup, true, allocNumber(num + 1.0), RunPhase);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num + 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
pushNumber(num);
baseVal = JS2VAL_VOID;
}
@ -965,10 +967,12 @@
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
if (!meta->readProperty(&baseVal, mn, &lookup, RunPhase, &a))
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, baseVal, limit, mn, &lookup, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
meta->writeProperty(baseVal, mn, &lookup, true, allocNumber(num - 1.0), RunPhase);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num - 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
pushNumber(num);
baseVal = JS2VAL_VOID;
}
@ -979,11 +983,13 @@
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
if (!meta->readProperty(&baseVal, mn, &lookup, RunPhase, &a))
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, baseVal, limit, mn, &lookup, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
meta->writeProperty(baseVal, mn, &lookup, true, a, RunPhase);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
baseVal = JS2VAL_VOID;
}
break;
@ -993,11 +999,13 @@
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
if (!meta->readProperty(&baseVal, mn, &lookup, RunPhase, &a))
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, baseVal, limit, mn, &lookup, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
meta->writeProperty(baseVal, mn, &lookup, true, a, RunPhase);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
baseVal = JS2VAL_VOID;
}
break;
@ -1009,10 +1017,12 @@
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
if (!meta->readProperty(&baseVal, &mn, &lookup, RunPhase, &a))
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);
float64 num = meta->toFloat64(a);
meta->writeProperty(baseVal, &mn, &lookup, true, allocNumber(num + 1.0), RunPhase);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num + 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
pushNumber(num);
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
@ -1026,10 +1036,12 @@
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
if (!meta->readProperty(&baseVal, &mn, &lookup, RunPhase, &a))
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);
float64 num = meta->toFloat64(a);
meta->writeProperty(baseVal, &mn, &lookup, true, allocNumber(num - 1.0), RunPhase);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num - 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
pushNumber(num);
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
@ -1043,11 +1055,13 @@
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
if (!meta->readProperty(&baseVal, &mn, &lookup, RunPhase, &a))
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);
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
meta->writeProperty(baseVal, &mn, &lookup, true, a, RunPhase);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
astr = NULL;
@ -1060,11 +1074,13 @@
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
if (!meta->readProperty(&baseVal, &mn, &lookup, RunPhase, &a))
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);
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
meta->writeProperty(baseVal, &mn, &lookup, true, a, RunPhase);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
astr = NULL;

Просмотреть файл

@ -68,7 +68,8 @@
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)
if (meta->readProperty(&a, &mn, &lookup, RunPhase, &protoVal)) {
JS2Class *limit = meta->objectType(a);
if (limit->read(meta, a, limit, &mn, &lookup, RunPhase, &protoVal)) {
if (!JS2VAL_IS_OBJECT(protoVal))
meta->reportError(Exception::badValueError, "Non-object prototype value", errorPos());
}

Просмотреть файл

@ -122,7 +122,7 @@
ASSERT(JS2VAL_IS_STRING(a));
astr = JS2VAL_TO_STRING(a);
b = pop();
meta->createDynamicProperty(sInst, astr, b, false, true);
meta->createDynamicProperty(sInst, astr, b, ReadWriteAccess, false, true);
}
push(baseVal);
baseVal = JS2VAL_VOID;
@ -138,7 +138,7 @@
baseVal = OBJECT_TO_JS2VAL(aInst);
for (uint16 i = 0; i < argCount; i++) {
b = pop();
meta->createDynamicProperty(aInst, numberToString((argCount - 1) - i), b, false, true);
meta->createDynamicProperty(aInst, numberToString((argCount - 1) - i), b, ReadWriteAccess, false, true);
}
setLength(meta, aInst, argCount);
push(baseVal);

Просмотреть файл

@ -62,63 +62,58 @@ namespace MetaData {
void RegExpInstance::setLastIndex(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["lastIndex"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["lastIndex"], true, a);
}
void RegExpInstance::setGlobal(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["global"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["global"], true, a);
}
void RegExpInstance::setMultiline(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["multiline"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["multiline"], true, a);
}
void RegExpInstance::setIgnoreCase(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["ignoreCase"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["ignoreCase"], true, a);
}
void RegExpInstance::setSource(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["source"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["source"], true, a);
}
js2val RegExpInstance::getLastIndex(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["lastIndex"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
if (meta->regexpClass->readPublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["lastIndex"], RunPhase, &r))
ASSERT(false);
return r;
}
js2val RegExpInstance::getGlobal(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["global"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
if (meta->regexpClass->readPublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["global"], RunPhase, &r))
ASSERT(false);
return r;
}
js2val RegExpInstance::getMultiline(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["multiline"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
if (meta->regexpClass->readPublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["multiline"], RunPhase, &r))
ASSERT(false);
return r;
}
js2val RegExpInstance::getIgnoreCase(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["ignoreCase"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
if (meta->regexpClass->readPublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["ignoreCase"], RunPhase, &r))
ASSERT(false);
return r;
}
js2val RegExpInstance::getSource(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["source"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
if (meta->regexpClass->readPublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, &meta->world.identifiers["source"], RunPhase, &r))
ASSERT(false);
return r;
}
@ -142,19 +137,17 @@ namespace MetaData {
REMatchState *match = REExecute(thisInst->mRegExp, str->begin(), index, toInt32(str->length()), meta->toBoolean(globalMultiline));
if (match) {
PrototypeInstance *A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
ArrayInstance *A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
result = OBJECT_TO_JS2VAL(A);
js2val matchStr = meta->engine->allocString(str->substr((uint32)match->startIndex, (uint32)match->endIndex - match->startIndex));
Multiname mname(&meta->world.identifiers[*meta->toString((long)0)], meta->publicNamespace);
meta->writeDynamicProperty(A, &mname, true, matchStr, RunPhase);
meta->createDynamicProperty(A, &meta->world.identifiers[*meta->toString((long)0)], matchStr, ReadWriteAccess, false, true);
for (int32 i = 0; i < match->parenCount; i++) {
Multiname mname(&meta->world.identifiers[*meta->toString(i + 1)], meta->publicNamespace);
if (match->parens[i].index != -1) {
js2val parenStr = meta->engine->allocString(str->substr((uint32)(match->parens[i].index), (uint32)(match->parens[i].length)));
meta->writeDynamicProperty(A, &mname, true, parenStr, RunPhase);
meta->createDynamicProperty(A, &meta->world.identifiers[*meta->toString(i + 1)], parenStr, ReadWriteAccess, false, true);
}
else
meta->writeDynamicProperty(A, &mname, true, JS2VAL_UNDEFINED, RunPhase);
else
meta->createDynamicProperty(A, &meta->world.identifiers[*meta->toString(i + 1)], JS2VAL_UNDEFINED, ReadWriteAccess, false, true);
}
/*
// XXX SpiderMonkey also adds 'index' and 'input' properties to the result
@ -184,7 +177,7 @@ namespace MetaData {
{
// XXX Change constructors to take js2val pointer for the result (which would be an already
// rooted pointer).
RegExpInstance *thisInst = new RegExpInstance(meta->regexpClass);
RegExpInstance *thisInst = new RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass);
RootKeeper rk(&thisInst);
js2val thatValue = OBJECT_TO_JS2VAL(thisInst);
REuint32 flags = 0;
@ -249,8 +242,9 @@ namespace MetaData {
for (uint32 i = 0; i < INSTANCE_VAR_COUNT; i++)
{
InstanceMember *m = new InstanceVariable(RegExpInstanceVars[i].type, false, false, meta->regexpClass->slotCount++);
meta->defineInstanceMember(meta->regexpClass, &meta->cxt, &meta->world.identifiers[RegExpInstanceVars[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
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++);
meta->defineInstanceMember(meta->regexpClass, &meta->cxt, mn->name, mn->nsList, Attribute::NoOverride, false, m, 0);
}
}

Просмотреть файл

@ -65,10 +65,7 @@ js2val String_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val
else
strInst->mValue = meta->engine->allocStringPtr("");
DynamicPropertyBinding *dpb = new DynamicPropertyBinding(*meta->engine->length_StringAtom,
DynamicPropertyValue(meta->engine->allocNumber(strInst->mValue->length()),
DynamicPropertyValue::READONLY | DynamicPropertyValue::PERMANENT));
strInst->dynamicProperties.insert(dpb->name, dpb);
meta->createDynamicProperty(strInst, meta->engine->length_StringAtom, meta->engine->allocNumber(strInst->mValue->length()), ReadAccess, true, false);
return thatValue;
}
@ -93,8 +90,8 @@ js2val String_fromCharCode(JS2Metadata *meta, const js2val /*thisValue*/, js2val
static js2val String_toString(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (!JS2VAL_IS_OBJECT(thisValue)
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->stringClass))
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->stringClass))
meta->reportError(Exception::typeError, "String.toString called on something other than a string thing", meta->engine->errorPos());
StringInstance *strInst = checked_cast<StringInstance *>(JS2VAL_TO_OBJECT(thisValue));
return STRING_TO_JS2VAL(strInst->mValue);
@ -103,8 +100,8 @@ static js2val String_toString(JS2Metadata *meta, const js2val thisValue, js2val
static js2val String_valueOf(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (!JS2VAL_IS_OBJECT(thisValue)
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->stringClass))
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->stringClass))
meta->reportError(Exception::typeError, "String.valueOf called on something other than a string thing", meta->engine->errorPos());
StringInstance *strInst = checked_cast<StringInstance *>(JS2VAL_TO_OBJECT(thisValue));
return STRING_TO_JS2VAL(strInst->mValue);
@ -171,7 +168,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar
return RegExp_exec(meta, regexp, &S, 1);
}
else {
PrototypeInstance *A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
ArrayInstance *A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
RootKeeper rk(&A);
int32 index = 0;
int32 lastIndex = 0;
@ -184,9 +181,8 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar
else
lastIndex = match->endIndex;
js2val matchStr = meta->engine->allocString(JS2VAL_TO_STRING(S)->substr(toUInt32(match->startIndex), toUInt32(match->endIndex) - match->startIndex));
Multiname mname(&meta->world.identifiers[*meta->engine->numberToString(index)], meta->publicNamespace);
index++;
meta->writeDynamicProperty(A, &mname, true, matchStr, RunPhase);
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(index), true, matchStr);
}
thisInst->setLastIndex(meta, meta->engine->allocNumber((float64)lastIndex));
return OBJECT_TO_JS2VAL(A);
@ -440,7 +436,6 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
return JSValue(A);
}
*/
Multiname mn(NULL, meta->publicNamespace);
if (s == 0) {
MatchResult z;
if (RE)
@ -449,8 +444,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
strSplitMatch(S, 0, R, z);
if (!z.failure)
return result;
mn.name = meta->engine->numberToString((int32)0); // XXX
meta->writeDynamicProperty(A, &mn, true, STRING_TO_JS2VAL(S), RunPhase);
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString((int32)0), true, STRING_TO_JS2VAL(S));
return result;
}
@ -459,8 +453,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
step11:
if (q == s) {
js2val v = meta->engine->allocString(new String(*S, p, (s - p)));
mn.name = meta->engine->numberToString(getLength(meta, A));
meta->writeDynamicProperty(A, &mn, true, v, RunPhase);
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(getLength(meta, A)), true, v);
return result;
}
MatchResult z;
@ -479,15 +472,13 @@ step11:
}
String *T = meta->engine->allocStringPtr(new String(*S, p, (q - p))); // XXX
js2val v = STRING_TO_JS2VAL(T);
mn.name = meta->engine->numberToString(getLength(meta, A));
meta->writeDynamicProperty(A, &mn, true, v, RunPhase);
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(getLength(meta, A)), true, v);
if (getLength(meta, A) == lim)
return result;
p = e;
for (uint32 i = 0; i < z.capturesCount; i++) {
mn.name = meta->engine->numberToString(getLength(meta, A));
meta->writeDynamicProperty(A, &mn, true, z.captures[i], RunPhase);
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(getLength(meta, A)), true, z.captures[i]);
if (getLength(meta, A) == lim)
return result;
}
@ -794,13 +785,10 @@ void initStringObject(JS2Metadata *meta)
};
StringInstance *strInst = new StringInstance(meta, meta->objectClass->prototype, meta->stringClass);
meta->stringClass->prototype = strInst;
meta->stringClass->prototype = OBJECT_TO_JS2VAL(strInst);
strInst->mValue = meta->engine->allocStringPtr("");
DynamicPropertyBinding *dpb = new DynamicPropertyBinding(*meta->engine->length_StringAtom,
DynamicPropertyValue(meta->engine->allocNumber(strInst->mValue->length()),
DynamicPropertyValue::READONLY | DynamicPropertyValue::PERMANENT));
strInst->dynamicProperties.insert(dpb->name, dpb);
meta->createDynamicProperty(strInst, meta->engine->length_StringAtom, meta->engine->allocNumber(strInst->mValue->length()), ReadAccess, true, false);
meta->initBuiltinClass(meta->stringClass, &prototypeFunctions[0], &staticFunctions[0], String_Constructor, String_Call);
}

Просмотреть файл

@ -65,6 +65,7 @@ namespace JavaScript {
class Multiname;
class FunctionWrapper;
class BlockFrame;
class FunctionInstance;
typedef uint32 LabelID;
}
#endif
@ -148,7 +149,8 @@ namespace JavaScript {
JS2Runtime::JSObject *scope; // ditto
#endif
#ifdef EPIMETHEUS
MetaData::Member *member; // the associated definition...
MetaData::Member *member; // the associated definition,
MetaData::Member *overridden; // overridden member...
MetaData::Multiname *mn; // ...and name constructed by the semantics phase
#endif
@ -396,7 +398,7 @@ namespace JavaScript {
void print(PrettyPrinter &f) const;
#ifdef EPIMETHEUS
MetaData::JS2Object *obj; // used by backend to store the function object
MetaData::FunctionInstance *obj; // used by backend to store the function object
#endif
};