static RefPtr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState* exec, JSValue value) { if (!value.isObject()) { throwTypeError(exec); return nullptr; } JSDictionary jsDictionary(exec, value.getObject()); auto result = adoptRef(*new CryptoAlgorithmRsaOaepParams); if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) { ASSERT(exec->hadException()); return nullptr; } JSValue labelValue = getProperty(exec, value.getObject(), "label"); if (exec->hadException()) return nullptr; result->hasLabel = !labelValue.isUndefinedOrNull(); if (!result->hasLabel) return WTFMove(result); CryptoOperationData labelData; if (!cryptoOperationDataFromJSValue(exec, labelValue, labelData)) { ASSERT(exec->hadException()); return nullptr; } result->label.append(labelData.first, labelData.second); return WTFMove(result); }
static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState* exec, JSValue value) { if (!value.isObject()) { throwTypeError(exec); return nullptr; } auto result = std::make_unique<CryptoAlgorithmRsaKeyGenParams>(); JSValue modulusLengthValue = getProperty(exec, value.getObject(), "modulusLength"); if (exec->hadException()) return nullptr; // FIXME: Why no EnforceRange? Filed as <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23779>. result->modulusLength = toUInt32(exec, modulusLengthValue, NormalConversion); if (exec->hadException()) return nullptr; JSValue publicExponentValue = getProperty(exec, value.getObject(), "publicExponent"); if (exec->hadException()) return nullptr; RefPtr<Uint8Array> publicExponentArray = toUint8Array(publicExponentValue); if (!publicExponentArray) { throwTypeError(exec, "Expected a Uint8Array in publicExponent"); return nullptr; } result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength()); return WTF::move(result); }
static RefPtr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState& state, JSValue value) { if (!value.isObject()) { throwTypeError(&state); return nullptr; } JSDictionary jsDictionary(&state, value.getObject()); auto result = adoptRef(*new CryptoAlgorithmRsaKeyGenParams); JSValue modulusLengthValue = getProperty(&state, value.getObject(), "modulusLength"); if (state.hadException()) return nullptr; // FIXME: Why no EnforceRange? Filed as <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23779>. result->modulusLength = convert<uint32_t>(state, modulusLengthValue, NormalConversion); if (state.hadException()) return nullptr; JSValue publicExponentValue = getProperty(&state, value.getObject(), "publicExponent"); if (state.hadException()) return nullptr; RefPtr<Uint8Array> publicExponentArray = toUint8Array(publicExponentValue); if (!publicExponentArray) { throwTypeError(&state, "Expected a Uint8Array in publicExponent"); return nullptr; } result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength()); result->hasHash = getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Optional); return WTFMove(result); }
int JSPrintFunction::rightValue( JSScopeStack* , JSValue *rv, JSParameterListObject *_param ) { // int ret = 0; if ( _param ) { JSValue *v; for ( v = _param->firstValue(); v != 0L; v = _param->nextValue() ) { if ( v->getObject()->isA() == TYPE_JSIntegerObject ) printf( "%i ", ((JSIntegerObject*)(v->getObject()))->getValue() ); else if ( v->getObject()->isA() == TYPE_JSStringObject ) printf( "%s ", ((JSStringObject*)(v->getObject()))->getString() ); else if ( v->getObject()->isA() == TYPE_JSBoolObject ) { if ( ((JSBoolObject*)(v->getObject()))->getValue() ) printf( "TRUE " ); else printf( "FALSE " ); } else if ( v->getObject()->isA() == TYPE_JSFloatObject ) printf( "%f ", ((JSFloatObject*)(v->getObject()))->getValue() ); } } rv->setObject( new JSObject() ); rv->setAutoDelete( TRUE ); rv->setLeftValue( FALSE ); return 0; }
int JSDocumentWriteFunction::rightValue( JSScopeStack*, JSValue *rv, JSParameterListObject *_param ) { int ret = 0; QString out; if ( _param ) { JSValue *v; int i = 0; for ( v = _param->firstValue(); v != 0L; v = _param->nextValue() ) { i++; if ( i > 1 ) object->getJSWindowObject()->getJSEnvironment()->writeOutput( " " ); if ( v->getObject()->isA() == TYPE_JSIntegerObject ) { out.sprintf("%i",((JSIntegerObject*)(v->getObject()))->getValue() ); object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() ); //printf( "%i ", ((JSIntegerObject*)(v->getObject()))->getValue() ); } else if ( v->getObject()->isA() == TYPE_JSStringObject ) { out = ((JSStringObject*)(v->getObject()))->getString(); object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() ); //printf( "%s ", ((JSStringObject*)(v->getObject()))->getString() ); } else if ( v->getObject()->isA() == TYPE_JSBoolObject ) { if ( ((JSBoolObject*)(v->getObject()))->getValue() ) { out = "TRUE"; object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() ); //printf( "TRUE " ); } else { out = "FALSE"; object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() ); //printf( "FALSE " ); } } else if ( v->getObject()->isA() == TYPE_JSFloatObject ) { out.sprintf( "%f", ((JSFloatObject*)(v->getObject()))->getValue() ); object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() ); //printf( "%f ", ((JSFloatObject*)(v->getObject()))->getValue() ); } } } rv->setObject( new JSObject() ); rv->setAutoDelete( TRUE ); rv->setLeftValue( FALSE ); return ret; }
static RefPtr<CryptoAlgorithmParameters> createAesCbcParams(ExecState* exec, JSValue value) { if (!value.isObject()) { throwTypeError(exec); return nullptr; } JSValue iv = getProperty(exec, value.getObject(), "iv"); if (exec->hadException()) return nullptr; auto result = adoptRef(*new CryptoAlgorithmAesCbcParams); CryptoOperationData ivData; if (!cryptoOperationDataFromJSValue(exec, iv, ivData)) { ASSERT(exec->hadException()); return nullptr; } if (ivData.second != 16) { exec->vm().throwException(exec, createError(exec, "AES-CBC initialization data must be 16 bytes")); return nullptr; } memcpy(result->iv.data(), ivData.first, ivData.second); return WTFMove(result); }
inline Structure* getBoundFunctionStructure(VM& vm, ExecState* exec, JSGlobalObject* globalObject, JSObject* targetFunction) { auto scope = DECLARE_THROW_SCOPE(vm); JSValue prototype = targetFunction->getPrototype(vm, exec); RETURN_IF_EXCEPTION(scope, nullptr); JSFunction* targetJSFunction = jsDynamicCast<JSFunction*>(vm, targetFunction); // We only cache the structure of the bound function if the bindee is a JSFunction since there // isn't any good place to put the structure on Internal Functions. if (targetJSFunction) { Structure* structure = targetJSFunction->rareData(vm)->getBoundFunctionStructure(); if (structure && structure->storedPrototype() == prototype && structure->globalObject() == globalObject) return structure; } Structure* result = globalObject->boundFunctionStructure(); // It would be nice if the structure map was keyed global objects in addition to the other things. Unfortunately, it is not // currently. Whoever works on caching structure changes for prototype transistions should consider this problem as well. // See: https://bugs.webkit.org/show_bug.cgi?id=152738 if (prototype.isObject() && prototype.getObject()->globalObject() == globalObject) { result = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype.getObject(), result); ASSERT_WITH_SECURITY_IMPLICATION(result->globalObject() == globalObject); } else result = Structure::create(vm, globalObject, prototype, result->typeInfo(), result->classInfo()); if (targetJSFunction) targetJSFunction->rareData(vm)->setBoundFunctionStructure(vm, result); return result; }
bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass) { if (!ctx || !jsClass) { ASSERT_NOT_REACHED(); return false; } ExecState* exec = toJS(ctx); JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); if (JSObject* o = jsValue.getObject()) { if (o->inherits(JSProxy::info())) o = jsCast<JSProxy*>(o)->target(); if (o->inherits(JSCallbackObject<JSGlobalObject>::info())) return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass); if (o->inherits(JSCallbackObject<JSDestructibleObject>::info())) return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass); #if JSC_OBJC_API_ENABLED if (o->inherits(JSCallbackObject<JSAPIWrapperObject>::info())) return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(o)->inherits(jsClass); #endif } return false; }
IterationRecord iteratorForIterable(ExecState* state, JSValue iterable) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue iteratorFunction = iterable.get(state, vm.propertyNames->iteratorSymbol); RETURN_IF_EXCEPTION(scope, { }); CallData iteratorFunctionCallData; CallType iteratorFunctionCallType = getCallData(vm, iteratorFunction, iteratorFunctionCallData); if (iteratorFunctionCallType == CallType::None) { throwTypeError(state, scope); return { }; } ArgList iteratorFunctionArguments; JSValue iterator = call(state, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments); RETURN_IF_EXCEPTION(scope, { }); if (!iterator.isObject()) { throwTypeError(state, scope); return { }; } JSValue nextMethod = iterator.getObject()->get(state, vm.propertyNames->next); RETURN_IF_EXCEPTION(scope, { }); return { iterator, nextMethod }; }
EncodedJSValue JSC_HOST_CALL constructJSHTMLElement(ExecState& exec) { auto* jsConstructor = jsCast<DOMConstructorObject*>(exec.callee()); auto* context = jsConstructor->scriptExecutionContext(); if (!is<Document>(context)) return throwConstructorDocumentUnavailableError(exec, "HTMLElement"); auto& document = downcast<Document>(*context); auto* window = document.domWindow(); if (!window) return throwVMTypeError(&exec, ASCIILiteral("new.target is not a valid custom element constructor")); auto* registry = window->customElementsRegistry(); if (!registry) return throwVMTypeError(&exec, ASCIILiteral("new.target is not a valid custom element constructor")); VM& vm = exec.vm(); JSValue newTargetValue = exec.thisValue(); JSObject* newTarget = newTargetValue.getObject(); auto* elementInterface = registry->findInterface(newTarget); if (!elementInterface) return throwVMTypeError(&exec, ASCIILiteral("new.target does not define a custom element")); if (!elementInterface->isUpgradingElement()) { auto* globalObject = jsConstructor->globalObject(); Structure* baseStructure = getDOMStructure<JSHTMLElement>(vm, *globalObject); auto* newElementStructure = InternalFunction::createSubclassStructure(&exec, newTargetValue, baseStructure); if (UNLIKELY(exec.hadException())) return JSValue::encode(jsUndefined()); Ref<HTMLElement> element = HTMLElement::create(elementInterface->name(), document); element->setIsUnresolvedCustomElement(); auto* jsElement = JSHTMLElement::create(newElementStructure, globalObject, element.get()); cacheWrapper(globalObject->world(), element.ptr(), jsElement); return JSValue::encode(jsElement); } Element* elementToUpgrade = elementInterface->lastElementInConstructionStack(); if (!elementToUpgrade) { throwInvalidStateError(exec, ASCIILiteral("Cannot instantiate a custom element inside its own constrcutor during upgrades")); return JSValue::encode(jsUndefined()); } JSValue elementWrapperValue = toJS(&exec, jsConstructor->globalObject(), *elementToUpgrade); ASSERT(elementWrapperValue.isObject()); JSValue newPrototype = newTarget->get(&exec, vm.propertyNames->prototype); if (exec.hadException()) return JSValue::encode(jsUndefined()); JSObject* elementWrapperObject = asObject(elementWrapperValue); JSObject::setPrototype(elementWrapperObject, &exec, newPrototype, true /* shouldThrowIfCantSet */); if (exec.hadException()) return JSValue::encode(jsUndefined()); elementInterface->didUpgradeLastElementInConstructionStack(); return JSValue::encode(elementWrapperValue); }
ScriptObject InjectedScriptManager::createInjectedScript(const String& source, ScriptState* scriptState, int id) { JSLockHolder lock(scriptState); SourceCode sourceCode = makeSource(source); JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); JSValue globalThisValue = scriptState->globalThisValue(); JSValue evaluationException; JSValue evaluationReturnValue; if (isMainThread()) evaluationReturnValue = JSMainThreadExecState::evaluate(scriptState, sourceCode, globalThisValue, &evaluationException); else { JSC::JSLockHolder lock(scriptState); evaluationReturnValue = JSC::evaluate(scriptState, sourceCode, globalThisValue, &evaluationException); } if (evaluationException) return ScriptObject(); JSValue functionValue = evaluationReturnValue; CallData callData; CallType callType = getCallData(functionValue, callData); if (callType == CallTypeNone) return ScriptObject(); MarkedArgumentBuffer args; args.append(toJS(scriptState, globalObject, m_injectedScriptHost.get())); args.append(globalThisValue); args.append(jsNumber(id)); JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args); if (result.isObject()) return ScriptObject(scriptState, result.getObject()); return ScriptObject(); }
Deprecated::ScriptObject InjectedScriptManager::createInjectedScript(const String& source, ExecState* scriptState, int id) { JSLockHolder lock(scriptState); SourceCode sourceCode = makeSource(source); JSGlobalObject* globalObject = scriptState->lexicalGlobalObject(); JSValue globalThisValue = scriptState->globalThisValue(); NakedPtr<Exception> evaluationException; InspectorEvaluateHandler evaluateHandler = m_environment.evaluateHandler(); JSValue functionValue = evaluateHandler(scriptState, sourceCode, globalThisValue, evaluationException); if (evaluationException) return Deprecated::ScriptObject(); CallData callData; CallType callType = getCallData(functionValue, callData); if (callType == CallTypeNone) return Deprecated::ScriptObject(); MarkedArgumentBuffer args; args.append(m_injectedScriptHost->wrapper(scriptState, globalObject)); args.append(globalThisValue); args.append(jsNumber(id)); JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args); scriptState->clearException(); if (result.isObject()) return Deprecated::ScriptObject(scriptState, result.getObject()); return Deprecated::ScriptObject(); }
JSValue JSHTMLCanvasElement::getContext(ExecState* exec) { HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(impl()); const String& contextId = exec->argument(0).toString(exec)->value(exec); RefPtr<CanvasContextAttributes> attrs; #if ENABLE(WEBGL) if (HTMLCanvasElement::is3dType(contextId)) { get3DContextAttributes(exec, attrs); if (exec->hadException()) return jsUndefined(); } #endif CanvasRenderingContext* context = canvas->getContext(contextId, attrs.get()); if (!context) return jsNull(); JSValue jsValue = toJS(exec, globalObject(), WTF::getPtr(context)); if (InspectorInstrumentation::canvasAgentEnabled(canvas->document())) { ScriptObject contextObject(exec, jsValue.getObject()); ScriptObject wrapped; if (context->is2d()) wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(canvas->document(), contextObject); #if ENABLE(WEBGL) else if (context->is3d()) wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(canvas->document(), contextObject); #endif if (!wrapped.hasNoValue()) return wrapped.jsValue(); } return jsValue; }
static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoGetterFuncToStringTag(ExecState* exec) { JSValue thisValue = exec->thisValue(); if (!thisValue.isObject()) return JSValue::encode(jsUndefined()); VM& vm = exec->vm(); switch (thisValue.getObject()->classInfo()->typedArrayStorageType) { case TypeUint8Clamped: return JSValue::encode(jsString(&vm, "Uint8ClampedArray")); case TypeInt32: return JSValue::encode(jsString(&vm, "Int32Array")); case TypeUint32: return JSValue::encode(jsString(&vm, "Uint32Array")); case TypeFloat64: return JSValue::encode(jsString(&vm, "Float64Array")); case TypeFloat32: return JSValue::encode(jsString(&vm, "Float32Array")); case TypeInt8: return JSValue::encode(jsString(&vm, "Int8Array")); case TypeUint8: return JSValue::encode(jsString(&vm, "Uint8Array")); case TypeInt16: return JSValue::encode(jsString(&vm, "Int16Array")); case TypeUint16: return JSValue::encode(jsString(&vm, "Uint16Array")); case NotTypedArray: case TypeDataView: return JSValue::encode(jsUndefined()); } RELEASE_ASSERT_NOT_REACHED(); }
ScriptObject InjectedScriptHost::createInjectedScript(const String& source, ScriptState* scriptState, long id) { SourceCode sourceCode = makeSource(stringToUString(source)); JSLock lock(SilenceAssertionsOnly); JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); JSValue globalThisValue = scriptState->globalThisValue(); Completion comp = JSMainThreadExecState::evaluate(scriptState, globalObject->globalScopeChain(), sourceCode, globalThisValue); if (comp.complType() != JSC::Normal && comp.complType() != JSC::ReturnValue) return ScriptObject(); JSValue functionValue = comp.value(); CallData callData; CallType callType = functionValue.getCallData(callData); if (callType == CallTypeNone) return ScriptObject(); MarkedArgumentBuffer args; args.append(toJS(scriptState, globalObject, this)); args.append(globalThisValue); args.append(jsNumber(scriptState, id)); args.append(jsString(scriptState, String("JSC"))); JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args); if (result.isObject()) return ScriptObject(scriptState, result.getObject()); return ScriptObject(); }
JSValue JSPopStateEvent::state(ExecState* exec) const { JSValue cachedValue = m_state.get(); if (!cachedValue.isEmpty()) { // We cannot use a cached object if we are in a different world than the one it was created in. if (!cachedValue.isObject() || &worldForDOMObject(cachedValue.getObject()) == ¤tWorld(exec)) return cachedValue; ASSERT_NOT_REACHED(); } PopStateEvent& event = impl(); if (!event.state().hasNoValue()) { // We need to make sure a PopStateEvent does not leak objects in its state property across isolated DOM worlds. // Ideally, we would check that the worlds have different privileges but that's not possible yet. JSValue state = event.state().jsValue(); if (state.isObject() && &worldForDOMObject(state.getObject()) != ¤tWorld(exec)) { if (RefPtr<SerializedScriptValue> serializedValue = event.trySerializeState(exec)) state = serializedValue->deserialize(exec, globalObject(), nullptr); else state = jsNull(); } return cacheState(exec, const_cast<JSPopStateEvent*>(this), state); } History* history = event.history(); if (!history || !event.serializedState()) return cacheState(exec, const_cast<JSPopStateEvent*>(this), jsNull()); // There's no cached value from a previous invocation, nor a state value was provided by the // event, but there is a history object, so first we need to see if the state object has been // deserialized through the history object already. // The current history state object might've changed in the meantime, so we need to take care // of using the correct one, and always share the same deserialization with history.state. bool isSameState = history->isSameAsCurrentState(event.serializedState().get()); JSValue result; if (isSameState) { JSHistory* jsHistory = jsCast<JSHistory*>(toJS(exec, globalObject(), history).asCell()); result = jsHistory->state(exec); } else result = event.serializedState()->deserialize(exec, globalObject(), 0); return cacheState(exec, const_cast<JSPopStateEvent*>(this), result); }
static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue val = state->argument(0); // If the given bytes argument is not a BufferSource, a TypeError exception is thrown. JSArrayBuffer* arrayBuffer = val.getObject() ? jsDynamicCast<JSArrayBuffer*>(val.getObject()) : nullptr; JSArrayBufferView* arrayBufferView = val.getObject() ? jsDynamicCast<JSArrayBufferView*>(val.getObject()) : nullptr; if (!(arrayBuffer || arrayBufferView)) return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val)))); if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered()) return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val)))); size_t byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0; size_t byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength(); const auto* base = arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data()); Wasm::Plan plan(&vm, base + byteOffset, byteSize); // On failure, a new WebAssembly.CompileError is thrown. plan.run(); if (plan.failed()) return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage()))); // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module. auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->jsCallee())->globalObject()->WebAssemblyModuleStructure()); RETURN_IF_EXCEPTION(scope, { }); // The export symbol table is the same for all Instances of a Module. SymbolTable* exportSymbolTable = SymbolTable::create(vm); for (auto& exp : plan.exports()) { auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary); exportSymbolTable->set(NoLockingNecessary, exp.field.impl(), SymbolTableEntry(VarOffset(offset))); } // Only wasm-internal functions have a callee, stubs to JS do not. unsigned calleeCount = plan.internalFunctionCount(); JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmToJSStubs(), plan.takeFunctionIndexSpace(), exportSymbolTable, calleeCount); plan.initializeCallees(state->jsCallee()->globalObject(), [&] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) { result->setJSEntrypointCallee(vm, calleeIndex, jsEntrypointCallee); result->setWasmEntrypointCallee(vm, calleeIndex, wasmEntrypointCallee); }); return JSValue::encode(result); }
bool JSValueIsObjectOfClass(JSContextRef, JSValueRef value, JSClassRef jsClass) { JSValue* jsValue = toJS(value); if (JSObject* o = jsValue->getObject()) if (o->inherits(&JSCallbackObject::info)) return static_cast<JSCallbackObject*>(o)->inherits(jsClass); return false; }
template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& state, JSValue value) { VM& vm = state.vm(); auto throwScope = DECLARE_THROW_SCOPE(vm); bool isNullOrUndefined = value.isUndefinedOrNull(); auto* object = isNullOrUndefined ? nullptr : value.getObject(); if (UNLIKELY(!isNullOrUndefined && !object)) { throwTypeError(&state, throwScope); return { }; } DictionaryImplName result; JSValue boolMemberValue; if (isNullOrUndefined) boolMemberValue = jsUndefined(); else { boolMemberValue = object->get(&state, Identifier::fromString(&state, "boolMember")); RETURN_IF_EXCEPTION(throwScope, { }); } if (!boolMemberValue.isUndefined()) { result.boolMember = convert<IDLBoolean>(state, boolMemberValue); RETURN_IF_EXCEPTION(throwScope, { }); } JSValue callbackMemberValue; if (isNullOrUndefined) callbackMemberValue = jsUndefined(); else { callbackMemberValue = object->get(&state, Identifier::fromString(&state, "callbackMember")); RETURN_IF_EXCEPTION(throwScope, { }); } if (!callbackMemberValue.isUndefined()) { result.callbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, callbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject())); RETURN_IF_EXCEPTION(throwScope, { }); } JSValue enumMemberValue; if (isNullOrUndefined) enumMemberValue = jsUndefined(); else { enumMemberValue = object->get(&state, Identifier::fromString(&state, "enumMember")); RETURN_IF_EXCEPTION(throwScope, { }); } if (!enumMemberValue.isUndefined()) { result.enumMember = convert<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, enumMemberValue); RETURN_IF_EXCEPTION(throwScope, { }); } JSValue stringMemberValue; if (isNullOrUndefined) stringMemberValue = jsUndefined(); else { stringMemberValue = object->get(&state, Identifier::fromString(&state, "stringMember")); RETURN_IF_EXCEPTION(throwScope, { }); } if (!stringMemberValue.isUndefined()) { result.stringMember = convert<IDLDOMString>(state, stringMemberValue); RETURN_IF_EXCEPTION(throwScope, { }); } return result; }
int main(int argc, char **argv) { // expecting a filename if (argc < 2) { fprintf(stderr, "You have to specify at least one filename\n"); return -1; } bool ret = true; { JSLock lock; // create interpreter w/ global object Global* global = new Global(); RefPtr<Interpreter> interp = new Interpreter(global); ExecState *exec = interp->globalExec(); MyObject *myObject = (MyObject *)_NPN_CreateObject (NPP(0), myFunctionPtrs); // FIXME // global->put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::CLanguage, (void *)myObject)); for (int i = 1; i < argc; i++) { const char *code = readJavaScriptFromFile(argv[i]); if (code) { // run Completion comp(interp->evaluate("", 0, code)); if (comp.complType() == Throw) { JSValue *exVal = comp.value(); char *msg = exVal->toString(exec).ascii(); int lineno = -1; if (exVal->type() == ObjectType) { JSValue *lineVal = exVal->getObject()->get(exec, Identifier("line")); if (lineVal->type() == NumberType) lineno = int(lineVal->toNumber(exec)); } if (lineno != -1) fprintf(stderr,"Exception, line %d: %s\n",lineno,msg); else fprintf(stderr,"Exception: %s\n",msg); ret = false; } else if (comp.complType() == ReturnValue) { char *msg = comp.value()->toString(interp->globalExec()).ascii(); fprintf(stderr,"Return value: %s\n",msg); } } } _NPN_ReleaseObject ((NPObject *)myObject); } // end block, so that Interpreter and global get deleted return ret ? 0 : 3; }
JSValue JSMessageEvent::data(ExecState& state) const { if (JSValue cachedValue = m_data.get()) { // We cannot use a cached object if we are in a different world than the one it was created in. if (!cachedValue.isObject() || &worldForDOMObject(cachedValue.getObject()) == ¤tWorld(&state)) return cachedValue; ASSERT_NOT_REACHED(); } MessageEvent& event = wrapped(); JSValue result; switch (event.dataType()) { case MessageEvent::DataTypeScriptValue: { JSValue dataValue = event.dataAsScriptValue(); if (!dataValue) result = jsNull(); else { // We need to make sure MessageEvents do not leak objects in their state property across isolated DOM worlds. // Ideally, we would check that the worlds have different privileges but that's not possible yet. if (dataValue.isObject() && &worldForDOMObject(dataValue.getObject()) != ¤tWorld(&state)) { RefPtr<SerializedScriptValue> serializedValue = event.trySerializeData(&state); if (serializedValue) result = serializedValue->deserialize(state, globalObject()); else result = jsNull(); } else result = dataValue; } break; } case MessageEvent::DataTypeSerializedScriptValue: if (RefPtr<SerializedScriptValue> serializedValue = event.dataAsSerializedScriptValue()) { Vector<RefPtr<MessagePort>> ports = wrapped().ports(); // FIXME: Why does this suppress exceptions? result = serializedValue->deserialize(state, globalObject(), ports, NonThrowing); } else result = jsNull(); break; case MessageEvent::DataTypeString: result = jsStringWithCache(&state, event.dataAsString()); break; case MessageEvent::DataTypeBlob: result = toJS(&state, globalObject(), event.dataAsBlob()); break; case MessageEvent::DataTypeArrayBuffer: result = toJS(&state, globalObject(), event.dataAsArrayBuffer()); break; } // Save the result so we don't have to deserialize the value again. m_data.set(state.vm(), this, result); return result; }
static RefPtr<InspectorValue> jsToInspectorValue(ExecState* scriptState, JSValue value, int maxDepth) { if (!value) { ASSERT_NOT_REACHED(); return nullptr; } if (!maxDepth) return nullptr; maxDepth--; if (value.isNull() || value.isUndefined()) return InspectorValue::null(); if (value.isBoolean()) return InspectorValue::create(value.asBoolean()); if (value.isNumber() && value.isDouble()) return InspectorValue::create(value.asNumber()); if (value.isNumber() && value.isMachineInt()) return InspectorValue::create(static_cast<int>(value.asMachineInt())); if (value.isString()) return InspectorValue::create(value.getString(scriptState)); if (value.isObject()) { if (isJSArray(value)) { Ref<InspectorArray> inspectorArray = InspectorArray::create(); JSArray* array = asArray(value); unsigned length = array->length(); for (unsigned i = 0; i < length; i++) { JSValue element = array->getIndex(scriptState, i); RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element, maxDepth); if (!elementValue) return nullptr; inspectorArray->pushValue(WTFMove(elementValue)); } return WTFMove(inspectorArray); } Ref<InspectorObject> inspectorObject = InspectorObject::create(); JSObject* object = value.getObject(); PropertyNameArray propertyNames(scriptState, PropertyNameMode::Strings); object->methodTable()->getOwnPropertyNames(object, scriptState, propertyNames, EnumerationMode()); for (size_t i = 0; i < propertyNames.size(); i++) { const Identifier& name = propertyNames[i]; JSValue propertyValue = object->get(scriptState, name); RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue, maxDepth); if (!inspectorValue) return nullptr; inspectorObject->setValue(name.string(), WTFMove(inspectorValue)); } return WTFMove(inspectorObject); } ASSERT_NOT_REACHED(); return nullptr; }
ExceptionOr<Ref<JSCustomXPathNSResolver>> JSCustomXPathNSResolver::create(ExecState& state, JSValue value) { if (value.isUndefinedOrNull()) return Exception { TypeError }; auto* resolverObject = value.getObject(); if (!resolverObject) return Exception { TYPE_MISMATCH_ERR }; return adoptRef(*new JSCustomXPathNSResolver(state.vm(), resolverObject, asJSDOMWindow(state.vmEntryGlobalObject()))); }
RefPtr<ReadableJSStream> ReadableJSStream::create(ExecState& state, ScriptExecutionContext& scriptExecutionContext) { // FIXME: We should consider reducing the binding code herei (using Dictionary/regular binding constructor and/or improving the IDL generator). JSObject* jsSource; JSValue value = state.argument(0); if (value.isObject()) jsSource = value.getObject(); else if (!value.isUndefined()) { throwVMError(&state, createTypeError(&state, ASCIILiteral("First argument, if any, should be an object"))); return nullptr; } else jsSource = JSFinalObject::create(state.vm(), JSFinalObject::createStructure(state.vm(), state.callee()->globalObject(), jsNull(), 1)); double highWaterMark = 1; JSFunction* sizeFunction = nullptr; value = state.argument(1); if (value.isObject()) { JSObject& strategyObject = *value.getObject(); highWaterMark = normalizeHighWaterMark(state, strategyObject); if (state.hadException()) return nullptr; if (!(sizeFunction = jsDynamicCast<JSFunction*>(getPropertyFromObject(state, strategyObject, "size")))) { if (!state.hadException()) throwVMError(&state, createTypeError(&state, ASCIILiteral("size parameter should be a function"))); return nullptr; } } else if (!value.isUndefined()) { throwVMError(&state, createTypeError(&state, ASCIILiteral("Second argument, if any, should be an object"))); return nullptr; } RefPtr<ReadableJSStream> readableStream = adoptRef(*new ReadableJSStream(scriptExecutionContext, state, jsSource, highWaterMark, sizeFunction)); readableStream->doStart(state); if (state.hadException()) return nullptr; return readableStream; }
PassRefPtr<VoidCallback> toVoidCallback(ExecState* exec, JSValue value) { JSObject* object = value.getObject(); if (!object) return 0; Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); if (!frame) return 0; return JSCustomVoidCallback::create(object, frame); }
static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, JSValue value, int maxDepth) { if (!value) { ASSERT_NOT_REACHED(); return 0; } if (!maxDepth) return 0; maxDepth--; if (value.isNull() || value.isUndefined()) return InspectorValue::null(); if (value.isBoolean()) return InspectorBasicValue::create(value.asBoolean()); if (value.isNumber()) return InspectorBasicValue::create(value.asNumber()); if (value.isString()) { String s = value.getString(scriptState); return InspectorString::create(String(s.characters(), s.length())); } if (value.isObject()) { if (isJSArray(value)) { RefPtr<InspectorArray> inspectorArray = InspectorArray::create(); JSArray* array = asArray(value); unsigned length = array->length(); for (unsigned i = 0; i < length; i++) { // FIXME: What if the array is in sparse mode? https://bugs.webkit.org/show_bug.cgi?id=95610 JSValue element = array->getIndexQuickly(i); RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element, maxDepth); if (!elementValue) return 0; inspectorArray->pushValue(elementValue); } return inspectorArray; } RefPtr<InspectorObject> inspectorObject = InspectorObject::create(); JSObject* object = value.getObject(); PropertyNameArray propertyNames(scriptState); object->methodTable()->getOwnPropertyNames(object, scriptState, propertyNames, ExcludeDontEnumProperties); for (size_t i = 0; i < propertyNames.size(); i++) { const Identifier& name = propertyNames[i]; JSValue propertyValue = object->get(scriptState, name); RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue, maxDepth); if (!inspectorValue) return 0; inspectorObject->setValue(String(name.characters(), name.length()), inspectorValue); } return inspectorObject; } ASSERT_NOT_REACHED(); return 0; }
bool JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(ExecState* exec, JSValue value, CryptoAlgorithmIdentifier& algorithmIdentifier) { // typedef (Algorithm or DOMString) AlgorithmIdentifier; String algorithmName; if (value.isString()) algorithmName = value.toString(exec)->value(exec); else if (value.isObject()) { if (value.getObject()->inherits(StringObject::info())) algorithmName = asString(asStringObject(value)->internalValue())->value(exec); else { // FIXME: This doesn't perform some checks mandated by WebIDL for dictionaries: // - null and undefined input should be treated as if all elements in the dictionary were undefined; // - undefined elements should be treated as having a default value, or as not present if there isn't such; // - RegExp and Date objects cannot be converted to dictionaries. // // This is partially because we don't implement it elsewhere in WebCore yet, and partially because // WebCrypto doesn't yet clearly specify what to do with non-present values in most cases anyway. JSDictionary dictionary(exec, value.getObject()); dictionary.get("name", algorithmName); } } if (exec->hadException()) return false; if (!algorithmName.containsOnlyASCII()) { throwSyntaxError(exec); return false; } if (!CryptoAlgorithmRegistry::singleton().getIdentifierForName(algorithmName, algorithmIdentifier)) { setDOMException(exec, NOT_SUPPORTED_ERR); return false; } return true; }
static JSObject* getCustomElementCallback(ExecState& state, JSObject& prototype, const Identifier& id) { JSValue callback = prototype.get(&state, id); if (state.hadException()) return nullptr; if (callback.isUndefined()) return nullptr; if (!callback.isFunction()) { throwTypeError(&state, ASCIILiteral("A custom element callback must be a function")); return nullptr; } return callback.getObject(); }
PassRefPtr<JSCustomXPathNSResolver> JSCustomXPathNSResolver::create(ExecState* exec, JSValue value) { if (value.isUndefinedOrNull()) return 0; JSObject* resolverObject = value.getObject(); if (!resolverObject) { setDOMException(exec, TYPE_MISMATCH_ERR); return 0; } return adoptRef(new JSCustomXPathNSResolver(exec, resolverObject, asJSDOMWindow(exec->dynamicGlobalObject()))); }
static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, JSValue value) { if (!value) { ASSERT_NOT_REACHED(); return 0; } if (value.isNull() || value.isUndefined()) return InspectorValue::null(); if (value.isBoolean()) return InspectorBasicValue::create(value.getBoolean()); if (value.isNumber()) return InspectorBasicValue::create(value.uncheckedGetNumber()); if (value.isString()) { UString s = value.getString(scriptState); return InspectorString::create(String(s.characters(), s.length())); } if (value.isObject()) { if (isJSArray(&scriptState->globalData(), value)) { RefPtr<InspectorArray> inspectorArray = InspectorArray::create(); JSArray* array = asArray(value); unsigned length = array->length(); for (unsigned i = 0; i < length; i++) { JSValue element = array->getIndex(i); RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element); if (!elementValue) { ASSERT_NOT_REACHED(); elementValue = InspectorValue::null(); } inspectorArray->pushValue(elementValue); } return inspectorArray; } RefPtr<InspectorObject> inspectorObject = InspectorObject::create(); JSObject* object = value.getObject(); PropertyNameArray propertyNames(scriptState); object->getOwnPropertyNames(scriptState, propertyNames); for (size_t i = 0; i < propertyNames.size(); i++) { const Identifier& name = propertyNames[i]; JSValue propertyValue = object->get(scriptState, name); RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue); if (!inspectorValue) { ASSERT_NOT_REACHED(); inspectorValue = InspectorValue::null(); } inspectorObject->setValue(String(name.characters(), name.length()), inspectorValue); } return inspectorObject; } ASSERT_NOT_REACHED(); return 0; }