Fiddling with delete and Array.length

This commit is contained in:
rogerl%netscape.com 2003-05-27 16:25:17 +00:00
Родитель 6c77c1ebda
Коммит dc2d7bff69
7 изменённых файлов: 72 добавлений и 41 удалений

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

@ -395,6 +395,20 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
printFormat(stdOut, "function = 0x%08X\n", im->fInst);
}
break;
case Member::InstanceGetterMember:
{
InstanceGetter *g = checked_cast<InstanceGetter *>(ns.second->content);
stdOut << "\t" << *(ns.first->name) << "::" << ibe->name;
stdOut << " get" << ":" << *g->type->name << "\n";
}
break;
case Member::InstanceSetterMember:
{
InstanceSetter *s = checked_cast<InstanceSetter *>(ns.second->content);
stdOut << "\t" << *(ns.first->name) << "::" << ibe->name;
stdOut << " set" << ":" << *s->type->name << "\n";
}
break;
}
}
}

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

@ -884,7 +884,7 @@ namespace MetaData {
bool JS2Class::Delete(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool *result)
{
InstanceMember *mBase = meta->findBaseInstanceMember(this, multiname, WriteAccess);
InstanceMember *mBase = meta->findBaseInstanceMember(this, multiname, ReadWriteAccess);
if (mBase) {
*result = false;
return true;
@ -892,9 +892,11 @@ namespace MetaData {
if (this != meta->objectType(base))
return false;
Member *m = meta->findCommonMember(&base, multiname, WriteAccess, false);
if (m == NULL)
return false;
Member *m = meta->findCommonMember(&base, multiname, ReadWriteAccess, false);
if (m == NULL) {
*result = true;
return true;
}
switch (m->memberKind) {
case Member::ForbiddenMember:
meta->reportError(Exception::propertyAccessError, "It is forbidden", meta->engine->errorPos());

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

@ -121,8 +121,11 @@ namespace MetaData {
|| (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);
FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thisValue));
if (fnInst->sourceText)
return STRING_TO_JS2VAL(fnInst->sourceText);
else
return STRING_TO_JS2VAL(meta->engine->Function_StringAtom);
}
static js2val Function_call(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)

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

@ -193,6 +193,11 @@ namespace MetaData {
}
break;
}
StringFormatter sFmt;
PrettyPrinter pp(sFmt);
fnDef->print(pp, NULL, true);
pp.end();
fnInst->sourceText = engine->allocStringPtr(&sFmt.getString());
}
void JS2Metadata::validateConstructor(Context *cxt, Environment *env, FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a, size_t pos)
@ -3844,9 +3849,15 @@ static const uint8 urlCharType[256] =
return GlobalObject_toString(meta, thisValue, NULL, 0);
}
else {
JS2Class *type = (checked_cast<SimpleInstance *>(obj))->type;
String s = "[object " + *type->name + "]";
return STRING_TO_JS2VAL(meta->engine->allocString(s));
if (obj->kind == ClassKind && meta->cxt.E3compatibility) {
String s = widenCString("[object Function]");
return STRING_TO_JS2VAL(meta->engine->allocString(s));
}
else {
JS2Class *type = (checked_cast<SimpleInstance *>(obj))->type;
String s = "[object " + *type->name + "]";
return STRING_TO_JS2VAL(meta->engine->allocString(s));
}
}
}
@ -4023,8 +4034,6 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
createDynamicProperty(glob, engine->undefined_StringAtom, JS2VAL_UNDEFINED, ReadAccess, true, false);
createDynamicProperty(glob, &world.identifiers["NaN"], engine->nanValue, ReadAccess, true, false);
createDynamicProperty(glob, &world.identifiers["Infinity"], engine->posInfValue, ReadAccess, true, false);
// XXX add 'version()'
// createDynamicProperty(glob, &world.identifiers["version"], INT_TO_JS2VAL(0), ReadAccess, true, false);
/*** ECMA 3 Object Class ***/
@ -4042,6 +4051,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
defineLocalMember(env, engine->length_StringAtom, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false);
env->removeTopFrame();
glob->super = objectClass->prototype;
/*** ECMA 3 Function Class ***/
// Need this initialized early, as subsequent FunctionInstances need the Function.prototype value
v = new Variable(classClass, OBJECT_TO_JS2VAL(functionClass), true);
@ -4078,7 +4089,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
defineInstanceMember(objectClass, &cxt, proto_mn.name, *proto_mn.nsList, Attribute::NoOverride, false, s, 0);
// Adding 'toString' to the Object.prototype XXX Or make this a static class member?
// Adding 'toString' etc to the Object.prototype XXX Or make this a static class member?
fInst = createFunctionInstance(env, true, true, Object_toString, 0, NULL);
createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), engine->toString_StringAtom, OBJECT_TO_JS2VAL(fInst), ReadAccess, true, false);
// and 'valueOf'
@ -4086,8 +4097,14 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), engine->valueOf_StringAtom, OBJECT_TO_JS2VAL(fInst), ReadAccess, true, false);
// and 'constructor'
fInst = createFunctionInstance(env, true, true, Object_Constructor, 0, NULL);
// XXX 'this' == JS2VAL_INACCESSIBLE for above???
createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["constructor"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false);
// and various property/enumerable functions
fInst = createFunctionInstance(env, true, true, Object_hasOwnProperty, 0, NULL);
createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["hasOwnProperty"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false);
fInst = createFunctionInstance(env, true, true, Object_isPropertyOf, 0, NULL);
createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["isPropertyOf"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false);
fInst = createFunctionInstance(env, true, true, Object_propertyIsEnumerble, 0, NULL);
createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["propertyIsEnumerable"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false);
/*** ECMA 4 Integer Class ***/
@ -4746,8 +4763,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
// Adding "prototype" & "length", etc as static members of the class - not dynamic properties; XXX
env->addFrame(builtinClass);
{
Variable *v = new Variable(builtinClass, INT_TO_JS2VAL(1), true);
defineLocalMember(env, engine->length_StringAtom, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false);
Variable *v = new Variable(integerClass, INT_TO_JS2VAL(1), true);
defineLocalMember(env, engine->length_StringAtom, NULL, Attribute::NoOverride, false, ReadAccess, v, 0, false);
pf = staticFunctions;
if (pf) {
@ -4978,10 +4995,6 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
: SimpleInstance(meta, parent, type)
{
length = 0;
// JS2Object *result = this;
// DEFINE_ROOTKEEPER(rk1, result);
// meta->createDynamicProperty(this, meta->engine->length_StringAtom, INT_TO_JS2VAL(0), ReadWriteAccess, true, false);
}
/************************************************************************************
@ -4991,7 +5004,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
************************************************************************************/
FunctionInstance::FunctionInstance(JS2Metadata *meta, js2val parent, JS2Class *type)
: SimpleInstance(meta, parent, type), isMethodClosure(false), fWrap(NULL), thisObject(JS2VAL_VOID)
: SimpleInstance(meta, parent, type), isMethodClosure(false), fWrap(NULL), thisObject(JS2VAL_VOID), sourceText(NULL)
{
// Add prototype property
JS2Object *result = this;
@ -5016,6 +5029,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
fWrap->bCon->mark();
}
GCMARKVALUE(thisObject);
if (sourceText) JS2Object::mark(sourceText);
}
FunctionInstance::~FunctionInstance()

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

@ -1008,6 +1008,7 @@ public:
bool isMethodClosure; // if true, use the thisObject from below
js2val thisObject;
const String *sourceText;
virtual void markChildren();
virtual ~FunctionInstance();

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

@ -306,7 +306,6 @@ doCall:
{
b = pop();
a = pop(); // doing 'a instanceof b'
if (!JS2VAL_IS_OBJECT(b))
meta->reportError(Exception::typeError, "Object expected for instanceof", errorPos());
JS2Object *obj = JS2VAL_TO_OBJECT(b);
@ -355,33 +354,24 @@ doInstanceOfLoop:
push(JS2VAL_FALSE);
else {
aObj = JS2VAL_TO_OBJECT(a);
if (aObj->kind != SimpleInstanceKind)
if (aObj->kind == SimpleInstanceKind)
a_protoVal = checked_cast<SimpleInstance *>(aObj)->super;
else
if (aObj->kind == PackageKind)
a_protoVal = checked_cast<Package *>(aObj)->super;
else
if (aObj->kind == ClassKind)
a_protoVal = checked_cast<JS2Class *>(aObj)->prototype;
else
meta->reportError(Exception::typeError, "Prototype instance expected for instanceof", errorPos());
a_protoVal = checked_cast<SimpleInstance *>(aObj)->super;
b_protoVal = checked_cast<JS2Class *>(obj)->prototype;
goto doInstanceOfLoop;
/*
bool result = false;
while (!JS2VAL_IS_NULL(a_protoVal) && !JS2VAL_IS_UNDEFINED(a_protoVal)) {
if (b_protoVal == a_protoVal) {
result = true;
break;
}
if (!JS2VAL_IS_OBJECT(a_protoVal))
meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos());
aObj = JS2VAL_TO_OBJECT(a_protoVal);
if (aObj->kind != SimpleInstanceKind)
meta->reportError(Exception::typeError, "Prototype instance expected for instanceof", errorPos());
a_protoVal = checked_cast<SimpleInstance *>(aObj)->super;
}
push(BOOLEAN_TO_JS2VAL(result));
*/
}
}
else
meta->reportError(Exception::typeError, "Function or Class expected in instanceOf", errorPos());
}
}
break;

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

@ -2038,7 +2038,11 @@ JS::StmtNode *JS::Parser::parseProgram()
// Parser Utilities
//
#ifdef DEBUG
const bool debugExprNodePrint = true; // Print extra parentheses around subexpressions?
#else
const bool debugExprNodePrint = false; // Print extra parentheses around subexpressions?
#endif
const int32 basicIndent = 4; // Size of one level of statement indentation
const int32 caseIndent = basicIndent/2; // Indentation before a case or default statement
const int32 varIndent = 2; // Indentation of var or const statement bindings
@ -2473,7 +2477,10 @@ void JS::StmtNode::printBlockStatements(PrettyPrinter &f, const StmtNode *statem
statements->print(f, false);
} else {
f.linearBreak(nSpaces, loose);
statements->print(f, !statements->next);
// XXX I overrode the 'nosemi' flag in order to
// get E3 regression tests to pass. Maybe use an E3
// compatibility flag instead?
statements->print(f, false/*!statements->next*/);
}
statements = statements->next;
nSpaces = 1;