static EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncSet(ExecState* exec) { VM& vm = exec->vm(); auto throwScope = DECLARE_THROW_SCOPE(vm); JSWebAssemblyTable* table = getTable(exec, vm, exec->thisValue()); RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); JSValue value = exec->argument(1); WebAssemblyFunction* wasmFunction; WebAssemblyWrapperFunction* wasmWrapperFunction; if (!value.isNull() && !isWebAssemblyHostFunction(vm, value, wasmFunction, wasmWrapperFunction)) return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, "WebAssembly.Table.prototype.set expects the second argument to be null or an instance of WebAssembly.Function"_s))); uint32_t index = toNonWrappingUint32(exec, exec->argument(0)); RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); if (index >= table->length()) return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, "WebAssembly.Table.prototype.set expects an integer less than the length of the table"_s))); if (value.isNull()) table->clearFunction(index); else { ASSERT(value.isObject() && isWebAssemblyHostFunction(vm, jsCast<JSObject*>(value), wasmFunction, wasmWrapperFunction)); ASSERT(!!wasmFunction || !!wasmWrapperFunction); if (wasmFunction) table->setFunction(vm, index, wasmFunction); else table->setFunction(vm, index, wasmWrapperFunction); } return JSValue::encode(jsUndefined()); }
// ECMA 8.6.2.2 void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { ASSERT(value); ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); if (propertyName == exec->propertyNames().underscoreProto) { // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla. if (!value.isObject() && !value.isNull()) return; if (!setPrototypeWithCycleCheck(value)) throwError(exec, createError(exec, "cyclic __proto__ value")); return; } // Check if there are any setters or getters in the prototype chain JSValue prototype; for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) { prototype = obj->prototype(); if (prototype.isNull()) { putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); return; } } unsigned attributes; JSCell* specificValue; if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) return; for (JSObject* obj = this; ; obj = asObject(prototype)) { if (JSValue gs = obj->getDirect(propertyName)) { if (gs.isGetterSetter()) { JSObject* setterFunc = asGetterSetter(gs)->setter(); if (!setterFunc) { throwSetterError(exec); return; } CallData callData; CallType callType = setterFunc->getCallData(callData); MarkedArgumentBuffer args; args.append(value); call(exec, setterFunc, callType, callData, this, args); return; } // If there's an existing property on the object or one of its // prototypes it should be replaced, so break here. break; } prototype = obj->prototype(); if (prototype.isNull()) break; } putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); return; }
// ECMA 8.7.2 bool JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (Optional<uint32_t> index = parseIndex(propertyName)) return putToPrimitiveByIndex(exec, index.value(), value, slot.isStrictMode()); // Check if there are any setters or getters in the prototype chain JSObject* obj = synthesizePrototype(exec); if (UNLIKELY(!obj)) return false; JSValue prototype; if (propertyName != exec->propertyNames().underscoreProto) { for (; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) { prototype = obj->getPrototypeDirect(); if (prototype.isNull()) { if (slot.isStrictMode()) throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError); return false; } } } for (; ; obj = asObject(prototype)) { unsigned attributes; PropertyOffset offset = obj->structure()->get(vm, propertyName, attributes); if (offset != invalidOffset) { if (attributes & ReadOnly) { if (slot.isStrictMode()) throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError); return false; } JSValue gs = obj->getDirect(offset); if (gs.isGetterSetter()) return callSetter(exec, *this, gs, value, slot.isStrictMode() ? StrictMode : NotStrictMode); if (gs.isCustomGetterSetter()) return callCustomSetter(exec, gs, attributes & CustomAccessor, obj, slot.thisValue(), value); // If there's an existing property on the object or one of its // prototypes it should be replaced, so break here. break; } prototype = obj->getPrototype(vm, exec); if (vm.exception()) return false; if (prototype.isNull()) break; } if (slot.isStrictMode()) throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError); return false; }
bool Structure::prototypeChainMayInterceptStoreTo(JSGlobalData& globalData, PropertyName propertyName) { unsigned i = propertyName.asIndex(); if (i != PropertyName::NotAnIndex) return anyObjectInChainMayInterceptIndexedAccesses(); for (Structure* current = this; ;) { JSValue prototype = current->storedPrototype(); if (prototype.isNull()) return false; current = prototype.asCell()->structure(); unsigned attributes; JSCell* specificValue; PropertyOffset offset = current->get(globalData, propertyName, attributes, specificValue); if (!JSC::isValidOffset(offset)) continue; if (attributes & (ReadOnly | Accessor)) return true; return false; } }
JSValue JSDOMWindow::atob(ExecState* exec, const ArgList& args) { if (args.size() < 1) return throwError(exec, SyntaxError, "Not enough arguments"); JSValue v = args.at(0); if (v.isNull()) return jsEmptyString(exec); UString s = v.toString(exec); if (!s.is8Bit()) { setDOMException(exec, INVALID_CHARACTER_ERR); return jsUndefined(); } Vector<char> in(s.size()); for (int i = 0; i < s.size(); ++i) in[i] = static_cast<char>(s.data()[i]); Vector<char> out; if (!base64Decode(in, out)) return throwError(exec, GeneralError, "Cannot decode base64"); return jsString(exec, String(out.data(), out.size())); }
RuntimeType runtimeTypeForValue(JSValue value) { if (UNLIKELY(!value)) return TypeNothing; if (value.isUndefined()) return TypeUndefined; if (value.isNull()) return TypeNull; if (value.isAnyInt()) return TypeAnyInt; if (value.isNumber()) return TypeNumber; if (value.isString()) return TypeString; if (value.isBoolean()) return TypeBoolean; if (value.isObject()) return TypeObject; if (value.isFunction()) return TypeFunction; if (value.isSymbol()) return TypeSymbol; return TypeNothing; }
JSValue JSCommandLineAPIHost::getEventListeners(ExecState& state) { if (state.argumentCount() < 1) return jsUndefined(); JSValue value = state.uncheckedArgument(0); if (!value.isObject() || value.isNull()) return jsUndefined(); Node* node = JSNode::toWrapped(value); if (!node) return jsUndefined(); Vector<EventListenerInfo> listenersArray; wrapped().getEventListenersImpl(node, listenersArray); JSObject* result = constructEmptyObject(&state); for (size_t i = 0; i < listenersArray.size(); ++i) { JSArray* listeners = getJSListenerFunctions(state, &node->document(), listenersArray[i]); if (!listeners->length()) continue; AtomicString eventType = listenersArray[i].eventType; result->putDirect(state.vm(), Identifier::fromString(&state, eventType.impl()), JSValue(listeners)); } return result; }
void dumpImmediate(JSValue value) { if (value.isNull()) write(NullTag); else if (value.isUndefined()) write(UndefinedTag); else if (value.isNumber()) { if (value.isInt32()) { if (!value.asInt32()) write(ZeroTag); else if (value.asInt32() == 1) write(OneTag); else { write(IntTag); write(static_cast<uint32_t>(value.asInt32())); } } else { write(DoubleTag); write(value.asDouble()); } } else if (value.isBoolean()) { if (value.isTrue()) write(TrueTag); else write(FalseTag); } }
JSValue JSInjectedScriptHost::getEventListeners(ExecState* exec) { if (exec->argumentCount() < 1) return jsUndefined(); JSValue value = exec->argument(0); if (!value.isObject() || value.isNull()) return jsUndefined(); Node* node = toNode(value); if (!node) return jsUndefined(); // This can only happen for orphan DocumentType nodes. Document* document = node->document(); if (!node->document()) return jsUndefined(); Vector<EventListenerInfo> listenersArray; impl()->getEventListenersImpl(node, listenersArray); JSObject* result = constructEmptyObject(exec); for (size_t i = 0; i < listenersArray.size(); ++i) { JSArray* listeners = getJSListenerFunctions(exec, document, listenersArray[i]); if (!listeners->length()) continue; AtomicString eventType = listenersArray[i].eventType; result->putDirect(exec->globalData(), Identifier(exec, eventType.impl()), JSValue(listeners)); } return result; }
RuntimeType TypeSet::getRuntimeTypeForValue(JSValue v) { RuntimeType ret; if (v.isFunction()) ret = TypeFunction; else if (v.isUndefined()) ret = TypeUndefined; else if (v.isNull()) ret = TypeNull; else if (v.isBoolean()) ret = TypeBoolean; else if (v.isMachineInt()) ret = TypeMachineInt; else if (v.isNumber()) ret = TypeNumber; else if (v.isString()) ret = TypeString; else if (v.isPrimitive()) ret = TypePrimitive; else if (v.isObject()) ret = TypeObject; else CRASH(); return ret; }
bool JSValueIsNull(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isNull(); }
void JSHTMLDataGridElement::setDataSource(ExecState*, JSValue value) { if (value.isNull()) { static_cast<HTMLDataGridElement*>(impl())->setDataSource(0); return; } static_cast<HTMLDataGridElement*>(impl())->setDataSource(JSDataGridDataSource::create(value, impl()->document()->frame())); }
bool JSValueIsNull(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSValue jsValue = toJS(exec, value); return jsValue.isNull(); }
std::unique_ptr<PolyProtoAccessChain> PolyProtoAccessChain::create(JSGlobalObject* globalObject, JSCell* base, JSObject* target, bool& usesPolyProto) { JSCell* current = base; VM& vm = *base->vm(); bool found = false; usesPolyProto = false; std::unique_ptr<PolyProtoAccessChain> result(new PolyProtoAccessChain()); for (unsigned iterationNumber = 0; true; ++iterationNumber) { Structure* structure = current->structure(vm); if (!structure->propertyAccessesAreCacheable()) return nullptr; if (structure->isProxy()) return nullptr; if (structure->isDictionary()) { ASSERT(structure->isObject()); if (structure->hasBeenFlattenedBefore()) return nullptr; structure->flattenDictionaryStructure(vm, asObject(current)); } // To save memory, we don't include the base in the chain. We let // AccessCase provide the base to us as needed. if (iterationNumber) result->m_chain.append(structure); else RELEASE_ASSERT(current == base); if (current == target) { found = true; break; } // We only have poly proto if we need to access our prototype via // the poly proto protocol. If the slot base is the only poly proto // thing in the chain, and we have a cache hit on it, then we're not // poly proto. usesPolyProto |= structure->hasPolyProto(); JSValue prototype = structure->prototypeForLookup(globalObject, current); if (prototype.isNull()) break; current = asObject(prototype); } if (!found && !!target) return nullptr; return result; }
IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, Structure* head) : m_globalObject(globalObject) , m_head(head) { JSValue prototype = head->prototypeForLookup(globalObject); if (prototype.isNull()) return; for (Structure* current = asObject(prototype)->structure(); current; current = current->storedPrototypeStructure()) m_vector.append(current); }
IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, JSValue prototype) : m_globalObject(globalObject) , m_prototype(prototype) { ASSERT(m_prototype.isNull() || m_prototype.isObject()); if (prototype.isNull()) return; for (Structure* current = asObject(prototype)->structure(); current; current = current->storedPrototypeStructure()) m_vector.append(current); }
bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; PrivateIdentifier* i = (PrivateIdentifier*)methodName; if (!i->isString) return false; // Special case the "eval" method. if (methodName == _NPN_GetStringIdentifier("eval")) { if (argCount != 1) return false; if (args[0].type != NPVariantType_String) return false; return _NPN_Evaluate(npp, o, (NPString *)&args[0].value.stringValue, result); } // Lookup the function object. RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); JSLock lock; JSValue* func = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string)); if (func->isNull()) { NULL_TO_NPVARIANT(*result); return false; } if (func->isUndefined()) { VOID_TO_NPVARIANT(*result); return false; } // Call the function object. JSObject *funcImp = static_cast<JSObject*>(func); JSObject *thisObj = const_cast<JSObject*>(obj->imp); List argList = listFromVariantArgs(exec, args, argCount, rootObject); rootObject->interpreter()->startTimeoutCheck(); JSValue *resultV = funcImp->call (exec, thisObj, argList); rootObject->interpreter()->stopTimeoutCheck(); // Convert and return the result of the function call. convertValueToNPVariant(exec, resultV, result); return true; } if (o->_class->invoke) return o->_class->invoke(o, methodName, args, argCount, result); VOID_TO_NPVARIANT(*result); return true; }
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; }
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 JSValueIsNull(JSContextRef ctx, JSValueRef value) { if (!ctx) { ASSERT_NOT_REACHED(); return false; } ExecState* exec = toJS(ctx); JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); return jsValue.isNull(); }
JSValue JSInspectorCallbackWrapper::wrap(ExecState* unwrappedExec, JSValue unwrappedValue) { if (!unwrappedValue.isObject()) return unwrappedValue; JSObject* unwrappedObject = asObject(unwrappedValue); if (unwrappedObject->inherits(&JSInspectorCallbackWrapper::s_info)) return unwrappedObject; if (JSInspectorCallbackWrapper* wrapper = wrappers().get(unwrappedObject)) return wrapper; JSValue prototype = unwrappedObject->prototype(); ASSERT(prototype.isNull() || prototype.isObject()); if (prototype.isNull()) { static Structure* structure = leakInspectorCallbackWrapperStructure(); return new (unwrappedExec) JSInspectorCallbackWrapper(unwrappedExec, unwrappedObject, structure); } return new (unwrappedExec) JSInspectorCallbackWrapper(unwrappedExec, unwrappedObject, createStructure(wrap(unwrappedExec, prototype))); }
static EncodedJSValue JSC_HOST_CALL performProxyRevoke(ExecState* exec) { ProxyRevoke* proxyRevoke = jsCast<ProxyRevoke*>(exec->jsCallee()); JSValue proxyValue = proxyRevoke->proxy(); if (proxyValue.isNull()) return JSValue::encode(jsUndefined()); ProxyObject* proxy = jsCast<ProxyObject*>(proxyValue); VM& vm = exec->vm(); proxy->revoke(vm); proxyRevoke->setProxyToNull(vm); return JSValue::encode(jsUndefined()); }
bool Structure::anyObjectInChainMayInterceptIndexedAccesses() const { for (const Structure* current = this; ;) { if (current->mayInterceptIndexedAccesses()) return true; JSValue prototype = current->storedPrototype(); if (prototype.isNull()) return false; current = asObject(prototype)->structure(); } }
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; }
EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec) { JSValue proto = exec->argument(0); if (!proto.isObject() && !proto.isNull()) return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null."))); JSObject* newObject = proto.isObject() ? constructEmptyObject(exec, asObject(proto)) : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure()); if (exec->argument(1).isUndefined()) return JSValue::encode(newObject); if (!exec->argument(1).isObject()) return throwVMError(exec, createTypeError(exec, ASCIILiteral("Property descriptor list must be an Object."))); return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1)))); }
void ScriptCallStack::initialize() { if (!m_caller || m_initialized) return; JSValue func = m_exec->interpreter()->retrieveCaller(m_exec, m_caller); while (!func.isNull()) { InternalFunction* internalFunction = asInternalFunction(func); ArgList emptyArgList; m_frames.append(ScriptCallFrame(internalFunction->name(m_exec), UString(), 0, emptyArgList, 0)); func = m_exec->interpreter()->retrieveCaller(m_exec, internalFunction); } m_initialized = true; }
bool jsIsObjectType(JSValue v) { if (!v.isCell()) return v.isNull(); JSType type = asCell(v)->structure()->typeInfo().type(); if (type == NumberType || type == StringType) return false; if (type == ObjectType) { if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined()) return false; CallData callData; if (asObject(v)->getCallData(callData) != CallTypeNone) return false; } return true; }
bool JSString::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSString* thisObject = jsCast<JSString*>(cell); // The semantics here are really getPropertySlot, not getOwnPropertySlot. // This function should only be called by JSValue::get. if (thisObject->getStringPropertySlot(exec, propertyName, slot)) return true; slot.setBase(thisObject); JSObject* object; for (JSValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) { object = asObject(prototype); if (object->methodTable()->getOwnPropertySlot(object, exec, propertyName, slot)) return true; } slot.setUndefined(); return true; }
void NPRuntimeObjectMap::convertJSValueToNPVariant(ExecState* exec, JSValue value, NPVariant& variant) { JSLock lock(SilenceAssertionsOnly); VOID_TO_NPVARIANT(variant); if (value.isNull()) { NULL_TO_NPVARIANT(variant); return; } if (value.isUndefined()) { VOID_TO_NPVARIANT(variant); return; } if (value.isBoolean()) { BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), variant); return; } if (value.isNumber()) { DOUBLE_TO_NPVARIANT(value.toNumber(exec), variant); return; } if (value.isString()) { CString utf8String = value.toString(exec).utf8(); // This should use NPN_MemAlloc, but we know that it uses malloc under the hood. char* utf8Characters = static_cast<char*>(malloc(utf8String.length())); memcpy(utf8Characters, utf8String.data(), utf8String.length()); STRINGN_TO_NPVARIANT(utf8Characters, utf8String.length(), variant); return; } if (value.isObject()) { NPObject* npObject = getOrCreateNPObject(asObject(value)); OBJECT_TO_NPVARIANT(npObject, variant); return; } ASSERT_NOT_REACHED(); }
bool jsIsObjectTypeOrNull(CallFrame* callFrame, JSValue v) { if (!v.isCell()) return v.isNull(); JSType type = v.asCell()->type(); if (type == StringType || type == SymbolType) return false; if (type >= ObjectType) { if (asObject(v)->structure(callFrame->vm())->masqueradesAsUndefined(callFrame->lexicalGlobalObject())) return false; CallData callData; JSObject* object = asObject(v); if (object->methodTable(callFrame->vm())->getCallData(object, callData) != CallTypeNone) return false; } return true; }