Exemple #1
0
void JSReportExtraMemoryCost(TiContextRef ctx, size_t size)
{
    TiExcState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    TiLock lock(exec);

    exec->globalData().heap.reportExtraMemoryCost(size);
}
Exemple #2
0
TiValueRef TiEvalScript(TiContextRef ctx, TiStringRef script, TiObjectRef thisObject, TiStringRef sourceURL, int startingLineNumber, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    TiLock lock(exec);

    TiObject* jsThisObject = toJS(thisObject);

    // evaluate sets "this" to the global object if it is NULL
    TiGlobalObject* globalObject = exec->dynamicGlobalObject();
    SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber);
    Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject);

    if (completion.complType() == Throw) {
        if (exception)
            *exception = toRef(exec, completion.value());
        return 0;
    }

    if (completion.value())
        return toRef(exec, completion.value());
    
    // happens, for example, when the only statement is an empty (';') statement
    return toRef(exec, jsUndefined());
}
Exemple #3
0
bool TiValueIsDate(TiContextRef ctx, TiValueRef value)
{
    TiExcState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    TiLock lock(exec);
    
    TiValue jsValue = toJS(exec, value);
    return jsValue.inherits(&DateInstance::info);
}
TiGlobalContextRef TiGlobalContextRetain(TiGlobalContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiGlobalData& globalData = exec->globalData();
    gcProtect(exec->dynamicGlobalObject());
    globalData.ref();
    return ctx;
}
Exemple #5
0
bool TiCheckScriptSyntax(TiContextRef ctx, TiStringRef script, TiStringRef sourceURL, int startingLineNumber, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    TiLock lock(exec);

    SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber);
    Completion completion = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source);
    if (completion.complType() == Throw) {
        if (exception)
            *exception = toRef(exec, completion.value());
        return false;
    }
    
    return true;
}
Exemple #6
0
void TiGarbageCollect(TiContextRef ctx)
{
    // We used to recommend passing NULL as an argument here, which caused the only heap to be collected.
    // As there is no longer a shared heap, the previously recommended usage became a no-op (but the GC
    // will happen when the context group is destroyed).
    // Because the function argument was originally ignored, some clients may pass their released context here,
    // in which case there is a risk of crashing if another thread performs GC on the same heap in between.
    if (!ctx)
        return;

    TiExcState* exec = toJS(ctx);
    TiGlobalData& globalData = exec->globalData();

    TiLock lock(globalData.isSharedInstance ? LockForReal : SilenceAssertionsOnly);

    if (!globalData.heap.isBusy())
        globalData.heap.collect();

    // FIXME: Perhaps we should trigger a second mark and sweep
    // once the garbage collector is done if this is called when
    // the collector is busy.
}
void TiGlobalContextRelease(TiGlobalContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    TiLock lock(exec);

    TiGlobalData& globalData = exec->globalData();
    TiGlobalObject* dgo = exec->dynamicGlobalObject();
    IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable);

    // One reference is held by TiGlobalObject, another added by TiGlobalContextRetain().
    bool releasingContextGroup = globalData.refCount() == 2;
    bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo);
    // If this is the last reference to a global data, it should also
    // be the only remaining reference to the global object too!
    ASSERT(!releasingContextGroup || releasingGlobalObject);

    // An API 'TiGlobalContextRef' retains two things - a global object and a
    // global data (or context group, in API terminology).
    // * If this is the last reference to any contexts in the given context group,
    //   call destroy on the heap (the global data is being  freed).
    // * If this was the last reference to the global object, then unprotecting
    //   it may release a lot of GC memory - tickle the activity callback to
    //   garbage collect soon.
    // * If there are more references remaining the the global object, then do nothing
    //   (specifically that is more protects, which we assume come from other TiGlobalContextRefs).
    if (releasingContextGroup) {
        globalData.clearBuiltinStructures();
        globalData.heap.destroy();
    } else if (releasingGlobalObject) {
        globalData.heap.activityCallback()->synchronize();
        (*globalData.heap.activityCallback())();
    }

    globalData.deref();

    wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
}
TiContextGroupRef TiContextGetGroup(TiContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    return toRef(&exec->globalData());
}