source: webkit/trunk/JavaScriptCore/API/JSValueRef.cpp@ 60057

Last change on this file since 60057 was 59941, checked in by [email protected], 15 years ago

2010-05-21 Oliver Hunt <[email protected]>

Reviewed by Geoffrey Garen.

All callable objects should have a global object reference
https://bugs.webkit.org/show_bug.cgi?id=39495

All objects that may ever return a value other CallTypeNone
or ConstructTypeNone now get a global object in their constructor
and store that in their first anonymous slot. We add a new type
JSObjectWithGlobalObject to allow us to share this logic as much
as possible, however some objects have specific inheritance
requirements so we can't just use it universally.

To enforce this requirement JSValue::getCallData and getConstructData
make use of a new "isValidCallee" function to assert that any object
that returns a value other than CallType/ConstructTypeNone has a
global object in anonymous slot 0.

In order to ensure that static function slots are converted into
function objects with the correct global object, all prototype objects
and other classes with static function slots also gain a global object
reference. Happily this fixes the long standing issue where host
function objects get a prototype from the lexical global object of the
first function that calls them, instead of the global object that they
are defined on.

  • API/JSCallbackConstructor.cpp: (JSC::JSCallbackConstructor::JSCallbackConstructor):
  • API/JSCallbackConstructor.h:
  • API/JSCallbackFunction.cpp: (JSC::JSCallbackFunction::JSCallbackFunction):
  • API/JSCallbackFunction.h:
  • API/JSCallbackObject.cpp: (JSC::):
  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h: (JSC::::JSCallbackObject): (JSC::::staticFunctionGetter):
  • API/JSClassRef.cpp: (OpaqueJSClass::prototype):
  • API/JSContextRef.cpp:
  • API/JSObjectRef.cpp: (JSObjectMake): (JSObjectMakeFunctionWithCallback): (JSObjectMakeConstructor): (JSObjectGetPrivate): (JSObjectSetPrivate): (JSObjectGetPrivateProperty): (JSObjectSetPrivateProperty): (JSObjectDeletePrivateProperty):
  • API/JSValueRef.cpp: (JSValueIsObjectOfClass):
  • API/JSWeakObjectMapRefPrivate.cpp:
  • CMakeLists.txt:
  • GNUmakefile.am:
  • JavaScriptCore.exp:
  • JavaScriptCore.gypi:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • interpreter/Interpreter.cpp: (JSC::Interpreter::privateExecute):
  • jit/JITStubs.cpp: (JSC::DEFINE_STUB_FUNCTION):
  • jsc.cpp: (GlobalObject::GlobalObject):
  • runtime/ArrayConstructor.cpp: (JSC::ArrayConstructor::ArrayConstructor):
  • runtime/ArrayConstructor.h:
  • runtime/ArrayPrototype.cpp: (JSC::ArrayPrototype::ArrayPrototype):
  • runtime/ArrayPrototype.h: (JSC::ArrayPrototype::createStructure):
  • runtime/BooleanConstructor.cpp: (JSC::BooleanConstructor::BooleanConstructor):
  • runtime/BooleanConstructor.h:
  • runtime/BooleanPrototype.cpp: (JSC::BooleanPrototype::BooleanPrototype):
  • runtime/BooleanPrototype.h:
  • runtime/DateConstructor.cpp: (JSC::DateConstructor::DateConstructor):
  • runtime/DateConstructor.h:
  • runtime/DatePrototype.cpp: (JSC::DatePrototype::DatePrototype):
  • runtime/DatePrototype.h:
  • runtime/ErrorConstructor.cpp: (JSC::ErrorConstructor::ErrorConstructor):
  • runtime/ErrorConstructor.h:
  • runtime/ErrorPrototype.cpp: (JSC::ErrorPrototype::ErrorPrototype):
  • runtime/ErrorPrototype.h:
  • runtime/FunctionConstructor.cpp: (JSC::FunctionConstructor::FunctionConstructor):
  • runtime/FunctionConstructor.h:
  • runtime/FunctionPrototype.cpp: (JSC::FunctionPrototype::FunctionPrototype): (JSC::FunctionPrototype::addFunctionProperties):
  • runtime/FunctionPrototype.h:
  • runtime/GlobalEvalFunction.cpp: (JSC::GlobalEvalFunction::GlobalEvalFunction):
  • runtime/GlobalEvalFunction.h:
  • runtime/InternalFunction.cpp: (JSC::InternalFunction::InternalFunction):
  • runtime/InternalFunction.h:
  • runtime/JSCell.h: (JSC::JSValue::getCallData): (JSC::JSValue::getConstructData):
  • runtime/JSFunction.cpp: (JSC::JSFunction::JSFunction):
  • runtime/JSFunction.h:
  • runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::reset):
  • runtime/JSGlobalObject.h: (JSC::JSGlobalObject::JSGlobalObject):
  • runtime/JSONObject.cpp: (JSC::JSONObject::JSONObject):
  • runtime/JSONObject.h:
  • runtime/JSObject.h:
  • runtime/JSObjectWithGlobalObject.cpp: Added. (JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):
  • runtime/JSObjectWithGlobalObject.h: Added. (JSC::JSObjectWithGlobalObject::createStructure): (JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):
  • runtime/JSValue.cpp: (JSC::JSValue::isValidCallee):
  • runtime/JSValue.h:
  • runtime/Lookup.cpp: (JSC::setUpStaticFunctionSlot):
  • runtime/MathObject.cpp: (JSC::MathObject::MathObject):
  • runtime/MathObject.h:
  • runtime/NativeErrorConstructor.cpp: (JSC::NativeErrorConstructor::NativeErrorConstructor):
  • runtime/NativeErrorConstructor.h:
  • runtime/NativeErrorPrototype.cpp: (JSC::NativeErrorPrototype::NativeErrorPrototype):
  • runtime/NativeErrorPrototype.h:
  • runtime/NumberConstructor.cpp: (JSC::NumberConstructor::NumberConstructor):
  • runtime/NumberConstructor.h:
  • runtime/NumberPrototype.cpp: (JSC::NumberPrototype::NumberPrototype):
  • runtime/NumberPrototype.h:
  • runtime/ObjectConstructor.cpp: (JSC::ObjectConstructor::ObjectConstructor):
  • runtime/ObjectConstructor.h:
  • runtime/ObjectPrototype.cpp: (JSC::ObjectPrototype::ObjectPrototype):
  • runtime/ObjectPrototype.h:
  • runtime/PrototypeFunction.cpp: (JSC::PrototypeFunction::PrototypeFunction):
  • runtime/PrototypeFunction.h:
  • runtime/RegExpConstructor.cpp: (JSC::RegExpConstructor::RegExpConstructor): (JSC::constructRegExp):
  • runtime/RegExpConstructor.h:
  • runtime/RegExpObject.cpp: (JSC::RegExpObject::RegExpObject):
  • runtime/RegExpObject.h:
  • runtime/RegExpPrototype.cpp: (JSC::RegExpPrototype::RegExpPrototype):
  • runtime/RegExpPrototype.h:
  • runtime/StringConstructor.cpp: (JSC::StringConstructor::StringConstructor):
  • runtime/StringConstructor.h:
  • runtime/StringPrototype.cpp: (JSC::StringPrototype::StringPrototype):
  • runtime/StringPrototype.h:

