зеркало из https://github.com/mozilla/pjs.git
Fiddling with delete and Array.length
This commit is contained in:
Родитель
6c77c1ebda
Коммит
dc2d7bff69
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче