source: webkit/trunk/JavaScriptCore/API/JSObjectRef.cpp@ 60762

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

Bug 40214 - Clean up error construction / throwing in JSC.

Reviewed by Sam Weinig.

The one egregious insanity here is that creating an error requires
a VM-entry-esqe-host call (the string argument is wrapped as a JS
object & pushed on the RegisterFile, then unwrapped back to a
UString). Changing this also means you only require a global
object, not an ExecState, to create an error.

The methods to create error objects are also parameterized
requiring a switch on the type, which can be made cleaner and
faster by moving to a separate method per error type. Code to add
divot information to error had been duplicated, and is coalesced
back into a single function.

Convenience methods added to create & throw type & syntax error
with a default error message, since this is a common case.

Also, errors are currently thrown either using
"throwError(exec, error)" or "exec->setException(error)" - unify
on the former, since this is more commonly used. Add
"throwVMError(exec, error)" equivalents, as a convenience for
cases where the result was being wrapped in "JSValue::encode(...)".

JavaScriptCore:

  • API/JSCallbackConstructor.cpp:

(JSC::constructJSCallback):

  • API/JSCallbackFunction.cpp:

(JSC::JSCallbackFunction::call):

  • API/JSCallbackObjectFunctions.h:

(JSC::::getOwnPropertySlot):
(JSC::::put):
(JSC::::deleteProperty):
(JSC::::construct):
(JSC::::hasInstance):
(JSC::::call):
(JSC::::toNumber):
(JSC::::toString):
(JSC::::staticValueGetter):
(JSC::::staticFunctionGetter):
(JSC::::callbackGetter):

  • API/JSObjectRef.cpp:

(JSObjectMakeError):

(JSC::BytecodeGenerator::emitNewError):
(JSC::BytecodeGenerator::emitThrowExpressionTooDeepException):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::ThrowableExpressionData::emitThrowError):
(JSC::RegExpNode::emitBytecode):
(JSC::PostfixErrorNode::emitBytecode):
(JSC::PrefixErrorNode::emitBytecode):
(JSC::AssignErrorNode::emitBytecode):
(JSC::ForInNode::emitBytecode):
(JSC::ContinueNode::emitBytecode):
(JSC::BreakNode::emitBytecode):
(JSC::ReturnNode::emitBytecode):
(JSC::LabelNode::emitBytecode):

  • interpreter/CallFrame.h:
  • interpreter/Interpreter.cpp:

(JSC::Interpreter::throwException):
(JSC::Interpreter::privateExecute):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jsc.cpp:

(functionRun):
(functionLoad):
(functionCheckSyntax):

  • parser/Nodes.h:
  • runtime/ArrayConstructor.cpp:

(JSC::constructArrayWithSizeQuirk):

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncToLocaleString):
(JSC::arrayProtoFuncJoin):
(JSC::arrayProtoFuncFilter):
(JSC::arrayProtoFuncMap):
(JSC::arrayProtoFuncEvery):
(JSC::arrayProtoFuncForEach):
(JSC::arrayProtoFuncSome):
(JSC::arrayProtoFuncReduce):
(JSC::arrayProtoFuncReduceRight):

  • runtime/BooleanPrototype.cpp:

(JSC::booleanProtoFuncToString):
(JSC::booleanProtoFuncValueOf):

  • runtime/DatePrototype.cpp:

