예제 #1
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());
}
예제 #2
0
TiGlobalContextRef TiGlobalContextRetain(TiGlobalContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiGlobalData& globalData = exec->globalData();
    gcProtect(exec->dynamicGlobalObject());
    globalData.ref();
    return ctx;
}
예제 #3
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;
}
예제 #4
0
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);
}