JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, const Identifier&) { JSActivation* activation = asActivation(slotBase); CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers)); int argumentsRegister = activation->m_argumentsRegister; if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue()) return arguments; int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister); JSValue arguments = JSValue(Arguments::create(callFrame->globalData(), callFrame)); callFrame->uncheckedR(argumentsRegister) = arguments; callFrame->uncheckedR(realArgumentsRegister) = arguments; ASSERT(callFrame->uncheckedR(realArgumentsRegister).jsValue().inherits(&Arguments::s_info)); return callFrame->uncheckedR(realArgumentsRegister).jsValue(); }
static EncodedJSValue JSC_HOST_CALL functionCodeBlockForFrame(ExecState* exec) { if (exec->argumentCount() < 1) return JSValue::encode(jsUndefined()); JSValue value = exec->uncheckedArgument(0); if (!value.isUInt32()) return JSValue::encode(jsUndefined()); // We need to inc the frame number because the caller would consider // its own frame as frame 0. Hence, we need discount the frame for this // function. unsigned frameNumber = value.asUInt32() + 1; CodeBlock* codeBlock = JSDollarVMPrototype::codeBlockForFrame(exec, frameNumber); return JSValue::encode(JSValue(bitwise_cast<double>(reinterpret_cast<uint64_t>(codeBlock)))); }
void JIT::compileCallEval(Instruction* instruction) { addPtr(TrustedImm32(-static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC))), stackPointerRegister, regT1); storePtr(callFrameRegister, Address(regT1, CallFrame::callerFrameOffset())); addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister); checkStackPointerAlignment(); callOperation(operationCallEval, regT1); addSlowCase(branch64(Equal, regT0, TrustedImm64(JSValue::encode(JSValue())))); sampleCodeBlock(m_codeBlock); emitPutCallResult(instruction); }
static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index) { // FIXME: the JIT used to handle these in compiled code! if (isJSArray(base) && asArray(base)->canGetIndex(index)) return JSValue::encode(asArray(base)->getIndex(index)); // FIXME: the JITstub used to relink this to an optimized form! if (isJSString(base) && asString(base)->canGetIndex(index)) return JSValue::encode(asString(base)->getIndex(exec, index)); // FIXME: the JITstub used to relink this to an optimized form! if (isJSByteArray(base) && asByteArray(base)->canAccessIndex(index)) return JSValue::encode(asByteArray(base)->getIndex(exec, index)); return JSValue::encode(JSValue(base).get(exec, index)); }
JSValue JSDOMWindow::setInterval(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (UNLIKELY(state.argumentCount() < 1)) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto* contentSecurityPolicy = wrapped().document() ? wrapped().document()->contentSecurityPolicy() : nullptr; auto action = ScheduledAction::create(&state, globalObject()->world(), contentSecurityPolicy); RETURN_IF_EXCEPTION(scope, JSValue()); if (!action) return jsNumber(0); int delay = state.argument(1).toInt32(&state); return toJS<IDLLong>(state, scope, wrapped().setInterval(WTFMove(action), delay)); }
JSValue::operator JSString() const { HAL_JSVALUE_LOCK_GUARD; JSValueRef exception { nullptr }; JSStringRef js_string_ref = JSValueToStringCopy(static_cast<JSContextRef>(js_context__), js_value_ref__, &exception); if (exception) { // If this assert fails then we need to JSStringRelease // js_string_ref. assert(!js_string_ref); detail::ThrowRuntimeError("JSValue", JSValue(js_context__, exception)); } assert(js_string_ref); JSString js_string(js_string_ref); JSStringRelease(js_string_ref); return js_string; }
void JSWeakValue::clear() { switch (m_tag) { case WeakTypeTag::NotSet: return; case WeakTypeTag::Primitive: m_value.primitive = JSValue(); return; case WeakTypeTag::Object: m_value.object.clear(); return; case WeakTypeTag::String: m_value.string.clear(); return; } RELEASE_ASSERT_NOT_REACHED(); }
void GetByIdVariant::dumpInContext(PrintStream& out, DumpContext* context) const { if (!isSet()) { out.print("<empty>"); return; } out.print( "<", inContext(structureSet(), context), ", ", "[", listDumpInContext(m_constantChecks, context), "]"); if (m_alternateBase) out.print(", alternateBase = ", inContext(JSValue(m_alternateBase), context)); out.print(", offset = ", offset()); if (m_callLinkStatus) out.print(", call = ", *m_callLinkStatus); out.print(">"); }
void ClonedArguments::materializeSpecials(ExecState* exec) { RELEASE_ASSERT(!specialsMaterialized()); VM& vm = exec->vm(); FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_callee->executable()); bool isStrictMode = executable->isStrictMode(); if (isStrictMode) putDirectAccessor(exec, vm.propertyNames->callee, globalObject()->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), DontDelete | DontEnum | Accessor); else putDirect(vm, vm.propertyNames->callee, JSValue(m_callee.get())); putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayProtoValuesFunction(), DontEnum); m_callee.clear(); }
void Debugger::exception(CallFrame* callFrame, JSValue exception, bool hasHandler) { if (m_isPaused) return; PauseReasonDeclaration reason(*this, PausedForException); if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasHandler)) { m_pauseOnNextStatement = true; setSteppingMode(SteppingModeEnabled); } m_hasHandlerForExceptionCallback = true; m_currentException = exception; updateCallFrameAndPauseIfNeeded(callFrame); m_currentException = JSValue(); m_hasHandlerForExceptionCallback = false; }
void GetByIdStatus::computeForChain(GetByIdStatus& result, CodeBlock* profiledBlock, Identifier& ident, Structure* structure) { #if ENABLE(JIT) && ENABLE(VALUE_PROFILER) // Validate the chain. If the chain is invalid, then currently the best thing // we can do is to assume that TakesSlow is true. In the future, it might be // worth exploring reifying the structure chain from the structure we've got // instead of using the one from the cache, since that will do the right things // if the structure chain has changed. But that may be harder, because we may // then end up having a different type of access altogether. And it currently // does not appear to be worth it to do so -- effectively, the heuristic we // have now is that if the structure chain has changed between when it was // cached on in the baseline JIT and when the DFG tried to inline the access, // then we fall back on a polymorphic access. Structure* currentStructure = structure; JSObject* currentObject = 0; for (unsigned i = 0; i < result.m_chain.size(); ++i) { ASSERT(!currentStructure->isDictionary()); currentObject = asObject(currentStructure->prototypeForLookup(profiledBlock)); currentStructure = result.m_chain[i]; if (currentObject->structure() != currentStructure) return; } ASSERT(currentObject); unsigned attributesIgnored; JSCell* specificValue; result.m_offset = currentStructure->get( *profiledBlock->vm(), ident, attributesIgnored, specificValue); if (currentStructure->isDictionary()) specificValue = 0; if (!isValidOffset(result.m_offset)) return; result.m_structureSet.add(structure); result.m_specificValue = JSValue(specificValue); #else UNUSED_PARAM(result); UNUSED_PARAM(profiledBlock); UNUSED_PARAM(ident); UNUSED_PARAM(structure); UNREACHABLE_FOR_PLATFORM(); #endif }
static EncodedJSValue JSC_HOST_CALL constructWeakMap(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject(); Structure* weakMapStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->weakMapStructure()); if (exec->hadException()) return JSValue::encode(JSValue()); JSWeakMap* weakMap = JSWeakMap::create(exec, weakMapStructure); JSValue iterable = exec->argument(0); if (iterable.isUndefinedOrNull()) return JSValue::encode(weakMap); JSValue adderFunction = weakMap->JSObject::get(exec, exec->propertyNames().set); if (exec->hadException()) return JSValue::encode(jsUndefined()); CallData adderFunctionCallData; CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData); if (adderFunctionCallType == CallType::None) return JSValue::encode(throwTypeError(exec, scope)); forEachInIterable(exec, iterable, [&](VM& vm, ExecState* exec, JSValue nextItem) { if (!nextItem.isObject()) { throwTypeError(exec, scope); return; } JSValue key = nextItem.get(exec, static_cast<unsigned>(0)); if (vm.exception()) return; JSValue value = nextItem.get(exec, static_cast<unsigned>(1)); if (vm.exception()) return; MarkedArgumentBuffer arguments; arguments.append(key); arguments.append(value); call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakMap, arguments); }); return JSValue::encode(weakMap); }
EncodedJSValue JSLexicalEnvironment::argumentsGetter(ExecState*, JSObject* slotBase, EncodedJSValue, PropertyName) { JSLexicalEnvironment* lexicalEnvironment = jsCast<JSLexicalEnvironment*>(slotBase); CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(lexicalEnvironment->m_registers)); return JSValue::encode(jsUndefined()); VirtualRegister argumentsRegister = callFrame->codeBlock()->argumentsRegister(); if (JSValue arguments = callFrame->uncheckedR(argumentsRegister.offset()).jsValue()) return JSValue::encode(arguments); int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister).offset(); JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame)); callFrame->uncheckedR(argumentsRegister.offset()) = arguments; callFrame->uncheckedR(realArgumentsRegister) = arguments; ASSERT(callFrame->uncheckedR(realArgumentsRegister).jsValue().inherits(Arguments::info())); return JSValue::encode(callFrame->uncheckedR(realArgumentsRegister).jsValue()); }
void AbstractValue::setType(Graph& graph, SpeculatedType type) { SpeculatedType cellType = type & SpecCell; if (cellType) { if (!(cellType & ~SpecString)) m_structure = graph.m_vm.stringStructure.get(); else if (isSymbolSpeculation(cellType)) m_structure = graph.m_vm.symbolStructure.get(); else m_structure.makeTop(); m_arrayModes = ALL_ARRAY_MODES; } else { m_structure.clear(); m_arrayModes = 0; } m_type = type; m_value = JSValue(); checkConsistency(); }
void JIT::compileCallEval(Instruction* instruction) { addPtr(TrustedImm32(-static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC))), stackPointerRegister, regT1); callOperationNoExceptionCheck(operationCallEval, regT1); Jump noException = emitExceptionCheck(InvertedExceptionCheck); addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister); exceptionCheck(jump()); noException.link(this); addSlowCase(branch64(Equal, regT0, TrustedImm64(JSValue::encode(JSValue())))); addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister); checkStackPointerAlignment(); sampleCodeBlock(m_codeBlock); emitPutCallResult(instruction); }
JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, PropertyName) { JSActivation* activation = jsCast<JSActivation*>(slotBase); if (activation->isTornOff()) return jsUndefined(); CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers)); int argumentsRegister = callFrame->codeBlock()->argumentsRegister(); if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue()) return arguments; int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister); JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame)); callFrame->uncheckedR(argumentsRegister) = arguments; callFrame->uncheckedR(realArgumentsRegister) = arguments; ASSERT(callFrame->uncheckedR(realArgumentsRegister).jsValue().inherits(Arguments::info())); return callFrame->uncheckedR(realArgumentsRegister).jsValue(); }
EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty) { JSValue property = JSValue::decode(encodedProperty); if (property.isUInt32()) return getByVal(exec, base, property.asUInt32()); if (property.isDouble()) { double propertyAsDouble = property.asDouble(); uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble); if (propertyAsUInt32 == propertyAsDouble) return getByVal(exec, base, propertyAsUInt32); } else if (property.isString()) { if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec))) return JSValue::encode(result); } Identifier ident(exec, property.toString(exec)); return JSValue::encode(JSValue(base).get(exec, ident)); }
static EncodedJSValue JSC_HOST_CALL functionCodeBlockForFrame(ExecState* exec) { if (exec->argumentCount() < 1) return JSValue::encode(jsUndefined()); JSValue value = exec->uncheckedArgument(0); if (!value.isUInt32()) return JSValue::encode(jsUndefined()); // We need to inc the frame number because the caller would consider // its own frame as frame 0. Hence, we need discount the frame for this // function. unsigned frameNumber = value.asUInt32() + 1; CodeBlock* codeBlock = JSDollarVMPrototype::codeBlockForFrame(exec, frameNumber); // Though CodeBlock is a JSCell, it is not safe to return it directly back to JS code // as it is an internal type that the JS code cannot handle. Hence, we first encode the // CodeBlock* as a double token (which is safe for JS code to handle) before returning it. return JSValue::encode(JSValue(bitwise_cast<double>(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(codeBlock))))); }
bool GetByIdVariant::attemptToMerge(const GetByIdVariant& other) { if (m_alternateBase != other.m_alternateBase) return false; if (m_offset != other.m_offset) return false; if (m_callLinkStatus || other.m_callLinkStatus) return false; if (!areCompatible(m_constantChecks, other.m_constantChecks)) return false; if (m_specificValue != other.m_specificValue) m_specificValue = JSValue(); mergeInto(other.m_constantChecks, m_constantChecks); m_structureSet.merge(other.m_structureSet); return true; }
void AbstractValue::filterValueByType() { // We could go further, and ensure that if the futurePossibleStructure contravenes // the value, then we could clear both of those things. But that's unlikely to help // in any realistic scenario, so we don't do it. Simpler is better. if (!!m_type) { // The type is still non-empty. It may be that the new type renders // the value empty because it contravenes the constant value we had. if (m_value && !validateType(m_value)) clear(); return; } // The type has been rendered empty. That means that the value must now be invalid, // as well. ASSERT(!m_value || !validateType(m_value)); m_value = JSValue(); }
JSObjectRef JSFunction::MakeFunction(const JSContext& js_context, const JSString& body, const std::vector<JSString>& parameter_names, const JSString& function_name, const JSString& source_url, int starting_line_number) { JSValueRef exception { nullptr }; JSStringRef source_url_ref = (source_url.length() > 0) ? static_cast<JSStringRef>(source_url) : nullptr; JSObjectRef js_object_ref = nullptr; if (!parameter_names.empty()) { std::vector<JSStringRef> parameter_name_array = detail::to_vector(parameter_names); js_object_ref = JSObjectMakeFunction(static_cast<JSContextRef>(js_context), static_cast<JSStringRef>(function_name), static_cast<unsigned>(parameter_name_array.size()), ¶meter_name_array[0], static_cast<JSStringRef>(body), source_url_ref, starting_line_number, &exception); } else { js_object_ref = JSObjectMakeFunction(static_cast<JSContextRef>(js_context), static_cast<JSStringRef>(function_name), 0, nullptr, static_cast<JSStringRef>(body), source_url_ref, starting_line_number, &exception); } if (exception) { // If this assert fails then we need to JSValueUnprotect // js_object_ref. assert(!js_object_ref); detail::ThrowRuntimeError("JSFunction", JSValue(js_context, exception)); } return js_object_ref; }
EncodedJSValue JSActivation::argumentsGetter(ExecState*, EncodedJSValue slotBase, EncodedJSValue, PropertyName) { JSActivation* activation = jsCast<JSActivation*>(JSValue::decode(slotBase)); CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers)); ASSERT(!activation->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())); if (activation->isTornOff() || !(callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())) return JSValue::encode(jsUndefined()); VirtualRegister argumentsRegister = callFrame->codeBlock()->argumentsRegister(); if (JSValue arguments = callFrame->uncheckedR(argumentsRegister.offset()).jsValue()) return JSValue::encode(arguments); int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister).offset(); JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame)); callFrame->uncheckedR(argumentsRegister.offset()) = arguments; callFrame->uncheckedR(realArgumentsRegister) = arguments; ASSERT(callFrame->uncheckedR(realArgumentsRegister).jsValue().inherits(Arguments::info())); return JSValue::encode(callFrame->uncheckedR(realArgumentsRegister).jsValue()); }
bool DebuggerScope::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { DebuggerScope* scope = jsCast<DebuggerScope*>(object); ASSERT(scope->isValid()); if (!scope->isValid()) return false; JSObject* thisObject = JSScope::objectAtScope(scope->jsScope()); slot.setThisValue(JSValue(thisObject)); // By default, JSObject::getPropertySlot() will look in the DebuggerScope's prototype // chain and not the wrapped scope, and JSObject::getPropertySlot() cannot be overridden // to behave differently for the DebuggerScope. // // Instead, we'll treat all properties in the wrapped scope and its prototype chain as // the own properties of the DebuggerScope. This is fine because the WebInspector // does not presently need to distinguish between what's owned at each level in the // prototype chain. Hence, we'll invoke getPropertySlot() on the wrapped scope here // instead of getOwnPropertySlot(). return thisObject->getPropertySlot(exec, propertyName, slot); }
static EncodedJSValue JSC_HOST_CALL promiseAllCountdownFunction(ExecState* exec) { JSValue x = exec->argument(0); VM& vm = exec->vm(); JSObject* F = exec->callee(); // 1. Let 'index' be the value of F's [[Index]] internal slot. uint32_t index = F->get(exec, vm.propertyNames->indexPrivateName).asUInt32(); // 2. Let 'values' be the value of F's [[Values]] internal slot.. JSArray* values = jsCast<JSArray*>(F->get(exec, vm.propertyNames->valuesPrivateName)); // 3. Let 'deferred' be the value of F's [[Deferred]] internal slot. JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(F->get(exec, vm.propertyNames->deferredPrivateName)); // 4. Let 'countdownHolder' be the value of F's [[CountdownHolder]] internal slot. NumberObject* countdownHolder = jsCast<NumberObject*>(F->get(exec, vm.propertyNames->countdownHolderPrivateName)); // 5. Let 'result' be the result of calling the [[DefineOwnProperty]] internal method // of 'values' with arguments 'index' and Property Descriptor { [[Value]]: x, // [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }. values->putDirectIndex(exec, index, x); // 6. RejectIfAbrupt(result, deferred). if (exec->hadException()) abruptRejection(exec, deferred); // 7. Set countdownHolder.[[Countdown]] to countdownHolder.[[Countdown]] - 1. uint32_t newCountdownValue = countdownHolder->internalValue().asUInt32() - 1; countdownHolder->setInternalValue(vm, JSValue(newCountdownValue)); // 8. If countdownHolder.[[Countdown]] is 0, if (!newCountdownValue) { // i. Return the result of calling the [[Call]] internal method of deferred.[[Resolve]] // with undefined as thisArgument and a List containing 'values' as argumentsList. performDeferredResolve(exec, deferred, values); } // 9. Return. return JSValue::encode(jsUndefined()); }
EncodedJSValue JSC_HOST_CALL IntlDateTimeFormatFuncFormatDateTime(ExecState* state) { // 12.3.4 DateTime Format Functions (ECMA-402 2.0) // 1. Let dtf be the this value. IntlDateTimeFormat* format = jsDynamicCast<IntlDateTimeFormat*>(state->thisValue()); // 2. Assert: Type(dtf) is Object and dtf has an [[initializedDateTimeFormat]] internal slot whose value is true. if (!format) return JSValue::encode(throwTypeError(state)); JSValue date = state->argument(0); double value; // 3. If date is not provided or is undefined, then if (date.isUndefined()) { // a. Let x be %Date_now%(). value = JSValue::decode(dateNow(state)).toNumber(state); } else { // 4. Else // a. Let x be ToNumber(date). value = date.toNumber(state); // b. ReturnIfAbrupt(x). if (state->hadException()) return JSValue::encode(jsUndefined()); } // 5. Return FormatDateTime(dtf, x). // 12.3.4 FormatDateTime abstract operation (ECMA-402 2.0) // 1. If x is not a finite Number, then throw a RangeError exception. if (!std::isfinite(value)) return JSValue::encode(throwRangeError(state, ASCIILiteral("date value is not finite in DateTimeFormat.format()"))); // FIXME: implement 2 - 9 // Return new Date(value).toString() until properly implemented. VM& vm = state->vm(); JSGlobalObject* globalObject = state->callee()->globalObject(); DateInstance* d = DateInstance::create(vm, globalObject->dateStructure(), value); return JSValue::encode(JSValue(d).toString(state)); }
// https://tc39.github.io/ecma262/#sec-reflect.setprototypeof EncodedJSValue JSC_HOST_CALL reflectObjectSetPrototypeOf(ExecState* exec) { JSValue target = exec->argument(0); if (!target.isObject()) return JSValue::encode(throwTypeError(exec, ASCIILiteral("Reflect.setPrototypeOf requires the first argument be an object"))); JSValue proto = exec->argument(1); if (!proto.isObject() && !proto.isNull()) return JSValue::encode(throwTypeError(exec, ASCIILiteral("Reflect.setPrototypeOf requires the second argument be either an object or null"))); JSObject* object = asObject(target); if (!checkProtoSetterAccessAllowed(exec, object)) return JSValue::encode(jsBoolean(false)); VM& vm = exec->vm(); bool shouldThrowIfCantSet = false; bool didSetPrototype = object->setPrototype(vm, exec, proto, shouldThrowIfCantSet); if (vm.exception()) return JSValue::encode(JSValue()); return JSValue::encode(jsBoolean(didSetPrototype)); }
static ALWAYS_INLINE JSValue callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName) { JSValue function = object->get(exec, propertyName); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return exec->exception(); // Prevent "toString" and "valueOf" from observing execution if an exception // is pending. if (exec->hadException()) return exec->exception(); JSValue result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList()); ASSERT(!result.isGetterSetter()); if (exec->hadException()) return exec->exception(); if (result.isObject()) return JSValue(); return result; }
static JSArray* getJSListenerFunctions(ExecState* exec, Document* document, const EventListenerInfo& listenerInfo) { JSArray* result = constructEmptyArray(exec); size_t handlersCount = listenerInfo.eventListenerVector.size(); for (size_t i = 0, outputIndex = 0; i < handlersCount; ++i) { const JSEventListener* jsListener = JSEventListener::cast(listenerInfo.eventListenerVector[i].listener.get()); if (!jsListener) { ASSERT_NOT_REACHED(); continue; } // Hide listeners from other contexts. if (jsListener->isolatedWorld() != currentWorld(exec)) continue; JSObject* function = jsListener->jsFunction(document); JSObject* listenerEntry = constructEmptyObject(exec); listenerEntry->putDirect(exec->globalData(), Identifier(exec, "listener"), function); listenerEntry->putDirect(exec->globalData(), Identifier(exec, "useCapture"), jsBoolean(listenerInfo.eventListenerVector[i].useCapture)); result->putDirectIndex(exec, outputIndex++, JSValue(listenerEntry)); } return result; }
template<> EncodedJSValue JSC_HOST_CALL JSTestInterfaceConstructor::construct(ExecState* state) { auto* castedThis = jsCast<JSTestInterfaceConstructor*>(state->callee()); if (UNLIKELY(state->argumentCount() < 1)) return throwVMError(state, createNotEnoughArgumentsError(state)); ExceptionCode ec = 0; auto str1 = state->argument(0).toWTFString(state); if (UNLIKELY(state->hadException())) return JSValue::encode(jsUndefined()); auto str2 = state->argument(1).isUndefined() ? ASCIILiteral("defaultString") : state->uncheckedArgument(1).toWTFString(state); if (UNLIKELY(state->hadException())) return JSValue::encode(jsUndefined()); ScriptExecutionContext* context = castedThis->scriptExecutionContext(); if (UNLIKELY(!context)) return throwConstructorDocumentUnavailableError(*state, "TestInterface"); auto object = TestInterface::create(*context, str1, str2, ec); if (UNLIKELY(ec)) { setDOMException(state, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)))); }
EncodedJSValue JSC_HOST_CALL JSTestNamedConstructorNamedConstructor::constructJSTestNamedConstructor(ExecState* exec) { JSTestNamedConstructorNamedConstructor* castedThis = jsCast<JSTestNamedConstructorNamedConstructor*>(exec->callee()); if (exec->argumentCount() < 1) return throwVMError(exec, createNotEnoughArgumentsError(exec)); ExceptionCode ec = 0; const String& str1(ustringToString(MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).toString(exec)->value(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); const String& str2(ustringToString(MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined).toString(exec)->value(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); const String& str3(ustringToString(MAYBE_MISSING_PARAMETER(exec, 2, DefaultIsNullString).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 2, DefaultIsNullString).toString(exec)->value(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); RefPtr<TestNamedConstructor> object = TestNamedConstructor::createForJSConstructor(castedThis->document(), str1, str2, str3, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get()))); }