2010-05-21 Oliver Hunt <[email protected]>

Reviewed by Geoffrey Garen.

All callable objects should have a global object reference
https://bugs.webkit.org/show_bug.cgi?id=39495

Update expected results as we now give all function objects
get their prototypes from the correct global object.

  • fast/dom/prototype-inheritance-expected.txt:

2010-05-21 Oliver Hunt <[email protected]>

Reviewed by Geoffrey Garen.

All callable objects should have a global object reference
https://bugs.webkit.org/show_bug.cgi?id=39495

Update the bindings generator to give prototype objects a
global object. Update all the manually written JSObject
subclasses to pass a global object.

  • ForwardingHeaders/runtime/JSObjectWithGlobalObject.h: Added.
  • WebCore.PluginHostProcess.exp:
  • bindings/js/JSDOMBinding.cpp: (WebCore::objectToStringFunctionGetter):
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::nonCachingStaticFunctionGetter):
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::setWindow):
  • bindings/js/JSHistoryCustom.cpp: (WebCore::nonCachingStaticBackFunctionGetter): (WebCore::nonCachingStaticForwardFunctionGetter): (WebCore::nonCachingStaticGoFunctionGetter):
  • bindings/js/JSLocationCustom.cpp: (WebCore::nonCachingStaticReplaceFunctionGetter): (WebCore::nonCachingStaticReloadFunctionGetter): (WebCore::nonCachingStaticAssignFunctionGetter):
  • bindings/js/WorkerScriptController.cpp: (WebCore::WorkerScriptController::initScript):
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/c/CRuntimeObject.cpp: (JSC::Bindings::CRuntimeObject::CRuntimeObject):
  • bridge/c/CRuntimeObject.h:
  • bridge/c/c_instance.cpp: (JSC::Bindings::CInstance::newRuntimeObject): (JSC::Bindings::CRuntimeMethod::CRuntimeMethod): (JSC::Bindings::CInstance::getMethod):
  • bridge/jni/jsc/JavaInstanceJSC.cpp: (JavaInstance::newRuntimeObject): (JavaRuntimeMethod::JavaRuntimeMethod): (JavaInstance::getMethod):
  • bridge/jni/jsc/JavaRuntimeObject.cpp: (JSC::Bindings::JavaRuntimeObject::JavaRuntimeObject):
  • bridge/jni/jsc/JavaRuntimeObject.h:
  • bridge/jsc/BridgeJSC.cpp: (JSC::Bindings::Instance::newRuntimeObject):
  • bridge/objc/ObjCRuntimeObject.h:
  • bridge/objc/ObjCRuntimeObject.mm: (JSC::Bindings::ObjCRuntimeObject::ObjCRuntimeObject):
  • bridge/objc/objc_class.mm: (JSC::Bindings::ObjcClass::fallbackObject):
  • bridge/objc/objc_instance.mm: (ObjcInstance::newRuntimeObject): (ObjCRuntimeMethod::ObjCRuntimeMethod): (ObjcInstance::getMethod):
  • bridge/objc/objc_runtime.h:
  • bridge/objc/objc_runtime.mm: (JSC::Bindings::ObjcFallbackObjectImp::ObjcFallbackObjectImp):
  • bridge/runtime_method.cpp: (JSC::RuntimeMethod::RuntimeMethod):
  • bridge/runtime_method.h:
  • bridge/runtime_object.cpp: (JSC::Bindings::RuntimeObject::RuntimeObject):
  • bridge/runtime_object.h:

