diff --git a/.gitignore b/.gitignore
index a4368367..08aabe92 100755
--- a/.gitignore
+++ b/.gitignore
@@ -9,7 +9,7 @@ build/
!default.mode2v3
*.perspectivev3
!default.perspectivev3
-*.xcworkspace
+*.xccheckout
!default.xcworkspace
xcuserdata
profile
@@ -17,3 +17,4 @@ profile
DerivedData
.idea/
.svn*
+*.pyc
diff --git a/JavaScriptCore-iOS-Static.xcconfig b/JavaScriptCore-iOS-Static.xcconfig
new file mode 100644
index 00000000..2b0ef2de
--- /dev/null
+++ b/JavaScriptCore-iOS-Static.xcconfig
@@ -0,0 +1,34 @@
+//
+// JavaScriptCore-iOS-Static.xcconfig
+// JavaScriptCore
+//
+// Created by Martijn The on 1/17/14.
+//
+//
+
+#include "JavaScriptCore/Configurations/JavaScriptCore.xcconfig"
+
+ARCHS = armv7 armv7s arm64;
+ONLY_ACTIVE_ARCH = NO;
+SDKROOT = iphoneos;
+VALID_ARCHS = arm64 armv7 i386;
+BUILD_VARIANTS = normal;
+IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+STRIP_INSTALLED_PRODUCT = YES;
+OTHER_LDFLAGS = ;
+PRODUCT_NAME = JavaScriptCore;
+HEADER_SEARCH_PATHS = "${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore" "${SOURCE_ROOT}/../WTF/" $(HEADER_SEARCH_PATHS);
+LIBRARY_SEARCH_PATHS = "${SOURCE_ROOT}/../Build/";
+
+SECTORDER_FLAGS = ;
+SECTORDER_FLAGS_iphoneos = ;
+
+GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+GCC_OPTIMIZATION_LEVEL = 3;
+GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) HAVE_DTRACE=$(HAVE_DTRACE) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST HAVE_HEADER_DETECTION_H JSC_OBJC_API_ENABLED=0 JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080 $(FEATURE_DEFINES) $(GCC_PREPROCESSOR_DEFINITIONS) __MAC_OS_X_VERSION_MIN_REQUIRED=0 ENABLE_YARR_JIT=0;
+
+ENABLE_REMOTE_INSPECTOR = ENABLE_REMOTE_INSPECTOR=0; // Requires XPC
+
+PRIVATE_HEADERS_FOLDER_PATH = /dev/null;
+PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+
diff --git a/JavaScriptCore-iOS.xcworkspace/contents.xcworkspacedata b/JavaScriptCore-iOS.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..7028adad
--- /dev/null
+++ b/JavaScriptCore-iOS.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/JavaScriptCore/API/APICallbackFunction.h b/JavaScriptCore/API/APICallbackFunction.h
new file mode 100644
index 00000000..65c519b7
--- /dev/null
+++ b/JavaScriptCore/API/APICallbackFunction.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APICallbackFunction_h
+#define APICallbackFunction_h
+
+#include "APICast.h"
+#include "APIShims.h"
+#include "Error.h"
+#include "JSCallbackConstructor.h"
+#include
+
+namespace JSC {
+
+struct APICallbackFunction {
+
+template static EncodedJSValue JSC_HOST_CALL call(ExecState*);
+template static EncodedJSValue JSC_HOST_CALL construct(ExecState*);
+
+};
+
+template
+EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
+{
+ JSContextRef execRef = toRef(exec);
+ JSObjectRef functionRef = toRef(exec->callee());
+ JSObjectRef thisObjRef = toRef(jsCast(exec->hostThisValue().toThis(exec, NotStrictMode)));
+
+ int argumentCount = static_cast(exec->argumentCount());
+ Vector arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (int i = 0; i < argumentCount; i++)
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
+
+ JSValueRef exception = 0;
+ JSValueRef result;
+ {
+ APICallbackShim callbackShim(exec);
+ result = jsCast(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
+ }
+ if (exception)
+ exec->vm().throwException(exec, toJS(exec, exception));
+
+ // result must be a valid JSValue.
+ if (!result)
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(toJS(exec, result));
+}
+
+template
+EncodedJSValue JSC_HOST_CALL APICallbackFunction::construct(ExecState* exec)
+{
+ JSObject* constructor = exec->callee();
+ JSContextRef ctx = toRef(exec);
+ JSObjectRef constructorRef = toRef(constructor);
+
+ JSObjectCallAsConstructorCallback callback = jsCast(constructor)->constructCallback();
+ if (callback) {
+ size_t argumentCount = exec->argumentCount();
+ Vector arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
+
+ JSValueRef exception = 0;
+ JSObjectRef result;
+ {
+ APICallbackShim callbackShim(exec);
+ result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
+ }
+ if (exception) {
+ exec->vm().throwException(exec, toJS(exec, exception));
+ return JSValue::encode(toJS(exec, exception));
+ }
+ // result must be a valid JSValue.
+ if (!result)
+ return throwVMTypeError(exec);
+ return JSValue::encode(toJS(result));
+ }
+
+ return JSValue::encode(toJS(JSObjectMake(ctx, jsCast(constructor)->classRef(), 0)));
+}
+
+} // namespace JSC
+
+#endif // APICallbackFunction_h
diff --git a/JavaScriptCore/API/APICast.h b/JavaScriptCore/API/APICast.h
index f019a7a4..6526d890 100644
--- a/JavaScriptCore/API/APICast.h
+++ b/JavaScriptCore/API/APICast.h
@@ -27,14 +27,14 @@
#define APICast_h
#include "JSAPIValueWrapper.h"
+#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
#include "JSGlobalObject.h"
-#include "JSValue.h"
-#include
namespace JSC {
class ExecState;
class PropertyNameArray;
- class JSGlobalData;
+ class VM;
class JSObject;
class JSValue;
}
@@ -63,46 +63,63 @@ inline JSC::ExecState* toJS(JSGlobalContextRef c)
inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v)
{
ASSERT_UNUSED(exec, exec);
- ASSERT(v);
#if USE(JSVALUE32_64)
JSC::JSCell* jsCell = reinterpret_cast(const_cast(v));
if (!jsCell)
- return JSC::JSValue();
+ return JSC::jsNull();
+ JSC::JSValue result;
if (jsCell->isAPIValueWrapper())
- return JSC::jsCast(jsCell)->value();
- return jsCell;
+ result = JSC::jsCast(jsCell)->value();
+ else
+ result = jsCell;
#else
- return JSC::JSValue::decode(reinterpret_cast(const_cast(v)));
+ JSC::JSValue result = JSC::JSValue::decode(reinterpret_cast(const_cast(v)));
#endif
+ if (!result)
+ return JSC::jsNull();
+ if (result.isCell())
+ RELEASE_ASSERT(result.asCell()->methodTable());
+ return result;
}
inline JSC::JSValue toJSForGC(JSC::ExecState* exec, JSValueRef v)
{
ASSERT_UNUSED(exec, exec);
- ASSERT(v);
#if USE(JSVALUE32_64)
JSC::JSCell* jsCell = reinterpret_cast(const_cast(v));
if (!jsCell)
return JSC::JSValue();
- return jsCell;
+ JSC::JSValue result = jsCell;
#else
- return JSC::JSValue::decode(reinterpret_cast(const_cast(v)));
+ JSC::JSValue result = JSC::JSValue::decode(reinterpret_cast(const_cast(v)));
#endif
+ if (result && result.isCell())
+ RELEASE_ASSERT(result.asCell()->methodTable());
+ return result;
}
-inline JSC::JSObject* toJS(JSObjectRef o)
+// Used in JSObjectGetPrivate as that may be called during finalization
+inline JSC::JSObject* uncheckedToJS(JSObjectRef o)
{
return reinterpret_cast(o);
}
+inline JSC::JSObject* toJS(JSObjectRef o)
+{
+ JSC::JSObject* object = uncheckedToJS(o);
+ if (object)
+ RELEASE_ASSERT(object->methodTable());
+ return object;
+}
+
inline JSC::PropertyNameArray* toJS(JSPropertyNameAccumulatorRef a)
{
return reinterpret_cast(a);
}
-inline JSC::JSGlobalData* toJS(JSContextGroupRef g)
+inline JSC::VM* toJS(JSContextGroupRef g)
{
- return reinterpret_cast(const_cast(g));
+ return reinterpret_cast(const_cast(g));
}
inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v)
@@ -145,7 +162,7 @@ inline JSPropertyNameAccumulatorRef toRef(JSC::PropertyNameArray* l)
return reinterpret_cast(l);
}
-inline JSContextGroupRef toRef(JSC::JSGlobalData* g)
+inline JSContextGroupRef toRef(JSC::VM* g)
{
return reinterpret_cast(g);
}
diff --git a/JavaScriptCore/API/APIShims.h b/JavaScriptCore/API/APIShims.h
index e1589f6a..a133b8ed 100644
--- a/JavaScriptCore/API/APIShims.h
+++ b/JavaScriptCore/API/APIShims.h
@@ -28,39 +28,29 @@
#include "CallFrame.h"
#include "GCActivityCallback.h"
+#include "IncrementalSweeper.h"
#include "JSLock.h"
#include
namespace JSC {
class APIEntryShimWithoutLock {
-public:
- enum RefGlobalDataTag { DontRefGlobalData = 0, RefGlobalData };
-
protected:
- APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread, RefGlobalDataTag shouldRefGlobalData)
- : m_shouldRefGlobalData(shouldRefGlobalData)
- , m_globalData(globalData)
- , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable))
+ APIEntryShimWithoutLock(VM* vm, bool registerThread)
+ : m_vm(vm)
+ , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(vm->identifierTable))
{
- if (shouldRefGlobalData)
- m_globalData->ref();
- UNUSED_PARAM(registerThread);
if (registerThread)
- globalData->heap.machineThreads().addCurrentThread();
- m_globalData->heap.activityCallback()->synchronize();
+ vm->heap.machineThreads().addCurrentThread();
}
~APIEntryShimWithoutLock()
{
wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
- if (m_shouldRefGlobalData)
- m_globalData->deref();
}
protected:
- RefGlobalDataTag m_shouldRefGlobalData;
- JSGlobalData* m_globalData;
+ RefPtr m_vm;
IdentifierTable* m_entryIdentifierTable;
};
@@ -68,57 +58,66 @@ class APIEntryShim : public APIEntryShimWithoutLock {
public:
// Normal API entry
APIEntryShim(ExecState* exec, bool registerThread = true)
- : APIEntryShimWithoutLock(&exec->globalData(), registerThread, RefGlobalData)
- {
- init();
- }
-
- // This constructor is necessary for HeapTimer to prevent it from accidentally resurrecting
- // the ref count of a "dead" JSGlobalData.
- APIEntryShim(JSGlobalData* globalData, RefGlobalDataTag refGlobalData, bool registerThread = true)
- : APIEntryShimWithoutLock(globalData, registerThread, refGlobalData)
+ : APIEntryShimWithoutLock(&exec->vm(), registerThread)
+ , m_lockHolder(exec->vm().exclusiveThread ? 0 : exec)
{
- init();
}
- // JSPropertyNameAccumulator only has a globalData.
- APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
- : APIEntryShimWithoutLock(globalData, registerThread, RefGlobalData)
+ // JSPropertyNameAccumulator only has a vm.
+ APIEntryShim(VM* vm, bool registerThread = true)
+ : APIEntryShimWithoutLock(vm, registerThread)
+ , m_lockHolder(vm->exclusiveThread ? 0 : vm)
{
- init();
}
~APIEntryShim()
{
- m_globalData->timeoutChecker.stop();
- m_globalData->apiLock().unlock();
+ // Destroying our JSLockHolder should also destroy the VM.
+ m_vm.clear();
}
private:
- void init()
- {
- m_globalData->apiLock().lock();
- m_globalData->timeoutChecker.start();
- }
+ JSLockHolder m_lockHolder;
};
class APICallbackShim {
public:
APICallbackShim(ExecState* exec)
- : m_dropAllLocks(exec)
- , m_globalData(&exec->globalData())
+ : m_dropAllLocks(shouldDropAllLocks(exec->vm()) ? exec : nullptr)
+ , m_vm(&exec->vm())
+ {
+ wtfThreadData().resetCurrentIdentifierTable();
+ }
+
+ APICallbackShim(VM& vm)
+ : m_dropAllLocks(shouldDropAllLocks(vm) ? &vm : nullptr)
+ , m_vm(&vm)
{
wtfThreadData().resetCurrentIdentifierTable();
}
~APICallbackShim()
{
- wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable);
+ wtfThreadData().setCurrentIdentifierTable(m_vm->identifierTable);
}
private:
+ static bool shouldDropAllLocks(VM& vm)
+ {
+ if (vm.exclusiveThread)
+ return false;
+
+ // If the VM is in the middle of being destroyed then we don't want to resurrect it
+ // by allowing DropAllLocks to ref it. By this point the APILock has already been
+ // released anyways, so it doesn't matter that DropAllLocks is a no-op.
+ if (!vm.refCount())
+ return false;
+
+ return true;
+ }
+
JSLock::DropAllLocks m_dropAllLocks;
- JSGlobalData* m_globalData;
+ VM* m_vm;
};
}
diff --git a/JavaScriptCore/API/JSAPIWrapperObject.h b/JavaScriptCore/API/JSAPIWrapperObject.h
new file mode 100644
index 00000000..90903977
--- /dev/null
+++ b/JavaScriptCore/API/JSAPIWrapperObject.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSAPIWrapperObject_h
+#define JSAPIWrapperObject_h
+
+#include "JSBase.h"
+#include "JSDestructibleObject.h"
+#include "WeakReferenceHarvester.h"
+
+#if JSC_OBJC_API_ENABLED
+
+namespace JSC {
+
+class JSAPIWrapperObject : public JSDestructibleObject {
+public:
+ typedef JSDestructibleObject Base;
+
+ void finishCreation(VM&);
+ static void visitChildren(JSCell*, JSC::SlotVisitor&);
+
+ void* wrappedObject() { return m_wrappedObject; }
+ void setWrappedObject(void*);
+
+protected:
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
+ JSAPIWrapperObject(VM&, Structure*);
+
+private:
+ void* m_wrappedObject;
+};
+
+} // namespace JSC
+
+#endif // JSC_OBJC_API_ENABLED
+
+#endif // JSAPIWrapperObject_h
diff --git a/JavaScriptCore/API/JSAPIWrapperObject.mm b/JavaScriptCore/API/JSAPIWrapperObject.mm
new file mode 100644
index 00000000..dd3af39f
--- /dev/null
+++ b/JavaScriptCore/API/JSAPIWrapperObject.mm
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSAPIWrapperObject.h"
+
+#include "DelayedReleaseScope.h"
+#include "JSCJSValueInlines.h"
+#include "JSCallbackObject.h"
+#include "JSCellInlines.h"
+#include "JSVirtualMachineInternal.h"
+#include "SlotVisitorInlines.h"
+#include "Structure.h"
+#include "StructureInlines.h"
+
+#if JSC_OBJC_API_ENABLED
+
+class JSAPIWrapperObjectHandleOwner : public JSC::WeakHandleOwner {
+public:
+ virtual void finalize(JSC::Handle, void*) OVERRIDE;
+ virtual bool isReachableFromOpaqueRoots(JSC::Handle, void* context, JSC::SlotVisitor&) OVERRIDE;
+};
+
+static JSAPIWrapperObjectHandleOwner* jsAPIWrapperObjectHandleOwner()
+{
+ DEFINE_STATIC_LOCAL(JSAPIWrapperObjectHandleOwner, jsWrapperObjectHandleOwner, ());
+ return &jsWrapperObjectHandleOwner;
+}
+
+void JSAPIWrapperObjectHandleOwner::finalize(JSC::Handle handle, void*)
+{
+ JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast(handle.get().asCell());
+ if (!wrapperObject->wrappedObject())
+ return;
+
+ JSC::Heap::heap(wrapperObject)->releaseSoon(adoptNS(static_cast(wrapperObject->wrappedObject())));
+ JSC::WeakSet::deallocate(JSC::WeakImpl::asWeakImpl(handle.slot()));
+}
+
+bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle handle, void*, JSC::SlotVisitor& visitor)
+{
+ JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast(handle.get().asCell());
+ // We use the JSGlobalObject when processing weak handles to prevent the situation where using
+ // the same Objective-C object in multiple global objects keeps all of the global objects alive.
+ if (!wrapperObject->wrappedObject())
+ return false;
+ return JSC::Heap::isMarked(wrapperObject->structure()->globalObject()) && visitor.containsOpaqueRoot(wrapperObject->wrappedObject());
+}
+
+namespace JSC {
+
+template <> const ClassInfo JSCallbackObject::s_info = { "JSAPIWrapperObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+
+template<> const bool JSCallbackObject::needsDestruction = true;
+
+template <>
+Structure* JSCallbackObject::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+{
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+}
+
+JSAPIWrapperObject::JSAPIWrapperObject(VM& vm, Structure* structure)
+ : Base(vm, structure)
+ , m_wrappedObject(0)
+{
+}
+
+void JSAPIWrapperObject::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ WeakSet::allocate(this, jsAPIWrapperObjectHandleOwner(), 0); // Balanced in JSAPIWrapperObjectHandleOwner::finalize.
+}
+
+void JSAPIWrapperObject::setWrappedObject(void* wrappedObject)
+{
+ ASSERT(!m_wrappedObject);
+ m_wrappedObject = [static_cast(wrappedObject) retain];
+}
+
+void JSAPIWrapperObject::visitChildren(JSCell* cell, JSC::SlotVisitor& visitor)
+{
+ JSAPIWrapperObject* thisObject = JSC::jsCast(cell);
+ COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
+ Base::visitChildren(cell, visitor);
+
+ if (thisObject->wrappedObject())
+ scanExternalObjectGraph(cell->structure()->globalObject()->vm(), visitor, thisObject->wrappedObject());
+}
+
+} // namespace JSC
+
+#endif // JSC_OBJC_API_ENABLED
diff --git a/JavaScriptCore/API/JSBase.cpp b/JavaScriptCore/API/JSBase.cpp
index d0ffa311..c0930a49 100644
--- a/JavaScriptCore/API/JSBase.cpp
+++ b/JavaScriptCore/API/JSBase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,31 +29,36 @@
#include "APICast.h"
#include "APIShims.h"
+#include "CallFrame.h"
+#include "Completion.h"
+#include "InitializeThreading.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "JSObject.h"
#include "OpaqueJSString.h"
+#include "Operations.h"
#include "SourceCode.h"
-#include
-#include
-#include
-#include
-#include
-#include
#include
using namespace JSC;
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsThisObject = toJS(thisObject);
// evaluate sets "this" to the global object if it is NULL
- JSGlobalObject* globalObject = exec->dynamicGlobalObject();
- SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+ JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
+ SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
JSValue evaluationException;
- JSValue returnValue = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject, &evaluationException);
+ JSValue returnValue = evaluate(globalObject->globalExec(), source, jsThisObject, &evaluationException);
if (evaluationException) {
if (exception)
@@ -70,13 +75,17 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
+ SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
JSValue syntaxException;
- bool isValidSyntax = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source, &syntaxException);
+ bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException);
if (!isValidSyntax) {
if (exception)
@@ -100,12 +109,50 @@ void JSGarbageCollect(JSContextRef ctx)
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec, false);
- exec->globalData().heap.reportAbandonedObjectGraph();
+ exec->vm().heap.reportAbandonedObjectGraph();
}
void JSReportExtraMemoryCost(JSContextRef ctx, size_t size)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- exec->globalData().heap.reportExtraMemoryCost(size);
+ exec->vm().heap.reportExtraMemoryCost(size);
}
+
+extern "C" JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef);
+
+void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx)
+{
+ if (!ctx)
+ return;
+
+ ExecState* exec = toJS(ctx);
+ APIEntryShim entryShim(exec);
+ exec->vm().heap.collectAllGarbage();
+}
+
+void JSDisableGCTimer(void)
+{
+ GCActivityCallback::s_shouldCreateGCTimer = false;
+}
+
+#if PLATFORM(IOS)
+// FIXME: Expose symbols to tell dyld where to find JavaScriptCore on older versions of
+// iOS (< 7.0). We should remove these symbols once we no longer need to support such
+// versions of iOS. See for more details.
+JS_EXPORT extern const char iosInstallName43 __asm("$ld$install_name$os4.3$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName50 __asm("$ld$install_name$os5.0$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName51 __asm("$ld$install_name$os5.1$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName60 __asm("$ld$install_name$os6.0$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+JS_EXPORT extern const char iosInstallName61 __asm("$ld$install_name$os6.1$/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore");
+
+const char iosInstallName43 = 0;
+const char iosInstallName50 = 0;
+const char iosInstallName51 = 0;
+const char iosInstallName60 = 0;
+const char iosInstallName61 = 0;
+#endif
diff --git a/JavaScriptCore/API/JSBase.h b/JavaScriptCore/API/JSBase.h
index fed54fe2..def4ea07 100644
--- a/JavaScriptCore/API/JSBase.h
+++ b/JavaScriptCore/API/JSBase.h
@@ -30,6 +30,10 @@
#include
#endif
+#ifdef __OBJC__
+#import
+#endif
+
/* JavaScript engine interface */
/*! @typedef JSContextGroupRef A group that associates JavaScript contexts with one another. Contexts in the same group may share and exchange JavaScript objects. */
@@ -71,7 +75,7 @@ typedef struct OpaqueJSValue* JSObjectRef;
#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__)
#define JS_EXPORT __attribute__((visibility("default")))
#elif defined(WIN32) || defined(_WIN32) || defined(_WIN32_WCE) || defined(__CC_ARM) || defined(__ARMCC__)
-#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
+#if defined(BUILDING_JavaScriptCore) || defined(STATICALLY_LINKED_WITH_JavaScriptCore)
#define JS_EXPORT __declspec(dllexport)
#else
#define JS_EXPORT __declspec(dllimport)
@@ -135,4 +139,13 @@ JS_EXPORT void JSGarbageCollect(JSContextRef ctx);
}
#endif
+/* Enable the Objective-C API for platforms with a modern runtime. */
+#if !defined(JSC_OBJC_API_ENABLED)
+#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080
+#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)))
+#else
+#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !defined(__i386__))
+#endif
+#endif
+
#endif /* JSBase_h */
diff --git a/JavaScriptCore/API/JSBasePrivate.h b/JavaScriptCore/API/JSBasePrivate.h
index befa3164..133176e1 100644
--- a/JavaScriptCore/API/JSBasePrivate.h
+++ b/JavaScriptCore/API/JSBasePrivate.h
@@ -43,7 +43,9 @@ owns a large non-GC memory region. Calling this function will encourage the
garbage collector to collect soon, hoping to reclaim that large non-GC memory
region.
*/
-JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) CF_AVAILABLE(10_6, 7_0);
+
+JS_EXPORT void JSDisableGCTimer(void);
#ifdef __cplusplus
}
diff --git a/JavaScriptCore/API/JSCTestRunnerUtils.cpp b/JavaScriptCore/API/JSCTestRunnerUtils.cpp
new file mode 100644
index 00000000..2e93ac11
--- /dev/null
+++ b/JavaScriptCore/API/JSCTestRunnerUtils.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCTestRunnerUtils.h"
+
+#include "APICast.h"
+#include "Operations.h"
+#include "TestRunnerUtils.h"
+
+namespace JSC {
+
+JSValueRef numberOfDFGCompiles(JSContextRef context, JSValueRef theFunctionValueRef)
+{
+ ExecState* exec= toJS(context);
+ return toRef(exec, numberOfDFGCompiles(toJS(exec, theFunctionValueRef)));
+}
+
+JSValueRef setNeverInline(JSContextRef context, JSValueRef theFunctionValueRef)
+{
+ ExecState* exec= toJS(context);
+ return toRef(exec, setNeverInline(toJS(exec, theFunctionValueRef)));
+}
+
+} // namespace JSC
+
diff --git a/JavaScriptCore/API/JSCTestRunnerUtils.h b/JavaScriptCore/API/JSCTestRunnerUtils.h
new file mode 100644
index 00000000..aaecdd5c
--- /dev/null
+++ b/JavaScriptCore/API/JSCTestRunnerUtils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSCTestRunnerUtils_h
+#define JSCTestRunnerUtils_h
+
+#include
+#include
+
+namespace JSC {
+
+JS_EXPORT_PRIVATE JSValueRef numberOfDFGCompiles(JSContextRef, JSValueRef theFunction);
+JS_EXPORT_PRIVATE JSValueRef setNeverInline(JSContextRef, JSValueRef theFunction);
+
+} // namespace JSC
+
+#endif // JSCTestRunnerUtils_h
diff --git a/JavaScriptCore/API/JSCallbackConstructor.cpp b/JavaScriptCore/API/JSCallbackConstructor.cpp
index c8b4c065..8ea97a44 100644
--- a/JavaScriptCore/API/JSCallbackConstructor.cpp
+++ b/JavaScriptCore/API/JSCallbackConstructor.cpp
@@ -26,20 +26,22 @@
#include "config.h"
#include "JSCallbackConstructor.h"
-#include "APIShims.h"
+#include "APICallbackFunction.h"
#include "APICast.h"
-#include
-#include
-#include
-#include
+#include "APIShims.h"
+#include "Error.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "ObjectPrototype.h"
+#include "Operations.h"
#include
namespace JSC {
-const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
+const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
- : JSNonFinalObject(globalObject->globalData(), structure)
+ : JSDestructibleObject(globalObject->vm(), structure)
, m_class(jsClass)
, m_callback(callback)
{
@@ -47,8 +49,8 @@ JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Struc
void JSCallbackConstructor::finishCreation(JSGlobalObject* globalObject, JSClassRef jsClass)
{
- Base::finishCreation(globalObject->globalData());
- ASSERT(inherits(&s_info));
+ Base::finishCreation(globalObject->vm());
+ ASSERT(inherits(info()));
if (m_class)
JSClassRetain(jsClass);
}
@@ -61,42 +63,12 @@ JSCallbackConstructor::~JSCallbackConstructor()
void JSCallbackConstructor::destroy(JSCell* cell)
{
- jsCast(cell)->JSCallbackConstructor::~JSCallbackConstructor();
-}
-
-static EncodedJSValue JSC_HOST_CALL constructJSCallback(ExecState* exec)
-{
- JSObject* constructor = exec->callee();
- JSContextRef ctx = toRef(exec);
- JSObjectRef constructorRef = toRef(constructor);
-
- JSObjectCallAsConstructorCallback callback = jsCast(constructor)->callback();
- if (callback) {
- int argumentCount = static_cast(exec->argumentCount());
- Vector arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
-
- JSValueRef exception = 0;
- JSObjectRef result;
- {
- APICallbackShim callbackShim(exec);
- result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
- }
- if (exception)
- throwError(exec, toJS(exec, exception));
- // result must be a valid JSValue.
- if (!result)
- return throwVMTypeError(exec);
- return JSValue::encode(toJS(result));
- }
-
- return JSValue::encode(toJS(JSObjectMake(ctx, jsCast(constructor)->classRef(), 0)));
+ static_cast(cell)->JSCallbackConstructor::~JSCallbackConstructor();
}
ConstructType JSCallbackConstructor::getConstructData(JSCell*, ConstructData& constructData)
{
- constructData.native.function = constructJSCallback;
+ constructData.native.function = APICallbackFunction::construct;
return ConstructTypeHost;
}
diff --git a/JavaScriptCore/API/JSCallbackConstructor.h b/JavaScriptCore/API/JSCallbackConstructor.h
index 25fde132..7eedb52e 100644
--- a/JavaScriptCore/API/JSCallbackConstructor.h
+++ b/JavaScriptCore/API/JSCallbackConstructor.h
@@ -27,13 +27,13 @@
#define JSCallbackConstructor_h
#include "JSObjectRef.h"
-#include
+#include "runtime/JSDestructibleObject.h"
namespace JSC {
-class JSCallbackConstructor : public JSNonFinalObject {
+class JSCallbackConstructor : public JSDestructibleObject {
public:
- typedef JSNonFinalObject Base;
+ typedef JSDestructibleObject Base;
static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback)
{
@@ -46,11 +46,11 @@ class JSCallbackConstructor : public JSNonFinalObject {
static void destroy(JSCell*);
JSClassRef classRef() const { return m_class; }
JSObjectCallAsConstructorCallback callback() const { return m_callback; }
- static const ClassInfo s_info;
+ DECLARE_INFO;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
}
protected:
@@ -59,8 +59,12 @@ class JSCallbackConstructor : public JSNonFinalObject {
static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
private:
+ friend struct APICallbackFunction;
+
static ConstructType getConstructData(JSCell*, ConstructData&);
+ JSObjectCallAsConstructorCallback constructCallback() { return m_callback; }
+
JSClassRef m_class;
JSObjectCallAsConstructorCallback m_callback;
};
diff --git a/JavaScriptCore/API/JSCallbackFunction.cpp b/JavaScriptCore/API/JSCallbackFunction.cpp
index d287ab77..1996991f 100644
--- a/JavaScriptCore/API/JSCallbackFunction.cpp
+++ b/JavaScriptCore/API/JSCallbackFunction.cpp
@@ -26,65 +26,47 @@
#include "config.h"
#include "JSCallbackFunction.h"
-#include "APIShims.h"
+#include "APICallbackFunction.h"
#include "APICast.h"
+#include "APIShims.h"
#include "CodeBlock.h"
+#include "Error.h"
#include "ExceptionHelpers.h"
-#include "JSFunction.h"
#include "FunctionPrototype.h"
-#include
-#include
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "Operations.h"
#include
namespace JSC {
-ASSERT_CLASS_FITS_IN_CELL(JSCallbackFunction);
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCallbackFunction);
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSCallbackFunction);
const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackFunction) };
-JSCallbackFunction::JSCallbackFunction(JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback)
- : InternalFunction(globalObject, globalObject->callbackFunctionStructure())
+JSCallbackFunction::JSCallbackFunction(VM& vm, Structure* structure, JSObjectCallAsFunctionCallback callback)
+ : InternalFunction(vm, structure)
, m_callback(callback)
{
}
-void JSCallbackFunction::finishCreation(JSGlobalData& globalData, const Identifier& name)
+void JSCallbackFunction::finishCreation(VM& vm, const String& name)
{
- Base::finishCreation(globalData, name);
- ASSERT(inherits(&s_info));
+ Base::finishCreation(vm, name);
+ ASSERT(inherits(info()));
}
-EncodedJSValue JSCallbackFunction::call(ExecState* exec)
+JSCallbackFunction* JSCallbackFunction::create(VM& vm, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const String& name)
{
- JSContextRef execRef = toRef(exec);
- JSObjectRef functionRef = toRef(exec->callee());
- JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
-
- int argumentCount = static_cast(exec->argumentCount());
- Vector arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
-
- JSValueRef exception = 0;
- JSValueRef result;
- {
- APICallbackShim callbackShim(exec);
- result = jsCast(toJS(functionRef))->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
- }
- if (exception)
- throwError(exec, toJS(exec, exception));
-
- // result must be a valid JSValue.
- if (!result)
- return JSValue::encode(jsUndefined());
-
- return JSValue::encode(toJS(exec, result));
+ JSCallbackFunction* function = new (NotNull, allocateCell(vm.heap)) JSCallbackFunction(vm, globalObject->callbackFunctionStructure(), callback);
+ function->finishCreation(vm, name);
+ return function;
}
CallType JSCallbackFunction::getCallData(JSCell*, CallData& callData)
{
- callData.native.function = call;
+ callData.native.function = APICallbackFunction::call;
return CallTypeHost;
}
diff --git a/JavaScriptCore/API/JSCallbackFunction.h b/JavaScriptCore/API/JSCallbackFunction.h
index fec4136f..dff18de5 100644
--- a/JavaScriptCore/API/JSCallbackFunction.h
+++ b/JavaScriptCore/API/JSCallbackFunction.h
@@ -32,33 +32,28 @@
namespace JSC {
class JSCallbackFunction : public InternalFunction {
-protected:
- JSCallbackFunction(JSGlobalObject*, JSObjectCallAsFunctionCallback);
- void finishCreation(JSGlobalData&, const Identifier& name);
-
+ friend struct APICallbackFunction;
public:
typedef InternalFunction Base;
- static JSCallbackFunction* create(ExecState* exec, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const Identifier& name)
- {
- JSCallbackFunction* function = new (NotNull, allocateCell(*exec->heap())) JSCallbackFunction(globalObject, callback);
- function->finishCreation(exec->globalData(), name);
- return function;
- }
+ static JSCallbackFunction* create(VM&, JSGlobalObject*, JSObjectCallAsFunctionCallback, const String& name);
- static const ClassInfo s_info;
+ DECLARE_INFO;
// InternalFunction mish-mashes constructor and function behavior -- we should
// refactor the code so this override isn't necessary
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
}
private:
+ JSCallbackFunction(VM&, Structure*, JSObjectCallAsFunctionCallback);
+ void finishCreation(VM&, const String& name);
+
static CallType getCallData(JSCell*, CallData&);
- static EncodedJSValue JSC_HOST_CALL call(ExecState*);
+ JSObjectCallAsFunctionCallback functionCallback() { return m_callback; }
JSObjectCallAsFunctionCallback m_callback;
};
diff --git a/JavaScriptCore/API/JSCallbackObject.cpp b/JavaScriptCore/API/JSCallbackObject.cpp
index 68c26824..94713da3 100644
--- a/JavaScriptCore/API/JSCallbackObject.cpp
+++ b/JavaScriptCore/API/JSCallbackObject.cpp
@@ -28,39 +28,43 @@
#include "JSCallbackObject.h"
#include "Heap.h"
+#include "Operations.h"
#include
namespace JSC {
-ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject);
-ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject);
-
// Define the two types of JSCallbackObjects we support.
-template <> const ClassInfo JSCallbackObject::s_info = { "CallbackObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
-template <> const ClassInfo JSCallbackObject::s_info = { "CallbackGlobalObject", &JSGlobalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+template <> const ClassInfo JSCallbackObject::s_info = { "CallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+template <> const ClassInfo JSCallbackObject::s_info = { "CallbackGlobalObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+
+template<> const bool JSCallbackObject::needsDestruction = true;
+template<> const bool JSCallbackObject::needsDestruction = false;
+
+template<>
+JSCallbackObject* JSCallbackObject::create(VM& vm, JSClassRef classRef, Structure* structure)
+{
+ JSCallbackObject* callbackObject = new (NotNull, allocateCell>(vm.heap)) JSCallbackObject(vm, classRef, structure);
+ callbackObject->finishCreation(vm);
+ vm.heap.addFinalizer(callbackObject, destroy);
+ return callbackObject;
+}
template <>
-Structure* JSCallbackObject::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+Structure* JSCallbackObject::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
}
template <>
-Structure* JSCallbackObject::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+Structure* JSCallbackObject::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
-}
-
-template
-void JSCallbackObject::destroy(JSCell* cell)
-{
- jsCast(cell)->JSCallbackObject::~JSCallbackObject();
+ return Structure::create(vm, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), info());
}
void JSCallbackObjectData::finalize(Handle handle, void* context)
{
JSClassRef jsClass = static_cast(context);
- JSObjectRef thisRef = toRef(asObject(handle.get()));
+ JSObjectRef thisRef = toRef(static_cast(handle.get().asCell()));
for (; jsClass; jsClass = jsClass->parentClass)
if (JSObjectFinalizeCallback finalize = jsClass->finalize)
diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h
index 9aca0c7e..7ad16080 100644
--- a/JavaScriptCore/API/JSCallbackObject.h
+++ b/JavaScriptCore/API/JSCallbackObject.h
@@ -42,7 +42,7 @@ struct JSCallbackObjectData : WeakHandleOwner {
JSClassRetain(jsClass);
}
- ~JSCallbackObjectData()
+ virtual ~JSCallbackObjectData()
{
JSClassRelease(jsClass);
}
@@ -54,11 +54,11 @@ struct JSCallbackObjectData : WeakHandleOwner {
return m_privateProperties->getPrivateProperty(propertyName);
}
- void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value)
+ void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
{
if (!m_privateProperties)
m_privateProperties = adoptPtr(new JSPrivatePropertyMap);
- m_privateProperties->setPrivateProperty(globalData, owner, propertyName, value);
+ m_privateProperties->setPrivateProperty(vm, owner, propertyName, value);
}
void deletePrivateProperty(const Identifier& propertyName)
@@ -83,13 +83,13 @@ struct JSCallbackObjectData : WeakHandleOwner {
PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.impl());
if (location == m_propertyMap.end())
return JSValue();
- return location->second.get();
+ return location->value.get();
}
- void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value)
+ void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
{
WriteBarrier empty;
- m_propertyMap.add(propertyName.impl(), empty).iterator->second.set(globalData, owner, value);
+ m_propertyMap.add(propertyName.impl(), empty).iterator->value.set(vm, owner, value);
}
void deletePrivateProperty(const Identifier& propertyName)
@@ -100,8 +100,8 @@ struct JSCallbackObjectData : WeakHandleOwner {
void visitChildren(SlotVisitor& visitor)
{
for (PrivatePropertyMap::iterator ptr = m_propertyMap.begin(); ptr != m_propertyMap.end(); ++ptr) {
- if (ptr->second)
- visitor.append(&ptr->second);
+ if (ptr->value)
+ visitor.append(&ptr->value);
}
}
@@ -110,7 +110,7 @@ struct JSCallbackObjectData : WeakHandleOwner {
PrivatePropertyMap m_propertyMap;
};
OwnPtr m_privateProperties;
- virtual void finalize(Handle, void*);
+ virtual void finalize(Handle, void*) OVERRIDE;
};
@@ -118,10 +118,10 @@ template
class JSCallbackObject : public Parent {
protected:
JSCallbackObject(ExecState*, Structure*, JSClassRef, void* data);
- JSCallbackObject(JSGlobalData&, JSClassRef, Structure*);
+ JSCallbackObject(VM&, JSClassRef, Structure*);
void finishCreation(ExecState*);
- void finishCreation(JSGlobalData&);
+ void finishCreation(VM&);
public:
typedef Parent Base;
@@ -133,31 +133,32 @@ class JSCallbackObject : public Parent {
callbackObject->finishCreation(exec);
return callbackObject;
}
- static JSCallbackObject* create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure)
+ static JSCallbackObject* create(VM&, JSClassRef, Structure*);
+
+ static const bool needsDestruction;
+ static void destroy(JSCell* cell)
{
- JSCallbackObject* callbackObject = new (NotNull, allocateCell(globalData.heap)) JSCallbackObject(globalData, classRef, structure);
- callbackObject->finishCreation(globalData);
- return callbackObject;
+ static_cast(cell)->JSCallbackObject::~JSCallbackObject();
}
void setPrivate(void* data);
void* getPrivate();
- static const ClassInfo s_info;
+ DECLARE_INFO;
JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
bool inherits(JSClassRef) const;
- static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue);
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
JSValue getPrivateProperty(const Identifier& propertyName) const
{
return m_callbackObjectData->getPrivateProperty(propertyName);
}
- void setPrivateProperty(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
+ void setPrivateProperty(VM& vm, const Identifier& propertyName, JSValue value)
{
- m_callbackObjectData->setPrivateProperty(globalData, this, propertyName, value);
+ m_callbackObjectData->setPrivateProperty(vm, this, propertyName, value);
}
void deletePrivateProperty(const Identifier& propertyName)
@@ -168,26 +169,25 @@ class JSCallbackObject : public Parent {
using Parent::methodTable;
protected:
- static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags;
+ static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags;
private:
- static UString className(const JSObject*);
-
- static void destroy(JSCell*);
+ static String className(const JSObject*);
static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
- static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+ static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
- static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&);
+ static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+ static void putByIndex(JSCell*, ExecState*, unsigned, JSValue, bool shouldThrow);
- static bool deleteProperty(JSCell*, ExecState*, const Identifier&);
+ static bool deleteProperty(JSCell*, ExecState*, PropertyName);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
- static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);
+ static bool customHasInstance(JSObject*, ExecState*, JSValue);
- static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static ConstructType getConstructData(JSCell*, ConstructData&);
static CallType getCallData(JSCell*, CallData&);
@@ -195,7 +195,7 @@ class JSCallbackObject : public Parent {
static void visitChildren(JSCell* cell, SlotVisitor& visitor)
{
JSCallbackObject* thisObject = jsCast(cell);
- ASSERT_GC_OBJECT_INHERITS((static_cast(thisObject)), &JSCallbackObject::s_info);
+ ASSERT_GC_OBJECT_INHERITS((static_cast(thisObject)), JSCallbackObject::info());
COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
ASSERT(thisObject->Parent::structure()->typeInfo().overridesVisitChildren());
Parent::visitChildren(thisObject, visitor);
@@ -205,13 +205,14 @@ class JSCallbackObject : public Parent {
void init(ExecState*);
static JSCallbackObject* asCallbackObject(JSValue);
+ static JSCallbackObject* asCallbackObject(EncodedJSValue);
static EncodedJSValue JSC_HOST_CALL call(ExecState*);
static EncodedJSValue JSC_HOST_CALL construct(ExecState*);
- JSValue getStaticValue(ExecState*, const Identifier&);
- static JSValue staticFunctionGetter(ExecState*, JSValue, const Identifier&);
- static JSValue callbackGetter(ExecState*, JSValue, const Identifier&);
+ JSValue getStaticValue(ExecState*, PropertyName);
+ static EncodedJSValue staticFunctionGetter(ExecState*, EncodedJSValue, EncodedJSValue, PropertyName);
+ static EncodedJSValue callbackGetter(ExecState*, EncodedJSValue, EncodedJSValue, PropertyName);
OwnPtr m_callbackObjectData;
};
diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h
index b909dde7..5be053f1 100644
--- a/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -45,13 +45,20 @@ namespace JSC {
template
inline JSCallbackObject* JSCallbackObject::asCallbackObject(JSValue value)
{
- ASSERT(asObject(value)->inherits(&s_info));
+ ASSERT(asObject(value)->inherits(info()));
return jsCast(asObject(value));
}
+template
+inline JSCallbackObject* JSCallbackObject::asCallbackObject(EncodedJSValue value)
+{
+ ASSERT(asObject(JSValue::decode(value))->inherits(info()));
+ return jsCast(asObject(JSValue::decode(value)));
+}
+
template
JSCallbackObject::JSCallbackObject(ExecState* exec, Structure* structure, JSClassRef jsClass, void* data)
- : Parent(exec->globalData(), structure)
+ : Parent(exec->vm(), structure)
, m_callbackObjectData(adoptPtr(new JSCallbackObjectData(data, jsClass)))
{
}
@@ -59,8 +66,8 @@ JSCallbackObject::JSCallbackObject(ExecState* exec, Structure* structure
// Global object constructor.
// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
template
-JSCallbackObject::JSCallbackObject(JSGlobalData& globalData, JSClassRef jsClass, Structure* structure)
- : Parent(globalData, structure)
+JSCallbackObject::JSCallbackObject(VM& vm, JSClassRef jsClass, Structure* structure)
+ : Parent(vm, structure)
, m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass)))
{
}
@@ -68,18 +75,18 @@ JSCallbackObject::JSCallbackObject(JSGlobalData& globalData, JSClassRef
template
void JSCallbackObject::finishCreation(ExecState* exec)
{
- Base::finishCreation(exec->globalData());
- ASSERT(Parent::inherits(&s_info));
+ Base::finishCreation(exec->vm());
+ ASSERT(Parent::inherits(info()));
init(exec);
}
// This is just for Global object, so we can assume that Base::finishCreation is JSGlobalObject::finishCreation.
template
-void JSCallbackObject::finishCreation(JSGlobalData& globalData)
+void JSCallbackObject::finishCreation(VM& vm)
{
- ASSERT(Parent::inherits(&s_info));
+ ASSERT(Parent::inherits(info()));
ASSERT(Parent::isGlobalObject());
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
init(jsCast(this)->globalExec());
}
@@ -111,10 +118,10 @@ void JSCallbackObject::init(ExecState* exec)
}
template
-UString JSCallbackObject::className(const JSObject* object)
+String JSCallbackObject::className(const JSObject* object)
{
const JSCallbackObject* thisObject = jsCast(object);
- UString thisClassName = thisObject->classRef()->className();
+ String thisClassName = thisObject->classRef()->className();
if (!thisClassName.isEmpty())
return thisClassName;
@@ -122,64 +129,72 @@ UString JSCallbackObject::className(const JSObject* object)
}
template
-bool JSCallbackObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool JSCallbackObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
- JSCallbackObject* thisObject = jsCast(cell);
+ JSCallbackObject* thisObject = jsCast(object);
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(thisObject);
RefPtr propertyNameRef;
- for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
- // optional optimization to bypass getProperty in cases when we only need to know if the property exists
- if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.ustring());
- APICallbackShim callbackShim(exec);
- if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
- slot.setCustom(thisObject, callbackGetter);
- return true;
- }
- } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.ustring());
- JSValueRef exception = 0;
- JSValueRef value;
- {
+ if (StringImpl* name = propertyName.publicName()) {
+ for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
+ // optional optimization to bypass getProperty in cases when we only need to know if the property exists
+ if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
+ if (!propertyNameRef)
+ propertyNameRef = OpaqueJSString::create(name);
APICallbackShim callbackShim(exec);
- value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
- }
- if (exception) {
- throwError(exec, toJS(exec, exception));
- slot.setValue(jsUndefined());
- return true;
- }
- if (value) {
- slot.setValue(toJS(exec, value));
- return true;
- }
- }
-
- if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
- if (staticValues->contains(propertyName.impl())) {
- JSValue value = thisObject->getStaticValue(exec, propertyName);
+ if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
+ slot.setCustom(thisObject, ReadOnly | DontEnum, callbackGetter);
+ return true;
+ }
+ } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
+ if (!propertyNameRef)
+ propertyNameRef = OpaqueJSString::create(name);
+ JSValueRef exception = 0;
+ JSValueRef value;
+ {
+ APICallbackShim callbackShim(exec);
+ value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+ }
+ if (exception) {
+ exec->vm().throwException(exec, toJS(exec, exception));
+ slot.setValue(thisObject, ReadOnly | DontEnum, jsUndefined());
+ return true;
+ }
if (value) {
- slot.setValue(value);
+ slot.setValue(thisObject, ReadOnly | DontEnum, toJS(exec, value));
return true;
}
}
- }
-
- if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
- if (staticFunctions->contains(propertyName.impl())) {
- slot.setCustom(thisObject, staticFunctionGetter);
- return true;
+
+ if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+ if (staticValues->contains(name)) {
+ JSValue value = thisObject->getStaticValue(exec, propertyName);
+ if (value) {
+ slot.setValue(thisObject, ReadOnly | DontEnum, value);
+ return true;
+ }
+ }
+ }
+
+ if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+ if (staticFunctions->contains(name)) {
+ slot.setCustom(thisObject, ReadOnly | DontEnum, staticFunctionGetter);
+ return true;
+ }
}
}
}
-
+
return Parent::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}
+template
+bool JSCallbackObject::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+ return object->methodTable()->getOwnPropertySlot(object, exec, Identifier::from(exec, propertyName), slot);
+}
+
template
JSValue JSCallbackObject::defaultValue(const JSObject* object, ExecState* exec, PreferredPrimitiveType hint)
{
@@ -193,7 +208,7 @@ JSValue JSCallbackObject::defaultValue(const JSObject* object, ExecState
JSValueRef exception = 0;
JSValueRef result = convertToType(ctx, thisRef, jsHint, &exception);
if (exception) {
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return jsUndefined();
}
if (result)
@@ -205,38 +220,78 @@ JSValue JSCallbackObject::defaultValue(const JSObject* object, ExecState
}
template
-bool JSCallbackObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+void JSCallbackObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
- JSCallbackObject* thisObject = jsCast(object);
- PropertySlot slot;
- if (thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
- // Ideally we should return an access descriptor, but returning a value descriptor is better than nothing.
- JSValue value = slot.getValue(exec, propertyName);
- if (!exec->hadException())
- descriptor.setValue(value);
- // We don't know whether the property is configurable, but assume it is.
- descriptor.setConfigurable(true);
- // We don't know whether the property is enumerable (we could call getOwnPropertyNames() to find out), but assume it isn't.
- descriptor.setEnumerable(false);
- return true;
+ JSCallbackObject* thisObject = jsCast(cell);
+ JSContextRef ctx = toRef(exec);
+ JSObjectRef thisRef = toRef(thisObject);
+ RefPtr propertyNameRef;
+ JSValueRef valueRef = toRef(exec, value);
+
+ if (StringImpl* name = propertyName.publicName()) {
+ for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
+ if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
+ if (!propertyNameRef)
+ propertyNameRef = OpaqueJSString::create(name);
+ JSValueRef exception = 0;
+ bool result;
+ {
+ APICallbackShim callbackShim(exec);
+ result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ }
+ if (exception)
+ exec->vm().throwException(exec, toJS(exec, exception));
+ if (result || exception)
+ return;
+ }
+
+ if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+ if (StaticValueEntry* entry = staticValues->get(name)) {
+ if (entry->attributes & kJSPropertyAttributeReadOnly)
+ return;
+ if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
+ JSValueRef exception = 0;
+ bool result;
+ {
+ APICallbackShim callbackShim(exec);
+ result = setProperty(ctx, thisRef, entry->propertyNameRef.get(), valueRef, &exception);
+ }
+ if (exception)
+ exec->vm().throwException(exec, toJS(exec, exception));
+ if (result || exception)
+ return;
+ }
+ }
+ }
+
+ if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+ if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+ if (entry->attributes & kJSPropertyAttributeReadOnly)
+ return;
+ thisObject->JSCallbackObject::putDirect(exec->vm(), propertyName, value); // put as override property
+ return;
+ }
+ }
+ }
}
- return Parent::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
+ return Parent::put(thisObject, exec, propertyName, value, slot);
}
template
-void JSCallbackObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+void JSCallbackObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyIndex, JSValue value, bool shouldThrow)
{
JSCallbackObject* thisObject = jsCast(cell);
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(thisObject);
RefPtr propertyNameRef;
JSValueRef valueRef = toRef(exec, value);
-
+ Identifier propertyName = Identifier::from(exec, propertyIndex);
+
for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+ propertyNameRef = OpaqueJSString::create(propertyName.impl());
JSValueRef exception = 0;
bool result;
{
@@ -244,86 +299,85 @@ void JSCallbackObject::put(JSCell* cell, ExecState* exec, const Identifi
result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
-
+
if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
if (entry->attributes & kJSPropertyAttributeReadOnly)
return;
if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSValueRef exception = 0;
bool result;
{
APICallbackShim callbackShim(exec);
- result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ result = setProperty(ctx, thisRef, entry->propertyNameRef.get(), valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
if (result || exception)
return;
}
}
}
-
+
if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
if (entry->attributes & kJSPropertyAttributeReadOnly)
return;
- thisObject->JSCallbackObject::putDirect(exec->globalData(), propertyName, value); // put as override property
- return;
+ break;
}
}
}
-
- return Parent::put(thisObject, exec, propertyName, value, slot);
+
+ return Parent::putByIndex(thisObject, exec, propertyIndex, value, shouldThrow);
}
template
-bool JSCallbackObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
+bool JSCallbackObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
{
JSCallbackObject* thisObject = jsCast(cell);
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(thisObject);
RefPtr propertyNameRef;
- for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
- if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.ustring());
- JSValueRef exception = 0;
- bool result;
- {
- APICallbackShim callbackShim(exec);
- result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+ if (StringImpl* name = propertyName.publicName()) {
+ for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
+ if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
+ if (!propertyNameRef)
+ propertyNameRef = OpaqueJSString::create(name);
+ JSValueRef exception = 0;
+ bool result;
+ {
+ APICallbackShim callbackShim(exec);
+ result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+ }
+ if (exception)
+ exec->vm().throwException(exec, toJS(exec, exception));
+ if (result || exception)
+ return true;
}
- if (exception)
- throwError(exec, toJS(exec, exception));
- if (result || exception)
- return true;
- }
-
- if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
- if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
- if (entry->attributes & kJSPropertyAttributeDontDelete)
- return false;
- return true;
+
+ if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+ if (StaticValueEntry* entry = staticValues->get(name)) {
+ if (entry->attributes & kJSPropertyAttributeDontDelete)
+ return false;
+ return true;
+ }
}
- }
-
- if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
- if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
- if (entry->attributes & kJSPropertyAttributeDontDelete)
- return false;
- return true;
+
+ if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+ if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+ if (entry->attributes & kJSPropertyAttributeDontDelete)
+ return false;
+ return true;
+ }
}
}
}
-
+
return Parent::deleteProperty(thisObject, exec, propertyName);
}
@@ -356,10 +410,11 @@ EncodedJSValue JSCallbackObject::construct(ExecState* exec)
for (JSClassRef jsClass = jsCast*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
- int argumentCount = static_cast(exec->argumentCount());
- Vector arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
+ size_t argumentCount = exec->argumentCount();
+ Vector arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
JSValueRef exception = 0;
JSObject* result;
{
@@ -367,17 +422,17 @@ EncodedJSValue JSCallbackObject::construct(ExecState* exec)
result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return JSValue::encode(result);
}
}
- ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here
+ RELEASE_ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here
return JSValue::encode(JSValue());
}
template
-bool JSCallbackObject::hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue)
+bool JSCallbackObject::customHasInstance(JSObject* object, ExecState* exec, JSValue value)
{
JSCallbackObject* thisObject = jsCast(object);
JSContextRef execRef = toRef(exec);
@@ -393,7 +448,7 @@ bool JSCallbackObject::hasInstance(JSObject* object, ExecState* exec, JS
result = hasInstance(execRef, thisRef, valueRef, &exception);
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return result;
}
}
@@ -418,14 +473,15 @@ EncodedJSValue JSCallbackObject::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
- JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
+ JSObjectRef thisObjRef = toRef(jsCast(exec->hostThisValue().toThis(exec, NotStrictMode)));
for (JSClassRef jsClass = jsCast*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
- int argumentCount = static_cast(exec->argumentCount());
- Vector arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
+ size_t argumentCount = exec->argumentCount();
+ Vector arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
JSValueRef exception = 0;
JSValue result;
{
@@ -433,17 +489,17 @@ EncodedJSValue JSCallbackObject::call(ExecState* exec)
result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
}
if (exception)
- throwError(exec, toJS(exec, exception));
+ exec->vm().throwException(exec, toJS(exec, exception));
return JSValue::encode(result);
}
}
- ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
+ RELEASE_ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
return JSValue::encode(JSValue());
}
template
-void JSCallbackObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+void JSCallbackObject::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
JSCallbackObject* thisObject = jsCast(object);
JSContextRef execRef = toRef(exec);
@@ -459,8 +515,8 @@ void JSCallbackObject::getOwnPropertyNames(JSObject* object, ExecState*
typedef OpaqueJSClassStaticValuesTable::const_iterator iterator;
iterator end = staticValues->end();
for (iterator it = staticValues->begin(); it != end; ++it) {
- StringImpl* name = it->first.get();
- StaticValueEntry* entry = it->second.get();
+ StringImpl* name = it->key.get();
+ StaticValueEntry* entry = it->value.get();
if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))
propertyNames.add(Identifier(exec, name));
}
@@ -470,15 +526,15 @@ void JSCallbackObject::getOwnPropertyNames(JSObject* object, ExecState*
typedef OpaqueJSClassStaticFunctionsTable::const_iterator iterator;
iterator end = staticFunctions->end();
for (iterator it = staticFunctions->begin(); it != end; ++it) {
- StringImpl* name = it->first.get();
- StaticFunctionEntry* entry = it->second.get();
+ StringImpl* name = it->key.get();
+ StaticFunctionEntry* entry = it->value.get();
if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))
propertyNames.add(Identifier(exec, name));
}
}
}
- Parent::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
+ Parent::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
}
template
@@ -496,95 +552,102 @@ void* JSCallbackObject::getPrivate()
template
bool JSCallbackObject::inherits(JSClassRef c) const
{
- for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
+ for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
if (jsClass == c)
return true;
-
+ }
return false;
}
template
-JSValue JSCallbackObject::getStaticValue(ExecState* exec, const Identifier& propertyName)
+JSValue JSCallbackObject::getStaticValue(ExecState* exec, PropertyName propertyName)
{
JSObjectRef thisRef = toRef(this);
- RefPtr propertyNameRef;
- for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
- if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec))
- if (StaticValueEntry* entry = staticValues->get(propertyName.impl()))
- if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.ustring());
- JSValueRef exception = 0;
- JSValueRef value;
- {
- APICallbackShim callbackShim(exec);
- value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
- }
- if (exception) {
- throwError(exec, toJS(exec, exception));
- return jsUndefined();
+ if (StringImpl* name = propertyName.publicName()) {
+ for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
+ if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+ if (StaticValueEntry* entry = staticValues->get(name)) {
+ if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
+ JSValueRef exception = 0;
+ JSValueRef value;
+ {
+ APICallbackShim callbackShim(exec);
+ value = getProperty(toRef(exec), thisRef, entry->propertyNameRef.get(), &exception);
+ }
+ if (exception) {
+ exec->vm().throwException(exec, toJS(exec, exception));
+ return jsUndefined();
+ }
+ if (value)
+ return toJS(exec, value);
}
- if (value)
- return toJS(exec, value);
}
+ }
+ }
+ }
return JSValue();
}
template
-JSValue JSCallbackObject::staticFunctionGetter(ExecState* exec, JSValue slotParent, const Identifier& propertyName)
+EncodedJSValue JSCallbackObject::staticFunctionGetter(ExecState* exec, EncodedJSValue slotParent, EncodedJSValue, PropertyName propertyName)
{
JSCallbackObject* thisObj = asCallbackObject(slotParent);
// Check for cached or override property.
PropertySlot slot2(thisObj);
if (Parent::getOwnPropertySlot(thisObj, exec, propertyName, slot2))
- return slot2.getValue(exec, propertyName);
-
- for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
- if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
- if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
- if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
-
- JSObject* o = JSCallbackFunction::create(exec, thisObj->globalObject(), callAsFunction, propertyName);
- thisObj->putDirect(exec->globalData(), propertyName, o, entry->attributes);
- return o;
+ return JSValue::encode(slot2.getValue(exec, propertyName));
+
+ if (StringImpl* name = propertyName.publicName()) {
+ for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
+ if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+ if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+ if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
+ VM& vm = exec->vm();
+ JSObject* o = JSCallbackFunction::create(vm, thisObj->globalObject(), callAsFunction, name);
+ thisObj->putDirect(vm, propertyName, o, entry->attributes);
+ return JSValue::encode(o);
+ }
}
}
}
}
-
- return throwError(exec, createReferenceError(exec, "Static function property defined with NULL callAsFunction callback."));
+
+ return JSValue::encode(exec->vm().throwException(exec, createReferenceError(exec, ASCIILiteral("Static function property defined with NULL callAsFunction callback."))));
}
template
-JSValue JSCallbackObject::callbackGetter(ExecState* exec, JSValue slotParent, const Identifier& propertyName)
+EncodedJSValue JSCallbackObject::callbackGetter(ExecState* exec, EncodedJSValue slotParent, EncodedJSValue, PropertyName propertyName)
{
JSCallbackObject* thisObj = asCallbackObject(slotParent);
JSObjectRef thisRef = toRef(thisObj);
RefPtr propertyNameRef;
- for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass)
- if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
- if (!propertyNameRef)
- propertyNameRef = OpaqueJSString::create(propertyName.ustring());
- JSValueRef exception = 0;
- JSValueRef value;
- {
- APICallbackShim callbackShim(exec);
- value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
- }
- if (exception) {
- throwError(exec, toJS(exec, exception));
- return jsUndefined();
+ if (StringImpl* name = propertyName.publicName()) {
+ for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
+ if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
+ if (!propertyNameRef)
+ propertyNameRef = OpaqueJSString::create(name);
+ JSValueRef exception = 0;
+ JSValueRef value;
+ {
+ APICallbackShim callbackShim(exec);
+ value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+ }
+ if (exception) {
+ exec->vm().throwException(exec, toJS(exec, exception));
+ return JSValue::encode(jsUndefined());
+ }
+ if (value)
+ return JSValue::encode(toJS(exec, value));
}
- if (value)
- return toJS(exec, value);
}
-
- return throwError(exec, createReferenceError(exec, "hasProperty callback returned true for a property that doesn't exist."));
+ }
+
+ return JSValue::encode(exec->vm().throwException(exec, createReferenceError(exec, ASCIILiteral("hasProperty callback returned true for a property that doesn't exist."))));
}
} // namespace JSC
diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp
index 08fa5c5e..544c359b 100644
--- a/JavaScriptCore/API/JSClassRef.cpp
+++ b/JavaScriptCore/API/JSClassRef.cpp
@@ -27,12 +27,13 @@
#include "JSClassRef.h"
#include "APICast.h"
+#include "Identifier.h"
+#include "InitializeThreading.h"
#include "JSCallbackObject.h"
+#include "JSGlobalObject.h"
#include "JSObjectRef.h"
-#include
-#include
-#include
-#include
+#include "ObjectPrototype.h"
+#include "Operations.h"
#include
#include
@@ -42,20 +43,6 @@ using namespace WTF::Unicode;
const JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-static inline UString tryCreateStringFromUTF8(const char* string)
-{
- if (!string)
- return UString();
-
- size_t length = strlen(string);
- Vector buffer(length);
- UChar* p = buffer.data();
- if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
- return UString();
-
- return UString(buffer.data(), p - buffer.data());
-}
-
OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* protoClass)
: parentClass(definition->parentClass)
, prototypeClass(0)
@@ -70,16 +57,16 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
, callAsConstructor(definition->callAsConstructor)
, hasInstance(definition->hasInstance)
, convertToType(definition->convertToType)
- , m_className(tryCreateStringFromUTF8(definition->className))
+ , m_className(String::fromUTF8(definition->className))
{
initializeThreading();
if (const JSStaticValue* staticValue = definition->staticValues) {
m_staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable);
while (staticValue->name) {
- UString valueName = tryCreateStringFromUTF8(staticValue->name);
+ String valueName = String::fromUTF8(staticValue->name);
if (!valueName.isNull())
- m_staticValues->set(valueName.impl(), adoptPtr(new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes)));
+ m_staticValues->set(valueName.impl(), std::make_unique(staticValue->getProperty, staticValue->setProperty, staticValue->attributes, valueName));
++staticValue;
}
}
@@ -87,9 +74,9 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
if (const JSStaticFunction* staticFunction = definition->staticFunctions) {
m_staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable);
while (staticFunction->name) {
- UString functionName = tryCreateStringFromUTF8(staticFunction->name);
+ String functionName = String::fromUTF8(staticFunction->name);
if (!functionName.isNull())
- m_staticFunctions->set(functionName.impl(), adoptPtr(new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes)));
+ m_staticFunctions->set(functionName.impl(), std::make_unique(staticFunction->callAsFunction, staticFunction->attributes));
++staticFunction;
}
}
@@ -107,13 +94,13 @@ OpaqueJSClass::~OpaqueJSClass()
if (m_staticValues) {
OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end();
for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it)
- ASSERT(!it->first->isIdentifier());
+ ASSERT(!it->key->isIdentifier());
}
if (m_staticFunctions) {
OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end();
for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it)
- ASSERT(!it->first->isIdentifier());
+ ASSERT(!it->key->isIdentifier());
}
#endif
@@ -140,40 +127,41 @@ PassRefPtr OpaqueJSClass::create(const JSClassDefinition* clientD
return adoptRef(new OpaqueJSClass(&definition, protoClass.get()));
}
-OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSClass* jsClass)
+OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass* jsClass)
: m_class(jsClass)
{
if (jsClass->m_staticValues) {
- staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable);
+ staticValues = std::make_unique();
OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end();
for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) {
- ASSERT(!it->first->isIdentifier());
- staticValues->add(StringImpl::create(it->first->characters(), it->first->length()), adoptPtr(new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes)));
+ ASSERT(!it->key->isIdentifier());
+ String valueName = it->key->isolatedCopy();
+ staticValues->add(valueName.impl(), std::make_unique(it->value->getProperty, it->value->setProperty, it->value->attributes, valueName));
}
}
if (jsClass->m_staticFunctions) {
- staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable);
+ staticFunctions = std::make_unique();
OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end();
for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) {
- ASSERT(!it->first->isIdentifier());
- staticFunctions->add(StringImpl::create(it->first->characters(), it->first->length()), adoptPtr(new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes)));
+ ASSERT(!it->key->isIdentifier());
+ staticFunctions->add(it->key->isolatedCopy(), std::make_unique(it->value->callAsFunction, it->value->attributes));
}
}
}
OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec)
{
- OwnPtr& contextData = exec->globalData().opaqueJSClassData.add(this, nullptr).iterator->second;
+ std::unique_ptr& contextData = exec->lexicalGlobalObject()->opaqueJSClassData().add(this, nullptr).iterator->value;
if (!contextData)
- contextData = adoptPtr(new OpaqueJSClassContextData(exec->globalData(), this));
+ contextData = std::make_unique(exec->vm(), this);
return *contextData;
}
-UString OpaqueJSClass::className()
+String OpaqueJSClass::className()
{
// Make a deep copy, so that the caller has no chance to put the original into IdentifierTable.
- return UString(m_className.characters(), m_className.length());
+ return m_className.isolatedCopy();
}
OpaqueJSClassStaticValuesTable* OpaqueJSClass::staticValues(JSC::ExecState* exec)
@@ -209,13 +197,16 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec)
OpaqueJSClassContextData& jsClassData = contextData(exec);
- if (!jsClassData.cachedPrototype) {
- // Recursive, but should be good enough for our purposes
- jsClassData.cachedPrototype = PassWeak(JSCallbackObject::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData), 0); // set jsClassData as the object's private data, so it can clear our reference on destruction
- if (parentClass) {
- if (JSObject* prototype = parentClass->prototype(exec))
- jsClassData.cachedPrototype->setPrototype(exec->globalData(), prototype);
- }
+ if (JSObject* prototype = jsClassData.cachedPrototype.get())
+ return prototype;
+
+ // Recursive, but should be good enough for our purposes
+ JSObject* prototype = JSCallbackObject::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData); // set jsClassData as the object's private data, so it can clear our reference on destruction
+ if (parentClass) {
+ if (JSObject* parentPrototype = parentClass->prototype(exec))
+ prototype->setPrototype(exec->vm(), parentPrototype);
}
- return jsClassData.cachedPrototype.get();
+
+ jsClassData.cachedPrototype = Weak(prototype);
+ return prototype;
}
diff --git a/JavaScriptCore/API/JSClassRef.h b/JavaScriptCore/API/JSClassRef.h
index 82c7ab3f..f979f3b2 100644
--- a/JavaScriptCore/API/JSClassRef.h
+++ b/JavaScriptCore/API/JSClassRef.h
@@ -26,25 +26,25 @@
#ifndef JSClassRef_h
#define JSClassRef_h
-#include "JSObjectRef.h"
-
-#include "Weak.h"
-#include "JSObject.h"
+#include "OpaqueJSString.h"
#include "Protect.h"
-#include "UString.h"
+#include "Weak.h"
+#include
#include
+#include
struct StaticValueEntry {
WTF_MAKE_FAST_ALLOCATED;
public:
- StaticValueEntry(JSObjectGetPropertyCallback _getProperty, JSObjectSetPropertyCallback _setProperty, JSPropertyAttributes _attributes)
- : getProperty(_getProperty), setProperty(_setProperty), attributes(_attributes)
+ StaticValueEntry(JSObjectGetPropertyCallback _getProperty, JSObjectSetPropertyCallback _setProperty, JSPropertyAttributes _attributes, String& propertyName)
+ : getProperty(_getProperty), setProperty(_setProperty), attributes(_attributes), propertyNameRef(OpaqueJSString::create(propertyName))
{
}
JSObjectGetPropertyCallback getProperty;
JSObjectSetPropertyCallback setProperty;
JSPropertyAttributes attributes;
+ RefPtr propertyNameRef;
};
struct StaticFunctionEntry {
@@ -59,8 +59,8 @@ struct StaticFunctionEntry {
JSPropertyAttributes attributes;
};
-typedef HashMap, OwnPtr > OpaqueJSClassStaticValuesTable;
-typedef HashMap, OwnPtr > OpaqueJSClassStaticFunctionsTable;
+typedef HashMap, std::unique_ptr> OpaqueJSClassStaticValuesTable;
+typedef HashMap, std::unique_ptr> OpaqueJSClassStaticFunctionsTable;
struct OpaqueJSClass;
@@ -69,27 +69,27 @@ struct OpaqueJSClass;
struct OpaqueJSClassContextData {
WTF_MAKE_NONCOPYABLE(OpaqueJSClassContextData); WTF_MAKE_FAST_ALLOCATED;
public:
- OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSClass*);
+ OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass*);
// It is necessary to keep OpaqueJSClass alive because of the following rare scenario:
- // 1. A class is created and used, so its context data is stored in JSGlobalData hash map.
+ // 1. A class is created and used, so its context data is stored in VM hash map.
// 2. The class is released, and when all JS objects that use it are collected, OpaqueJSClass
// is deleted (that's the part prevented by this RefPtr).
// 3. Another class is created at the same address.
- // 4. When it is used, the old context data is found in JSGlobalData and used.
+ // 4. When it is used, the old context data is found in VM and used.
RefPtr m_class;
- OwnPtr staticValues;
- OwnPtr staticFunctions;
+ std::unique_ptr staticValues;
+ std::unique_ptr