// ECMA-262 5.1, 15.11.4.4 EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 1. Let O be the this value. JSValue thisValue = exec->thisValue(); // 2. If Type(O) is not Object, throw a TypeError exception. if (!thisValue.isObject()) return throwVMTypeError(exec, scope); JSObject* thisObj = asObject(thisValue); // Guard against recursion! StringRecursionChecker checker(exec, thisObj); ASSERT(!scope.exception() || checker.earlyReturnValue()); if (JSValue earlyReturnValue = checker.earlyReturnValue()) return JSValue::encode(earlyReturnValue); // 3. Let name be the result of calling the [[Get]] internal method of O with argument "name". JSValue name = thisObj->get(exec, exec->propertyNames().name); RETURN_IF_EXCEPTION(scope, encodedJSValue()); // 4. If name is undefined, then let name be "Error"; else let name be ToString(name). String nameString; if (name.isUndefined()) nameString = ASCIILiteral("Error"); else { nameString = name.toWTFString(exec); RETURN_IF_EXCEPTION(scope, encodedJSValue()); } // 5. Let msg be the result of calling the [[Get]] internal method of O with argument "message". JSValue message = thisObj->get(exec, exec->propertyNames().message); RETURN_IF_EXCEPTION(scope, encodedJSValue()); // (sic) // 6. If msg is undefined, then let msg be the empty String; else let msg be ToString(msg). // 7. If msg is undefined, then let msg be the empty String; else let msg be ToString(msg). String messageString; if (message.isUndefined()) messageString = String(); else { messageString = message.toWTFString(exec); RETURN_IF_EXCEPTION(scope, encodedJSValue()); } // 8. If name is the empty String, return msg. if (!nameString.length()) return JSValue::encode(message.isString() ? message : jsString(exec, messageString)); // 9. If msg is the empty String, return name. if (!messageString.length()) return JSValue::encode(name.isString() ? name : jsString(exec, nameString)); // 10. Return the result of concatenating name, ":", a single space character, and msg. scope.release(); return JSValue::encode(jsMakeNontrivialString(exec, nameString, ": ", messageString)); }
static std::error_code getDomainList(ExecState& exec, const JSObject* arrayObject, Vector<String>& vector) { VM& vm = exec.vm(); auto scope = DECLARE_THROW_SCOPE(vm); ASSERT(vector.isEmpty()); if (!arrayObject || !isJSArray(arrayObject)) return ContentExtensionError::JSONInvalidDomainList; const JSArray* array = jsCast<const JSArray*>(arrayObject); unsigned length = array->length(); for (unsigned i = 0; i < length; ++i) { const JSValue value = array->getIndex(&exec, i); if (scope.exception() || !value.isString()) return ContentExtensionError::JSONInvalidDomainList; // Domains should be punycode encoded lower case. const String& domain = jsCast<JSString*>(value)->value(&exec); if (domain.isEmpty()) return ContentExtensionError::JSONInvalidDomainList; if (!containsOnlyASCIIWithNoUppercase(domain)) return ContentExtensionError::JSONDomainNotLowerCaseASCII; vector.append(domain); } return { }; }
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; }
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; }
EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty) { VM& vm = exec->vm(); NativeCallFrameTracer tracer(&vm, exec); 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()) { Structure& structure = *base->structure(vm); if (JSCell::canUseFastGetOwnProperty(structure)) { if (AtomicStringImpl* existingAtomicString = asString(property)->toExistingAtomicString(exec)) { if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString)) return JSValue::encode(result); } } } PropertyName propertyName = property.toPropertyKey(exec); return JSValue::encode(JSValue(base).get(exec, propertyName)); }
EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) { JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); JSValue baseValue = JSValue::decode(encodedBase); JSValue property = JSValue::decode(encodedProperty); if (LIKELY(baseValue.isCell())) { JSCell* base = baseValue.asCell(); if (property.isUInt32()) { return getByVal(exec, base, property.asUInt32()); } else 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)->value(exec)); return JSValue::encode(baseValue.get(exec, ident)); }
EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec) { VM& vm = exec->vm(); JSValue thisValue = exec->thisValue().toThis(exec, StrictMode); if (thisValue.isUndefinedOrNull()) return JSValue::encode(thisValue.isUndefined() ? vm.smallStrings.undefinedObjectString() : vm.smallStrings.nullObjectString()); JSObject* thisObject = thisValue.toObject(exec); JSValue stringTag = thisObject->get(exec, exec->propertyNames().toStringTagSymbol); if (stringTag.isString()) { JSRopeString::RopeBuilder<RecordOverflow> ropeBuilder(vm); ropeBuilder.append(vm.smallStrings.objectStringStart()); ropeBuilder.append(jsCast<JSString*>(stringTag)); ropeBuilder.append(vm.smallStrings.singleCharacterString(']')); if(ropeBuilder.hasOverflowed()) return JSValue::encode(throwOutOfMemoryError(exec)); return JSValue::encode(ropeBuilder.release()); } JSString* result = thisObject->structure(vm)->objectToStringValue(); if (!result) { RefPtr<StringImpl> newString = WTF::tryMakeString("[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]"); if (!newString) return JSValue::encode(throwOutOfMemoryError(exec)); result = jsNontrivialString(&vm, newString.release()); thisObject->structure(vm)->setObjectToStringValue(vm, result); } return JSValue::encode(result); }
// 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 bool extractSourceInformationFromException(JSC::ExecState* exec, JSObject* exceptionObject, int* lineNumber, int* columnNumber, String* sourceURL) { VM& vm = exec->vm(); auto scope = DECLARE_CATCH_SCOPE(vm); // FIXME: <http://webkit.org/b/115087> Web Inspector: Should not need to evaluate JavaScript handling exceptions JSValue lineValue = exceptionObject->getDirect(vm, Identifier::fromString(exec, "line")); JSValue columnValue = exceptionObject->getDirect(vm, Identifier::fromString(exec, "column")); JSValue sourceURLValue = exceptionObject->getDirect(vm, Identifier::fromString(exec, "sourceURL")); bool result = false; if (lineValue && lineValue.isNumber() && sourceURLValue && sourceURLValue.isString()) { *lineNumber = int(lineValue.toNumber(exec)); *columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0; *sourceURL = sourceURLValue.toWTFString(exec); result = true; } else if (ErrorInstance* error = jsDynamicCast<ErrorInstance*>(vm, exceptionObject)) { unsigned unsignedLine; unsigned unsignedColumn; result = getLineColumnAndSource(error->stackTrace(), unsignedLine, unsignedColumn, *sourceURL); *lineNumber = static_cast<int>(unsignedLine); *columnNumber = static_cast<int>(unsignedColumn); } if (sourceURL->isEmpty()) *sourceURL = "undefined"_s; scope.clearException(); return result; }
JSValue JSInjectedScriptHost::type(ExecState* exec) { if (exec->argumentCount() < 1) return jsUndefined(); JSValue value = exec->argument(0); if (value.isString()) return jsString(exec, String("string")); if (value.inherits(&JSArray::s_info)) return jsString(exec, String("array")); if (value.isBoolean()) return jsString(exec, String("boolean")); if (value.isNumber()) return jsString(exec, String("number")); if (value.inherits(&DateInstance::s_info)) return jsString(exec, String("date")); if (value.inherits(&RegExpObject::s_info)) return jsString(exec, String("regexp")); if (value.inherits(&JSNode::s_info)) return jsString(exec, String("node")); if (value.inherits(&JSNodeList::s_info)) return jsString(exec, String("array")); if (value.inherits(&JSHTMLCollection::s_info)) return jsString(exec, String("array")); if (value.inherits(&JSInt8Array::s_info) || value.inherits(&JSInt16Array::s_info) || value.inherits(&JSInt32Array::s_info)) return jsString(exec, String("array")); if (value.inherits(&JSUint8Array::s_info) || value.inherits(&JSUint16Array::s_info) || value.inherits(&JSUint32Array::s_info)) return jsString(exec, String("array")); if (value.inherits(&JSFloat32Array::s_info) || value.inherits(&JSFloat64Array::s_info)) return jsString(exec, String("array")); return jsUndefined(); }
JSValue jsTypeStringForValue(VM& vm, JSGlobalObject* globalObject, JSValue v) { if (v.isUndefined()) return vm.smallStrings.undefinedString(); if (v.isBoolean()) return vm.smallStrings.booleanString(); if (v.isNumber()) return vm.smallStrings.numberString(); if (v.isString()) return vm.smallStrings.stringString(); if (v.isSymbol()) return vm.smallStrings.symbolString(); if (v.isObject()) { JSObject* object = asObject(v); // Return "undefined" for objects that should be treated // as null when doing comparisons. if (object->structure(vm)->masqueradesAsUndefined(globalObject)) return vm.smallStrings.undefinedString(); if (object->type() == JSFunctionType) return vm.smallStrings.functionString(); if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) { CallData callData; JSObject* object = asObject(v); if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone) return vm.smallStrings.functionString(); } } return vm.smallStrings.objectString(); }
static void populateContextMenuItems(ExecState* exec, JSArray* array, ContextMenu& menu) { for (size_t i = 0; i < array->length(); ++i) { JSObject* item = asObject(array->getIndex(exec, i)); JSValue label = item->get(exec, Identifier::fromString(exec, "label")); JSValue type = item->get(exec, Identifier::fromString(exec, "type")); JSValue id = item->get(exec, Identifier::fromString(exec, "id")); JSValue enabled = item->get(exec, Identifier::fromString(exec, "enabled")); JSValue checked = item->get(exec, Identifier::fromString(exec, "checked")); JSValue subItems = item->get(exec, Identifier::fromString(exec, "subItems")); if (!type.isString()) continue; String typeString = type.toWTFString(exec); if (typeString == "separator") { ContextMenuItem item(SeparatorType, ContextMenuItemTagNoAction, String()); menu.appendItem(item); } else if (typeString == "subMenu" && subItems.inherits(JSArray::info())) { ContextMenu subMenu; JSArray* subItemsArray = asArray(subItems); populateContextMenuItems(exec, subItemsArray, subMenu); ContextMenuItem item(SubmenuType, ContextMenuItemTagNoAction, label.toWTFString(exec), &subMenu); menu.appendItem(item); } else { ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(exec)); ContextMenuItem menuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, label.toWTFString(exec)); if (!enabled.isUndefined()) menuItem.setEnabled(enabled.toBoolean(exec)); if (!checked.isUndefined()) menuItem.setChecked(checked.toBoolean(exec)); menu.appendItem(menuItem); } } }
JSValue JSInjectedScriptHost::subtype(ExecState* exec) { if (exec->argumentCount() < 1) return jsUndefined(); JSValue value = exec->uncheckedArgument(0); if (value.isString()) return exec->vm().smallStrings.stringString(); if (value.isBoolean()) return exec->vm().smallStrings.booleanString(); if (value.isNumber()) return exec->vm().smallStrings.numberString(); if (value.isSymbol()) return exec->vm().smallStrings.symbolString(); JSObject* object = asObject(value); if (object) { if (object->isErrorInstance()) return jsNontrivialString(exec, ASCIILiteral("error")); // Consider class constructor functions class objects. JSFunction* function = jsDynamicCast<JSFunction*>(value); if (function && function->isClassConstructorFunction()) return jsNontrivialString(exec, ASCIILiteral("class")); } if (value.inherits(JSArray::info())) return jsNontrivialString(exec, ASCIILiteral("array")); if (value.inherits(DirectArguments::info()) || value.inherits(ScopedArguments::info())) return jsNontrivialString(exec, ASCIILiteral("array")); if (value.inherits(DateInstance::info())) return jsNontrivialString(exec, ASCIILiteral("date")); if (value.inherits(RegExpObject::info())) return jsNontrivialString(exec, ASCIILiteral("regexp")); if (value.inherits(JSMap::info())) return jsNontrivialString(exec, ASCIILiteral("map")); if (value.inherits(JSSet::info())) return jsNontrivialString(exec, ASCIILiteral("set")); if (value.inherits(JSWeakMap::info())) return jsNontrivialString(exec, ASCIILiteral("weakmap")); if (value.inherits(JSWeakSet::info())) return jsNontrivialString(exec, ASCIILiteral("weakset")); if (value.inherits(JSArrayIterator::info()) || value.inherits(JSMapIterator::info()) || value.inherits(JSSetIterator::info()) || value.inherits(JSStringIterator::info())) return jsNontrivialString(exec, ASCIILiteral("iterator")); if (value.inherits(JSInt8Array::info()) || value.inherits(JSInt16Array::info()) || value.inherits(JSInt32Array::info())) return jsNontrivialString(exec, ASCIILiteral("array")); if (value.inherits(JSUint8Array::info()) || value.inherits(JSUint16Array::info()) || value.inherits(JSUint32Array::info())) return jsNontrivialString(exec, ASCIILiteral("array")); if (value.inherits(JSFloat32Array::info()) || value.inherits(JSFloat64Array::info())) return jsNontrivialString(exec, ASCIILiteral("array")); return impl().subtype(exec, value); }
EncodedJSValue JSC_HOST_CALL jsHTMLDocumentPrototypeFunctionWrite(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSHTMLDocument::s_info)) return throwVMTypeError(exec); JSHTMLDocument* castedThis = static_cast<JSHTMLDocument*>(asObject(thisValue)); #ifdef JSC_TAINTED /* if we comment out the following code segement and move the detection to bindings/js/JSHTMLDocumentCustom.cpp one of the test case like below cannot be detected anymore. need to investigate the reason behind. document.write("hello"+document.location.href.substring(document.location.href.indexOf("default=")+8));\ the guess is the following code does not cover the primitive string. */ JSValue s = exec->argument(0); if (s.isString() && s.isTainted()) { HTMLDocument* d1 = static_cast<HTMLDocument*>(castedThis->impl()); d1->setTainted(s.isTainted()); TaintedStructure trace_struct; trace_struct.taintedno = s.isTainted(); trace_struct.internalfunc = "jsHTMLDocumentPrototypeFunctionWrite"; trace_struct.jsfunc = "document.write"; trace_struct.action = "sink"; char msg[20]; stringstream msgss; snprintf(msg, 20, "%s", s.toString(exec).utf8(true).data()); msgss << msg; msgss >> trace_struct.value; TaintedTrace* trace = TaintedTrace::getInstance(); trace->addTaintedTrace(trace_struct); }
PassRefPtr<ScriptCallStack> createScriptCallStackFromException(JSC::ExecState* exec, JSC::JSValue& exception, size_t maxStackSize) { Vector<ScriptCallFrame> frames; RefCountedArray<StackFrame> stackTrace = exec->vm().exceptionStack(); for (size_t i = 0; i < stackTrace.size() && i < maxStackSize; i++) { if (!stackTrace[i].callee && frames.size()) break; String functionName = stackTrace[i].friendlyFunctionName(exec); unsigned line; unsigned column; stackTrace[i].computeLineAndColumn(line, column); frames.append(ScriptCallFrame(functionName, stackTrace[i].sourceURL, line, column)); } // FIXME: <http://webkit.org/b/115087> Web Inspector: WebCore::reportException should not evaluate JavaScript handling exceptions // Fallback to getting at least the line and sourceURL from the exception if it has values and the exceptionStack doesn't. if (frames.size() > 0) { const ScriptCallFrame& firstCallFrame = frames.first(); JSObject* exceptionObject = exception.toObject(exec); if (exception.isObject() && firstCallFrame.sourceURL().isEmpty()) { JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line")); int lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0; JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL")); String exceptionSourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : ASCIILiteral("undefined"); frames[0] = ScriptCallFrame(firstCallFrame.functionName(), exceptionSourceURL, lineNumber, 0); } } return ScriptCallStack::create(frames); }
static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset) { ErrorInstance::SourceAppender appender = exception->sourceAppender(); exception->clearSourceAppender(); RuntimeType type = exception->runtimeTypeForCause(); exception->clearRuntimeTypeForCause(); if (!callFrame->codeBlock()->hasExpressionInfo()) return; int startOffset = 0; int endOffset = 0; int divotPoint = 0; unsigned line = 0; unsigned column = 0; CodeBlock* codeBlock; CodeOrigin codeOrigin = callFrame->codeOrigin(); if (codeOrigin && codeOrigin.inlineCallFrame) codeBlock = baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame); else codeBlock = callFrame->codeBlock(); codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column); int expressionStart = divotPoint - startOffset; int expressionStop = divotPoint + endOffset; StringView sourceString = codeBlock->source()->source(); if (!expressionStop || expressionStart > static_cast<int>(sourceString.length())) return; VM* vm = &callFrame->vm(); JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message); if (!jsMessage || !jsMessage.isString()) return; String message = asString(jsMessage)->value(callFrame); if (expressionStart < expressionStop) message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop).toString(), type, ErrorInstance::FoundExactSource); else { // No range information, so give a few characters of context. int dataLength = sourceString.length(); int start = expressionStart; int stop = expressionStart; // Get up to 20 characters of context to the left and right of the divot, clamping to the line. // Then strip whitespace. while (start > 0 && (expressionStart - start < 20) && sourceString[start - 1] != '\n') start--; while (start < (expressionStart - 1) && isStrWhiteSpace(sourceString[start])) start++; while (stop < dataLength && (stop - expressionStart < 20) && sourceString[stop] != '\n') stop++; while (stop > expressionStart && isStrWhiteSpace(sourceString[stop - 1])) stop--; message = appender(message, codeBlock->source()->getRange(start, stop).toString(), type, ErrorInstance::FoundApproximateSource); } exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message)); }
bool JSValueIsString(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isString(); }
bool JSValueIsString(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); exec->globalData().heap.registerThread(); JSLock lock(exec); JSValue jsValue = toJS(exec, value); return jsValue.isString(); }
void JSCanvasRenderingContext2D::setFillStyle(ExecState* exec, JSValue value) { CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(impl()); if (value.isString()) { context->setFillColor(asString(value)->value(exec)); return; } context->setFillStyle(toHTMLCanvasStyle(exec, 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); }
static std::error_code loadAction(ExecState& exec, const JSObject& ruleObject, Action& action, bool& validSelector) { VM& vm = exec.vm(); auto scope = DECLARE_THROW_SCOPE(vm); validSelector = true; const JSValue actionObject = ruleObject.get(&exec, Identifier::fromString(&exec, "action")); if (!actionObject || scope.exception() || !actionObject.isObject()) return ContentExtensionError::JSONInvalidAction; const JSValue typeObject = actionObject.get(&exec, Identifier::fromString(&exec, "type")); if (!typeObject || scope.exception() || !typeObject.isString()) return ContentExtensionError::JSONInvalidActionType; String actionType = typeObject.toWTFString(&exec); if (actionType == "block") action = ActionType::BlockLoad; else if (actionType == "ignore-previous-rules") action = ActionType::IgnorePreviousRules; else if (actionType == "block-cookies") action = ActionType::BlockCookies; else if (actionType == "css-display-none") { JSValue selector = actionObject.get(&exec, Identifier::fromString(&exec, "selector")); if (!selector || scope.exception() || !selector.isString()) return ContentExtensionError::JSONInvalidCSSDisplayNoneActionType; String s = selector.toWTFString(&exec); if (!isValidSelector(s)) { // Skip rules with invalid selectors to be backwards-compatible. validSelector = false; return { }; } action = Action(ActionType::CSSDisplayNoneSelector, s); } else if (actionType == "make-https") { action = ActionType::MakeHTTPS; } else return ContentExtensionError::JSONInvalidActionType; return { }; }
JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { // Also used for valueOf. if (thisValue.isString()) return thisValue; if (thisValue.isObject(&StringObject::info)) return asStringObject(thisValue)->internalValue(); return throwError(exec, TypeError); }
static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset) { exception->clearAppendSourceToMessage(); if (!callFrame->codeBlock()->hasExpressionInfo()) return; int startOffset = 0; int endOffset = 0; int divotPoint = 0; unsigned line = 0; unsigned column = 0; CodeBlock* codeBlock = callFrame->codeBlock(); codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column); int expressionStart = divotPoint - startOffset; int expressionStop = divotPoint + endOffset; const String& sourceString = codeBlock->source()->source(); if (!expressionStop || expressionStart > static_cast<int>(sourceString.length())) return; VM* vm = &callFrame->vm(); JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message); if (!jsMessage || !jsMessage.isString()) return; String message = asString(jsMessage)->value(callFrame); if (expressionStart < expressionStop) message = makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')"); else { // No range information, so give a few characters of context. const StringImpl* data = sourceString.impl(); int dataLength = sourceString.length(); int start = expressionStart; int stop = expressionStart; // Get up to 20 characters of context to the left and right of the divot, clamping to the line. // Then strip whitespace. while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n') start--; while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start])) start++; while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n') stop++; while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1])) stop--; message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')"); } exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message)); }
JSValue RegExpConstructor::getLastParen(ExecState* exec) { JSArray* array = m_cachedResult.lastResult(exec, this); unsigned length = array->length(); if (length > 1) { JSValue result = JSValue(array).get(exec, length - 1); ASSERT(result.isString() || result.isUndefined()); if (!result.isUndefined()) return result; } return jsEmptyString(exec); }
JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i) { JSArray* array = m_cachedResult.lastResult(exec, this); if (i < array->length()) { JSValue result = JSValue(array).get(exec, i); ASSERT(result.isString() || result.isUndefined()); if (!result.isUndefined()) return result; } return jsEmptyString(exec); }
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; }
static TriState equalToStringImpl(JSValue value, StringImpl* stringImpl) { if (!value.isString()) return FalseTriState; JSString* jsString = asString(value); const StringImpl* string = jsString->tryGetValueImpl(); if (!string) return MixedTriState; return triState(WTF::equal(stringImpl, string)); }
bool JSValueIsString(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.isString(); }
// 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); }