(JSC::dateProtoFuncToString):
(JSC::dateProtoFuncToUTCString):
(JSC::dateProtoFuncToISOString):
(JSC::dateProtoFuncToDateString):
(JSC::dateProtoFuncToTimeString):
(JSC::dateProtoFuncToLocaleString):
(JSC::dateProtoFuncToLocaleDateString):
(JSC::dateProtoFuncToLocaleTimeString):
(JSC::dateProtoFuncGetTime):
(JSC::dateProtoFuncGetFullYear):
(JSC::dateProtoFuncGetUTCFullYear):
(JSC::dateProtoFuncToGMTString):
(JSC::dateProtoFuncGetMonth):
(JSC::dateProtoFuncGetUTCMonth):
(JSC::dateProtoFuncGetDate):
(JSC::dateProtoFuncGetUTCDate):
(JSC::dateProtoFuncGetDay):
(JSC::dateProtoFuncGetUTCDay):
(JSC::dateProtoFuncGetHours):
(JSC::dateProtoFuncGetUTCHours):
(JSC::dateProtoFuncGetMinutes):
(JSC::dateProtoFuncGetUTCMinutes):
(JSC::dateProtoFuncGetSeconds):
(JSC::dateProtoFuncGetUTCSeconds):
(JSC::dateProtoFuncGetMilliSeconds):
(JSC::dateProtoFuncGetUTCMilliseconds):
(JSC::dateProtoFuncGetTimezoneOffset):
(JSC::dateProtoFuncSetTime):
(JSC::setNewValueFromTimeArgs):
(JSC::setNewValueFromDateArgs):
(JSC::dateProtoFuncSetMilliSeconds):
(JSC::dateProtoFuncSetUTCMilliseconds):
(JSC::dateProtoFuncSetSeconds):
(JSC::dateProtoFuncSetUTCSeconds):
(JSC::dateProtoFuncSetMinutes):
(JSC::dateProtoFuncSetUTCMinutes):
(JSC::dateProtoFuncSetHours):
(JSC::dateProtoFuncSetUTCHours):
(JSC::dateProtoFuncSetDate):
(JSC::dateProtoFuncSetUTCDate):
(JSC::dateProtoFuncSetMonth):
(JSC::dateProtoFuncSetUTCMonth):
(JSC::dateProtoFuncSetFullYear):
(JSC::dateProtoFuncSetUTCFullYear):
(JSC::dateProtoFuncSetYear):
(JSC::dateProtoFuncGetYear):
(JSC::dateProtoFuncToJSON):

  • runtime/Error.cpp:

(JSC::createError):
(JSC::createEvalError):
(JSC::createRangeError):
(JSC::createReferenceError):
(JSC::createSyntaxError):
(JSC::createTypeError):
(JSC::createURIError):
(JSC::addErrorSourceInfo):
(JSC::addErrorDivotInfo):
(JSC::addErrorInfo):
(JSC::hasErrorInfo):
(JSC::throwError):
(JSC::throwTypeError):
(JSC::throwSyntaxError):

  • runtime/Error.h:

(JSC::throwVMError):
(JSC::throwVMTypeError):

  • runtime/ErrorConstructor.cpp:

(JSC::constructWithErrorConstructor):
(JSC::callErrorConstructor):

  • runtime/ErrorConstructor.h:
  • runtime/ErrorInstance.cpp:

(JSC::ErrorInstance::ErrorInstance):
(JSC::ErrorInstance::create):

  • runtime/ErrorInstance.h:
  • runtime/ErrorPrototype.cpp:

(JSC::ErrorPrototype::ErrorPrototype):

  • runtime/ExceptionHelpers.cpp:

(JSC::createStackOverflowError):
(JSC::createUndefinedVariableError):
(JSC::createInvalidParamError):
(JSC::createNotAConstructorError):
(JSC::createNotAFunctionError):
(JSC::createNotAnObjectError):
(JSC::throwOutOfMemoryError):

  • runtime/ExceptionHelpers.h:
  • runtime/Executable.cpp:

(JSC::EvalExecutable::compile):
(JSC::ProgramExecutable::checkSyntax):
(JSC::ProgramExecutable::compile):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunction):

  • runtime/FunctionPrototype.cpp:

(JSC::functionProtoFuncToString):
(JSC::functionProtoFuncApply):
(JSC::functionProtoFuncCall):

  • runtime/Identifier.cpp:

(JSC::Identifier::from):

  • runtime/Identifier.h:
  • runtime/JSArray.cpp:

(JSC::JSArray::put):

  • runtime/JSFunction.cpp:

