inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); VM* vm = &exec->vm(); NativeCallFrameTracer tracer(vm, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind)); JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScope(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->prepareForExecution(execCallee, callee->scope(), kind); if (error) { vm->throwException(exec, createStackOverflowError(exec)); return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); } codeBlock = functionExecutable->codeBlockFor(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(execCallee->returnPC()); if (!callLinkInfo.seenOnce()) callLinkInfo.setSeen(); else linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); return reinterpret_cast<char*>(codePtr.executableAddress()); }
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 = asFunction(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(); }
JSValue JSHTMLCanvasElement::getContext(ExecState& state) { if (UNLIKELY(state.argumentCount() < 1)) return state.vm().throwException(&state, createNotEnoughArgumentsError(&state)); HTMLCanvasElement& canvas = wrapped(); const String& contextId = state.uncheckedArgument(0).toWTFString(&state); RefPtr<CanvasContextAttributes> attrs; #if ENABLE(WEBGL) if (HTMLCanvasElement::is3dType(contextId)) { get3DContextAttributes(state, attrs); if (state.hadException()) return jsUndefined(); } #endif CanvasRenderingContext* context = canvas.getContext(contextId, attrs.get()); if (!context) return jsNull(); return toJS(&state, globalObject(), *context); }
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); JSLockHolder locker(exec); startingLineNumber = std::max(1, startingLineNumber); Identifier nameID = name ? name->identifier(&exec->vm()) : Identifier::fromString(exec, "anonymous"); MarkedArgumentBuffer args; for (unsigned i = 0; i < parameterCount; i++) args.append(jsString(exec, parameterNames[i]->string())); args.append(jsString(exec, body->string())); JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first())); if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow) result = 0; return toRef(result); }
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; }
String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) { ASSERT(m_customResolver); JSLockHolder lock(JSDOMWindowBase::commonVM()); ExecState* exec = m_globalObject->globalExec(); JSValue function = m_customResolver->get(exec, Identifier(exec, "lookupNamespaceURI")); CallData callData; CallType callType = getCallData(function, callData); if (callType == CallTypeNone) { callType = m_customResolver->methodTable()->getCallData(m_customResolver.get(), callData); if (callType == CallTypeNone) { // FIXME: <http://webkit.org/b/114312> JSCustomXPathNSResolver::lookupNamespaceURI Console Message should include Line, Column, and SourceURL if (PageConsole* console = m_globalObject->impl().pageConsole()) console->addMessage(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method."); return String(); } function = m_customResolver.get(); } Ref<JSCustomXPathNSResolver> selfProtector(*this); MarkedArgumentBuffer args; args.append(jsStringWithCache(exec, prefix)); JSValue retval = JSMainThreadExecState::call(exec, function, callType, callData, m_customResolver.get(), args); String result; if (exec->hadException()) reportCurrentException(exec); else { if (!retval.isUndefinedOrNull()) result = retval.toString(exec)->value(exec); } return result; }
JSValue JSInspectorFrontendHost::showContextMenu(ExecState& state) { #if ENABLE(CONTEXT_MENUS) if (state.argumentCount() < 2) return jsUndefined(); Event* event = JSEvent::toWrapped(state.argument(0)); JSArray* array = asArray(state.argument(1)); ContextMenu menu; populateContextMenuItems(&state, array, menu); #if !USE(CROSS_PLATFORM_CONTEXT_MENUS) Vector<ContextMenuItem> items = contextMenuItemVector(menu.platformDescription()); #else Vector<ContextMenuItem> items = menu.items(); #endif impl().showContextMenu(event, items); #else UNUSED_PARAM(state); #endif return jsUndefined(); }
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(); } }
JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSValue message = argumentCount ? toJS(exec, arguments[0]) : jsUndefined(); Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure(); JSObject* result = ErrorInstance::create(exec, errorStructure, message); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); exec->clearException(); result = 0; } return toRef(result); }
JSValue JSWebGLRenderingContextBase::getAttachedShaders(ExecState& state) { if (state.argumentCount() < 1) return state.vm().throwException(&state, createNotEnoughArgumentsError(&state)); ExceptionCode ec = 0; WebGLRenderingContextBase& context = wrapped(); WebGLProgram* program = JSWebGLProgram::toWrapped(state.uncheckedArgument(0)); if (!program && !state.uncheckedArgument(0).isUndefinedOrNull()) return throwTypeError(&state); Vector<RefPtr<WebGLShader>> shaders; bool succeed = context.getAttachedShaders(program, shaders, ec); if (ec) { setDOMException(&state, ec); return jsNull(); } if (!succeed) return jsNull(); JSC::MarkedArgumentBuffer list; for (size_t ii = 0; ii < shaders.size(); ++ii) list.append(toJS(&state, globalObject(), shaders[ii].get())); return constructArray(&state, 0, globalObject(), list); }
bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return false; } ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first())); JSValue syntaxException; bool isValidSyntax = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source, &syntaxException); if (!isValidSyntax) { if (exception) *exception = toRef(exec, syntaxException); return false; } return true; }
JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { ExecState* exec = toJS(ctx); JSLockHolder locker(exec); JSObject* jsObject = toJS(object); JSValue result; Identifier name(propertyName->identifier(&exec->vm())); // Get wrapped object if proxied if (jsObject->inherits(JSProxy::info())) jsObject = jsCast<JSProxy*>(jsObject)->target(); if (jsObject->inherits(JSCallbackObject<JSGlobalObject>::info())) result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name); else if (jsObject->inherits(JSCallbackObject<JSDestructibleObject>::info())) result = jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivateProperty(name); #if JSC_OBJC_API_ENABLED else if (jsObject->inherits(JSCallbackObject<JSAPIWrapperObject>::info())) result = jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->getPrivateProperty(name); #endif return toRef(exec, result); }
void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value) { if (!ctx) { ASSERT_NOT_REACHED(); return; } ExecState* exec = toJS(ctx); JSLockHolder locker(exec); JSObject* jsObject = toJS(object); JSValue jsValue = toJS(exec, value); if (JSProxy* proxy = jsDynamicCast<JSProxy*>(jsObject)) { if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(proxy->target())) { globalObject->resetPrototype(exec->vm(), jsValue.isObject() ? jsValue : jsNull()); return; } // Someday we might use proxies for something other than JSGlobalObjects, but today is not that day. RELEASE_ASSERT_NOT_REACHED(); } jsObject->setPrototype(exec->vm(), exec, jsValue.isObject() ? jsValue : jsNull()); }
JSValue JSWebKitSubtleCrypto::generateKey(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (state.argumentCount() < 1) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto algorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(0)); ASSERT(scope.exception() || algorithm); if (!algorithm) return jsUndefined(); auto parameters = JSCryptoAlgorithmDictionary::createParametersForGenerateKey(&state, algorithm->identifier(), state.uncheckedArgument(0)); ASSERT(scope.exception() || parameters); if (!parameters) return jsUndefined(); bool extractable = false; if (state.argumentCount() >= 2) { extractable = state.uncheckedArgument(1).toBoolean(&state); RETURN_IF_EXCEPTION(scope, JSValue()); } CryptoKeyUsageBitmap keyUsages = 0; if (state.argumentCount() >= 3) { auto success = cryptoKeyUsagesFromJSValue(state, state.argument(2), keyUsages); ASSERT(scope.exception() || success); if (!success) return jsUndefined(); } RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow()); auto promise = wrapper->promise(); auto successCallback = [wrapper](CryptoKey* key, CryptoKeyPair* keyPair) mutable { ASSERT(key || keyPair); ASSERT(!key || !keyPair); if (key) wrapper->resolve(key); else wrapper->resolve(keyPair); }; auto failureCallback = [wrapper]() mutable { wrapper->reject(nullptr); }; auto result = algorithm->generateKey(*parameters, extractable, keyUsages, WTFMove(successCallback), WTFMove(failureCallback), *scriptExecutionContextFromExecState(&state)); if (result.hasException()) { propagateException(state, scope, result.releaseException()); return { }; } return promise; }
void JSCustomVoidCallback::handleEvent() { ASSERT(m_callback); ASSERT(m_frame); if (!m_frame->script()->isEnabled()) return; JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); KJS::JSLock lock(false); JSValue* function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function->getCallData(callData); if (callType == CallTypeNone) { callType = m_callback->getCallData(callData); if (callType == CallTypeNone) { // FIXME: Should an exception be thrown here? return; } function = m_callback; } RefPtr<JSCustomVoidCallback> protect(this); ArgList args; globalObject->startTimeoutCheck(); call(exec, function, callType, callData, m_callback, args); globalObject->stopTimeoutCheck(); if (exec->hadException()) m_frame->domWindow()->console()->reportCurrentException(exec); Document::updateDocumentsRendering(); }
void JSCustomVoidCallback::handleEvent() { ASSERT(m_callback); ASSERT(m_frame); if (!m_frame->script()->isEnabled()) return; JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); JSC::JSLock lock(SilenceAssertionsOnly); JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { callType = m_callback->getCallData(callData); if (callType == CallTypeNone) { // FIXME: Should an exception be thrown here? return; } function = m_callback; } RefPtr<JSCustomVoidCallback> protect(this); MarkedArgumentBuffer args; globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) reportCurrentException(exec); Document::updateStyleForAllDocuments(); }
static void JSMediaDevicesGetUserMediaPromiseFunction(ExecState& state, Ref<DeferredPromise>&& promise) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (UNLIKELY(state.argumentCount() < 1)) { throwVMError(&state, scope, createNotEnoughArgumentsError(&state)); return; } auto constraintsDictionary = Dictionary(&state, state.uncheckedArgument(0)); MediaTrackConstraintSetMap mandatoryAudioConstraints; Vector<MediaTrackConstraintSetMap> advancedAudioConstraints; bool areAudioConstraintsValid = false; Dictionary audioConstraintsDictionary; if (constraintsDictionary.get("audio", audioConstraintsDictionary) && !audioConstraintsDictionary.isUndefinedOrNull()) { parseMediaConstraintsDictionary(audioConstraintsDictionary, mandatoryAudioConstraints, advancedAudioConstraints); areAudioConstraintsValid = true; } else constraintsDictionary.get("audio", areAudioConstraintsValid); MediaTrackConstraintSetMap mandatoryVideoConstraints; Vector<MediaTrackConstraintSetMap> advancedVideoConstraints; bool areVideoConstraintsValid = false; Dictionary videoConstraintsDictionary; if (constraintsDictionary.get("video", videoConstraintsDictionary) && !videoConstraintsDictionary.isUndefinedOrNull()) { parseMediaConstraintsDictionary(videoConstraintsDictionary, mandatoryVideoConstraints, advancedVideoConstraints); areVideoConstraintsValid = true; } else constraintsDictionary.get("video", areVideoConstraintsValid); auto audioConstraints = MediaConstraintsImpl::create(WTFMove(mandatoryAudioConstraints), WTFMove(advancedAudioConstraints), areAudioConstraintsValid); auto videoConstraints = MediaConstraintsImpl::create(WTFMove(mandatoryVideoConstraints), WTFMove(advancedVideoConstraints), areVideoConstraintsValid); propagateException(state, scope, castThisValue<JSMediaDevices>(state).wrapped().getUserMedia(WTFMove(audioConstraints), WTFMove(videoConstraints), WTFMove(promise))); }
void JSCustomPositionCallback::handleEvent(Geoposition* geoposition) { #if ENABLE(GEOLOCATION) ASSERT(m_callback); ASSERT(m_globalObject); ExecState* exec = m_globalObject->globalExec(); JSC::JSLock lock(SilenceAssertionsOnly); JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { callType = m_callback->getCallData(callData); if (callType == CallTypeNone) { // FIXME: Should an exception be thrown here? return; } function = m_callback; } RefPtr<JSCustomPositionCallback> protect(this); MarkedArgumentBuffer args; args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), geoposition)); m_globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); m_globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) reportCurrentException(exec); Document::updateStyleForAllDocuments(); #endif }
ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) { // evaluate code. Returns the JS return value or 0 // if there was none, an error occured or the type couldn't be converted. const SourceCode& jsSourceCode = sourceCode.jsSourceCode(); initScriptIfNeeded(); // inlineCode is true for <a href="javascript:doSomething()"> // and false for <script>doSomething()</script>. Check if it has the // expected value in all cases. // See smart window.open policy for where this is used. ExecState* exec = m_windowShell->window()->globalExec(); const String* savedSourceURL = m_sourceURL; String sourceURL = jsSourceCode.provider()->url(); m_sourceURL = &sourceURL; JSLock lock(false); // Evaluating the JavaScript could cause the frame to be deallocated // so we start the keep alive timer here. m_frame->keepAlive(); m_windowShell->window()->startTimeoutCheck(); Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, m_windowShell); m_windowShell->window()->stopTimeoutCheck(); if (comp.complType() == Normal || comp.complType() == ReturnValue) { m_sourceURL = savedSourceURL; return comp.value(); } if (comp.complType() == Throw) reportException(exec, comp.value()); m_sourceURL = savedSourceURL; return noValue(); }
ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode, DOMWrapperWorld* world) { const SourceCode& jsSourceCode = sourceCode.jsSourceCode(); String sourceURL = jsSourceCode.provider()->url(); // evaluate code. Returns the JS return value or 0 // if there was none, an error occurred or the type couldn't be converted. // inlineCode is true for <a href="javascript:doSomething()"> // and false for <script>doSomething()</script>. Check if it has the // expected value in all cases. // See smart window.open policy for where this is used. JSDOMWindowShell* shell = windowShell(world); ExecState* exec = shell->window()->globalExec(); const String* savedSourceURL = m_sourceURL; m_sourceURL = &sourceURL; JSLockHolder lock(exec); Ref<Frame> protect(m_frame); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(&m_frame, sourceURL, sourceCode.startLine()); JSValue evaluationException; JSValue returnValue = JSMainThreadExecState::evaluate(exec, jsSourceCode, shell, &evaluationException); InspectorInstrumentation::didEvaluateScript(cookie); if (evaluationException) { reportException(exec, evaluationException, sourceCode.cachedScript()); m_sourceURL = savedSourceURL; return ScriptValue(); } m_sourceURL = savedSourceURL; return ScriptValue(exec->vm(), returnValue); }
ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception) { { MutexLocker lock(m_sharedDataMutex); if (m_executionForbidden) return JSValue(); } initScriptIfNeeded(); JSLock lock(SilenceAssertionsOnly); ExecState* exec = m_workerContextWrapper->globalExec(); m_workerContextWrapper->globalData().timeoutChecker.start(); Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper); m_workerContextWrapper->globalData().timeoutChecker.stop(); if (comp.complType() == Normal || comp.complType() == ReturnValue) return comp.value(); if (comp.complType() == Throw) *exception = comp.value(); return JSValue(); }
JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } JSObject* jsObject = toJS(object); ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); VM* vm = &exec->vm(); JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(vm); PropertyNameArray array(vm); 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.uncheckedAppend(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].string()).leakRef())); return JSPropertyNameArrayRetain(propertyNames); }
bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); JSValue jsValue = value ? toJS(exec, value) : JSValue(); Identifier name(propertyName->identifier(&exec->vm())); if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) { jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue); return true; } if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue); return true; } #if JSC_OBJC_API_ENABLED if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) { jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue); return true; } #endif return false; }
JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); MarkedArgumentBuffer argList; for (size_t i = 0; i < argumentCount; ++i) argList.append(toJS(exec, arguments[i])); JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); exec->clearException(); result = 0; } return toRef(result); }
void reportMemoryForDocumentIfFrameless(ExecState& state, Document& document) { // Make sure the document is kept around by the window object, and works right with the back/forward cache. if (document.frame()) return; size_t memoryCost = 0; for (Node* node = &document; node; node = NodeTraversal::next(*node)) memoryCost += node->approximateMemoryCost(); // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated. // https://bugs.webkit.org/show_bug.cgi?id=142595 state.heap()->deprecatedReportExtraMemory(memoryCost); }
static bool get(ExecState& exec, JSValue object, const String& keyPathElement, JSValue& result) { if (object.isString() && keyPathElement == "length") { result = jsNumber(asString(object)->length()); return true; } if (!object.isObject()) return false; Identifier identifier = Identifier::fromString(&exec.vm(), keyPathElement); if (!asObject(object)->hasProperty(&exec, identifier)) return false; result = asObject(object)->get(&exec, identifier); return true; }
static RefPtr<IDBKey> createIDBKeyFromValue(ExecState& exec, JSValue value, Vector<JSArray*>& stack) { VM& vm = exec.vm(); if (value.isNumber() && !std::isnan(value.toNumber(&exec))) return IDBKey::createNumber(value.toNumber(&exec)); if (value.isString()) return IDBKey::createString(asString(value)->value(&exec)); if (value.inherits<DateInstance>(vm)) { auto dateValue = valueToDate(exec, value); if (!std::isnan(dateValue)) return IDBKey::createDate(dateValue); } if (value.isObject()) { JSObject* object = asObject(value); if (auto* array = jsDynamicCast<JSArray*>(vm, object)) { size_t length = array->length(); if (stack.contains(array)) return nullptr; if (stack.size() >= maximumDepth) return nullptr; stack.append(array); Vector<RefPtr<IDBKey>> subkeys; for (size_t i = 0; i < length; i++) { JSValue item = array->getIndex(&exec, i); RefPtr<IDBKey> subkey = createIDBKeyFromValue(exec, item, stack); if (!subkey) subkeys.append(IDBKey::createInvalid()); else subkeys.append(subkey); } stack.removeLast(); return IDBKey::createArray(subkeys); } if (auto* arrayBuffer = jsDynamicCast<JSArrayBuffer*>(vm, value)) return IDBKey::createBinary(*arrayBuffer); if (auto* arrayBufferView = jsDynamicCast<JSArrayBufferView*>(vm, value)) return IDBKey::createBinary(*arrayBufferView); } return nullptr; }
void JSDOMWindow::setLocation(ExecState& state, JSValue value) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); #if ENABLE(DASHBOARD_SUPPORT) // To avoid breaking old widgets, make "var location =" in a top-level frame create // a property named "location" instead of performing a navigation (<rdar://problem/5688039>). if (Frame* activeFrame = activeDOMWindow(&state).frame()) { if (activeFrame->settings().usesDashboardBackwardCompatibilityMode() && !activeFrame->tree().parent()) { if (BindingSecurity::shouldAllowAccessToDOMWindow(&state, wrapped())) putDirect(state.vm(), Identifier::fromString(&state, "location"), value); return; } } #endif String locationString = value.toString(&state)->value(&state); RETURN_IF_EXCEPTION(scope, void()); if (Location* location = wrapped().location()) location->setHref(activeDOMWindow(&state), firstDOMWindow(&state), locationString); }
void call() { if (!canInvokeCallback()) return; Ref<JSGlobalObjectCallback> protectedThis(*this); JSLockHolder lock(m_globalObject->vm()); ExecState* exec = m_globalObject->globalExec(); ScriptExecutionContext* context = m_globalObject->scriptExecutionContext(); // We will fail to get the context if the frame has been detached. if (!context) return; // When on the main thread (e.g. the document's thread), we need to make sure to // push the current ExecState on to the JSMainThreadExecState stack. if (context->isDocument()) JSMainThreadExecState::runTask(exec, m_task); else m_task->run(exec); ASSERT(!exec->hadException()); }
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return; } ExecState* exec = toJS(ctx); JSLockHolder locker(exec); JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(&exec->vm())); JSValue jsValue = toJS(exec, value); if (attributes && !jsObject->hasProperty(exec, name)) { PropertyDescriptor desc(jsValue, attributes); jsObject->methodTable()->defineOwnProperty(jsObject, exec, name, desc, false); } else { PutPropertySlot slot(jsObject); jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot); } handleExceptionIfNeeded(exec, exception); }