JavaScriptCore:
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Apr 2004 20:07:47 +0000 (20:07 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Apr 2004 20:07:47 +0000 (20:07 +0000)
        Reviewed by John.

Changed things so that newly created objects get a prototype based
on the scope chain of the current function, rather than the
interpreter that started execution. This fixes the following bugs:

<rdar://problem/3368523>: ARCH: wrong prototype used to create new objects (hang on lookup.atomica.com)
        <rdar://problem/3559173>: ARCH: Cannot scan using a HP Jetdirect product (JS object prototypes bind incorrectly)

* JavaScriptCore.pbproj/project.pbxproj:
        * kjs/array_object.cpp:
        (CompareWithCompareFunctionArguments::CompareWithCompareFunctionArguments):
        (ArrayProtoFuncImp::ArrayProtoFuncImp):
        (ArrayProtoFuncImp::call):
        (ArrayObjectImp::construct):
        * kjs/bool_object.cpp:
        (BooleanObjectImp::construct):
        * kjs/date_object.cpp:
        (DateProtoFuncImp::DateProtoFuncImp):
        (DateProtoFuncImp::call):
        (DateObjectImp::construct):
        * kjs/error_object.cpp:
        (ErrorObjectImp::construct):
        * kjs/function.cpp:
        (FunctionImp::FunctionImp):
        (FunctionImp::call):
        (DeclaredFunctionImp::construct):
        (ArgumentsImp::ArgumentsImp):
        (GlobalFuncImp::call):
        * kjs/function_object.cpp:
        (FunctionProtoFuncImp::call):
        (FunctionObjectImp::construct):
        * kjs/internal.cpp:
        (BooleanImp::toObject):
        (StringImp::toObject):
        (NumberImp::toObject):
        (InterpreterImp::InterpreterImp):
        (InterpreterImp::clear):
        (InterpreterImp::interpreterWithGlobalObject):
        * kjs/internal.h:
        * kjs/interpreter.cpp:
        (ExecState::lexicalInterpreter):
        * kjs/interpreter.h:
        (KJS::ExecState::dynamicInterpreter):
        (KJS::ExecState::interpreter):
        * kjs/math_object.cpp:
        (MathFuncImp::MathFuncImp):
        * kjs/nodes.cpp:
        (StatementNode::hitStatement):
        (StatementNode::abortStatement):
        (RegExpNode::evaluate):
        (ElementNode::evaluate):
        (ArrayNode::evaluate):
        (ObjectLiteralNode::evaluate):
        (PropertyValueNode::evaluate):
        (FunctionCallNode::evaluate):
        (FuncDeclNode::processFuncDecl):
        (FuncExprNode::evaluate):
        * kjs/number_object.cpp:
        (NumberObjectImp::construct):
        * kjs/object.cpp:
        (KJS::ObjectImp::defaultValue):
        (KJS::Error::create):
        * kjs/object_object.cpp:
        (ObjectObjectImp::construct):
        * kjs/reference.cpp:
        (Reference::putValue):
        * kjs/regexp_object.cpp:
        (RegExpProtoFuncImp::call):
        (RegExpObjectImp::arrayOfMatches):
        (RegExpObjectImp::construct):
        * kjs/scope_chain.cpp:
        (KJS::ScopeChain::bottom):
        * kjs/scope_chain.h:
        * kjs/string_object.cpp:
        (StringProtoFuncImp::StringProtoFuncImp):
        (StringProtoFuncImp::call):
        (StringObjectImp::construct):

WebCore:

        Reviewed by John.

Changed things so that newly created objects get a prototype based
on the scope chain of the current function, rather than the
interpreter that started execution. This fixes the following bugs:

<rdar://problem/3368523>: ARCH: wrong prototype used to create new objects (hang on lookup.atomica.com)
        <rdar://problem/3559173>: ARCH: Cannot scan using a HP Jetdirect product (JS object prototypes bind incorrectly)

* khtml/ecma/kjs_binding.h:
        (KJS::cacheDOMObject):
        (KJS::cacheGlobalObject):
        * khtml/ecma/kjs_css.cpp:
        (KJS::getDOMStyleSheet):
        (KJS::getDOMStyleSheetList):
        (KJS::getDOMCSSValue):
        * khtml/ecma/kjs_dom.cpp:
        (KJS::getDOMDocumentNode):
        (KJS::getDOMNode):
        * khtml/ecma/kjs_events.cpp:
        (KJS::getDOMEvent):
        * khtml/ecma/kjs_html.cpp:
        (KJS::HTMLDocument::tryGet):
        (KJS::HTMLDocument::putValue):
        (KJS::getSelectHTMLCollection):
        * khtml/ecma/kjs_navigator.cpp:
        (Navigator::Navigator):
        (PluginBase::PluginBase):
        * khtml/ecma/kjs_window.cpp:
        (KJS::History::History):
        (KJS::FrameArray::FrameArray):
        (Screen::Screen):
        (Window::retrieveActive):
        (Window::put):
        (Window::isSafeScript):
        (WindowFunc::tryCall):
        (Location::put):
        (LocationFunc::tryCall):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@6347 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
JavaScriptCore/kjs/array_object.cpp
JavaScriptCore/kjs/bool_object.cpp
JavaScriptCore/kjs/date_object.cpp
JavaScriptCore/kjs/error_object.cpp
JavaScriptCore/kjs/function.cpp
JavaScriptCore/kjs/function_object.cpp
JavaScriptCore/kjs/internal.cpp
JavaScriptCore/kjs/internal.h
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/interpreter.h
JavaScriptCore/kjs/interpreter_map.cpp [new file with mode: 0644]
JavaScriptCore/kjs/interpreter_map.h [new file with mode: 0644]
JavaScriptCore/kjs/math_object.cpp
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/number_object.cpp
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object_object.cpp
JavaScriptCore/kjs/reference.cpp
JavaScriptCore/kjs/regexp_object.cpp
JavaScriptCore/kjs/scope_chain.cpp
JavaScriptCore/kjs/scope_chain.h
JavaScriptCore/kjs/string_object.cpp
WebCore/ChangeLog-2005-08-23
WebCore/khtml/ecma/kjs_binding.h
WebCore/khtml/ecma/kjs_css.cpp
WebCore/khtml/ecma/kjs_dom.cpp
WebCore/khtml/ecma/kjs_events.cpp
WebCore/khtml/ecma/kjs_html.cpp
WebCore/khtml/ecma/kjs_navigator.cpp
WebCore/khtml/ecma/kjs_window.cpp

index 7cc89fd2ad1c0728e87513afdaf9c4e7fbc3aca1..7201d9c6db5255cdb2a61aeecdbbfb7aabf4f65b 100644 (file)
@@ -1,3 +1,84 @@
+2004-04-09  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by John.
+
+       Changed things so that newly created objects get a prototype based
+       on the scope chain of the current function, rather than the
+       interpreter that started execution. This fixes the following bugs:
+       
+       <rdar://problem/3368523>: ARCH: wrong prototype used to create new objects (hang on lookup.atomica.com)
+        <rdar://problem/3559173>: ARCH: Cannot scan using a HP Jetdirect product (JS object prototypes bind incorrectly)
+
+       * JavaScriptCore.pbproj/project.pbxproj:
+        * kjs/array_object.cpp:
+        (CompareWithCompareFunctionArguments::CompareWithCompareFunctionArguments):
+        (ArrayProtoFuncImp::ArrayProtoFuncImp):
+        (ArrayProtoFuncImp::call):
+        (ArrayObjectImp::construct):
+        * kjs/bool_object.cpp:
+        (BooleanObjectImp::construct):
+        * kjs/date_object.cpp:
+        (DateProtoFuncImp::DateProtoFuncImp):
+        (DateProtoFuncImp::call):
+        (DateObjectImp::construct):
+        * kjs/error_object.cpp:
+        (ErrorObjectImp::construct):
+        * kjs/function.cpp:
+        (FunctionImp::FunctionImp):
+        (FunctionImp::call):
+        (DeclaredFunctionImp::construct):
+        (ArgumentsImp::ArgumentsImp):
+        (GlobalFuncImp::call):
+        * kjs/function_object.cpp:
+        (FunctionProtoFuncImp::call):
+        (FunctionObjectImp::construct):
+        * kjs/internal.cpp:
+        (BooleanImp::toObject):
+        (StringImp::toObject):
+        (NumberImp::toObject):
+        (InterpreterImp::InterpreterImp):
+        (InterpreterImp::clear):
+        (InterpreterImp::interpreterWithGlobalObject):
+        * kjs/internal.h:
+        * kjs/interpreter.cpp:
+        (ExecState::lexicalInterpreter):
+        * kjs/interpreter.h:
+        (KJS::ExecState::dynamicInterpreter):
+        (KJS::ExecState::interpreter):
+        * kjs/math_object.cpp:
+        (MathFuncImp::MathFuncImp):
+        * kjs/nodes.cpp:
+        (StatementNode::hitStatement):
+        (StatementNode::abortStatement):
+        (RegExpNode::evaluate):
+        (ElementNode::evaluate):
+        (ArrayNode::evaluate):
+        (ObjectLiteralNode::evaluate):
+        (PropertyValueNode::evaluate):
+        (FunctionCallNode::evaluate):
+        (FuncDeclNode::processFuncDecl):
+        (FuncExprNode::evaluate):
+        * kjs/number_object.cpp:
+        (NumberObjectImp::construct):
+        * kjs/object.cpp:
+        (KJS::ObjectImp::defaultValue):
+        (KJS::Error::create):
+        * kjs/object_object.cpp:
+        (ObjectObjectImp::construct):
+        * kjs/reference.cpp:
+        (Reference::putValue):
+        * kjs/regexp_object.cpp:
+        (RegExpProtoFuncImp::call):
+        (RegExpObjectImp::arrayOfMatches):
+        (RegExpObjectImp::construct):
+        * kjs/scope_chain.cpp:
+        (KJS::ScopeChain::bottom):
+        * kjs/scope_chain.h:
+        * kjs/string_object.cpp:
+        (StringProtoFuncImp::StringProtoFuncImp):
+        (StringProtoFuncImp::call):
+        (StringObjectImp::construct):
+
 === Safari-136 ===
 
 === Safari-135 ===
index 9482b81aed2aaa64d57ddcc8d70cf98e2ea7a233..fe6e6838569f170766dd93fba17bbc79c0a2be26 100644 (file)
                                517BE7F50610E39600221947,
                                5199B1C0061B65BC0070C006,
                                5199B266061BB1300070C006,
+                               65AB004B06261CBA0076DE63,
                        );
                        isa = PBXHeadersBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                5182A4FC06010F8200CBD2F2,
                                5182A53C06012C3000CBD2F2,
                                5199B1BF061B65BC0070C006,