(JSC::callHostFunctionAsConstructor):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::encode):
(JSC::decode):
(JSC::globalFuncEval):

  • runtime/JSONObject.cpp:

(JSC::Stringifier::appendStringifiedValue):
(JSC::Walker::walk):
(JSC::JSONProtoFuncParse):
(JSC::JSONProtoFuncStringify):

  • runtime/JSObject.cpp:

(JSC::throwSetterError):
(JSC::JSObject::put):
(JSC::JSObject::putWithAttributes):
(JSC::JSObject::defaultValue):
(JSC::JSObject::hasInstance):
(JSC::JSObject::defineOwnProperty):

  • runtime/JSObject.h:
  • runtime/JSValue.cpp:

(JSC::JSValue::toObjectSlowCase):
(JSC::JSValue::synthesizeObject):
(JSC::JSValue::synthesizePrototype):

  • runtime/NativeErrorConstructor.cpp:

(JSC::constructWithNativeErrorConstructor):
(JSC::callNativeErrorConstructor):

  • runtime/NativeErrorConstructor.h:
  • runtime/NumberPrototype.cpp:

(JSC::numberProtoFuncToString):
(JSC::numberProtoFuncToLocaleString):
(JSC::numberProtoFuncValueOf):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToPrecision):

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorGetPrototypeOf):
(JSC::objectConstructorGetOwnPropertyDescriptor):
(JSC::objectConstructorGetOwnPropertyNames):
(JSC::objectConstructorKeys):
(JSC::toPropertyDescriptor):
(JSC::objectConstructorDefineProperty):
(JSC::objectConstructorDefineProperties):
(JSC::objectConstructorCreate):

  • runtime/ObjectPrototype.cpp:

(JSC::objectProtoFuncDefineGetter):
(JSC::objectProtoFuncDefineSetter):

  • runtime/RegExpConstructor.cpp:

(JSC::constructRegExp):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::match):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncTest):
(JSC::regExpProtoFuncExec):
(JSC::regExpProtoFuncCompile):
(JSC::regExpProtoFuncToString):

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncToString):

WebCore:

  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSArrayBufferConstructor.h:

(WebCore::construct):

  • bindings/js/JSArrayBufferViewHelper.h:

(WebCore::setWebGLArrayHelper):

  • bindings/js/JSAudioConstructor.cpp:

(WebCore::constructAudio):

  • bindings/js/JSCanvasRenderingContext2DCustom.cpp:

(WebCore::JSCanvasRenderingContext2D::setFillColor):
(WebCore::JSCanvasRenderingContext2D::setStrokeColor):
(WebCore::JSCanvasRenderingContext2D::drawImage):
(WebCore::JSCanvasRenderingContext2D::drawImageFromRect):
(WebCore::JSCanvasRenderingContext2D::setShadow):
(WebCore::JSCanvasRenderingContext2D::createPattern):
(WebCore::JSCanvasRenderingContext2D::fillText):
(WebCore::JSCanvasRenderingContext2D::strokeText):

  • bindings/js/JSClipboardCustom.cpp:

(WebCore::JSClipboard::clearData):
(WebCore::JSClipboard::getData):
(WebCore::JSClipboard::setDragImage):

  • bindings/js/JSDOMBinding.cpp:

(WebCore::setDOMException):
(WebCore::toJSSequence):

  • bindings/js/JSDOMWrapper.cpp:

(WebCore::DOMObject::defineOwnProperty):

  • bindings/js/JSDesktopNotificationsCustom.cpp:

(WebCore::JSNotificationCenter::requestPermission):

  • bindings/js/JSEventSourceConstructor.cpp:

(WebCore::constructEventSource):

  • bindings/js/JSHTMLDocumentCustom.cpp:

(WebCore::JSHTMLDocument::open):

  • bindings/js/JSHTMLInputElementCustom.cpp:

