static inline UString gap(ExecState* exec, JSValue space) { const unsigned maxGapLength = 10; space = unwrapBoxedPrimitive(exec, space); // If the space value is a number, create a gap string with that number of spaces. double spaceCount; if (space.getNumber(spaceCount)) { int count; if (spaceCount > maxGapLength) count = maxGapLength; else if (!(spaceCount > 0)) count = 0; else count = static_cast<int>(spaceCount); UChar spaces[maxGapLength]; for (int i = 0; i < count; ++i) spaces[i] = ' '; return UString(spaces, count); } // If the space value is a string, use it as the gap string, otherwise use no gap string. UString spaces = space.getString(exec); if (spaces.length() > maxGapLength) { spaces = spaces.substringSharingImpl(0, maxGapLength); } return spaces; }
// ECMA 15.9.3 JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, JSValue newTarget, const ArgList& args) { VM& vm = exec->vm(); int numArgs = args.size(); double value; if (numArgs == 0) // new Date() ECMA 15.9.3.3 value = NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(globalObject)); else if (numArgs == 1) { if (args.at(0).inherits(DateInstance::info())) value = asDateInstance(args.at(0))->internalNumber(); else { JSValue primitive = args.at(0).toPrimitive(exec); if (primitive.isString()) value = parseDate(vm, primitive.getString(exec)); else value = primitive.toNumber(exec); } } else value = millisecondsFromComponents(exec, args, WTF::LocalTime); Structure* dateStructure = InternalFunction::createSubclassStructure(exec, newTarget, globalObject->dateStructure()); return DateInstance::create(vm, dateStructure, value); }
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; }
// ECMA 15.9.3 JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args) { VM& vm = exec->vm(); int numArgs = args.size(); double value; if (numArgs == 0) // new Date() ECMA 15.9.3.3 value = jsCurrentTime(); else if (numArgs == 1) { if (args.at(0).inherits(DateInstance::info())) value = asDateInstance(args.at(0))->internalNumber(); else { JSValue primitive = args.at(0).toPrimitive(exec); if (primitive.isString()) value = parseDate(vm, primitive.getString(exec)); else value = primitive.toNumber(exec); } } else { double doubleArguments[7] = { args.at(0).toNumber(exec), args.at(1).toNumber(exec), args.at(2).toNumber(exec), args.at(3).toNumber(exec), args.at(4).toNumber(exec), args.at(5).toNumber(exec), args.at(6).toNumber(exec) }; if (!std::isfinite(doubleArguments[0]) || !std::isfinite(doubleArguments[1]) || (numArgs >= 3 && !std::isfinite(doubleArguments[2])) || (numArgs >= 4 && !std::isfinite(doubleArguments[3])) || (numArgs >= 5 && !std::isfinite(doubleArguments[4])) || (numArgs >= 6 && !std::isfinite(doubleArguments[5])) || (numArgs >= 7 && !std::isfinite(doubleArguments[6]))) value = QNaN; else { GregorianDateTime t; int year = JSC::toInt32(doubleArguments[0]); t.setYear((year >= 0 && year <= 99) ? (year + 1900) : year); t.setMonth(JSC::toInt32(doubleArguments[1])); t.setMonthDay((numArgs >= 3) ? JSC::toInt32(doubleArguments[2]) : 1); t.setHour(JSC::toInt32(doubleArguments[3])); t.setMinute(JSC::toInt32(doubleArguments[4])); t.setSecond(JSC::toInt32(doubleArguments[5])); t.setIsDST(-1); double ms = (numArgs >= 7) ? doubleArguments[6] : 0; value = gregorianDateTimeToMS(vm, t, ms, false); } } return DateInstance::create(vm, globalObject->dateStructure(), value); }
// ECMA 15.9.3 JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args) { int numArgs = args.size(); double value; if (numArgs == 0) // new Date() ECMA 15.9.3.3 value = jsCurrentTime(); else if (numArgs == 1) { if (args.at(0).inherits(&DateInstance::s_info)) value = asDateInstance(args.at(0))->internalNumber(); else { JSValue primitive = args.at(0).toPrimitive(exec); if (primitive.isString()) value = parseDate(exec, primitive.getString(exec)); else value = primitive.toNumber(exec); } } else { double doubleArguments[7] = { args.at(0).toNumber(exec), args.at(1).toNumber(exec), args.at(2).toNumber(exec), args.at(3).toNumber(exec), args.at(4).toNumber(exec), args.at(5).toNumber(exec), args.at(6).toNumber(exec) }; if (isnan(doubleArguments[0]) || isnan(doubleArguments[1]) || (numArgs >= 3 && isnan(doubleArguments[2])) || (numArgs >= 4 && isnan(doubleArguments[3])) || (numArgs >= 5 && isnan(doubleArguments[4])) || (numArgs >= 6 && isnan(doubleArguments[5])) || (numArgs >= 7 && isnan(doubleArguments[6]))) value = NaN; else { GregorianDateTime t; int year = JSC::toInt32(doubleArguments[0]); t.year = (year >= 0 && year <= 99) ? year : year - 1900; t.month = JSC::toInt32(doubleArguments[1]); t.monthDay = (numArgs >= 3) ? JSC::toInt32(doubleArguments[2]) : 1; t.hour = JSC::toInt32(doubleArguments[3]); t.minute = JSC::toInt32(doubleArguments[4]); t.second = JSC::toInt32(doubleArguments[5]); t.isDST = -1; double ms = (numArgs >= 7) ? doubleArguments[6] : 0; value = gregorianDateTimeToMS(exec, t, ms, false); } } return new (exec) DateInstance(exec, globalObject->dateStructure(), value); }
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; }
void JSCryptoKeySerializationJWK::reconcileUsages(CryptoKeyUsage& suggestedUsages) const { CryptoKeyUsage jwkUsages = 0; JSArray* keyOps; if (getJSArrayFromJSON(m_exec, m_json.get(), "key_ops", keyOps)) { for (size_t i = 0; i < keyOps->length(); ++i) { JSValue jsValue = keyOps->getIndex(m_exec, i); String operation; if (!jsValue.getString(m_exec, operation)) { if (!m_exec->hadException()) throwTypeError(m_exec, "JWK key_ops attribute could not be processed"); return; } if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("sign"), CryptoKeyUsageSign)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("verify"), CryptoKeyUsageVerify)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("encrypt"), CryptoKeyUsageEncrypt)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("decrypt"), CryptoKeyUsageDecrypt)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("wrapKey"), CryptoKeyUsageWrapKey)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("unwrapKey"), CryptoKeyUsageUnwrapKey)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("deriveKey"), CryptoKeyUsageDeriveKey)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("deriveBits"), CryptoKeyUsageDeriveBits)) return; } } else { if (m_exec->hadException()) return; String jwkUseString; if (!getStringFromJSON(m_exec, m_json.get(), "use", jwkUseString)) { // We have neither key_ops nor use. return; } if (jwkUseString == "enc") jwkUsages |= (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey); else if (jwkUseString == "sig") jwkUsages |= (CryptoKeyUsageSign | CryptoKeyUsageVerify); else { throwTypeError(m_exec, "Unsupported JWK key use value \"" + jwkUseString + "\""); return; } } suggestedUsages = suggestedUsages & jwkUsages; }
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; }
Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space) : m_nextStringifierToMark(exec->globalData().firstStringifierToMark) , m_exec(exec) , m_replacer(replacer) , m_usingArrayReplacer(false) , m_arrayReplacerPropertyNames(exec) , m_replacerCallType(CallTypeNone) , m_gap(gap(exec, space)) { exec->globalData().firstStringifierToMark = this; if (!m_replacer.isObject()) return; if (asObject(m_replacer)->inherits(&JSArray::info)) { m_usingArrayReplacer = true; JSObject* array = asObject(m_replacer); unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec); for (unsigned i = 0; i < length; ++i) { JSValue name = array->get(exec, i); if (exec->hadException()) break; UString propertyName; if (name.getString(exec, propertyName)) { m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName)); continue; } double value = 0; if (name.getNumber(value)) { m_arrayReplacerPropertyNames.add(Identifier::from(exec, value)); continue; } if (name.isObject()) { if (!asObject(name)->inherits(&NumberObject::info) && !asObject(name)->inherits(&StringObject::info)) continue; propertyName = name.toString(exec); if (exec->hadException()) break; m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName)); } } return; } m_replacerCallType = asObject(m_replacer)->getCallData(m_replacerCallData); }
// ECMA 15.9.3 JSObject* constructDate(ExecState* exec, const ArgList& args) { int numArgs = args.size(); double value; if (numArgs == 0) // new Date() ECMA 15.9.3.3 value = getCurrentUTCTime(); else if (numArgs == 1) { if (args.at(exec, 0)->isObject(&DateInstance::info)) value = asDateInstance(args.at(exec, 0))->internalNumber(); else { JSValue* primitive = args.at(exec, 0)->toPrimitive(exec); if (primitive->isString()) value = parseDate(primitive->getString()); else value = primitive->toNumber(exec); } } else { if (isnan(args.at(exec, 0)->toNumber(exec)) || isnan(args.at(exec, 1)->toNumber(exec)) || (numArgs >= 3 && isnan(args.at(exec, 2)->toNumber(exec))) || (numArgs >= 4 && isnan(args.at(exec, 3)->toNumber(exec))) || (numArgs >= 5 && isnan(args.at(exec, 4)->toNumber(exec))) || (numArgs >= 6 && isnan(args.at(exec, 5)->toNumber(exec))) || (numArgs >= 7 && isnan(args.at(exec, 6)->toNumber(exec)))) value = NaN; else { GregorianDateTime t; int year = args.at(exec, 0)->toInt32(exec); t.year = (year >= 0 && year <= 99) ? year : year - 1900; t.month = args.at(exec, 1)->toInt32(exec); t.monthDay = (numArgs >= 3) ? args.at(exec, 2)->toInt32(exec) : 1; t.hour = args.at(exec, 3)->toInt32(exec); t.minute = args.at(exec, 4)->toInt32(exec); t.second = args.at(exec, 5)->toInt32(exec); t.isDST = -1; double ms = (numArgs >= 7) ? args.at(exec, 6)->toNumber(exec) : 0; value = gregorianDateTimeToMS(t, ms, false); } } DateInstance* result = new (exec) DateInstance(exec->lexicalGlobalObject()->dateStructure()); result->setInternalValue(jsNumber(exec, timeClip(value))); return result; }
static bool getStringFromJSON(ExecState* exec, JSObject* json, const char* key, String& result) { Identifier identifier(exec, key); PropertySlot slot(json); if (!json->getPropertySlot(exec, identifier, slot)) return false; JSValue jsValue = slot.getValue(exec, identifier); ASSERT(!exec->hadException()); if (!jsValue.getString(exec, result)) { // Can get an out of memory exception. if (exec->hadException()) return false; throwTypeError(exec, String::format("Expected a string value for \"%s\" JSON key", key)); return false; } return true; }