SVN commit 1121539 by orlovich: Simplify call sequence a bit. Might be a hair faster, but I care more about the stack space here. M +30 -1 bytecode/machine.cpp.in M +5 -46 object.cpp M +6 -1 object.h --- trunk/KDE/kdelibs/kjs/bytecode/machine.cpp.in #1121538:1121539 @@ -34,6 +34,16 @@ #include +// maximum global call stack size. Protects against accidental or +// malicious infinite recursions. Define to -1 if you want no limit. +#if PLATFORM(DARWIN) +// Given OS X stack sizes we run out of stack at about 350 levels. +// If we improve our stack usage, we can bump this number. +#define KJS_MAX_STACK 100 +#else +#define KJS_MAX_STACK 700 // ### set system specific +#endif + namespace KJS { #ifdef __GNUC__ @@ -78,7 +88,7 @@ string = newString; } -void throwUndefinedVariableError(ExecState* exec, const Identifier& ident) +NEVER_INLINE void throwUndefinedVariableError(ExecState* exec, const Identifier& ident) { UString msg = "Can't find variable: %s"; substitute(msg, ident.ustring()); @@ -156,8 +166,21 @@ } } +static int depth; +NEVER_INLINE JSValue* handleStackOverflow(ExecState* exec) { + depth -= 11; //Give the debugger some room.. + JSValue *ret = throwError(exec, RangeError, "Maximum call stack size exceeded."); + depth += 10; //Put it back.. + return ret; +} +struct DepthCleanup +{ + ~DepthCleanup() { --depth; } +}; + + ALWAYS_INLINE_INTO JSValue* Machine::runBlock(ExecState* exec, const CodeBlock& codeBlock, ExecState* parentExec) { @@ -166,6 +189,12 @@ @generate #endif + ++depth; + if (depth > KJS_MAX_STACK) + return handleStackOverflow(exec); + + DepthCleanup dc; + const unsigned char* base = codeBlock.data(); const unsigned char* pc = base; List workList; --- trunk/KDE/kdelibs/kjs/object.cpp #1121538:1121539 @@ -35,54 +35,10 @@ #include -// maximum global call stack size. Protects against accidental or -// malicious infinite recursions. Define to -1 if you want no limit. -#if PLATFORM(DARWIN) -// Given OS X stack sizes we run out of stack at about 350 levels. -// If we improve our stack usage, we can bump this number. -#define KJS_MAX_STACK 100 -#else -#define KJS_MAX_STACK 700 // ### set system specific -#endif - - #define JAVASCRIPT_MARK_TRACING 0 namespace KJS { -// ------------------------------ Object --------------------------------------- - -JSValue *JSObject::call(ExecState *exec, JSObject *thisObj, const List &args) -{ - assert(implementsCall()); - -#if KJS_MAX_STACK > 0 - static int depth = 0; // sum of all concurrent interpreters - - if (++depth > KJS_MAX_STACK) { - depth -= 11; //Give the debugger some room.. - JSValue *ret = throwError(exec, RangeError, "Maximum call stack size exceeded."); - depth += 10; //Put it back.. - return ret; - } -#endif - - JSValue *ret = callAsFunction(exec,thisObj,args); - -#ifndef NDEBUG - if (!ret) { - fprintf(stderr, "callAsFunction returned 0 on:%s\n", typeid(*this).name()); - assert(ret); - } -#endif - -#if KJS_MAX_STACK > 0 - --depth; -#endif - - return ret; -} - // ------------------------------ JSObject ------------------------------------ void JSObject::mark() @@ -129,8 +85,11 @@ { PropertySlot slot; - if (const_cast(this)->getPropertySlot(exec, propertyName, slot)) - return slot.getValue(exec, const_cast(this), propertyName); + if (const_cast(this)->getPropertySlot(exec, propertyName, slot)) { + JSValue* val = slot.getValue(exec, const_cast(this), propertyName); + assert(val); + return val; + } return jsUndefined(); } --- trunk/KDE/kdelibs/kjs/object.h #1121538:1121539 @@ -393,7 +393,7 @@ * @param args List of arguments to be passed to the function * @return The return value from the function */ - JSValue *call(ExecState *exec, JSObject *thisObj, const List &args); + JSValue *call(ExecState *exec, JSObject *thisObj, const List &args); // ### TODO: consolidate with below virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); /** @@ -611,6 +611,11 @@ return defaultValue(exec, preferredType); } +inline JSValue* JSObject::call(ExecState *exec, JSObject *thisObj, const List &args) +{ + return callAsFunction(exec, thisObj, args); +} + } // namespace #endif // KJS_OBJECT_H