(WebCore::JSHTMLInputElement::selectionStart):
(WebCore::JSHTMLInputElement::setSelectionStart):
(WebCore::JSHTMLInputElement::selectionEnd):
(WebCore::JSHTMLInputElement::setSelectionEnd):
(WebCore::JSHTMLInputElement::setSelectionRange):

  • bindings/js/JSImageConstructor.cpp:

(WebCore::constructImage):

  • bindings/js/JSJavaScriptCallFrameCustom.cpp:

(WebCore::JSJavaScriptCallFrame::evaluate):

  • bindings/js/JSMessageChannelConstructor.cpp:

(WebCore::JSMessageChannelConstructor::construct):

  • bindings/js/JSMessagePortCustom.cpp:

(WebCore::fillMessagePortArray):

  • bindings/js/JSOptionConstructor.cpp:

(WebCore::constructHTMLOptionElement):

  • bindings/js/JSSVGMatrixCustom.cpp:

(WebCore::JSSVGMatrix::multiply):

  • bindings/js/JSSharedWorkerConstructor.cpp:

(WebCore::constructSharedWorker):

  • bindings/js/JSWebGLRenderingContextCustom.cpp:

(WebCore::JSWebGLRenderingContext::bufferData):
(WebCore::JSWebGLRenderingContext::bufferSubData):
(WebCore::getObjectParameter):
(WebCore::JSWebGLRenderingContext::getFramebufferAttachmentParameter):
(WebCore::JSWebGLRenderingContext::getParameter):
(WebCore::JSWebGLRenderingContext::getProgramParameter):
(WebCore::JSWebGLRenderingContext::getShaderParameter):
(WebCore::JSWebGLRenderingContext::getUniform):
(WebCore::JSWebGLRenderingContext::texImage2D):
(WebCore::JSWebGLRenderingContext::texSubImage2D):
(WebCore::dataFunctionf):
(WebCore::dataFunctioni):
(WebCore::dataFunctionMatrix):

  • bindings/js/JSWebSocketConstructor.cpp:

(WebCore::constructWebSocket):

  • bindings/js/JSWebSocketCustom.cpp:

(WebCore::JSWebSocket::send):

  • bindings/js/JSWorkerConstructor.cpp:

(WebCore::constructWorker):

  • bindings/js/JSXMLHttpRequestConstructor.cpp:

(WebCore::constructXMLHttpRequest):

  • bindings/js/JSXMLHttpRequestCustom.cpp:

(WebCore::JSXMLHttpRequest::open):

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::BaseWalker::throwStackOverflow):
(WebCore::BaseWalker::throwInterruptedException):
(WebCore::SerializingTreeWalker::startArray):
(WebCore::SerializingTreeWalker::startObject):

  • bindings/js/WorkerScriptController.cpp:

(WebCore::WorkerScriptController::setException):

  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/c/c_instance.cpp:

(JSC::Bindings::CInstance::moveGlobalExceptionToExecState):
(JSC::Bindings::CInstance::invokeMethod):
(JSC::Bindings::CInstance::invokeDefaultMethod):
(JSC::Bindings::CInstance::invokeConstruct):

  • bridge/jni/jsc/JNIBridgeJSC.cpp:

(JavaField::dispatchValueFromInstance):
(JavaField::dispatchSetValueToInstance):

  • bridge/jni/jsc/JavaInstanceJSC.cpp:

(JavaInstance::invokeMethod):

  • bridge/objc/objc_instance.mm:

(ObjcInstance::moveGlobalExceptionToExecState):
(ObjcInstance::invokeMethod):

  • bridge/objc/objc_runtime.mm:

(JSC::Bindings::ObjcField::valueFromInstance):
(JSC::Bindings::ObjcField::setValueToInstance):
(JSC::Bindings::ObjcArray::setValueAt):
(JSC::Bindings::ObjcArray::valueAt):
(JSC::Bindings::callObjCFallbackObject):

  • bridge/objc/objc_utility.h:
  • bridge/objc/objc_utility.mm:

(JSC::Bindings::throwError):

  • bridge/runtime_array.cpp:

(JSC::RuntimeArray::put):

  • bridge/runtime_method.cpp:

