Commit 74da9e05 authored by darin@apple.com's avatar darin@apple.com

- re-fix http://bugs.webkit.org/show_bug.cgi?id=16471

          Completions need to be smaller (or not exist at all)

        Same patch as last time with the test failures problem fixed.

        * kjs/function.cpp:
        (KJS::GlobalFuncImp::callAsFunction): Make sure to check the completion
        type from newExec to see if the execute raised an exception.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@28907 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 5d9b83ab
......@@ -31,7 +31,6 @@
#include "JSCallbackObject.h"
#include "JSClassRef.h"
#include "JSGlobalObject.h"
#include "completion.h"
#include "object.h"
#include <wtf/Platform.h>
......
2007-12-20 Darin Adler <darin@apple.com>
- re-fix http://bugs.webkit.org/show_bug.cgi?id=16471
Completions need to be smaller (or not exist at all)
Same patch as last time with the test failures problem fixed.
* kjs/function.cpp:
(KJS::GlobalFuncImp::callAsFunction): Make sure to check the completion
type from newExec to see if the execute raised an exception.
2007-12-20 Darin Adler <darin@apple.com>
- roll out that last change -- it was causing test failures;
......
......@@ -92,8 +92,3 @@ JSValue *RuntimeMethod::callAsFunction(ExecState *exec, JSObject *thisObj, const
instance->end();
return aValue;
}
Completion RuntimeMethod::execute(ExecState*)
{
return Completion(Normal, jsUndefined());
}
......@@ -32,9 +32,7 @@
namespace KJS {
class RuntimeMethod : public InternalFunctionImp
{
class RuntimeMethod : public InternalFunctionImp {
public:
RuntimeMethod(ExecState *exec, const Identifier &n, Bindings::MethodList &methodList);
......@@ -42,8 +40,6 @@ public:
virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
virtual Completion execute(ExecState *exec);
private:
static JSValue *lengthGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
......
......@@ -108,7 +108,69 @@ namespace KJS {
const CommonIdentifiers& propertyNames() const { return *m_propertyNames; }
LocalStorage& localStorage() { return *m_localStorage; }
// These are only valid right after calling execute().
ComplType completionType() const { return m_completionType; }
const Identifier& breakOrContinueTarget() const
{
ASSERT(m_completionType == Break || m_completionType == Continue);
return *m_breakOrContinueTarget;
}
// Only for use in the implementation of execute().
void setCompletionType(ComplType type)
{
ASSERT(type != Break);
ASSERT(type != Continue);
m_completionType = type;
}
JSValue* setNormalCompletion()
{
ASSERT(!hadException());
m_completionType = Normal;
return 0;
}
JSValue* setNormalCompletion(JSValue* value)
{
ASSERT(!hadException());
m_completionType = Normal;
return value;
}
JSValue* setBreakCompletion(const Identifier* target)
{
ASSERT(!hadException());
m_completionType = Break;
m_breakOrContinueTarget = target;
return 0;
}
JSValue* setContinueCompletion(const Identifier* target)
{
ASSERT(!hadException());
m_completionType = Continue;
m_breakOrContinueTarget = target;
return 0;
}
JSValue* setReturnValueCompletion(JSValue* returnValue)
{
ASSERT(!hadException());
ASSERT(returnValue);
m_completionType = ReturnValue;
return returnValue;
}
JSValue* setThrowCompletion(JSValue* exception)
{
ASSERT(!hadException());
ASSERT(exception);
m_completionType = Throw;
return exception;
}
JSValue* setInterruptedCompletion()
{
ASSERT(!hadException());
m_completionType = Interrupted;
return 0;
}
public:
ExecState(JSGlobalObject* glob, JSObject* thisV,
ScopeNode* scopeNode, CodeType type = GlobalCode,
......@@ -141,6 +203,9 @@ namespace KJS {
int m_iterationDepth;
int m_switchDepth;
CodeType m_codeType;
ComplType m_completionType;
const Identifier* m_breakOrContinueTarget;
};
} // namespace KJS
......
......@@ -26,7 +26,6 @@
namespace KJS {
class Identifier;
class JSValue;
enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted };
......@@ -44,20 +43,16 @@ namespace KJS {
class Completion {
public:
Completion(ComplType type = Normal, JSValue* value = 0)
: m_type(type), m_value(value), m_target(0) { }
Completion(ComplType type, const Identifier* target)
: m_type(type), m_value(0), m_target(target) { }
: m_type(type), m_value(value) { }
ComplType complType() const { return m_type; }
JSValue* value() const { return m_value; }
void setValue(JSValue* v) { m_value = v; }
const Identifier& target() const { return *m_target; }
bool isValueCompletion() const { return !!m_value; }
private:
ComplType m_type;
JSValue* m_value;
const Identifier* m_target;
};
}
......
......@@ -132,7 +132,6 @@ FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
virtual JSObject *construct(ExecState *, const List &args);
virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args);
Completion execute(const List &);
JSObject *construct(const List &);
};
......
......@@ -70,24 +70,14 @@ void FunctionImp::mark()
JSValue* FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
{
// enter a new execution context
ExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), FunctionCode, exec, exec->dynamicGlobalObject()->currentExec(), this, &args);
if (exec->hadException())
newExec.setException(exec->exception());
Completion comp = execute(&newExec);
// if an exception occured, propogate it back to the previous execution object
if (newExec.hadException())
comp = Completion(Throw, newExec.exception());
if (comp.complType() == Throw) {
exec->setException(comp.value());
return comp.value();
}
else if (comp.complType() == ReturnValue)
return comp.value();
else
ExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), FunctionCode, exec, exec->dynamicGlobalObject()->currentExec(), this, &args);
JSValue* result = body->execute(&newExec);
if (newExec.completionType() == Throw) {
exec->setException(result);
return result;
}
if (newExec.completionType() == ReturnValue)
return result;
return jsUndefined();
}
......@@ -214,15 +204,6 @@ JSObject* FunctionImp::construct(ExecState* exec, const List& args)
return obj;
}
Completion FunctionImp::execute(ExecState* exec)
{
Completion result = body->execute(exec);
if (result.complType() == Throw || result.complType() == ReturnValue)
return result;
return Completion(Normal, jsUndefined()); // TODO: or ReturnValue ?
}
// ------------------------------ IndexToNameMap ---------------------------------
// We map indexes in the arguments array to their corresponding argument names.
......@@ -718,30 +699,21 @@ JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* thisObj, const
JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
JSObject* thisVal = static_cast<JSObject*>(exec->thisValue());
ExecState newExec(globalObject, thisVal, evalNode.get(), EvalCode, exec, globalObject->currentExec());
if (exec->hadException())
newExec.setException(exec->exception());
if (switchGlobal) {
newExec.pushScope(thisObj);
newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj));
}
Completion c = evalNode->execute(&newExec);
JSValue* value = evalNode->execute(&newExec);
if (switchGlobal)
newExec.popScope();
// if an exception occured, propogate it back to the previous execution object
if (newExec.hadException())
exec->setException(newExec.exception());
res = jsUndefined();
if (c.complType() == Throw)
exec->setException(c.value());
else if (c.isValueCompletion())
res = c.value();
if (newExec.completionType() == Throw) {
exec->setException(value);
return value;
}
return value ? value : jsUndefined();
}
break;
}
case ParseInt:
res = jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
......
......@@ -82,7 +82,6 @@ namespace KJS {
virtual JSObject* construct(ExecState*, const List& args);
virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
Completion execute(ExecState*);
// Note: unlike body->paramName, this returns Identifier::null for parameters
// that will never get set, due to later param having the same name
......
......@@ -120,7 +120,8 @@ Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int
else {
// execute the code
ExecState newExec(globalObject, thisObj, progNode.get());
res = progNode->execute(&newExec);
JSValue* value = progNode->execute(&newExec);
res = Completion(newExec.completionType(), value);
}
globalObject->decRecursion();
......
This diff is collapsed.
This diff is collapsed.
......@@ -88,7 +88,6 @@ namespace KJS {
static const ClassInfo info;
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
Completion execute(const List &);
JSObject *construct(const List &);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment