bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock 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(completion.value()); return false; } return true; }
bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(&exec->globalData())); if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) { static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name); return true; } if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) { static_cast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->deletePrivateProperty(name); return true; } return false; }
void JSGlobalContextRelease(JSGlobalContextRef ctx) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(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. globalData.heap.destroy(); } else globalData.heap.collectAllGarbage(); globalData.deref(); }
void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSObject* jsObject = toJS(object); JSValuePtr jsValue = toJS(value); jsObject->put(exec, propertyIndex, jsValue); if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); } }
JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); JSValue result; Identifier name(propertyName->identifier(&exec->globalData())); if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name); else if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) result = jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivateProperty(name); #if JSC_OBJC_API_ENABLED else if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) result = jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->getPrivateProperty(name); #endif return toRef(exec, result); }
JSValueRef JSValueMakeNumber(JSContextRef ctx, double value) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); #if 1 // added at webkit.org trunk r64706 // Our JSValue representation relies on a standard bit pattern for NaN. NaNs // generated internally to JavaScriptCore naturally have that representation, // but an external NaN might not. if (isnan(value)) value = NaN; #endif return toRef(exec, jsNumber(exec, value)); }
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSValuePtr jsValue = toJS(value); JSObjectRef objectRef = toRef(jsValue.toObject(exec)); if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); objectRef = 0; } return objectRef; }
double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSValuePtr jsValue = toJS(value); double number = jsValue.toNumber(exec); if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); number = NaN; } return number; }
bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSValuePtr jsA = toJS(a); JSValuePtr jsB = toJS(b); bool result = JSValuePtr::equal(exec, jsA, jsB); // false if an exception is thrown if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); } return result; }
JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSValuePtr jsValue = toJS(value); RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec))); if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); stringRef.clear(); } return stringRef.release().releaseRef(); }
bool OAGlobalObject::garbageCollection() { AJOAGlobalObject *globalObject = wrapper(); if (globalObject) { ExecState *exec = globalObject->globalExec(); s_explicit_gc = true; AJLock lock(exec); AJGlobalData& globalData = exec->globalData(); if (!globalData.heap.isBusy()) { globalData.heap.collectAllGarbage(); s_explicit_gc = false; return true; } } return false; }
bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSValuePtr jsValue = toJS(value); JSObject* 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->exception()); exec->clearException(); } return result; }
void JSGlobalContextRelease(JSGlobalContextRef ctx) { 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(); }
void JSGlobalContextRelease(JSGlobalContextRef ctx) { IdentifierTable* savedIdentifierTable; ExecState* exec = toJS(ctx); { JSLockHolder lock(exec); JSGlobalData& globalData = exec->globalData(); savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable); bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject()); if (protectCountIsZero) globalData.heap.reportAbandonedObjectGraph(); globalData.deref(); } wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable); }
JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object) { JSObject* jsObject = toJS(object); ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSGlobalData* globalData = &exec->globalData(); JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(globalData); PropertyNameArray array(globalData); jsObject->methodTable()->getPropertyNames(jsObject, exec, array, ExcludeDontEnumProperties); size_t size = array.size(); propertyNames->array.reserveInitialCapacity(size); for (size_t i = 0; i < size; ++i) propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).leakRef())); return JSPropertyNameArrayRetain(propertyNames); }
JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); ArgList argList; for (size_t i = 0; i < argumentCount; ++i) argList.append(toJS(arguments[i])); JSObject* result = constructRegExp(exec, argList); if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); result = 0; } return toRef(result); }
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous"); MarkedArgumentBuffer args; for (unsigned i = 0; i < parameterCount; i++) args.append(jsString(exec, parameterNames[i]->ustring())); args.append(jsString(exec, body->ustring())); JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->ustring(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first())); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); exec->clearException(); result = 0; } return toRef(result); }
inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (UNLIKELY(!calleeAsFunctionCell)) return handleHostCall(execCallee, calleeAsValue, kind); JSFunction* function = asFunction(calleeAsFunctionCell); execCallee->setScopeChain(function->scopeUnchecked()); ExecutableBase* executable = function->executable(); if (UNLIKELY(!executable->hasJITCodeFor(kind))) { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind); if (error) { exec->globalData().exception = error; return 0; } } return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress(); }
bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(&exec->globalData())); if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) { jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name); return true; } if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->deletePrivateProperty(name); return true; } #if JSC_OBJC_API_ENABLED if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) { jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->deletePrivateProperty(name); return true; } #endif return false; }
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(&exec->globalData())); JSValue jsValue = toJS(exec, value); if (attributes && !jsObject->hasProperty(exec, name)) jsObject->methodTable()->putDirectVirtual(jsObject, exec, name, jsValue, attributes); else { PutPropertySlot slot; jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot); } if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); exec->clearException(); } }
inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) return handleHostCall(execCallee, calleeAsValue, kind); JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScopeChain(callee->scopeUnchecked()); ExecutableBase* executable = callee->executable(); MacroAssemblerCodePtr codePtr; CodeBlock* codeBlock = 0; if (executable->isHostFunction()) codePtr = executable->generatedJITCodeFor(kind).addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind); if (error) { globalData->exception = createStackOverflowError(exec); return 0; } codeBlock = &functionExecutable->generatedBytecodeFor(kind); if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); else codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall(); } CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress); if (!callLinkInfo.seenOnce()) callLinkInfo.setSeen(); else dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); return codePtr.executableAddress(); }
void JSGarbageCollect(JSContextRef 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; ExecState* exec = toJS(ctx); JSGlobalData& globalData = exec->globalData(); JSLock lock(globalData.isSharedInstance); 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. }
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap->registerThread(); JSLock lock(exec); Identifier nameID = name ? name->identifier(exec) : Identifier(exec, "anonymous"); ArgList args; for (unsigned i = 0; i < parameterCount; i++) args.append(jsString(exec, parameterNames[i]->ustring())); args.append(jsString(exec, body->ustring())); JSObject* result = constructFunction(exec, args, nameID, sourceURL->ustring(), startingLineNumber); if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); result = 0; } return toRef(result); }
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception) { ExecState* exec = toJS(ctx); exec->globalData().heap->registerThread(); JSLock lock(exec); JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(exec)); JSValue* jsValue = toJS(value); if (attributes && !jsObject->hasProperty(exec, name)) jsObject->putWithAttributes(exec, name, jsValue, attributes); else { PutPropertySlot slot; jsObject->put(exec, name, jsValue, slot); } if (exec->hadException()) { if (exception) *exception = toRef(exec->exception()); exec->clearException(); } }
void JSGlobalContextRelease(JSGlobalContextRef ctx) { ExecState* exec = toJS(ctx); JSLock lock(exec); JSGlobalData& globalData = exec->globalData(); JSGlobalObject* dgo = exec->dynamicGlobalObject(); IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable); // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). 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 'JSGlobalContextRef' 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 JSGlobalContextRefs). if (releasingContextGroup) { globalData.clearBuiltinStructures(); globalData.heap.destroy(); } else if (releasingGlobalObject) { globalData.heap.activityCallback()->synchronize(); (*globalData.heap.activityCallback())(); } globalData.deref(); wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable); }
ScriptValue idbKeyToScriptValue(DOMRequestState* requestState, PassRefPtr<IDBKey> key) { ExecState* exec = requestState->exec(); return ScriptValue(exec->globalData(), idbKeyToJSValue(exec, jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), key.get())); }
JSContextGroupRef JSContextGetGroup(JSContextRef ctx) { ExecState* exec = toJS(ctx); return toRef(&exec->globalData()); }
void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); exec->globalData().heap.reportExtraMemoryCost(size); }
bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->globalData())); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); exec->clearException(); } return result; }
void JSDOMWindowBase::updateDocument() { ASSERT(m_impl->document()); ExecState* exec = globalExec(); symbolTablePutWithAttributes(exec->globalData(), Identifier(exec, "document"), toJS(exec, this, m_impl->document()), DontDelete | ReadOnly); }