diff --git a/mozilla/js/js2/icodegenerator.cpp b/mozilla/js/js2/icodegenerator.cpp index 73f585027a0..38bfcae61d1 100644 --- a/mozilla/js/js2/icodegenerator.cpp +++ b/mozilla/js/js2/icodegenerator.cpp @@ -2533,6 +2533,7 @@ void ICodeGenerator::readICode(const char *fileName) ParameterList *theParameterList = new ParameterList(); theParameterList->add(mContext->getWorld().identifiers["this"], TypedRegister(0, thisClass), false); uint32 pCount = 1; + StringFormatter s; XMLNodeList ¶meters = element->children(); for (XMLNodeList::const_iterator k = parameters.begin(); k != parameters.end(); k++) { XMLNode *parameter = *k; @@ -2542,10 +2543,15 @@ void ICodeGenerator::readICode(const char *fileName) element->getValue(widenCString("name"), parameterName); element->getValue(widenCString("type"), parameterTypeName); JSType *parameterType = findType(mContext->getWorld().identifiers[parameterTypeName]); - theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount++, parameterType), false); + theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount, parameterType), false); + s << pCount - 1; + theParameterList->add(mContext->getWorld().identifiers[s.getString()], TypedRegister(pCount, parameterType), false); + s.clear(); + pCount++; } } - + theParameterList->setPositionalCount(pCount); + JSType *resultType = findType(mContext->getWorld().identifiers[resultTypeName]); String &body = element->body(); if (body.length()) { diff --git a/mozilla/js/js2/interpreter.cpp b/mozilla/js/js2/interpreter.cpp index a761328927c..c8226f5b23c 100644 --- a/mozilla/js/js2/interpreter.cpp +++ b/mozilla/js/js2/interpreter.cpp @@ -966,7 +966,28 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) else (*registers)[dst(gp).first] = value.object->getProperty(*src2(gp)); } else { - (*registers)[dst(gp).first] = value.object->getProperty(*src2(gp)); + JSFunction *getter = value.object->getter(*src2(gp)); + if (getter) { + if (getter->isNative()) { + JSValues argv(1); + JSValues::size_type i = 1; + argv[0] = value; + JSValue result = static_cast(getter)->mCode(this, argv); + if (dst(gp).first != NotARegister) + (*registers)[dst(gp).first] = result; + break; + } + else { + mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, dst(gp), mICode, mCurrentClosure); + mICode = getter->getICode(); + mActivation = new Activation(mICode->itsMaxRegister, value); + registers = &mActivation->mRegisters; + mPC = mICode->its_iCode->begin(); + endPC = mICode->its_iCode->end(); + } + } + else + (*registers)[dst(gp).first] = value.object->getProperty(*src2(gp)); } } // XXX runtime error @@ -1055,14 +1076,24 @@ using JSString throughout. if (inst) { if (inst->hasGetter(src2(gs))) { JSFunction* getter = inst->getter(src2(gs)); - ASSERT(!getter->isNative()); - mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, dst(gs), mICode, mCurrentClosure); - mICode = getter->getICode(); - mActivation = new Activation(mICode->itsMaxRegister, value); - registers = &mActivation->mRegisters; - mPC = mICode->its_iCode->begin(); - endPC = mICode->its_iCode->end(); - continue; + if (getter->isNative()) { + JSValues argv(1); + JSValues::size_type i = 1; + argv[0] = value; + JSValue result = static_cast(getter)->mCode(this, argv); + if (dst(gs).first != NotARegister) + (*registers)[dst(gs).first] = result; + break; + } + else { + mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, dst(gs), mICode, mCurrentClosure); + mICode = getter->getICode(); + mActivation = new Activation(mICode->itsMaxRegister, value); + registers = &mActivation->mRegisters; + mPC = mICode->its_iCode->begin(); + endPC = mICode->its_iCode->end(); + continue; + } } else (*registers)[dst(gs).first] = (*inst)[src2(gs)]; @@ -1089,14 +1120,25 @@ using JSString throughout. if (inst) { if (inst->hasSetter(src1(ss))) { JSFunction* setter = inst->setter(src1(ss)); - ASSERT(!setter->isNative()); - mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, TypedRegister(NotARegister, &Null_Type), mICode, mCurrentClosure); - mICode = setter->getICode(); - mActivation = new Activation(mICode->itsMaxRegister, value, (*registers)[src2(ss).first]); - registers = &mActivation->mRegisters; - mPC = mICode->its_iCode->begin(); - endPC = mICode->its_iCode->end(); - continue; + if (setter->isNative()) { + JSValues argv(2); + JSValues::size_type i = 1; + argv[0] = value; + argv[1] = (*registers)[src2(ss).first]; + JSValue result = static_cast(setter)->mCode(this, argv); + if (dst(ss).first != NotARegister) + (*registers)[dst(ss).first] = result; + break; + } + else { + mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, TypedRegister(NotARegister, &Null_Type), mICode, mCurrentClosure); + mICode = setter->getICode(); + mActivation = new Activation(mICode->itsMaxRegister, value, (*registers)[src2(ss).first]); + registers = &mActivation->mRegisters; + mPC = mICode->its_iCode->begin(); + endPC = mICode->its_iCode->end(); + continue; + } } else (*inst)[src1(ss)] = (*registers)[src2(ss).first]; diff --git a/mozilla/js/js2/js2.cpp b/mozilla/js/js2/js2.cpp index f15c084e7df..3f26f0dc1ec 100644 --- a/mozilla/js/js2/js2.cpp +++ b/mozilla/js/js2/js2.cpp @@ -171,6 +171,25 @@ static JSValue load(Context *cx, const JSValues &argv) return result; } +static JSValue loadxml(Context *cx, const JSValues &argv) +{ + + JSValue result; + size_t n = argv.size(); + if (n > 1) { + for (size_t i = 1; i < n; ++i) { + JSValue val = argv[i].toString(); + if (val.isString()) { + String fileName(*val.string); + std::string str(fileName.length(), char()); + std::transform(fileName.begin(), fileName.end(), str.begin(), narrow); + cx->loadClass(str.c_str()); + } + } + } + return result; +} + static bool goGeorge = false; static JSValue george(Context *, const JSValues &) @@ -234,6 +253,7 @@ static void readEvalPrint(FILE *in, World &world) global.defineNativeFunction(world.identifiers["print"], print); global.defineNativeFunction(world.identifiers["dump"], dump); global.defineNativeFunction(world.identifiers["load"], load); + global.defineNativeFunction(world.identifiers["loadxml"], loadxml); global.defineNativeFunction(world.identifiers["george"], george); // global.defineNativeFunction(world.identifiers["time"], time); diff --git a/mozilla/js/js2/jstypes.cpp b/mozilla/js/js2/jstypes.cpp index f279443b13f..f3cbf86b7f8 100644 --- a/mozilla/js/js2/jstypes.cpp +++ b/mozilla/js/js2/jstypes.cpp @@ -253,23 +253,37 @@ static JSValue date_invokor(Context *, const JSValues&) JSString* JSArray::ArrayString = new JSString("Array"); JSObject *JSArray::ArrayPrototypeObject = NULL; +JSFunction *JSArray::Array_length_getter = NULL; + +static JSValue array_length(Context *cx, const JSValues& argv) +{ + // argv[0] better be an array object + uint32 argCount = argv.size(); + if ((argCount > 0) & argv[0].isArray()) { + JSArray *thisArray = argv[0].array; + return thisArray->length(); + } + return kUndefinedValue; +} static JSValue array_constructor(Context *, const JSValues& argv) { + JSArray *result = NULL; // argv[0] will be NULL uint32 argCount = argv.size(); if (argCount > 1) if (argCount > 2) { // then it's a bunch of elements - JSArray *result = new JSArray(argCount - 1); + result = new JSArray(argCount - 1); for (uint32 i = 1; i < argCount; i++) { (*result)[i - 1] = argv[i]; } - return JSValue(result); } else - return JSValue(new JSArray(JSValue::valueToUInt32(argv[1]).u32)); + result = new JSArray(JSValue::valueToUInt32(argv[1]).u32); else - return JSValue(new JSArray()); + result = new JSArray(); + result->setGetter(widenCString("length"), JSArray::Array_length_getter); + return JSValue(result); } static JSValue array_toString(Context *, const JSValues& argv) @@ -308,6 +322,8 @@ void JSArray::initArrayObject(JSScope *g) ASSERT(g->getProperty(*ArrayString).isObject()); JSObject *arrayVariable = g->getProperty(*ArrayString).object; arrayVariable->setProperty(widenCString("prototype"), JSValue(ArrayPrototypeObject)); // should be DontEnum, DontDelete, ReadOnly + + Array_length_getter = new JSNativeFunction(array_length); } /**************************************************************************************/ diff --git a/mozilla/js/js2/jstypes.h b/mozilla/js/js2/jstypes.h index 71e63d4f1e3..0c7c2f161c2 100644 --- a/mozilla/js/js2/jstypes.h +++ b/mozilla/js/js2/jstypes.h @@ -305,6 +305,7 @@ namespace JSTypes { { if (mGetter == NULL) mGetter = new FunctionMap(); + mProperties[name] = kUndefinedValue; (*mGetter)[name] = getter; } @@ -312,6 +313,7 @@ namespace JSTypes { { if (mSetter == NULL) mSetter = new FunctionMap(); + mProperties[name] = kUndefinedValue; (*mSetter)[name] = setter; } @@ -398,6 +400,7 @@ namespace JSTypes { uint32 top; public: + static JSFunction *Array_length_getter; static void initArrayObject(JSScope *g); JSArray() : JSObject(ArrayPrototypeObject), elements(1) { setClass(ArrayString); top = 0; } diff --git a/mozilla/js/js2/xmlparser.cpp b/mozilla/js/js2/xmlparser.cpp index da0fee62718..c89f8def48b 100644 --- a/mozilla/js/js2/xmlparser.cpp +++ b/mozilla/js/js2/xmlparser.cpp @@ -25,6 +25,7 @@ bool XMLTag::getValue(const String &name, String &value) XMLLexer::XMLLexer(const char *filename) { + base = NULL; FILE *f = fopen(filename, "r"); if (f) { fseek(f, 0, SEEK_END); diff --git a/mozilla/js2/src/icodegenerator.cpp b/mozilla/js2/src/icodegenerator.cpp index 73f585027a0..38bfcae61d1 100644 --- a/mozilla/js2/src/icodegenerator.cpp +++ b/mozilla/js2/src/icodegenerator.cpp @@ -2533,6 +2533,7 @@ void ICodeGenerator::readICode(const char *fileName) ParameterList *theParameterList = new ParameterList(); theParameterList->add(mContext->getWorld().identifiers["this"], TypedRegister(0, thisClass), false); uint32 pCount = 1; + StringFormatter s; XMLNodeList ¶meters = element->children(); for (XMLNodeList::const_iterator k = parameters.begin(); k != parameters.end(); k++) { XMLNode *parameter = *k; @@ -2542,10 +2543,15 @@ void ICodeGenerator::readICode(const char *fileName) element->getValue(widenCString("name"), parameterName); element->getValue(widenCString("type"), parameterTypeName); JSType *parameterType = findType(mContext->getWorld().identifiers[parameterTypeName]); - theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount++, parameterType), false); + theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount, parameterType), false); + s << pCount - 1; + theParameterList->add(mContext->getWorld().identifiers[s.getString()], TypedRegister(pCount, parameterType), false); + s.clear(); + pCount++; } } - + theParameterList->setPositionalCount(pCount); + JSType *resultType = findType(mContext->getWorld().identifiers[resultTypeName]); String &body = element->body(); if (body.length()) { diff --git a/mozilla/js2/src/interpreter.cpp b/mozilla/js2/src/interpreter.cpp index a761328927c..c8226f5b23c 100644 --- a/mozilla/js2/src/interpreter.cpp +++ b/mozilla/js2/src/interpreter.cpp @@ -966,7 +966,28 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) else (*registers)[dst(gp).first] = value.object->getProperty(*src2(gp)); } else { - (*registers)[dst(gp).first] = value.object->getProperty(*src2(gp)); + JSFunction *getter = value.object->getter(*src2(gp)); + if (getter) { + if (getter->isNative()) { + JSValues argv(1); + JSValues::size_type i = 1; + argv[0] = value; + JSValue result = static_cast(getter)->mCode(this, argv); + if (dst(gp).first != NotARegister) + (*registers)[dst(gp).first] = result; + break; + } + else { + mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, dst(gp), mICode, mCurrentClosure); + mICode = getter->getICode(); + mActivation = new Activation(mICode->itsMaxRegister, value); + registers = &mActivation->mRegisters; + mPC = mICode->its_iCode->begin(); + endPC = mICode->its_iCode->end(); + } + } + else + (*registers)[dst(gp).first] = value.object->getProperty(*src2(gp)); } } // XXX runtime error @@ -1055,14 +1076,24 @@ using JSString throughout. if (inst) { if (inst->hasGetter(src2(gs))) { JSFunction* getter = inst->getter(src2(gs)); - ASSERT(!getter->isNative()); - mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, dst(gs), mICode, mCurrentClosure); - mICode = getter->getICode(); - mActivation = new Activation(mICode->itsMaxRegister, value); - registers = &mActivation->mRegisters; - mPC = mICode->its_iCode->begin(); - endPC = mICode->its_iCode->end(); - continue; + if (getter->isNative()) { + JSValues argv(1); + JSValues::size_type i = 1; + argv[0] = value; + JSValue result = static_cast(getter)->mCode(this, argv); + if (dst(gs).first != NotARegister) + (*registers)[dst(gs).first] = result; + break; + } + else { + mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, dst(gs), mICode, mCurrentClosure); + mICode = getter->getICode(); + mActivation = new Activation(mICode->itsMaxRegister, value); + registers = &mActivation->mRegisters; + mPC = mICode->its_iCode->begin(); + endPC = mICode->its_iCode->end(); + continue; + } } else (*registers)[dst(gs).first] = (*inst)[src2(gs)]; @@ -1089,14 +1120,25 @@ using JSString throughout. if (inst) { if (inst->hasSetter(src1(ss))) { JSFunction* setter = inst->setter(src1(ss)); - ASSERT(!setter->isNative()); - mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, TypedRegister(NotARegister, &Null_Type), mICode, mCurrentClosure); - mICode = setter->getICode(); - mActivation = new Activation(mICode->itsMaxRegister, value, (*registers)[src2(ss).first]); - registers = &mActivation->mRegisters; - mPC = mICode->its_iCode->begin(); - endPC = mICode->its_iCode->end(); - continue; + if (setter->isNative()) { + JSValues argv(2); + JSValues::size_type i = 1; + argv[0] = value; + argv[1] = (*registers)[src2(ss).first]; + JSValue result = static_cast(setter)->mCode(this, argv); + if (dst(ss).first != NotARegister) + (*registers)[dst(ss).first] = result; + break; + } + else { + mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, TypedRegister(NotARegister, &Null_Type), mICode, mCurrentClosure); + mICode = setter->getICode(); + mActivation = new Activation(mICode->itsMaxRegister, value, (*registers)[src2(ss).first]); + registers = &mActivation->mRegisters; + mPC = mICode->its_iCode->begin(); + endPC = mICode->its_iCode->end(); + continue; + } } else (*inst)[src1(ss)] = (*registers)[src2(ss).first]; diff --git a/mozilla/js2/src/jstypes.cpp b/mozilla/js2/src/jstypes.cpp index f279443b13f..f3cbf86b7f8 100644 --- a/mozilla/js2/src/jstypes.cpp +++ b/mozilla/js2/src/jstypes.cpp @@ -253,23 +253,37 @@ static JSValue date_invokor(Context *, const JSValues&) JSString* JSArray::ArrayString = new JSString("Array"); JSObject *JSArray::ArrayPrototypeObject = NULL; +JSFunction *JSArray::Array_length_getter = NULL; + +static JSValue array_length(Context *cx, const JSValues& argv) +{ + // argv[0] better be an array object + uint32 argCount = argv.size(); + if ((argCount > 0) & argv[0].isArray()) { + JSArray *thisArray = argv[0].array; + return thisArray->length(); + } + return kUndefinedValue; +} static JSValue array_constructor(Context *, const JSValues& argv) { + JSArray *result = NULL; // argv[0] will be NULL uint32 argCount = argv.size(); if (argCount > 1) if (argCount > 2) { // then it's a bunch of elements - JSArray *result = new JSArray(argCount - 1); + result = new JSArray(argCount - 1); for (uint32 i = 1; i < argCount; i++) { (*result)[i - 1] = argv[i]; } - return JSValue(result); } else - return JSValue(new JSArray(JSValue::valueToUInt32(argv[1]).u32)); + result = new JSArray(JSValue::valueToUInt32(argv[1]).u32); else - return JSValue(new JSArray()); + result = new JSArray(); + result->setGetter(widenCString("length"), JSArray::Array_length_getter); + return JSValue(result); } static JSValue array_toString(Context *, const JSValues& argv) @@ -308,6 +322,8 @@ void JSArray::initArrayObject(JSScope *g) ASSERT(g->getProperty(*ArrayString).isObject()); JSObject *arrayVariable = g->getProperty(*ArrayString).object; arrayVariable->setProperty(widenCString("prototype"), JSValue(ArrayPrototypeObject)); // should be DontEnum, DontDelete, ReadOnly + + Array_length_getter = new JSNativeFunction(array_length); } /**************************************************************************************/ diff --git a/mozilla/js2/src/jstypes.h b/mozilla/js2/src/jstypes.h index 71e63d4f1e3..0c7c2f161c2 100644 --- a/mozilla/js2/src/jstypes.h +++ b/mozilla/js2/src/jstypes.h @@ -305,6 +305,7 @@ namespace JSTypes { { if (mGetter == NULL) mGetter = new FunctionMap(); + mProperties[name] = kUndefinedValue; (*mGetter)[name] = getter; } @@ -312,6 +313,7 @@ namespace JSTypes { { if (mSetter == NULL) mSetter = new FunctionMap(); + mProperties[name] = kUndefinedValue; (*mSetter)[name] = setter; } @@ -398,6 +400,7 @@ namespace JSTypes { uint32 top; public: + static JSFunction *Array_length_getter; static void initArrayObject(JSScope *g); JSArray() : JSObject(ArrayPrototypeObject), elements(1) { setClass(ArrayString); top = 0; } diff --git a/mozilla/js2/src/xmlparser.cpp b/mozilla/js2/src/xmlparser.cpp index da0fee62718..c89f8def48b 100644 --- a/mozilla/js2/src/xmlparser.cpp +++ b/mozilla/js2/src/xmlparser.cpp @@ -25,6 +25,7 @@ bool XMLTag::getValue(const String &name, String &value) XMLLexer::XMLLexer(const char *filename) { + base = NULL; FILE *f = fopen(filename, "r"); if (f) { fseek(f, 0, SEEK_END); diff --git a/mozilla/js2/tests/cpp/js2_shell.cpp b/mozilla/js2/tests/cpp/js2_shell.cpp index f15c084e7df..3f26f0dc1ec 100644 --- a/mozilla/js2/tests/cpp/js2_shell.cpp +++ b/mozilla/js2/tests/cpp/js2_shell.cpp @@ -171,6 +171,25 @@ static JSValue load(Context *cx, const JSValues &argv) return result; } +static JSValue loadxml(Context *cx, const JSValues &argv) +{ + + JSValue result; + size_t n = argv.size(); + if (n > 1) { + for (size_t i = 1; i < n; ++i) { + JSValue val = argv[i].toString(); + if (val.isString()) { + String fileName(*val.string); + std::string str(fileName.length(), char()); + std::transform(fileName.begin(), fileName.end(), str.begin(), narrow); + cx->loadClass(str.c_str()); + } + } + } + return result; +} + static bool goGeorge = false; static JSValue george(Context *, const JSValues &) @@ -234,6 +253,7 @@ static void readEvalPrint(FILE *in, World &world) global.defineNativeFunction(world.identifiers["print"], print); global.defineNativeFunction(world.identifiers["dump"], dump); global.defineNativeFunction(world.identifiers["load"], load); + global.defineNativeFunction(world.identifiers["loadxml"], loadxml); global.defineNativeFunction(world.identifiers["george"], george); // global.defineNativeFunction(world.identifiers["time"], time);