From 9c6cd66f8fc03484bb26f4b822011c3b8c38bd49 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Sat, 10 May 2003 19:30:34 +0000 Subject: [PATCH] Minor e3 fixes. Adding type handling for function parameters & result. git-svn-id: svn://10.0.0.236/trunk@142306 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/epimetheus.cpp | 12 +++++++++ mozilla/js2/src/js2engine.cpp | 2 +- mozilla/js2/src/js2eval.cpp | 2 ++ mozilla/js2/src/js2metadata.cpp | 47 +++++++++++++++++++++++++++++---- mozilla/js2/src/js2metadata.h | 35 ++++++++++++++++++++---- mozilla/js2/src/js2string.cpp | 8 +++--- 6 files changed, 91 insertions(+), 15 deletions(-) diff --git a/mozilla/js2/src/epimetheus.cpp b/mozilla/js2/src/epimetheus.cpp index 4818150df2d..44d18f2bee1 100644 --- a/mozilla/js2/src/epimetheus.cpp +++ b/mozilla/js2/src/epimetheus.cpp @@ -263,6 +263,18 @@ void printLocalBindings(LocalBindingMap *lMap, ValueList *frameSlots) stdOut << " forbidden\n"; } break; + case Member::GetterMember: + { + Getter *g = checked_cast(m); + stdOut << " get" << ":" << *g->type->name << "\n"; + } + break; + case Member::SetterMember: + { + Setter *s = checked_cast(m); + stdOut << " set" << ":" << *s->type->name << "\n"; + } + break; case Member::DynamicVariableMember: { DynamicVariable *dv = checked_cast(m); diff --git a/mozilla/js2/src/js2engine.cpp b/mozilla/js2/src/js2engine.cpp index 160514012a9..a1f81a066f7 100644 --- a/mozilla/js2/src/js2engine.cpp +++ b/mozilla/js2/src/js2engine.cpp @@ -395,7 +395,7 @@ namespace MetaData { if ((d == 0.0) || !JSDOUBLE_IS_FINITE(d) ) return 0; d = fd::fmod(d, two32); - d = (d >= 0) ? d : d + two32; + d = (d >= 0) ? fd::floor(d) : fd::ceil(d) + two32; if (d >= two31) return (int32)(d - two32); else diff --git a/mozilla/js2/src/js2eval.cpp b/mozilla/js2/src/js2eval.cpp index 825209f0888..b33945d1dcd 100644 --- a/mozilla/js2/src/js2eval.cpp +++ b/mozilla/js2/src/js2eval.cpp @@ -477,6 +477,8 @@ namespace MetaData { d = stringToDouble(str1, strEnd, numEnd); if (numEnd == str1) return nan; + if (skipWhiteSpace(numEnd, strEnd) != strEnd) + return nan; } return (neg) ? -d : d; } diff --git a/mozilla/js2/src/js2metadata.cpp b/mozilla/js2/src/js2metadata.cpp index b85278f6772..38a0ba2aabf 100644 --- a/mozilla/js2/src/js2metadata.cpp +++ b/mozilla/js2/src/js2metadata.cpp @@ -110,10 +110,15 @@ namespace MetaData { pb = fnDef->parameters; while (pb) { FrameVariable *v = new FrameVariable(compileFrame->allocateSlot(), FrameVariable::Parameter); + if (pb->type) + ValidateTypeExpression(cxt, env, pb->type); + pb->member = v; pb->mn = defineLocalMember(env, pb->name, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos, true); pb = pb->next; } } + if (fnDef->resultType) + ValidateTypeExpression(cxt, env, fnDef->resultType); createDynamicProperty(result, engine->length_StringAtom, INT_TO_JS2VAL(pCount), ReadAccess, true, false); result->fWrap->length = pCount; compileFrame->isConstructor = isConstructor; @@ -150,7 +155,7 @@ namespace MetaData { ASSERT(!(unchecked || hoisted)); // XXX shouldn't be using validateStaticFunction fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos); - Getter *g = new Getter(fnInst); + Getter *g = new Getter(fnInst->fWrap->resultType, fnInst); defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadAccess, g, pos, true); } break; @@ -161,7 +166,7 @@ namespace MetaData { ASSERT(!(unchecked || hoisted)); // XXX shouldn't be using validateStaticFunction fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos); - Setter *s = new Setter(fnInst); + Setter *s = new Setter(fnInst->fWrap->resultType, fnInst); defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, WriteAccess, s, pos, true); } break; @@ -1297,6 +1302,20 @@ namespace MetaData { #ifdef DEBUG bCon->fName = *f->function.name; #endif + VariableBinding *pb = f->function.parameters; + while (pb) { + FrameVariable *v = checked_cast(pb->member); + if (pb->type) + v->type = EvalTypeExpression(env, CompilePhase, pb->type); + else + v->type = objectClass; + pb = pb->next; + } + if (f->function.resultType) + f->function.fWrap->resultType = EvalTypeExpression(env, CompilePhase, f->function.resultType); + else + f->function.fWrap->resultType = objectClass; + SetupStmt(env, phase, f->function.body); // XXX need to make sure that all paths lead to an exit of some kind bCon->emitOp(eReturnVoid, p->pos); @@ -1369,7 +1388,6 @@ namespace MetaData { } } else { - ASSERT(vb->member->memberKind == Member::InstanceVariableMember); InstanceVariable *v = checked_cast(vb->member); JS2Class *t; if (vb->type) @@ -3960,7 +3978,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... initBooleanObject(this); /*** ECMA 3 Math Object ***/ - SimpleInstance *mathObject = new SimpleInstance(this, objectClass->prototype, objectClass); + MAKEBUILTINCLASS(mathClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Math"]), JS2VAL_FALSE); + SimpleInstance *mathObject = new SimpleInstance(this, objectClass->prototype, mathClass); v = new Variable(objectClass, OBJECT_TO_JS2VAL(mathObject), true); defineLocalMember(env, &world.identifiers["Math"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initMathObject(this, mathObject); @@ -4444,6 +4463,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... GCMARKOBJECT(generalNumberClass); GCMARKOBJECT(integerClass); GCMARKOBJECT(numberClass); + GCMARKOBJECT(mathClass); GCMARKOBJECT(characterClass); GCMARKOBJECT(stringClass); GCMARKOBJECT(namespaceClass); @@ -4553,6 +4573,16 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... } } } + + static js2val class_ProtoGetter(JS2Metadata *meta, const js2val thisValue, js2val /* argv */ [], uint32 /* argc */) + { + ASSERT(JS2VAL_IS_OBJECT(thisValue)); + JS2Object *obj = JS2VAL_TO_OBJECT(thisValue); + ASSERT(obj->kind == ClassKind); + JS2Class *c = checked_cast(obj); + + return OBJECT_TO_JS2VAL(c->super); + } void JS2Metadata::initBuiltinClass(JS2Class *builtinClass, FunctionData *staticFunctions, NativeCode *construct, NativeCode *call) { @@ -4567,10 +4597,17 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... Variable *v = new Variable(builtinClass, INT_TO_JS2VAL(1), true); defineLocalMember(env, engine->length_StringAtom, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); + FunctionInstance *callInst = new FunctionInstance(this, functionClass->prototype, functionClass); + callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), class_ProtoGetter, env); + callInst->fWrap->length = 0; + Getter *g = new Getter(objectClass, callInst); + defineLocalMember(env, &world.identifiers["__proto__"], NULL, Attribute::NoOverride, false, ReadAccess, g, 0, true); + + pf = staticFunctions; if (pf) { while (pf->name) { - FunctionInstance *callInst = new FunctionInstance(this, functionClass->prototype, functionClass); + callInst = new FunctionInstance(this, functionClass->prototype, functionClass); callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, env); callInst->fWrap->length = pf->length; v = new Variable(functionClass, OBJECT_TO_JS2VAL(callInst), true); diff --git a/mozilla/js2/src/js2metadata.h b/mozilla/js2/src/js2metadata.h index c2b55a7354c..7db1ce1dc50 100644 --- a/mozilla/js2/src/js2metadata.h +++ b/mozilla/js2/src/js2metadata.h @@ -488,11 +488,19 @@ public: typedef enum { Local, Package, Parameter } FrameVariableKind; - FrameVariable(uint16 frameSlot, FrameVariableKind kind) : LocalMember(Member::FrameVariableMember), frameSlot(frameSlot), kind(kind), sealed(false) { } + FrameVariable(uint16 frameSlot, FrameVariableKind kind) + : LocalMember(Member::FrameVariableMember), + frameSlot(frameSlot), + kind(kind), + type(NULL), + sealed(false) + { } uint16 frameSlot; FrameVariableKind kind; // the kind of frame this variable is in + JS2Class *type; + bool sealed; // true if this variable cannot be deleted using the delete operator virtual LocalMember *clone() { return new FrameVariable(frameSlot, kind); } }; @@ -509,7 +517,7 @@ public: class Getter : public LocalMember { public: - Getter(FunctionInstance *code) : LocalMember(Member::GetterMember), type(NULL), code(code) { } + Getter(JS2Class *type, FunctionInstance *code) : LocalMember(Member::GetterMember), type(type), code(code) { } JS2Class *type; // The type of the value read from this getter FunctionInstance *code; // calling this object does the read @@ -519,7 +527,7 @@ public: class Setter : public LocalMember { public: - Setter(FunctionInstance *code) : LocalMember(Member::SetterMember), type(NULL), code(code) { } + Setter(JS2Class *type, FunctionInstance *code) : LocalMember(Member::SetterMember), type(type), code(code) { } JS2Class *type; // The type of the value written into the setter FunctionInstance *code; // calling this object does the write @@ -836,9 +844,24 @@ class ParameterFrame; class FunctionWrapper { public: FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, Environment *env) - : bCon(new BytecodeContainer()), code(NULL), unchecked(unchecked), compileFrame(compileFrame), env(new Environment(env)), length(0) { } + : bCon(new BytecodeContainer()), + code(NULL), + unchecked(unchecked), + compileFrame(compileFrame), + env(new Environment(env)), + length(0), + resultType(NULL) + { } + FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, NativeCode *code, Environment *env) - : bCon(NULL), code(code), unchecked(unchecked), compileFrame(compileFrame), env(new Environment(env)), length(0) { } + : bCon(NULL), + code(code), + unchecked(unchecked), + compileFrame(compileFrame), + env(new Environment(env)), + length(0), + resultType(NULL) + { } virtual ~FunctionWrapper() { if (bCon) delete bCon; } @@ -848,6 +871,7 @@ public: ParameterFrame *compileFrame; Environment *env; uint32 length; + JS2Class *resultType; }; @@ -1491,6 +1515,7 @@ public: JS2Class *booleanClass; JS2Class *generalNumberClass; JS2Class *numberClass; + JS2Class *mathClass; JS2Class *integerClass; JS2Class *characterClass; JS2Class *stringClass; diff --git a/mozilla/js2/src/js2string.cpp b/mozilla/js2/src/js2string.cpp index 58085713fdc..28fcfab7fb0 100644 --- a/mozilla/js2/src/js2string.cpp +++ b/mozilla/js2/src/js2string.cpp @@ -756,7 +756,7 @@ static js2val String_substring(JS2Metadata *meta, const js2val thisValue, js2val if (argc > 1) { float64 farg1 = meta->toFloat64(argv[1]); if (JSDOUBLE_IS_NaN(farg1) || (farg1 < 0)) - end = sourceLength; + end = 0; else { if (!JSDOUBLE_IS_FINITE(farg1)) end = sourceLength; @@ -788,14 +788,14 @@ void initStringObject(JS2Metadata *meta) { "charAt", 1, String_charAt }, { "charCodeAt", 1, String_charCodeAt }, { "concat", 1, String_concat }, - { "indexOf", 2, String_indexOf }, // XXX ECMA spec says 1, but tests want 2 XXX - { "lastIndexOf", 2, String_lastIndexOf }, // XXX ECMA spec says 1, but tests want 2 XXX + { "indexOf", 1, String_indexOf }, + { "lastIndexOf", 1, String_lastIndexOf }, { "localeCompare", 1, String_localeCompare }, { "match", 1, String_match }, { "replace", 2, String_replace }, { "search", 1, String_search }, { "slice", 2, String_slice }, - { "split", 1, String_split }, // XXX ECMA spec says 2, but tests want 1 XXX + { "split", 2, String_split }, { "substring", 2, String_substring }, { "toSource", 0, String_toString }, { "toLocaleUpperCase", 0, String_toUpperCase }, // (sic)