X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/b37bf2e156556c589aea3e1f58a377f2b1189665..9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73:/API/JSContextRef.cpp?ds=sidebyside diff --git a/API/JSContextRef.cpp b/API/JSContextRef.cpp index 203326e..c331179 100644 --- a/API/JSContextRef.cpp +++ b/API/JSContextRef.cpp @@ -1,4 +1,3 @@ -// -*- mode: c++; c-basic-offset: 4 -*- /* * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * @@ -28,49 +27,128 @@ #include "JSContextRef.h" #include "APICast.h" +#include "InitializeThreading.h" #include "JSCallbackObject.h" #include "JSClassRef.h" #include "JSGlobalObject.h" -#include "object.h" +#include "JSObject.h" #include -using namespace KJS; +#if PLATFORM(DARWIN) +#include + +static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500; // 528.5.0 +#endif + +using namespace JSC; + +JSContextGroupRef JSContextGroupCreate() +{ + initializeThreading(); + return toRef(JSGlobalData::create().releaseRef()); +} + +JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) +{ + toJS(group)->ref(); + return group; +} + +void JSContextGroupRelease(JSContextGroupRef group) +{ + toJS(group)->deref(); +} JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) { - JSLock lock; + initializeThreading(); +#if PLATFORM(DARWIN) + // When running on Tiger or Leopard, or if the application was linked before JSGlobalContextCreate was changed + // to use a unique JSGlobalData, we use a shared one for compatibility. +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + if (NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitFirstVersionWithConcurrentGlobalContexts) { +#else + { +#endif + JSLock lock(true); + return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass); + } +#endif // PLATFORM(DARWIN) + + return JSGlobalContextCreateInGroup(0, globalObjectClass); +} + +JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) +{ + initializeThreading(); + + JSLock lock(true); + + RefPtr globalData = group ? PassRefPtr(toJS(group)) : JSGlobalData::create(); + +#if ENABLE(JSC_MULTIPLE_THREADS) + globalData->makeUsableFromMultipleThreads(); +#endif if (!globalObjectClass) { - JSGlobalObject* globalObject = new JSGlobalObject; + JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject; return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec())); } - JSGlobalObject* globalObject = new JSCallbackObject(globalObjectClass); - JSGlobalContextRef ctx = toGlobalRef(globalObject->globalExec()); - JSValue* prototype = globalObjectClass->prototype(ctx); + JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject(globalObjectClass); + ExecState* exec = globalObject->globalExec(); + JSValuePtr prototype = globalObjectClass->prototype(exec); if (!prototype) prototype = jsNull(); - globalObject->reset(prototype); - return JSGlobalContextRetain(ctx); + globalObject->resetPrototype(prototype); + return JSGlobalContextRetain(toGlobalRef(exec)); } JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx) { - JSLock lock; ExecState* exec = toJS(ctx); + JSLock lock(exec); + + JSGlobalData& globalData = exec->globalData(); + + globalData.heap.registerThread(); + gcProtect(exec->dynamicGlobalObject()); + globalData.ref(); return ctx; } void JSGlobalContextRelease(JSGlobalContextRef ctx) { - JSLock lock; ExecState* exec = toJS(ctx); + JSLock lock(exec); + gcUnprotect(exec->dynamicGlobalObject()); + + JSGlobalData& globalData = exec->globalData(); + if (globalData.refCount() == 2) { // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). + // The last reference was released, this is our last chance to collect. + ASSERT(!globalData.heap.protectedObjectCount()); + ASSERT(!globalData.heap.isBusy()); + globalData.heap.destroy(); + } else + globalData.heap.collect(); + + globalData.deref(); } JSObjectRef JSContextGetGlobalObject(JSContextRef ctx) { ExecState* exec = toJS(ctx); - return toRef(exec->dynamicGlobalObject()); + exec->globalData().heap.registerThread(); + JSLock lock(exec); + + // It is necessary to call toThisObject to get the wrapper object when used with WebCore. + return toRef(exec->lexicalGlobalObject()->toThisObject(exec)); +} + +JSContextGroupRef JSContextGetGroup(JSContextRef ctx) +{ + ExecState* exec = toJS(ctx); + return toRef(&exec->globalData()); }