source: webkit/trunk/JavaScriptCore/kjs/reference.cpp@ 7245

Last change on this file since 7245 was 6347, checked in by mjs, 21 years ago

JavaScriptCore:

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):
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.6 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 2003 Apple Computer, Inc
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 *
21 */
22
23#include "reference.h"
24#include "internal.h"
25
26using namespace KJS;
27
28// ------------------------------ Reference ------------------------------------
29
30Reference::Reference(const Object& b, const Identifier& p)
31 : base(b),
32 baseIsValue(false),
33 propertyNameIsNumber(false),
34 prop(p)
35{
36}
37
38Reference::Reference(const Object& b, unsigned p)
39 : base(b),
40 propertyNameAsNumber(p),
41 baseIsValue(false),
42 propertyNameIsNumber(true)
43{
44}
45
46Reference::Reference(ObjectImp *b, const Identifier& p)
47 : base(b),
48 baseIsValue(false),
49 propertyNameIsNumber(false),
50 prop(p)
51{
52}
53
54Reference::Reference(ObjectImp *b, unsigned p)
55 : base(b),
56 propertyNameAsNumber(p),
57 baseIsValue(false),
58 propertyNameIsNumber(true)
59{
60}
61
62Reference::Reference(const Null& b, const Identifier& p)
63 : base(b),
64 baseIsValue(false),
65 propertyNameIsNumber(false),
66 prop(p)
67{
68}
69
70Reference::Reference(const Null& b, unsigned p)
71 : base(b),
72 propertyNameAsNumber(p),
73 baseIsValue(false),
74 propertyNameIsNumber(true)
75{
76}
77
78Reference Reference::makeValueReference(const Value& v)
79{
80 Reference valueRef;
81 valueRef.base = v;
82 valueRef.baseIsValue = true;
83 return valueRef;
84}
85
86Reference::Reference()
87{
88}
89
90Value Reference::getBase(ExecState *exec) const
91{
92 if (baseIsValue) {
93 Object err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base"));
94 exec->setException(err);
95 return err;
96 }
97
98 return base;
99}
100
101Identifier Reference::getPropertyName(ExecState *exec) const
102{
103 if (baseIsValue) {
104 // the spec wants a runtime error here. But getValue() and putValue()
105 // will catch this case on their own earlier. When returning a Null
106 // string we should be on the safe side.
107 return Identifier();
108 }
109
110 if (propertyNameIsNumber && prop.isNull())
111 prop = Identifier::from(propertyNameAsNumber);
112 return prop;
113}
114
115Value Reference::getValue(ExecState *exec) const
116{
117 if (baseIsValue) {
118 return base;
119 }
120
121 Value o = getBase(exec);
122
123 if (o.isNull() || o.type() == NullType) {
124 UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec).ustring();
125 Object err = Error::create(exec, ReferenceError, m.ascii());
126 exec->setException(err);
127 return err;
128 }
129
130 if (o.type() != ObjectType) {
131 UString m = I18N_NOOP("Base is not an object");
132 Object err = Error::create(exec, ReferenceError, m.ascii());
133 exec->setException(err);
134 return err;
135 }
136
137 if (propertyNameIsNumber)
138 return static_cast<ObjectImp*>(o.imp())->get(exec,propertyNameAsNumber);
139 return static_cast<ObjectImp*>(o.imp())->get(exec,prop);
140}
141
142void Reference::putValue(ExecState *exec, const Value &w)
143{
144 if (baseIsValue) {
145 Object err = Error::create(exec,ReferenceError);
146 exec->setException(err);
147 return;
148 }
149
150#ifdef KJS_VERBOSE
151 printInfo(exec,(UString("setting property ")+getPropertyName(exec)).cstring().c_str(),w);
152#endif
153 Value o = getBase(exec);
154 if (o.type() == NullType)
155 o = exec->dynamicInterpreter()->globalObject();
156
157 if (propertyNameIsNumber)
158 return static_cast<ObjectImp*>(o.imp())->put(exec,propertyNameAsNumber, w);
159 return static_cast<ObjectImp*>(o.imp())->put(exec,prop, w);
160}
161
162bool Reference::deleteValue(ExecState *exec)
163{
164 if (baseIsValue) {
165 Object err = Error::create(exec,ReferenceError);
166 exec->setException(err);
167 return false;
168 }
169
170 Value b = getBase(exec);
171
172 // The spec doesn't mention what to do if the base is null... just return true
173 if (b.type() != ObjectType) {
174 assert(b.type() == NullType);
175 return true;
176 }
177
178 if (propertyNameIsNumber)
179 return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,propertyNameAsNumber);
180 return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,prop);
181}
182
183bool Reference::isMutable()
184{
185 return !baseIsValue;
186}
Note: See TracBrowser for help on using the repository browser.