+                               65AB004A06261CBA0076DE63,
                        );
                        isa = PBXSourcesBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                08FB77AEFE84172EC02AAC07 = {
                        children = (
                                938772E5038BFE19008635CE,
+                               65AB004806261CBA0076DE63,
+                               65AB004906261CBA0076DE63,
                                F692A84E0255597D01FF60F7,
                                F692A84D0255597D01FF60F7,
                                F692A84F0255597D01FF60F7,
                        settings = {
                        };
                };
+               65AB004806261CBA0076DE63 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       path = interpreter_map.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               65AB004906261CBA0076DE63 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = interpreter_map.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               65AB004A06261CBA0076DE63 = {
+                       fileRef = 65AB004806261CBA0076DE63;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               65AB004B06261CBA0076DE63 = {
+                       fileRef = 65AB004906261CBA0076DE63;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
 //650
 //651
 //652
index 865133478cc0e8216eb60dd8e121ba3349854106..562ae4bcc54e0d8768b473c8a6eead458e62201b 100644 (file)
@@ -303,7 +303,7 @@ struct CompareWithCompareFunctionArguments {
     CompareWithCompareFunctionArguments(ExecState *e, ObjectImp *cf)
         : exec(e)
         , compareFunction(cf)
-        , globalObject(e->interpreter()->globalObject())
+        , globalObject(e->dynamicInterpreter()->globalObject())
     {
         arguments.append(Undefined());
         arguments.append(Undefined());
@@ -425,7 +425,7 @@ Value ArrayPrototypeImp::get(ExecState *exec, const Identifier &propertyName) co
 
 ArrayProtoFuncImp::ArrayProtoFuncImp(ExecState *exec, int i, int len)
   : InternalFunctionImp(
-    static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+    static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
     ), id(i)
 {
   Value protect(this);
@@ -476,7 +476,7 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
     break;
   }
   case Concat: {
-    Object arr = Object::dynamicCast(exec->interpreter()->builtinArray().construct(exec,List::empty()));
+    Object arr = Object::dynamicCast(exec->lexicalInterpreter()->builtinArray().construct(exec,List::empty()));
     int n = 0;
     Value curArg = thisObj;
     Object curObj = Object::dynamicCast(thisObj);
@@ -578,7 +578,7 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
     // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
 
     // We return a new array
-    Object resObj = Object::dynamicCast(exec->interpreter()->builtinArray().construct(exec,List::empty()));
+    Object resObj = Object::dynamicCast(exec->lexicalInterpreter()->builtinArray().construct(exec,List::empty()));
     result = resObj;
     double begin = args[0].toInteger(exec);
     if (begin < 0) {
@@ -664,7 +664,7 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
                 List l;
                 l.append(jObj);
                 l.append(minObj);
-                cmp = sortFunction.call(exec, exec->interpreter()->globalObject(), l).toNumber(exec);
+                cmp = sortFunction.call(exec, exec->dynamicInterpreter()->globalObject(), l).toNumber(exec);
             } else {
               cmp = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
             }
@@ -692,7 +692,7 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
   }
   case Splice: {
     // 15.4.4.12 - oh boy this is huge
-    Object resObj = Object::dynamicCast(exec->interpreter()->builtinArray().construct(exec,List::empty()));
+    Object resObj = Object::dynamicCast(exec->lexicalInterpreter()->builtinArray().construct(exec,List::empty()));
     result = resObj;
     int begin = args[0].toUInt32(exec);
     if ( begin < 0 )
@@ -802,11 +802,11 @@ Object ArrayObjectImp::construct(ExecState *exec, const List &args)
       exec->setException(error);
       return error;
     }
-    return Object(new ArrayInstanceImp(exec->interpreter()->builtinArrayPrototype().imp(), n));
+    return Object(new ArrayInstanceImp(exec->lexicalInterpreter()->builtinArrayPrototype().imp(), n));
   }
 
   // otherwise the array is constructed with the arguments in it
-  return Object(new ArrayInstanceImp(exec->interpreter()->builtinArrayPrototype().imp(), args));
+  return Object(new ArrayInstanceImp(exec->lexicalInterpreter()->builtinArrayPrototype().imp(), args));
 }
 
 bool ArrayObjectImp::implementsCall() const
index 214243c6a1e8179af19e465396cb30884abc12ae..d9722fed0d22b69abfebf3dad151142c264d727d 100644 (file)
@@ -120,7 +120,7 @@ bool BooleanObjectImp::implementsConstruct() const
 // ECMA 15.6.2
 Object BooleanObjectImp::construct(ExecState *exec, const List &args)
 {
-  Object obj(new BooleanInstanceImp(exec->interpreter()->builtinBooleanPrototype().imp()));
+  Object obj(new BooleanInstanceImp(exec->lexicalInterpreter()->builtinBooleanPrototype().imp()));
 
   Boolean b;
   if (args.size() > 0)
index 994119588d222a3a998aa0ef889b2d80e92714cf..3d75057b20680b901841f5e4c37043669ed5cb8c 100644 (file)
@@ -325,7 +325,7 @@ Value DatePrototypeImp::get(ExecState *exec, const Identifier &propertyName) con
 
 DateProtoFuncImp::DateProtoFuncImp(ExecState *exec, int i, int len)
   : InternalFunctionImp(
-    static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+    static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
     ), id(abs(i)), utc(i<0)
   // We use a negative ID to denote the "UTC" variant.
 {
@@ -465,7 +465,7 @@ Value DateProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
     break;
   case GetYear:
     // IE returns the full year even in getYear.
-    if ( exec->interpreter()->compatMode() == Interpreter::IECompat )
+    if ( exec->dynamicInterpreter()->compatMode() == Interpreter::IECompat )
       result = Number(1900 + t->tm_year);
     else
       result = Number(t->tm_year);
@@ -661,7 +661,7 @@ Object DateObjectImp::construct(ExecState *exec, const List &args)
     }
   }
 
-  Object proto = exec->interpreter()->builtinDatePrototype();
+  Object proto = exec->lexicalInterpreter()->builtinDatePrototype();
   Object ret(new DateInstanceImp(proto.imp()));
   ret.setInternalValue(timeClip(value));
   return ret;
index 669a5f8c9bdafe0f605e348b8a160e3d48f1c85b..543f5fbee14b6c069429459aab51623f3ec9d723 100644 (file)
@@ -105,7 +105,7 @@ bool ErrorObjectImp::implementsConstruct() const
 // ECMA 15.9.3
 Object ErrorObjectImp::construct(ExecState *exec, const List &args)
 {
-  Object proto = Object::dynamicCast(exec->interpreter()->builtinErrorPrototype());
+  Object proto = Object::dynamicCast(exec->lexicalInterpreter()->builtinErrorPrototype());
   ObjectImp *imp = new ObjectImp(proto);
   Object obj(imp);
 
index 3e891e9ecb6e382b482570356e04b982e1905970..85d21150d38f49f677917f6c562b72bb2dac3e1e 100644 (file)
@@ -56,7 +56,7 @@ namespace KJS {
 
 FunctionImp::FunctionImp(ExecState *exec, const Identifier &n)
   : InternalFunctionImp(
-      static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+      static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
       ), param(0L), ident(n)
 {
 }
@@ -73,9 +73,9 @@ bool FunctionImp::implementsCall() const
 
 Value FunctionImp::call(ExecState *exec, Object &thisObj, const List &args)
 {
-  Object &globalObj = exec->interpreter()->globalObject();
+  Object &globalObj = exec->dynamicInterpreter()->globalObject();
 
-  Debugger *dbg = exec->interpreter()->imp()->debugger();
+  Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
   int sid = -1;
   int lineno = -1;
   if (dbg) {
@@ -93,9 +93,9 @@ Value FunctionImp::call(ExecState *exec, Object &thisObj, const List &args)
   }
 
   // enter a new execution context
-  ContextImp ctx(globalObj, exec->interpreter()->imp(), thisObj, codeType(),
+  ContextImp ctx(globalObj, exec->dynamicInterpreter()->imp(), thisObj, codeType(),
                  exec->context().imp(), this, &args);
-  ExecState newExec(exec->interpreter(), &ctx);
+  ExecState newExec(exec->dynamicInterpreter(), &ctx);
   newExec.setException(exec->exception()); // could be null
 
   // assign user supplied arguments to parameters
@@ -282,7 +282,7 @@ Object DeclaredFunctionImp::construct(ExecState *exec, const List &args)
   if (p.type() == ObjectType)
     proto = Object(static_cast<ObjectImp*>(p.imp()));
   else
-    proto = exec->interpreter()->builtinObjectPrototype();
+    proto = exec->lexicalInterpreter()->builtinObjectPrototype();
 
   Object obj(new ObjectImp(proto));
 
@@ -314,14 +314,14 @@ const ClassInfo ArgumentsImp::info = {"Arguments", 0, 0, 0};
 
 // ECMA 10.1.8
 ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func)
-  : ArrayInstanceImp(exec->interpreter()->builtinObjectPrototype().imp(), 0)
+  : ArrayInstanceImp(exec->lexicalInterpreter()->builtinObjectPrototype().imp(), 0)
 {
   Value protect(this);
   putDirect(calleePropertyName, func, DontEnum);
 }
 
 ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args)
-  : ArrayInstanceImp(exec->interpreter()->builtinObjectPrototype().imp(), args)
+  : ArrayInstanceImp(exec->lexicalInterpreter()->builtinObjectPrototype().imp(), args)
 {
   Value protect(this);
   putDirect(calleePropertyName, func, DontEnum);
@@ -540,13 +540,13 @@ Value GlobalFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args
 
       // enter a new execution context
       Object thisVal(Object::dynamicCast(exec->context().thisValue()));
-      ContextImp ctx(exec->interpreter()->globalObject(),
-                     exec->interpreter()->imp(),
+      ContextImp ctx(exec->dynamicInterpreter()->globalObject(),
+                     exec->dynamicInterpreter()->imp(),
                      thisVal,
                      EvalCode,
                      exec->context().imp());
 
-      ExecState newExec(exec->interpreter(), &ctx);
+      ExecState newExec(exec->dynamicInterpreter(), &ctx);
       newExec.setException(exec->exception()); // could be null
 
       // execute the code
index e84993f49b4d26fa64a55bf4b42899c6d84cd707..0847ea5fe4aef6a20c78c0e38631f2404134fa0a 100644 (file)
@@ -121,7 +121,7 @@ Value FunctionProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &a
 
     Object applyThis;
     if (thisArg.isA(NullType) || thisArg.isA(UndefinedType))
-      applyThis = exec->interpreter()->globalObject();
+      applyThis = exec->dynamicInterpreter()->globalObject();
     else
       applyThis = thisArg.toObject(exec);
 
@@ -157,7 +157,7 @@ Value FunctionProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &a
 
     Object callThis;
     if (thisArg.isA(NullType) || thisArg.isA(UndefinedType))
-      callThis = exec->interpreter()->globalObject();
+      callThis = exec->dynamicInterpreter()->globalObject();
     else
       callThis = thisArg.toObject(exec);
 
@@ -214,7 +214,7 @@ Object FunctionObjectImp::construct(ExecState *exec, const List &args)
   ProgramNode *progNode = Parser::parse(body.data(),body.size(),&sid,&errLine,&errMsg);
 
   // notify debugger that source has been parsed
-  Debugger *dbg = exec->interpreter()->imp()->debugger();
+  Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
   if (dbg) {
     bool cont = dbg->sourceParsed(exec,sid,body,errLine);
     if (!cont) {
@@ -233,7 +233,7 @@ Object FunctionObjectImp::construct(ExecState *exec, const List &args)
   }
 
   ScopeChain scopeChain;
-  scopeChain.push(exec->interpreter()->globalObject().imp());
+  scopeChain.push(exec->dynamicInterpreter()->globalObject().imp());
   FunctionBodyNode *bodyNode = progNode;
 
   FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), bodyNode,
@@ -278,7 +278,7 @@ Object FunctionObjectImp::construct(ExecState *exec, const List &args)
 
   List consArgs;
 
-  Object objCons = exec->interpreter()->builtinObject();
+  Object objCons = exec->lexicalInterpreter()->builtinObject();
   Object prototype = objCons.construct(exec,List::empty());
   prototype.put(exec, constructorPropertyName, Value(fimp), DontEnum|DontDelete|ReadOnly);
   fimp->put(exec, prototypePropertyName, prototype, DontEnum|DontDelete|ReadOnly);
index 7e98eb9cf73d03a5ffda8529f568026f4c3a50a3..ee817619a6ef9dd51d3bfb293baf506d638d9a50 100644 (file)
@@ -38,6 +38,7 @@
 #include "error_object.h"
 #include "function_object.h"
 #include "internal.h"
+#include "interpreter_map.h"
 #include "lexer.h"
 #include "math_object.h"
 #include "nodes.h"
@@ -194,7 +195,7 @@ Object BooleanImp::toObject(ExecState *exec) const
 {
   List args;
   args.append(const_cast<BooleanImp*>(this));
-  return Object::dynamicCast(exec->interpreter()->builtinBoolean().construct(exec,args));
+  return Object::dynamicCast(exec->lexicalInterpreter()->builtinBoolean().construct(exec,args));
 }
 
 // ------------------------------ StringImp ------------------------------------
@@ -223,7 +224,7 @@ Object StringImp::toObject(ExecState *exec) const
 {
   List args;
   args.append(const_cast<StringImp*>(this));
-  return Object::dynamicCast(exec->interpreter()->builtinString().construct(exec,args));
+  return Object::dynamicCast(exec->lexicalInterpreter()->builtinString().construct(exec,args));
 }
 
 // ------------------------------ NumberImp ------------------------------------
@@ -274,7 +275,7 @@ Object NumberImp::toObject(ExecState *exec) const
 {
   List args;
   args.append(const_cast<NumberImp*>(this));
-  return Object::dynamicCast(exec->interpreter()->builtinNumber().construct(exec,args));
+  return Object::dynamicCast(exec->lexicalInterpreter()->builtinNumber().construct(exec,args));
 }
 
 bool NumberImp::toUInt32(unsigned& uint32) const
@@ -527,6 +528,8 @@ InterpreterImp::InterpreterImp(Interpreter *interp, const Object &glob)
     globalInit();
   }
 
+  InterpreterMap::setInterpreterForGlobalObject(this, glob.imp());
+
   global = glob;
   globExec = new ExecState(m_interpreter,0);
   dbg = 0;
@@ -704,6 +707,8 @@ void InterpreterImp::clear()
     s_hook = 0L;
     globalClear();
   }
+  InterpreterMap::removeInterpreterForGlobalObject(global.imp());
+
 #if APPLE_CHANGES
   unlockInterpreter();
 #endif
@@ -921,6 +926,12 @@ void InterpreterImp::restoreBuiltins (const SavedBuiltins &builtins)
   b_uriErrorPrototype = builtins._internal->b_uriErrorPrototype;
 }
 
+InterpreterImp *InterpreterImp::interpreterWithGlobalObject(ObjectImp *global)
+{
+  return InterpreterMap::getInterpreterForGlobalObject(global);
+}
+
+
 // ------------------------------ InternalFunctionImp --------------------------
 
 const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};
index bcd5fb35ad84da252d24fdc7df1d0f5ca81d08e6..92df4841d395b5fd243d3eb58d628c337c7e7c44 100644 (file)
@@ -315,6 +315,8 @@ namespace KJS {
     static InterpreterImp* firstInterpreter() { return s_hook; }
     InterpreterImp *nextInterpreter() const { return next; }
     InterpreterImp *prevInterpreter() const { return prev; }
+
+    static InterpreterImp *interpreterWithGlobalObject(ObjectImp *);
     
     void setContext(ContextImp *c) { _context = c; }
 
index b00efe8b8e163d0880434162a64f1a258e3bd8bf..2c6ab148042b3dcec9bc252b1de3c25388778571 100644 (file)
@@ -354,3 +354,19 @@ SavedBuiltins::~SavedBuiltins()
 
 void Interpreter::virtual_hook( int, void* )
 { /*BASE::virtual_hook( id, data );*/ }
+
+
+Interpreter *ExecState::lexicalInterpreter() const
+{
+  if (!_context) {
+    return dynamicInterpreter();
+  }
+
+  InterpreterImp *result = InterpreterImp::interpreterWithGlobalObject(_context->scopeChain().bottom());
+
+  if (!result) {
+    return dynamicInterpreter();
+  }
+
+  return result->interpreter();
+}
index 81b767c6e9c9e89013b794abfb41ec785ec4e758..d3649085bca61b2fa9f89fb6370616c8fb0df3ab 100644 (file)
@@ -397,7 +397,18 @@ namespace KJS {
      *
      * @return The interpreter executing the script
      */
-    Interpreter *interpreter() const { return _interpreter; }
+    Interpreter *dynamicInterpreter() const { return _interpreter; }
+
+    // for compatibility
+    Interpreter *interpreter() const { return dynamicInterpreter(); }
+
+    /**
+     * Returns the interpreter associated with the current scope's
+     * global object
+     *
+     * @return The interpreter currently in scope
+     */
+    Interpreter *lexicalInterpreter() const;
 
     /**
      * Returns the execution context associated with this execution state
diff --git a/JavaScriptCore/kjs/interpreter_map.cpp b/JavaScriptCore/kjs/interpreter_map.cpp
new file mode 100644 (file)
index 0000000..dafed25
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 2004 Apple Computer, Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "interpreter_map.h"
+
+namespace KJS {
+
+const int _minTableSize = 64;
+
+InterpreterMap::KeyValue *InterpreterMap::_table;
+int InterpreterMap::_tableSize;
+int InterpreterMap::_tableSizeMask;
+int InterpreterMap::_keyCount;
+
+
+InterpreterImp * InterpreterMap::getInterpreterForGlobalObject(ObjectImp *global)
+{
+    if (!_table)
+        expand();
+    
+    unsigned hash = computeHash(global);
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i].key && _table[i].key != global;
+#endif
+    while (ObjectImp *key = _table[i].key) {
+        if (key == global) {
+           return _table[i].value;
+       }
+        i = (i + 1) & _tableSizeMask;
+    }
+    
+    return 0;
+}
+
+
+void InterpreterMap::setInterpreterForGlobalObject(InterpreterImp *interpreter, ObjectImp *global)
+{
+    if (!_table)
+        expand();
+    
+    unsigned hash = computeHash(global);
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i].key && _table[i].key != global;
+#endif
+    while (ObjectImp *key = _table[i].key) {
+        if (key == global) {
+           _table[i].value = interpreter;
+           return;
+       }
+        i = (i + 1) & _tableSizeMask;
+    }
+    
+    _table[i].key = global;
+    _table[i].value = interpreter;
+    ++_keyCount;
+    
+    if (_keyCount * 2 >= _tableSize)
+        expand();
+}
+
+inline void InterpreterMap::insert(InterpreterImp *interpreter, ObjectImp *global)
+{
+    unsigned hash = computeHash(global);
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i] != 0;
+#endif
+    while (_table[i].key)
+        i = (i + 1) & _tableSizeMask;
+    
+    _table[i].key = global;
+    _table[i].value = interpreter;
+}
+
+void InterpreterMap::removeInterpreterForGlobalObject(ObjectImp *global)
+{
+    unsigned hash = computeHash(global);
+    
+    ObjectImp *key;
+    
+    int i = hash & _tableSizeMask;
+#if DUMP_STATISTICS
+    ++numProbes;
+    numCollisions += _table[i].key && _table[i].key == global;
+#endif
+    while ((key = _table[i].key)) {
+        if (key == global)
+            break;
+        i = (i + 1) & _tableSizeMask;
+    }
+    if (!key)
+        return;
+    
+    _table[i].key = 0;
+    _table[i].value = 0;
+    --_keyCount;
+    
+    if (_keyCount * 6 < _tableSize && _tableSize > _minTableSize) {
+        shrink();
+        return;
+    }
+    
+    // Reinsert all the items to the right in the same cluster.
+    while (1) {
+        i = (i + 1) & _tableSizeMask;
+        key = _table[i].key;
+       InterpreterImp *value = _table[i].value;
+        if (!key)
+            break;
+        _table[i].key = 0;
+        _table[i].value = 0;
+        insert(value,key);
+    }
+}
+
+void InterpreterMap::expand()
+{
+    rehash(_tableSize == 0 ? _minTableSize : _tableSize * 2);
+}
+
+void InterpreterMap::shrink()
+{
+    rehash(_tableSize / 2);
+}
+
+void InterpreterMap::rehash(int newTableSize)
+{
+    int oldTableSize = _tableSize;
+    KeyValue *oldTable = _table;
+
+    _tableSize = newTableSize;
+    _tableSizeMask = newTableSize - 1;
+    _table = (KeyValue *)calloc(newTableSize, sizeof(KeyValue));
+
+    for (int i = 0; i != oldTableSize; ++i)
+        if (oldTable[i].key)
+            insert(oldTable[i].value, oldTable[i].key);
+
+    free(oldTable);
+}
+
+// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+// or anything like that.
+const unsigned PHI = 0x9e3779b9U;
+
+// This hash algorithm comes from:
+// http://burtleburtle.net/bob/hash/hashfaq.html
+// http://burtleburtle.net/bob/hash/doobs.html
+unsigned InterpreterMap::computeHash(ObjectImp *pointer)
+{
+    int length = sizeof(ObjectImp *);
+    char s[sizeof(ObjectImp *)];
+               
+    memcpy((void *)s, (void *)&pointer, sizeof(ObjectImp *));
+
+    unsigned h = PHI;
+    h += length;
+    h += (h << 10); 
+    h ^= (h << 6); 
+
+    for (int i = 0; i < length; i++) {
+        h += (unsigned char)s[i];
+       h += (h << 10); 
+       h ^= (h << 6); 
+    }
+
+    h += (h << 3);
+    h ^= (h >> 11);
+    h += (h << 15);
+
+    if (h == 0)
+        h = 0x80000000;
+
+    return h;
+}
+
+
+}; // namespace
diff --git a/JavaScriptCore/kjs/interpreter_map.h b/JavaScriptCore/kjs/interpreter_map.h
new file mode 100644 (file)
index 0000000..90a7d77
--- /dev/null
@@ -0,0 +1,58 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 2004 Apple Computer, Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _KJS_INTERPRETER_MAP_H_
+#define _KJS_INTERPRETER_MAP_H_
+
+namespace KJS {
+    class ObjectImp;
+    class InterpreterImp;
+
+    class InterpreterMap {
+       struct KeyValue {
+           ObjectImp *key;
+           InterpreterImp *value;
+       };
+
+    public:
+       static InterpreterImp * InterpreterMap::getInterpreterForGlobalObject(ObjectImp *global);
+       static void setInterpreterForGlobalObject(InterpreterImp *interpreter, ObjectImp *global);
+       static void removeInterpreterForGlobalObject(ObjectImp *global);
+
+    private:
+       static void insert(InterpreterImp *interpreter, ObjectImp *global);
+       static void expand();
+       static void shrink();
+       static void rehash(int newTableSize);
+       static unsigned computeHash(ObjectImp *pointer);
+
+
+       static KeyValue * InterpreterMap::_table;
+       static int InterpreterMap::_tableSize;
+       static int InterpreterMap::_tableSizeMask;
+       static int InterpreterMap::_keyCount;
+    };
+
+}; // namespace
+
+
+#endif // _KJS_INTERPRETER_MAP_H_
index b5ec4c39346e1a0ead367ce912f05d6174fb5b66..870924e039127ba8cc0f993aefb451859aa9b51e 100644 (file)
@@ -126,7 +126,7 @@ Value MathObjectImp::getValueProperty(ExecState *, int token) const
 
 MathFuncImp::MathFuncImp(ExecState *exec, int i, int l)
   : InternalFunctionImp(
-    static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+    static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
     ), id(i)
 {
   Value protect(this);
index 65da755deab282b8d67046e29253ad424f7af504..422cb9ad9525ebc9b0066d90df030fe2e4d03164 100644 (file)
@@ -52,8 +52,8 @@ using namespace KJS;
     return Completion(Normal);
 
 #define KJS_ABORTPOINT \
-  if (exec->interpreter()->imp()->debugger() && \
-      exec->interpreter()->imp()->debugger()->imp()->aborted()) \
+  if (exec->dynamicInterpreter()->imp()->debugger() && \
+      exec->dynamicInterpreter()->imp()->debugger()->imp()->aborted()) \
     return Completion(Normal);
 
 #define KJS_CHECKEXCEPTION \
@@ -176,7 +176,7 @@ void StatementNode::setLoc(int line0, int line1, int sourceId)
 // return true if the debugger wants us to stop at this point
 bool StatementNode::hitStatement(ExecState *exec)
 {
-  Debugger *dbg = exec->interpreter()->imp()->debugger();
+  Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
   if (dbg)
     return dbg->atStatement(exec,sid,l0,l1);
   else
@@ -186,7 +186,7 @@ bool StatementNode::hitStatement(ExecState *exec)
 // return true if the debugger wants us to stop at this point
 bool StatementNode::abortStatement(ExecState *exec)
 {
-  Debugger *dbg = exec->interpreter()->imp()->debugger();
+  Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
   if (dbg)
     return dbg->imp()->aborted();
   else
@@ -235,7 +235,7 @@ Value RegExpNode::evaluate(ExecState *exec)
   list.append(p);
   list.append(f);
 
-  Object reg = exec->interpreter()->imp()->builtinRegExp();
+  Object reg = exec->lexicalInterpreter()->imp()->builtinRegExp();
   return reg.construct(exec,list);
 }
 
@@ -328,7 +328,7 @@ bool ElementNode::deref()
 // ECMA 11.1.4
 Value ElementNode::evaluate(ExecState *exec)
 {
-  Object array = exec->interpreter()->builtinArray().construct(exec, List::empty());
+  Object array = exec->lexicalInterpreter()->builtinArray().construct(exec, List::empty());
   int length = 0;
   for (ElementNode *n = this; n; n = n->list) {
     Value val = n->node->evaluate(exec);
@@ -366,7 +366,7 @@ Value ArrayNode::evaluate(ExecState *exec)
     KJS_CHECKEXCEPTIONVALUE
     length = opt ? array.get(exec,lengthPropertyName).toInt32(exec) : 0;
   } else {
-    Value newArr = exec->interpreter()->builtinArray().construct(exec,List::empty());
+    Value newArr = exec->lexicalInterpreter()->builtinArray().construct(exec,List::empty());
     array = Object(static_cast<ObjectImp*>(newArr.imp()));
     length = 0;
   }
@@ -399,7 +399,7 @@ Value ObjectLiteralNode::evaluate(ExecState *exec)
   if (list)
     return list->evaluate(exec);
 
-  return exec->interpreter()->builtinObject().construct(exec,List::empty());
+  return exec->lexicalInterpreter()->builtinObject().construct(exec,List::empty());
 }
 
 // ------------------------------ PropertyValueNode ----------------------------
@@ -433,7 +433,7 @@ bool PropertyValueNode::deref()
 // ECMA 11.1.5
 Value PropertyValueNode::evaluate(ExecState *exec)
 {
-  Object obj = exec->interpreter()->builtinObject().construct(exec, List::empty());
+  Object obj = exec->lexicalInterpreter()->builtinObject().construct(exec, List::empty());
   
   for (PropertyValueNode *p = this; p; p = p->list) {
     Value n = p->name->evaluate(exec);
@@ -716,7 +716,7 @@ Value FunctionCallNode::evaluate(ExecState *exec)
     // of implementation we use the global object anyway here. This guarantees
     // that in host objects you always get a valid object for this.
     // thisVal = Null();
-    thisVal = exec->interpreter()->globalObject();
+    thisVal = exec->dynamicInterpreter()->globalObject();
   }
 
   Object thisObj = Object::dynamicCast(thisVal);
@@ -2725,9 +2725,9 @@ void FuncDeclNode::processFuncDecl(ExecState *exec)
   FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body, exec->context().imp()->scopeChain());
   Object func(fimp); // protect from GC
 
-  //  Value proto = exec->interpreter()->builtinObject().construct(exec,List::empty());
+  //  Value proto = exec->lexicalInterpreter()->builtinObject().construct(exec,List::empty());
   List empty;
-  Object proto = exec->interpreter()->builtinObject().construct(exec,empty);
+  Object proto = exec->lexicalInterpreter()->builtinObject().construct(exec,empty);
   proto.put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum);
   func.put(exec, prototypePropertyName, proto, Internal|DontDelete);
 
@@ -2778,7 +2778,7 @@ Value FuncExprNode::evaluate(ExecState *exec)
   FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), body, exec->context().imp()->scopeChain());
   Value ret(fimp);
   List empty;
-  Value proto = exec->interpreter()->builtinObject().construct(exec,empty);
+  Value proto = exec->lexicalInterpreter()->builtinObject().construct(exec,empty);
   fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete);
 
   int plen = 0;
index c623ab2660ad9055a5d9a2315325d2ba95fdc717..8950714095d2fb071ae9001ca82e5aa1e8a55849 100644 (file)
@@ -181,7 +181,7 @@ bool NumberObjectImp::implementsConstruct() const
 // ECMA 15.7.1
 Object NumberObjectImp::construct(ExecState *exec, const List &args)
 {
-  ObjectImp *proto = exec->interpreter()->builtinNumberPrototype().imp();
+  ObjectImp *proto = exec->lexicalInterpreter()->builtinNumberPrototype().imp();
   Object obj(new NumberInstanceImp(proto));
 
   Number n;
index 8e0093e341a8af4ffd1bd74a2434d547809554f6..f6c01fcf61570d549fea02cd6ed099d609875922 100644 (file)
@@ -293,7 +293,7 @@ Value ObjectImp::defaultValue(ExecState *exec, Type hint) const
 {
   if (hint != StringType && hint != NumberType) {
     /* Prefer String for Date objects */
-    if (_proto == exec->interpreter()->builtinDatePrototype().imp())
+    if (_proto == exec->lexicalInterpreter()->builtinDatePrototype().imp())
       hint = StringType;
     else
       hint = NumberType;
@@ -494,25 +494,25 @@ Object Error::create(ExecState *exec, ErrorType errtype, const char *message,
 
   switch (errtype) {
   case EvalError:
-    cons = exec->interpreter()->builtinEvalError();
+    cons = exec->lexicalInterpreter()->builtinEvalError();
     break;
   case RangeError:
-    cons = exec->interpreter()->builtinRangeError();
+    cons = exec->lexicalInterpreter()->builtinRangeError();
     break;
   case ReferenceError:
-    cons = exec->interpreter()->builtinReferenceError();
+    cons = exec->lexicalInterpreter()->builtinReferenceError();
     break;
   case SyntaxError:
-    cons = exec->interpreter()->builtinSyntaxError();
+    cons = exec->lexicalInterpreter()->builtinSyntaxError();
     break;
   case TypeError:
-    cons = exec->interpreter()->builtinTypeError();
+    cons = exec->lexicalInterpreter()->builtinTypeError();
     break;
   case URIError:
-    cons = exec->interpreter()->builtinURIError();
+    cons = exec->lexicalInterpreter()->builtinURIError();
     break;
   default:
-    cons = exec->interpreter()->builtinError();
+    cons = exec->lexicalInterpreter()->builtinError();
     break;
   }
 
index 9e57824c0c58423857d2dd3601d8b5da72f5409e..84023280db8e0392516886c4f0149e37cbec56b9 100644 (file)
@@ -96,7 +96,7 @@ Object ObjectObjectImp::construct(ExecState *exec, const List &args)
 {
   // if no arguments have been passed ...
   if (args.isEmpty()) {
-    Object proto = exec->interpreter()->builtinObjectPrototype();
+    Object proto = exec->lexicalInterpreter()->builtinObjectPrototype();
     Object result(new ObjectImp(proto));
     return result;
   }
@@ -116,7 +116,7 @@ Object ObjectObjectImp::construct(ExecState *exec, const List &args)
     assert(!"unhandled switch case in ObjectConstructor");
   case NullType:
   case UndefinedType:
-    Object proto = exec->interpreter()->builtinObjectPrototype();
+    Object proto = exec->lexicalInterpreter()->builtinObjectPrototype();
     return Object(new ObjectImp(proto));
   }
 }
index a248a118ca5265738e6cecfc127277ee930f32fd..862a4577e92386e57e6957d5b8249de00896e59b 100644 (file)
@@ -152,7 +152,7 @@ void Reference::putValue(ExecState *exec, const Value &w)
 #endif
   Value o = getBase(exec);
   if (o.type() == NullType)
-    o = exec->interpreter()->globalObject();
+    o = exec->dynamicInterpreter()->globalObject();
 
   if (propertyNameIsNumber)
     return static_cast<ObjectImp*>(o.imp())->put(exec,propertyNameAsNumber, w);
index 7dccc0158eb7857e1b7b7f194d5d7cf512d5fc62..9122cb5479fd3db6385c2ca7238d7ed5a29d2b3a 100644 (file)
@@ -100,7 +100,7 @@ Value RegExpProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
       else
         Null();
     }
-    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->interpreter()->builtinRegExp().imp());
+    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp().imp());
     int **ovector = regExpObj->registerRegexp( re, s.value() );
 
     str = re->match(s.value(), i, 0L, ovector);
@@ -190,7 +190,7 @@ Object RegExpObjectImp::arrayOfMatches(ExecState *exec, const UString &result) c
       UString substring = lastString.substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
       list.append(String(substring));
     }
-  Object arr = exec->interpreter()->builtinArray().construct(exec, list);
+  Object arr = exec->lexicalInterpreter()->builtinArray().construct(exec, list);
   arr.put(exec, "index", Number(lastOvector[0]));
   arr.put(exec, "input", String(lastString));
   return arr;
@@ -227,7 +227,7 @@ Object RegExpObjectImp::construct(ExecState *exec, const List &args)
   UString p = args.isEmpty() ? UString("") : args[0].toString(exec);
   UString flags = args[1].toString(exec);
 
-  RegExpPrototypeImp *proto = static_cast<RegExpPrototypeImp*>(exec->interpreter()->builtinRegExpPrototype().imp());
+  RegExpPrototypeImp *proto = static_cast<RegExpPrototypeImp*>(exec->lexicalInterpreter()->builtinRegExpPrototype().imp());
   RegExpImp *dat = new RegExpImp(proto);
   Object obj(dat); // protect from GC
 
index b0c3bd31d3cc1c0cb5bd46938ade9db747bf04ad..88f7f7439ba4b3cbae25f0a33fea9ba306c390ee 100644 (file)
@@ -84,4 +84,17 @@ void ScopeChain::mark()
     }
 }
 
