예제 #1
0
TiGlobalContextRef TiContextGetGlobalContext(TiContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    return toGlobalRef(exec->lexicalGlobalObject()->globalExec());
}
예제 #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());
}
예제 #3
0
TiObjectRef TiContextGetGlobalObject(TiContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    // It is necessary to call toThisObject to get the wrapper object when used with WebCore.
    return toRef(exec->lexicalGlobalObject()->toThisObject(exec));
}
예제 #4
0
void JSReportExtraMemoryCost(TiContextRef ctx, size_t size)
{
    TiExcState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    TiLock lock(exec);

    exec->globalData().heap.reportExtraMemoryCost(size);
}
예제 #5
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);
}
예제 #6
0
TiGlobalContextRef TiGlobalContextRetain(TiGlobalContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiGlobalData& globalData = exec->globalData();
    gcProtect(exec->dynamicGlobalObject());
    globalData.ref();
    return ctx;
}
예제 #7
0
TiStringRef TiContextCreateBacktrace(TiContextRef ctx, unsigned maxStackSize)
{
    TiExcState* exec = toJS(ctx);
    TiLock lock(exec);

    unsigned count = 0;
    UStringBuilder builder;
    CallFrame* callFrame = exec;
    UString functionName;
    if (exec->callee()) {
        if (asObject(exec->callee())->inherits(&InternalFunction::s_info)) {
            functionName = asInternalFunction(exec->callee())->name(exec);
            builder.append("#0 ");
            builder.append(functionName);
            builder.append("() ");
            count++;
        }
    }
    while (true) {
        ASSERT(callFrame);
        int signedLineNumber;
        intptr_t sourceID;
        UString urlString;
        TiValue function;
        
        UString levelStr = UString::number(count);
        
        exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function);

        if (function)
            functionName = asFunction(function)->name(exec);
        else {
            // Caller is unknown, but if frame is empty we should still add the frame, because
            // something called us, and gave us arguments.
            if (count)
                break;
        }
        unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0;
        if (!builder.isEmpty())
            builder.append("\n");
        builder.append("#");
        builder.append(levelStr);
        builder.append(" ");
        builder.append(functionName);
        builder.append("() at ");
        builder.append(urlString);
        builder.append(":");
        builder.append(UString::number(lineNumber));
        if (!function || ++count == maxStackSize)
            break;
        callFrame = callFrame->callerFrame();
    }
    return OpaqueTiString::create(builder.toUString()).leakRef();
}
예제 #8
0
TiObjectRef TiValueToObject(TiContextRef ctx, TiValueRef value, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiValue jsValue = toJS(exec, value);
    
    TiObjectRef objectRef = toRef(jsValue.toObject(exec));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
        objectRef = 0;
    }
    return objectRef;
}    
예제 #9
0
TiStringRef TiValueToStringCopy(TiContextRef ctx, TiValueRef value, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiValue jsValue = toJS(exec, value);
    
    RefPtr<OpaqueTiString> stringRef(OpaqueTiString::create(jsValue.toString(exec)));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
        stringRef.clear();
    }
    return stringRef.release().releaseRef();
}
예제 #10
0
double TiValueToNumber(TiContextRef ctx, TiValueRef value, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiValue jsValue = toJS(exec, value);

    double number = jsValue.toNumber(exec);
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
        number = NaN;
    }
    return number;
}
예제 #11
0
TiStringRef TiValueCreateJSONString(TiContextRef ctx, TiValueRef apiValue, unsigned indent, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);
    TiValue value = toJS(exec, apiValue);
    UString result = JSONStringify(exec, value, indent);
    if (exception)
        *exception = 0;
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
        return 0;
    }
    return OpaqueTiString::create(result).releaseRef();
}
예제 #12
0
bool TiValueIsEqual(TiContextRef ctx, TiValueRef a, TiValueRef b, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiValue jsA = toJS(exec, a);
    TiValue jsB = toJS(exec, b);

    bool result = TiValue::equal(exec, jsA, jsB); // false if an exception is thrown
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
    }
    return result;
}
예제 #13
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;
}
예제 #14
0
bool TiValueIsInstanceOfConstructor(TiContextRef ctx, TiValueRef value, TiObjectRef constructor, TiValueRef* exception)
{
    TiExcState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    TiValue jsValue = toJS(exec, value);

    TiObject* jsConstructor = toJS(constructor);
    if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
        return false;
    bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
    }
    return result;
}
예제 #15
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.
}
예제 #16
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);
}
예제 #17
0
TiContextGroupRef TiContextGetGroup(TiContextRef ctx)
{
    TiExcState* exec = toJS(ctx);
    return toRef(&exec->globalData());
}