2010-05-21 Oliver Hunt <[email protected]>

Reviewed by Geoffrey Garen.

All callable objects should have a global object reference
https://bugs.webkit.org/show_bug.cgi?id=39495

Update the plugin proxy to handle the need for global object.

  • Plugins/Hosted/ProxyInstance.mm: (WebKit::ProxyInstance::newRuntimeObject): (WebKit::ProxyRuntimeMethod::ProxyRuntimeMethod): (WebKit::ProxyInstance::getMethod):
  • Plugins/Hosted/ProxyRuntimeObject.h:
  • Plugins/Hosted/ProxyRuntimeObject.mm: (WebKit::ProxyRuntimeObject::ProxyRuntimeObject):
  • Property svn:eol-style set to native
File size: 9.2 KB
Line 
1/*
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "JSValueRef.h"
28
29#include "APICast.h"
30#include "APIShims.h"
31#include "JSCallbackObject.h"
32
33#include <runtime/JSGlobalObject.h>
34#include <runtime/JSONObject.h>
35#include <runtime/JSString.h>
36#include <runtime/LiteralParser.h>
37#include <runtime/Operations.h>
38#include <runtime/Protect.h>
39#include <runtime/UString.h>
40#include <runtime/JSValue.h>
41
42#include <wtf/Assertions.h>
43#include <wtf/text/StringHash.h>
44
45#include <algorithm> // for std::min
46
47using namespace JSC;
48
49::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
50{
51 ExecState* exec = toJS(ctx);
52 APIEntryShim entryShim(exec);
53
54 JSValue jsValue = toJS(exec, value);
55
56 if (jsValue.isUndefined())
57 return kJSTypeUndefined;
58 if (jsValue.isNull())
59 return kJSTypeNull;
60 if (jsValue.isBoolean())
61 return kJSTypeBoolean;
62 if (jsValue.isNumber())
63 return kJSTypeNumber;
64 if (jsValue.isString())
65 return kJSTypeString;
66 ASSERT(jsValue.isObject());
67 return kJSTypeObject;
68}
69
70bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
71{
72 ExecState* exec = toJS(ctx);
73 APIEntryShim entryShim(exec);
74
75 JSValue jsValue = toJS(exec, value);
76 return jsValue.isUndefined();
77}
78
79bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
80{
81 ExecState* exec = toJS(ctx);
82 APIEntryShim entryShim(exec);
83
84 JSValue jsValue = toJS(exec, value);
85 return jsValue.isNull();
86}
87
88bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
89{
90 ExecState* exec = toJS(ctx);
91 APIEntryShim entryShim(exec);
92
93 JSValue jsValue = toJS(exec, value);
94 return jsValue.isBoolean();
95}
96
97bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
98{
99 ExecState* exec = toJS(ctx);
100 APIEntryShim entryShim(exec);
101
102 JSValue jsValue = toJS(exec, value);
103 return jsValue.isNumber();
104}
105
106bool JSValueIsString(JSContextRef ctx, JSValueRef value)
107{
108 ExecState* exec = toJS(ctx);
109 APIEntryShim entryShim(exec);
110
111 JSValue jsValue = toJS(exec, value);
112 return jsValue.isString();
113}
114
115bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
116{
117 ExecState* exec = toJS(ctx);
118 APIEntryShim entryShim(exec);
119
120 JSValue jsValue = toJS(exec, value);
121 return jsValue.isObject();
122}
123
124bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
125{
126 ExecState* exec = toJS(ctx);
127 APIEntryShim entryShim(exec);
128
129 JSValue jsValue = toJS(exec, value);
130
131 if (JSObject* o = jsValue.getObject()) {
132 if (o->inherits(&JSCallbackObject<JSGlobalObject>::info))
133 return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
134 else if (o->inherits(&JSCallbackObject<JSObjectWithGlobalObject>::info))
135 return static_cast<JSCallbackObject<JSObjectWithGlobalObject>*>(o)->inherits(jsClass);
136 }
137 return false;
138}
139
140bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
141{
142 ExecState* exec = toJS(ctx);
143 APIEntryShim entryShim(exec);
144
145 JSValue jsA = toJS(exec, a);
146 JSValue jsB = toJS(exec, b);
147
148 bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
149 if (exec->hadException()) {
150 if (exception)
151 *exception = toRef(exec, exec->exception());
152 exec->clearException();
153 }
154 return result;
155}
156
157bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
158{
159 ExecState* exec = toJS(ctx);
160 APIEntryShim entryShim(exec);
161
162 JSValue jsA = toJS(exec, a);
163 JSValue jsB = toJS(exec, b);
164
165 return JSValue::strictEqual(exec, jsA, jsB);
166}
167
168bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
169{
170 ExecState* exec = toJS(ctx);
171 APIEntryShim entryShim(exec);
172
173 JSValue jsValue = toJS(exec, value);
174
175 JSObject* jsConstructor = toJS(constructor);
176 if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
177 return false;
178 bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
179 if (exec->hadException()) {
180 if (exception)
181 *exception = toRef(exec, exec->exception());
182 exec->clearException();
183 }
184 return result;
185}
186
187JSValueRef JSValueMakeUndefined(JSContextRef ctx)
188{
189 ExecState* exec = toJS(ctx);
190 APIEntryShim entryShim(exec);
191
192 return toRef(exec, jsUndefined());
193}
194
195JSValueRef JSValueMakeNull(JSContextRef ctx)
196{
197 ExecState* exec = toJS(ctx);
198 APIEntryShim entryShim(exec);
199
200 return toRef(exec, jsNull());
201}
202
203JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
204{
205 ExecState* exec = toJS(ctx);
206 APIEntryShim entryShim(exec);
207
208 return toRef(exec, jsBoolean(value));
209}
210
211JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
212{
213 ExecState* exec = toJS(ctx);
214 APIEntryShim entryShim(exec);
215
216 return toRef(exec, jsNumber(exec, value));
217}
218
219JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
220{
221 ExecState* exec = toJS(ctx);
222 APIEntryShim entryShim(exec);
223
224 return toRef(exec, jsString(exec, string->ustring()));
225}
226
227JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
228{
229 ExecState* exec = toJS(ctx);
230 APIEntryShim entryShim(exec);
231 LiteralParser parser(exec, string->ustring(), LiteralParser::StrictJSON);
232 return toRef(exec, parser.tryLiteralParse());
233}
234
235JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsigned indent, JSValueRef* exception)
236{
237 ExecState* exec = toJS(ctx);
238 APIEntryShim entryShim(exec);
239 JSValue value = toJS(exec, apiValue);
240 UString result = JSONStringify(exec, value, indent);
241 if (exception)
242 *exception = 0;
243 if (exec->hadException()) {
244 if (exception)
245 *exception = toRef(exec, exec->exception());
246 exec->clearException();
247 return 0;
248 }
249 return OpaqueJSString::create(result).releaseRef();
250}
251
252bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
253{
254 ExecState* exec = toJS(ctx);
255 APIEntryShim entryShim(exec);
256
257 JSValue jsValue = toJS(exec, value);
258 return jsValue.toBoolean(exec);
259}
260
261double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
262{
263 ExecState* exec = toJS(ctx);
264 APIEntryShim entryShim(exec);
265
266 JSValue jsValue = toJS(exec, value);
267
268 double number = jsValue.toNumber(exec);
269 if (exec->hadException()) {
270 if (exception)
271 *exception = toRef(exec, exec->exception());
272 exec->clearException();
273 number = NaN;
274 }
275 return number;
276}
277
278JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
279{
280 ExecState* exec = toJS(ctx);
281 APIEntryShim entryShim(exec);
282
283 JSValue jsValue = toJS(exec, value);
284
285 RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
286 if (exec->hadException()) {
287 if (exception)
288 *exception = toRef(exec, exec->exception());
289 exec->clearException();
290 stringRef.clear();
291 }
292 return stringRef.release().releaseRef();
293}
294
295JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
296{
297 ExecState* exec = toJS(ctx);
298 APIEntryShim entryShim(exec);
299
300 JSValue jsValue = toJS(exec, value);
301
302 JSObjectRef objectRef = toRef(jsValue.toObject(exec));
303 if (exec->hadException()) {
304 if (exception)
305 *exception = toRef(exec, exec->exception());
306 exec->clearException();
307 objectRef = 0;
308 }
309 return objectRef;
310}
311
312void JSValueProtect(JSContextRef ctx, JSValueRef value)
313{
314 ExecState* exec = toJS(ctx);
315 APIEntryShim entryShim(exec);
316
317 JSValue jsValue = toJSForGC(exec, value);
318 gcProtect(jsValue);
319}
320
321void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
322{
323 ExecState* exec = toJS(ctx);
324 APIEntryShim entryShim(exec);
325
326 JSValue jsValue = toJSForGC(exec, value);
327 gcUnprotect(jsValue);
328}
Note: See TracBrowser for help on using the repository browser.