+ObjectImp *ScopeChain::bottom() const
+{
+    ScopeChainNode *last;
+    for (ScopeChainNode *n = _node; n; n = n->next) {
+       if (!n->next) {
+           last = n;
+       }
+    }
+    return last->object;
+}
+
+
+
 } // namespace KJS
index 06e8b4598b15ba30557d65a8a8986071924b6302..1b8ec4a077eb9340f5ec7e01f4de0d9b6e574288 100644 (file)
@@ -48,6 +48,8 @@ namespace KJS {
         bool isEmpty() const { return !_node; }
         ObjectImp *top() const { return _node->object; }
 
+       ObjectImp *bottom() const;
+
         void clear() { deref(); _node = 0; }
         void push(ObjectImp *);
         void pop();
index 877e9e600e8f3ea9a7168399488f7b34616476a1..72bb72c7c8347cc7d06fe3b0a4176d6b91fc2da7 100644 (file)
@@ -158,7 +158,7 @@ Value StringPrototypeImp::get(ExecState *exec, const Identifier &propertyName) c
 
 StringProtoFuncImp::StringProtoFuncImp(ExecState *exec, int i, int len)
   : InternalFunctionImp(
-    static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+    static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
     ), id(i)
 {
   Value protect(this);
@@ -275,7 +275,7 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
        */
       reg = tmpReg = new RegExp(a0.toString(exec), RegExp::None);
     }
-    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->interpreter()->builtinRegExp().imp());
+    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp().imp());
     int **ovector = regExpObj->registerRegexp(reg, u);
     UString mstr = reg->match(u, -1, &pos, ovector);
     if (id == Search) {
@@ -309,7 +309,7 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
          // other browsers and because Null is a false value.
          result = Null(); 
        } else {
-         result = exec->interpreter()->builtinArray().construct(exec, list);
+         result = exec->lexicalInterpreter()->builtinArray().construct(exec, list);
        }
       }
     }