(JSC::callRuntimeMethod):

  • bridge/runtime_object.cpp:

(JSC::Bindings::RuntimeObject::throwInvalidAccessError):

WebKit/mac:

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm:

(WebKit::NetscapePluginInstanceProxy::moveGlobalExceptionToExecState):

  • Plugins/Hosted/ProxyInstance.mm:

(WebKit::ProxyInstance::invokeMethod):

  • Property svn:eol-style set to native
File size: 18.1 KB
Line 
1/*
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Kelvin W Sherlock ([email protected])
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "JSObjectRef.h"
29#include "JSObjectRefPrivate.h"
30
31#include "APICast.h"
32#include "CodeBlock.h"
33#include "DateConstructor.h"
34#include "ErrorConstructor.h"
35#include "FunctionConstructor.h"
36#include "Identifier.h"
37#include "InitializeThreading.h"
38#include "JSArray.h"
39#include "JSCallbackConstructor.h"
40#include "JSCallbackFunction.h"
41#include "JSCallbackObject.h"
42#include "JSClassRef.h"
43#include "JSFunction.h"
44#include "JSGlobalObject.h"
45#include "JSObject.h"
46#include "JSRetainPtr.h"
47#include "JSString.h"
48#include "JSValueRef.h"
49#include "ObjectPrototype.h"
50#include "PropertyNameArray.h"
51#include "RegExpConstructor.h"
52
53using namespace JSC;
54
55JSClassRef JSClassCreate(const JSClassDefinition* definition)
56{
57 initializeThreading();
58 RefPtr<OpaqueJSClass> jsClass = (definition->attributes & kJSClassAttributeNoAutomaticPrototype)
59 ? OpaqueJSClass::createNoAutomaticPrototype(definition)
60 : OpaqueJSClass::create(definition);
61
62 return jsClass.release().releaseRef();
63}
64
65JSClassRef JSClassRetain(JSClassRef jsClass)
66{
67 jsClass->ref();
68 return jsClass;
69}
70
71void JSClassRelease(JSClassRef jsClass)
72{
73 jsClass->deref();
74}
75
76JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
77{
78 ExecState* exec = toJS(ctx);
79 APIEntryShim entryShim(exec);
80
81 if (!jsClass)
82 return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure())); // slightly more efficient
83
84 JSCallbackObject<JSObjectWithGlobalObject>* object = new (exec) JSCallbackObject<JSObjectWithGlobalObject>(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data);
85 if (JSObject* prototype = jsClass->prototype(exec))
86 object->setPrototype(prototype);
87
88 return toRef(object);
89}
90
91JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
92{
93 ExecState* exec = toJS(ctx);
94 APIEntryShim entryShim(exec);
95
96 Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
97
98 return toRef(new (exec) JSCallbackFunction(exec, exec->lexicalGlobalObject(), callAsFunction, nameID));
99}
100
101JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
102{
103 ExecState* exec = toJS(ctx);
104 APIEntryShim entryShim(exec);
105
106 JSValue jsPrototype = jsClass ? jsClass->prototype(exec) : 0;
107 if (!jsPrototype)
108 jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
109
110 JSCallbackConstructor* constructor = new (exec) JSCallbackConstructor(exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackConstructorStructure(), jsClass, callAsConstructor);
111 constructor->putDirect(exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
112 return toRef(constructor);
113}
114
115JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
116{
117 ExecState* exec = toJS(ctx);
118 APIEntryShim entryShim(exec);
119
120 Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
121
122 MarkedArgumentBuffer args;
123 for (unsigned i = 0; i < parameterCount; i++)
124 args.append(jsString(exec, parameterNames[i]->ustring()));
125 args.append(jsString(exec, body->ustring()));
126
127 JSObject* result = constructFunction(exec, args, nameID, sourceURL->ustring(), startingLineNumber);
128 if (exec->hadException()) {
129 if (exception)
130 *exception = toRef(exec, exec->exception());
131 exec->clearException();
132 result = 0;
133 }
134 return toRef(result);
135}
136
137JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
138{
139 ExecState* exec = toJS(ctx);
140 APIEntryShim entryShim(exec);
141
142 JSObject* result;
143 if (argumentCount) {
144 MarkedArgumentBuffer argList;
145 for (size_t i = 0; i < argumentCount; ++i)
146 argList.append(toJS(exec, arguments[i]));
147
148 result = constructArray(exec, argList);
149 } else
150 result = constructEmptyArray(exec);
151
152 if (exec->hadException()) {
153 if (exception)
154 *exception = toRef(exec, exec->exception());
155 exec->clearException();
156 result = 0;
157 }
158
159 return toRef(result);
160}
161
162JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
163{
164 ExecState* exec = toJS(ctx);
165 APIEntryShim entryShim(exec);
166
167 MarkedArgumentBuffer argList;
168 for (size_t i = 0; i < argumentCount; ++i)
169 argList.append(toJS(exec, arguments[i]));
170
171 JSObject* result = constructDate(exec, argList);
172 if (exec->hadException()) {
173 if (exception)
174 *exception = toRef(exec, exec->exception());
175 exec->clearException();
176 result = 0;
177 }
178
179 return toRef(result);
180}
181
182JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
183{
184 ExecState* exec = toJS(ctx);
185 APIEntryShim entryShim(exec);
186
187 JSValue message = argumentCount ? toJS(exec, arguments[0]) : jsUndefined();
188 Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
189 JSObject* result = ErrorInstance::create(exec, errorStructure, message);
190
191 if (exec->hadException()) {
192 if (exception)
193 *exception = toRef(exec, exec->exception());
194 exec->clearException();
195 result = 0;
196 }
197
198 return toRef(result);
199}
200
201JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
202{
203 ExecState* exec = toJS(ctx);
204 APIEntryShim entryShim(exec);
205
206 MarkedArgumentBuffer argList;
207 for (size_t i = 0; i < argumentCount; ++i)
208 argList.append(toJS(exec, arguments[i]));
209
210 JSObject* result = constructRegExp(exec, argList);
211 if (exec->hadException()) {
212 if (exception)
213 *exception = toRef(exec, exec->exception());
214 exec->clearException();
215 result = 0;
216 }
217
218 return toRef(result);
219}
220
221JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
222{
223 ExecState* exec = toJS(ctx);
224 APIEntryShim entryShim(exec);
225
226 JSObject* jsObject = toJS(object);
227 return toRef(exec, jsObject->prototype());
228}
229
230void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value)
231{
232 ExecState* exec = toJS(ctx);
233 APIEntryShim entryShim(exec);
234
235 JSObject* jsObject = toJS(object);
236 JSValue jsValue = toJS(exec, value);
237
238 jsObject->setPrototypeWithCycleCheck(jsValue.isObject() ? jsValue : jsNull());
239}
240
241bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
242{
243 ExecState* exec = toJS(ctx);
244 APIEntryShim entryShim(exec);
245
246 JSObject* jsObject = toJS(object);
247
248 return jsObject->hasProperty(exec, propertyName->identifier(&exec->globalData()));
249}
250
251JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
252{
253 ExecState* exec = toJS(ctx);
254 APIEntryShim entryShim(exec);
255
256 JSObject* jsObject = toJS(object);
257
258 JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->globalData()));
259 if (exec->hadException()) {
260 if (exception)
261 *exception = toRef(exec, exec->exception());
262 exec->clearException();
263 }
264 return toRef(exec, jsValue);
265}
266
267void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
268{
269 ExecState* exec = toJS(ctx);
270 APIEntryShim entryShim(exec);
271
272 JSObject* jsObject = toJS(object);
273 Identifier name(propertyName->identifier(&exec->globalData()));
274 JSValue jsValue = toJS(exec, value);
275
276 if (attributes && !jsObject->hasProperty(exec, name))
277 jsObject->putWithAttributes(exec, name, jsValue, attributes);
278 else {
279 PutPropertySlot slot;
280 jsObject->put(exec, name, jsValue, slot);
281 }
282
283 if (exec->hadException()) {
284 if (exception)
285 *exception = toRef(exec, exec->exception());
286 exec->clearException();
287 }
288}
289
290JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
291{
292 ExecState* exec = toJS(ctx);
293 APIEntryShim entryShim(exec);
294
295 JSObject* jsObject = toJS(object);
296
297 JSValue jsValue = jsObject->get(exec, propertyIndex);
298 if (exec->hadException()) {
299 if (exception)
300 *exception = toRef(exec, exec->exception());
301 exec->clearException();
302 }
303 return toRef(exec, jsValue);
304}
305
306
307void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception)
308{
309 ExecState* exec = toJS(ctx);
310 APIEntryShim entryShim(exec);
311
312 JSObject* jsObject = toJS(object);
313 JSValue jsValue = toJS(exec, value);
314
315 jsObject->put(exec, propertyIndex, jsValue);
316 if (exec->hadException()) {
317 if (exception)
318 *exception = toRef(exec, exec->exception());
319 exec->clearException();
320 }
321}
322
323bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
324{
325 ExecState* exec = toJS(ctx);
326 APIEntryShim entryShim(exec);
327
328 JSObject* jsObject = toJS(object);
329
330 bool result = jsObject->deleteProperty(exec, propertyName->identifier(&exec->globalData()));
331 if (exec->hadException()) {
332 if (exception)
333 *exception = toRef(exec, exec->exception());
334 exec->clearException();
335 }
336 return result;
337}
338
339void* JSObjectGetPrivate(JSObjectRef object)
340{
341 JSObject* jsObject = toJS(object);
342
343 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info))
344 return static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate();
345 else if (jsObject->inherits(&JSCallbackObject<JSObjectWithGlobalObject>::info))
346 return static_cast<JSCallbackObject<JSObjectWithGlobalObject>*>(jsObject)->getPrivate();
347
348 return 0;
349}
350
351bool JSObjectSetPrivate(JSObjectRef object, void* data)
352{
353 JSObject* jsObject = toJS(object);
354
355 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) {
356 static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivate(data);
357 return true;
358 } else if (jsObject->inherits(&JSCallbackObject<JSObjectWithGlobalObject>::info)) {
359 static_cast<JSCallbackObject<JSObjectWithGlobalObject>*>(jsObject)->setPrivate(data);
360 return true;
361 }
362
363 return false;
364}
365
366JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
367{
368 ExecState* exec = toJS(ctx);
369 APIEntryShim entryShim(exec);
370 JSObject* jsObject = toJS(object);
371 JSValue result;
372 Identifier name(propertyName->identifier(&exec->globalData()));
373 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info))
374 result = static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name);
375 else if (jsObject->inherits(&JSCallbackObject<JSObjectWithGlobalObject>::info))
376 result = static_cast<JSCallbackObject<JSObjectWithGlobalObject>*>(jsObject)->getPrivateProperty(name);
377 return toRef(exec, result);
378}
379
380bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value)
381{
382 ExecState* exec = toJS(ctx);
383 APIEntryShim entryShim(exec);
384 JSObject* jsObject = toJS(object);
385 JSValue jsValue = toJS(exec, value);
386 Identifier name(propertyName->identifier(&exec->globalData()));
387 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) {
388 static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(name, jsValue);
389 return true;
390 }
391 if (jsObject->inherits(&JSCallbackObject<JSObjectWithGlobalObject>::info)) {
392 static_cast<JSCallbackObject<JSObjectWithGlobalObject>*>(jsObject)->setPrivateProperty(name, jsValue);
393 return true;
394 }
395 return false;
396}
397
398bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
399{
400 ExecState* exec = toJS(ctx);
401 APIEntryShim entryShim(exec);
402 JSObject* jsObject = toJS(object);
403 Identifier name(propertyName->identifier(&exec->globalData()));
404 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) {
405 static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name);
406 return true;
407 }
408 if (jsObject->inherits(&JSCallbackObject<JSObjectWithGlobalObject>::info)) {
409 static_cast<JSCallbackObject<JSObjectWithGlobalObject>*>(jsObject)->deletePrivateProperty(name);
410 return true;
411 }
412 return false;
413}
414
415bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
416{
417 CallData callData;
418 return toJS(object)->getCallData(callData) != CallTypeNone;
419}
420
421JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
422{
423 ExecState* exec = toJS(ctx);
424 APIEntryShim entryShim(exec);
425
426 JSObject* jsObject = toJS(object);
427 JSObject* jsThisObject = toJS(thisObject);
428
429 if (!jsThisObject)
430 jsThisObject = exec->globalThisValue();
431
432 MarkedArgumentBuffer argList;
433 for (size_t i = 0; i < argumentCount; i++)
434 argList.append(toJS(exec, arguments[i]));
435
436 CallData callData;
437 CallType callType = jsObject->getCallData(callData);
438 if (callType == CallTypeNone)
439 return 0;
440
441 JSValueRef result = toRef(exec, call(exec, jsObject, callType, callData, jsThisObject, argList));
442 if (exec->hadException()) {
443 if (exception)
444 *exception = toRef(exec, exec->exception());
445 exec->clearException();
446 result = 0;
447 }
448 return result;
449}
450
451bool JSObjectIsConstructor(JSContextRef, JSObjectRef object)
452{
453 JSObject* jsObject = toJS(object);
454 ConstructData constructData;
455 return jsObject->getConstructData(constructData) != ConstructTypeNone;
456}
457
458JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
459{
460 ExecState* exec = toJS(ctx);
461 APIEntryShim entryShim(exec);
462
463 JSObject* jsObject = toJS(object);
464
465 ConstructData constructData;
466 ConstructType constructType = jsObject->getConstructData(constructData);
467 if (constructType == ConstructTypeNone)
468 return 0;
469
470 MarkedArgumentBuffer argList;
471 for (size_t i = 0; i < argumentCount; i++)
472 argList.append(toJS(exec, arguments[i]));
473 JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
474 if (exec->hadException()) {
475 if (exception)
476 *exception = toRef(exec, exec->exception());
477 exec->clearException();
478 result = 0;
479 }
480 return result;
481}
482
483struct OpaqueJSPropertyNameArray : FastAllocBase {
484 OpaqueJSPropertyNameArray(JSGlobalData* globalData)
485 : refCount(0)
486 , globalData(globalData)
487 {
488 }
489
490 unsigned refCount;
491 JSGlobalData* globalData;
492 Vector<JSRetainPtr<JSStringRef> > array;
493};
494
495JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object)
496{
497 JSObject* jsObject = toJS(object);
498 ExecState* exec = toJS(ctx);
499 APIEntryShim entryShim(exec);
500
501 JSGlobalData* globalData = &exec->globalData();
502
503 JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(globalData);
504 PropertyNameArray array(globalData);
505 jsObject->getPropertyNames(exec, array);
506
507 size_t size = array.size();
508 propertyNames->array.reserveInitialCapacity(size);
509 for (size_t i = 0; i < size; ++i)
510 propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).releaseRef()));
511
512 return JSPropertyNameArrayRetain(propertyNames);
513}
514
515JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
516{
517 ++array->refCount;
518 return array;
519}
520
521void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
522{
523 if (--array->refCount == 0) {
524 APIEntryShim entryShim(array->globalData, false);
525 delete array;
526 }
527}
528
529size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array)
530{
531 return array->array.size();
532}
533
534JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index)
535{
536 return array->array[static_cast<unsigned>(index)].get();
537}
538
539void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
540{
541 PropertyNameArray* propertyNames = toJS(array);
542 APIEntryShim entryShim(propertyNames->globalData());
543 propertyNames->add(propertyName->identifier(propertyNames->globalData()));
544}
Note: See TracBrowser for help on using the repository browser.