JSContextRef.cpp 4.29 KB
Newer Older
ggaren's avatar
ggaren committed
1
/*
darin@apple.com's avatar
darin@apple.com committed
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
ggaren's avatar
ggaren committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * 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 COMPUTER, 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 COMPUTER, 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. 
 */

darin@apple.com's avatar
darin@apple.com committed
26 27 28
#include "config.h"
#include "JSContextRef.h"

ggaren's avatar
ggaren committed
29
#include "APICast.h"
ap@webkit.org's avatar
ap@webkit.org committed
30
#include "InitializeThreading.h"
ggaren's avatar
ggaren committed
31
#include "JSCallbackObject.h"
32
#include "JSClassRef.h"
33
#include "JSGlobalObject.h"
darin@apple.com's avatar
darin@apple.com committed
34
#include "JSObject.h"
ggaren@apple.com's avatar
ggaren@apple.com committed
35
#include <wtf/Platform.h>
ggaren's avatar
ggaren committed
36

37
using namespace JSC;
ggaren's avatar
ggaren committed
38

ap@webkit.org's avatar
ap@webkit.org committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
JSContextGroupRef JSContextGroupCreate()
{
    return toRef(JSGlobalData::create().releaseRef());
}

JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
{
    toJS(group)->ref();
    return group;
}

void JSContextGroupRelease(JSContextGroupRef group)
{
    toJS(group)->deref();
}

ggaren's avatar
ggaren committed
55
JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
ap@webkit.org's avatar
ap@webkit.org committed
56
{
ap@webkit.org's avatar
ap@webkit.org committed
57 58
    JSLock lock(true);
    return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass);
ap@webkit.org's avatar
ap@webkit.org committed
59 60 61
}

JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass)
ggaren's avatar
ggaren committed
62
{
ap@webkit.org's avatar
ap@webkit.org committed
63 64
    initializeThreading();

ap@webkit.org's avatar
ap@webkit.org committed
65 66 67
    JSLock lock(true);

    RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::create();
ap@webkit.org's avatar
ap@webkit.org committed
68

ggaren@apple.com's avatar
ggaren@apple.com committed
69
    if (!globalObjectClass) {
weinig@apple.com's avatar
weinig@apple.com committed
70
        JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject(globalData.get());
ggaren@apple.com's avatar
ggaren@apple.com committed
71 72
        return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
    }
ggaren's avatar
ggaren committed
73

weinig@apple.com's avatar
weinig@apple.com committed
74
    JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalData.get(), globalObjectClass);
ap@webkit.org's avatar
ap@webkit.org committed
75 76
    ExecState* exec = globalObject->globalExec();
    JSValue* prototype = globalObjectClass->prototype(exec);
ggaren@apple.com's avatar
ggaren@apple.com committed
77 78
    if (!prototype)
        prototype = jsNull();
weinig@apple.com's avatar
weinig@apple.com committed
79
    globalObject->resetPrototype(prototype);
ap@webkit.org's avatar
ap@webkit.org committed
80
    return JSGlobalContextRetain(toGlobalRef(exec));
ggaren's avatar
ggaren committed
81 82
}

mjs's avatar
mjs committed
83
JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
ggaren's avatar
ggaren committed
84
{
mjs's avatar
mjs committed
85
    ExecState* exec = toJS(ctx);
ap@webkit.org's avatar
ap@webkit.org committed
86 87
    JSLock lock(exec);

ap@webkit.org's avatar
ap@webkit.org committed
88 89 90
    JSGlobalData& globalData = exec->globalData();

    globalData.heap->registerThread();
ap@webkit.org's avatar
ap@webkit.org committed
91

ggaren@apple.com's avatar
ggaren@apple.com committed
92
    gcProtect(exec->dynamicGlobalObject());
ap@webkit.org's avatar
ap@webkit.org committed
93
    globalData.ref();
mjs's avatar
mjs committed
94
    return ctx;
ggaren's avatar
ggaren committed
95 96
}

mjs's avatar
mjs committed
97
void JSGlobalContextRelease(JSGlobalContextRef ctx)
ggaren's avatar
ggaren committed
98
{
mjs's avatar
mjs committed
99
    ExecState* exec = toJS(ctx);
ap@webkit.org's avatar
ap@webkit.org committed
100
    JSLock lock(exec);
ap@webkit.org's avatar
ap@webkit.org committed
101

ggaren@apple.com's avatar
ggaren@apple.com committed
102
    gcUnprotect(exec->dynamicGlobalObject());
ap@webkit.org's avatar
ap@webkit.org committed
103 104

    JSGlobalData& globalData = exec->globalData();
ap@webkit.org's avatar
ap@webkit.org committed
105
    if (globalData.refCount() == 2) { // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain().
ap@webkit.org's avatar
ap@webkit.org committed
106 107 108 109 110 111 112
        // The last reference was released, this is our last chance to collect.
        Heap* heap = globalData.heap;

        ASSERT(!heap->protectedObjectCount());
        ASSERT(!heap->isBusy());

        delete heap;
ap@webkit.org's avatar
ap@webkit.org committed
113
        globalData.heap = 0;
ap@webkit.org's avatar
ap@webkit.org committed
114 115
    } else
        globalData.heap->collect();
ap@webkit.org's avatar
ap@webkit.org committed
116 117

    globalData.deref();
ggaren's avatar
ggaren committed
118 119
}

mjs's avatar
mjs committed
120
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
ggaren's avatar
ggaren committed
121
{
mjs's avatar
mjs committed
122
    ExecState* exec = toJS(ctx);
ap@webkit.org's avatar
ap@webkit.org committed
123
    exec->globalData().heap->registerThread();
ap@webkit.org's avatar
ap@webkit.org committed
124
    JSLock lock(exec);
weinig@apple.com's avatar
weinig@apple.com committed
125 126 127

    // It is necessary to call toThisObject to get the wrapper object when used with WebCore.
    return toRef(exec->dynamicGlobalObject()->toThisObject(exec));
ggaren's avatar
ggaren committed
128
}
ap@webkit.org's avatar
ap@webkit.org committed
129 130 131 132 133 134

JSContextGroupRef JSContextGetGroup(JSContextRef ctx)
{
    ExecState* exec = toJS(ctx);
    return toRef(&exec->globalData());
}