@@ -326,7 +326,7 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
       if (tmp.type() != UndefinedType && tmp.toBoolean(exec) == true)
         global = true;
 
-      RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->interpreter()->builtinRegExp().imp());
+      RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp().imp());
       int lastIndex = 0;
       u3 = a1.toString(exec); // replacement string
       // This is either a loop (if global is set) or a one-way (if not).
@@ -411,7 +411,7 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
         break;
     }
     case Split: {
-    Object constructor = exec->interpreter()->builtinArray();
+    Object constructor = exec->lexicalInterpreter()->builtinArray();
     Object res = Object::dynamicCast(constructor.construct(exec,List::empty()));
     result = res;
     u = s;
@@ -599,7 +599,7 @@ bool StringObjectImp::implementsConstruct() const
 // ECMA 15.5.2
 Object StringObjectImp::construct(ExecState *exec, const List &args)
 {
-  ObjectImp *proto = exec->interpreter()->builtinStringPrototype().imp();
+  ObjectImp *proto = exec->lexicalInterpreter()->builtinStringPrototype().imp();
   if (args.size() == 0)
     return Object(new StringInstanceImp(proto));
   return Object(new StringInstanceImp(proto, args.begin()->dispatchToString(exec)));
index 761f652da6f813a27eca05475627564333d27868..237e47fbd347e2c6d868cac0d4f4e42fb2087625 100644 (file)
@@ -1,3 +1,44 @@
+2004-04-08  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by John.
+
+       Changed things so that newly created objects get a prototype based
+       on the scope chain of the current function, rather than the
+       interpreter that started execution. This fixes the following bugs:
+       
+       <rdar://problem/3368523>: ARCH: wrong prototype used to create new objects (hang on lookup.atomica.com)
+        <rdar://problem/3559173>: ARCH: Cannot scan using a HP Jetdirect product (JS object prototypes bind incorrectly)
+
+       * khtml/ecma/kjs_binding.h:
+        (KJS::cacheDOMObject):
+        (KJS::cacheGlobalObject):
+        * khtml/ecma/kjs_css.cpp:
+        (KJS::getDOMStyleSheet):
+        (KJS::getDOMStyleSheetList):
+        (KJS::getDOMCSSValue):
+        * khtml/ecma/kjs_dom.cpp:
+        (KJS::getDOMDocumentNode):
+        (KJS::getDOMNode):
+        * khtml/ecma/kjs_events.cpp:
+        (KJS::getDOMEvent):
+        * khtml/ecma/kjs_html.cpp:
+        (KJS::HTMLDocument::tryGet):
+        (KJS::HTMLDocument::putValue):
+        (KJS::getSelectHTMLCollection):
+        * khtml/ecma/kjs_navigator.cpp:
+        (Navigator::Navigator):
+        (PluginBase::PluginBase):
+        * khtml/ecma/kjs_window.cpp:
+        (KJS::History::History):
+        (KJS::FrameArray::FrameArray):
+        (Screen::Screen):
+        (Window::retrieveActive):
+        (Window::put):
+        (Window::isSafeScript):
+        (WindowFunc::tryCall):
+        (Location::put):
+        (LocationFunc::tryCall):
+
 2004-04-09  David Hyatt  <hyatt@apple.com>
 
        Fix for 3613081, repaint glitches when using overflow:auto/overlay.
index bddd9905d9ac283d07fb4b3f22933b737ca0bafa..3aaa3bb29b3a484ac4b5db2d183af469ccbaa2f7 100644 (file)
@@ -149,7 +149,7 @@ namespace KJS {
     DOMObject *ret;
     if (domObj.isNull())
       return Null();
-    ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+    ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
     if ((ret = interp->getDOMObject(domObj.handle())))
       return Value(ret);
     else {
@@ -244,13 +244,13 @@ namespace KJS {
   template <class ClassCtor>
   inline Object cacheGlobalObject(ExecState *exec, const Identifier &propertyName)
   {
-    ValueImp *obj = static_cast<ObjectImp*>(exec->interpreter()->globalObject().imp())->getDirect(propertyName);
+    ValueImp *obj = static_cast<ObjectImp*>(exec->lexicalInterpreter()->globalObject().imp())->getDirect(propertyName);
     if (obj)
       return Object::dynamicCast(Value(obj));
     else
     {
       Object newObject(new ClassCtor(exec));
-      exec->interpreter()->globalObject().put(exec, propertyName, newObject, Internal);
+      exec->lexicalInterpreter()->globalObject().put(exec, propertyName, newObject, Internal);
       return newObject;
     }
   }
@@ -282,7 +282,7 @@ namespace KJS {
     } \
   protected: \
     ClassProto( ExecState *exec ) \
-      : ObjectImp( exec->interpreter()->builtinObjectPrototype() ) {} \
+      : ObjectImp( exec->lexicalInterpreter()->builtinObjectPrototype() ) {} \
     \
   public: \
     virtual const ClassInfo *classInfo() const { return &info; } \
index 627092e3763c0fa7892403a10f1276e298e706c5..a55f1ae60039dbc514230762fbf20f0a8e3c6359 100644 (file)
@@ -287,7 +287,7 @@ Value KJS::getDOMStyleSheet(ExecState *exec, DOM::StyleSheet ss)
   DOMObject *ret;
   if (ss.isNull())
     return Null();
-  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
   if ((ret = interp->getDOMObject(ss.handle())))
     return Value(ret);
   else {
@@ -376,7 +376,7 @@ Value KJS::getDOMStyleSheetList(ExecState *exec, DOM::StyleSheetList ssl, DOM::D
   DOMObject *ret;
   if (ssl.isNull())
     return Null();
-  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
   if ((ret = interp->getDOMObject(ssl.handle())))
     return Value(ret);
   else {
@@ -893,7 +893,7 @@ Value KJS::getDOMCSSValue(ExecState *exec, DOM::CSSValue v)
   DOMObject *ret;
   if (v.isNull())
     return Null();
-  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
   if ((ret = interp->getDOMObject(v.handle())))
     return Value(ret);
   else {
index 9950d6a0c4a4b7a7f981dd36cd4ab1f4e9671b49..6d5603a79583ceec1a114778e1bb7e314a43db91 100644 (file)
@@ -1312,7 +1312,7 @@ Value DOMEntity::getValueProperty(ExecState *, int token) const
 Value KJS::getDOMDocumentNode(ExecState *exec, const DOM::Document &n)
 {
   DOMDocument *ret = 0;
-  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
 
   if ((ret = static_cast<DOMDocument *>(interp->getDOMObject(n.handle()))))
     return Value(ret);
@@ -1355,7 +1355,7 @@ Value KJS::getDOMNode(ExecState *exec, const DOM::Node &n)
   DOMObject *ret = 0;
   if (n.isNull())
     return Null();
-  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
   DOM::NodeImpl *doc = n.ownerDocument().handle();
 
   if ((ret = interp->getDOMObjectForDocument(static_cast<DOM::DocumentImpl *>(doc), n.handle())))
index 40e9dfbaafbb7aa2c87b85dd99a658f311997dbf..07fb673a308cc9d29c3d30481ef1f2db1d18562d 100644 (file)
@@ -389,7 +389,7 @@ Value KJS::getDOMEvent(ExecState *exec, DOM::Event e)
   DOM::EventImpl *ei = e.handle();
   if (!ei)
     return Null();
-  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
 
   KJS::Interpreter::lock();
 
index 14059c92f52d51fb99c70a20af7d9b991700be49..c4e3a8003fb38292d2e322e06bf0eab02abf71fb 100644 (file)
@@ -236,7 +236,7 @@ Value KJS::HTMLDocument::tryGet(ExecState *exec, const Identifier &propertyName)
     }
     case All:
       // Disable document.all when we try to be Netscape-compatible
-      if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat )
+      if ( exec->dynamicInterpreter()->compatMode() == Interpreter::NetscapeCompat )
         return Undefined();
       return getHTMLCollection(exec,doc.all());
     case Clear:
@@ -371,7 +371,7 @@ void KJS::HTMLDocument::putValue(ExecState *exec, int token, const Value& value,
       // When assinging location, IE and Mozilla both resolve the URL
       // relative to the frame where the JavaScript is executing not
       // the target frame.
-      KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->interpreter() )->part();
+      KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->dynamicInterpreter() )->part();
       if (activePart) {
        KURL resolvedURL(activePart->baseURL(), str);
        str = resolvedURL.url();
@@ -379,7 +379,7 @@ void KJS::HTMLDocument::putValue(ExecState *exec, int token, const Value& value,
 
 #if APPLE_CHANGES
       // We want a new history item if this JS was called via a user gesture
-      bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+      bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
       part->scheduleRedirection(0, str, !userGesture);
 #else
       part->scheduleRedirection(0, str, false/*don't lock history*/);
@@ -3312,7 +3312,7 @@ Value KJS::getSelectHTMLCollection(ExecState *exec, const DOM::HTMLCollection &c
   DOMObject *ret;
   if (c.isNull())
     return Null();
-  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
   if ((ret = interp->getDOMObject(c.handle())))
     return Value(ret);
   else {
index fa47d5aa5987c916049eb819236df45b93a24068..1fc7117c63100338c15e6cd92f474f6d48a305f3 100644 (file)
@@ -147,7 +147,7 @@ const ClassInfo Navigator::info = { "Navigator", 0, &NavigatorTable, 0 };
 IMPLEMENT_PROTOFUNC(NavigatorFunc)
 
 Navigator::Navigator(ExecState *exec, KHTMLPart *p)
-  : ObjectImp(exec->interpreter()->builtinObjectPrototype()), m_part(p) { }
+  : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), m_part(p) { }
 
 Value Navigator::get(ExecState *exec, const Identifier &propertyName) const
 {
@@ -244,7 +244,7 @@ Value Navigator::getValueProperty(ExecState *exec, int token) const
 /*******************************************************************/
 
 PluginBase::PluginBase(ExecState *exec)
-  : ObjectImp(exec->interpreter()->builtinObjectPrototype() )
+  : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype() )
 {
     if ( !plugins ) {
         plugins = new QPtrList<PluginInfo>;
index 5a33e60aa67ba26c13a3d353fe32458a4f255259..1f072888505047a1991e18a2999b83d9ee0b9dc6 100644 (file)
@@ -76,7 +76,7 @@ namespace KJS {
     friend class HistoryFunc;
   public:
     History(ExecState *exec, KHTMLPart *p)
-      : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
+      : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -90,7 +90,7 @@ namespace KJS {
   class FrameArray : public ObjectImp {
   public:
     FrameArray(ExecState *exec, KHTMLPart *p)
-      : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
+      : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
     virtual UString toString(ExecState *exec) const;
   private:
@@ -133,7 +133,7 @@ const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
 
 // We set the object prototype so that toString is implemented
 Screen::Screen(ExecState *exec)
-  : ObjectImp(exec->interpreter()->builtinObjectPrototype()) {}
+  : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()) {}
 
 Value Screen::get(ExecState *exec, const Identifier &p) const
 {
@@ -320,7 +320,7 @@ Window *Window::retrieveWindow(KHTMLPart *p)
 
 Window *Window::retrieveActive(ExecState *exec)
 {
-  ValueImp *imp = exec->interpreter()->globalObject().imp();
+  ValueImp *imp = exec->dynamicInterpreter()->globalObject().imp();
   assert( imp );
 #ifndef QWS
   assert( dynamic_cast<KJS::Window*>(imp) );
@@ -818,7 +818,7 @@ void Window::put(ExecState* exec, const Identifier &propertyName, const Value &v
         QString dstUrl = p->htmlDocument().completeURL(value.toString(exec).string()).string();
         if (dstUrl.find("javascript:", 0, false) || isSafeScript(exec))
         {
-          bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+          bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
 #if APPLE_CHANGES
           // We want a new history item if this JS was called via a user gesture
           m_part->scheduleRedirection(0, dstUrl, !userGesture, userGesture);
@@ -1010,7 +1010,7 @@ bool Window::isSafeScript(ExecState *exec) const
     kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
     return false;
   }
-  KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->interpreter() )->part();
+  KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->dynamicInterpreter() )->part();
   if (!activePart) {
     kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
     return false;
@@ -1219,7 +1219,7 @@ Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
     } else if ( policy == 3 ) // smart
     {
       // window.open disabled unless from a key/mouse event
-      if (static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture())
+      if (static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture())
 #if !APPLE_CHANGES
         policy = 0;
 #else
@@ -1374,7 +1374,7 @@ Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
          // FIXME: referrer?
           while ( part->parentPart() )
               part = part->parentPart();
-          bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+          bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
           part->scheduleRedirection(0, url.url(), false/*don't lock history*/, userGesture);
           return Window::retrieve(part);
       }
@@ -1383,7 +1383,7 @@ Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
          // FIXME: referrer?
           if ( part->parentPart() )
               part = part->parentPart();
-          bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+          bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
           part->scheduleRedirection(0, url.url(), false/*don't lock history*/, userGesture);
           return Window::retrieve(part);
       }
@@ -1412,7 +1412,7 @@ Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
         }
 #if APPLE_CHANGES
         if (!url.isEmpty()) {
-          bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+          bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
           // FIXME: Need to pass referrer here.
           khtmlpart->scheduleRedirection(0, url.url(), false, userGesture);
        }
@@ -2035,7 +2035,7 @@ void Location::put(ExecState *exec, const Identifier &p, const Value &v, int att
     ObjectImp::put(exec, p, v, attr);
     return;
   }
-  bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+  bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
 #if APPLE_CHANGES
   // We want a new history item if this JS was called via a user gesture
   m_part->scheduleRedirection(0, url.url(), !userGesture, userGesture);
@@ -2078,14 +2078,14 @@ Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
       QString str = args[0].toString(exec).qstring();
       KHTMLPart* p = Window::retrieveActive(exec)->part();
       if ( p ) {
-       bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+       bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
         part->scheduleRedirection(0, p->htmlDocument().completeURL(str).string(), true /*lock history*/, userGesture);
       }
       break;
     }
     case Location::Reload:
     {
-      bool userGesture = static_cast<ScriptInterpreter *>(exec->interpreter())->wasRunByUserGesture();
+      bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
       part->scheduleRedirection(0, part->url().url(), true/*lock history*/, userGesture);
       break;
     }