// 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]]) EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSGlobalObject* globalObject = exec->callee()->globalObject(); // Let Target be the this value. JSValue target = exec->thisValue(); // If IsCallable(Target) is false, throw a TypeError exception. CallData callData; CallType callType = getCallData(target, callData); if (callType == CallType::None) return throwVMTypeError(exec, scope); // Primitive values are not callable. ASSERT(target.isObject()); JSObject* targetObject = asObject(target); // Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order. size_t numBoundArgs = exec->argumentCount() > 1 ? exec->argumentCount() - 1 : 0; JSArray* boundArgs; if (numBoundArgs) { boundArgs = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), numBoundArgs); if (!boundArgs) return JSValue::encode(throwOutOfMemoryError(exec, scope)); for (size_t i = 0; i < numBoundArgs; ++i) boundArgs->initializeIndex(vm, i, exec->argument(i + 1)); } else boundArgs = nullptr; // If the [[Class]] internal property of Target is "Function", then ... // Else set the length own property of F to 0. unsigned length = 0; if (targetObject->hasOwnProperty(exec, exec->propertyNames().length)) { if (exec->hadException()) return JSValue::encode(jsUndefined()); // a. Let L be the length property of Target minus the length of A. // b. Set the length own property of F to either 0 or L, whichever is larger. JSValue lengthValue = target.get(exec, exec->propertyNames().length); if (lengthValue.isNumber()) { unsigned targetLength = (unsigned)lengthValue.asNumber(); if (targetLength > numBoundArgs) length = targetLength - numBoundArgs; } } JSValue nameProp = target.get(exec, exec->propertyNames().name); JSString* name = nameProp.isString() ? nameProp.toString(exec) : jsEmptyString(exec); return JSValue::encode(JSBoundFunction::create(vm, exec, globalObject, targetObject, exec->argument(0), boundArgs, length, name->value(exec))); }
JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, JSObject* callee, JSValue newTarget) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue patternArg = args.at(0); JSValue flagsArg = args.at(1); bool isPatternRegExp = patternArg.inherits(vm, RegExpObject::info()); bool constructAsRegexp = isRegExp(vm, exec, patternArg); RETURN_IF_EXCEPTION(scope, nullptr); if (newTarget.isUndefined() && constructAsRegexp && flagsArg.isUndefined()) { JSValue constructor = patternArg.get(exec, vm.propertyNames->constructor); RETURN_IF_EXCEPTION(scope, nullptr); if (callee == constructor) { // We know that patternArg is a object otherwise constructAsRegexp would be false. return patternArg.getObject(); } } if (isPatternRegExp) { RegExp* regExp = jsCast<RegExpObject*>(patternArg)->regExp(); Structure* structure = getRegExpStructure(exec, globalObject, newTarget); RETURN_IF_EXCEPTION(scope, nullptr); if (!flagsArg.isUndefined()) { RegExpFlags flags = toFlags(exec, flagsArg); ASSERT(!!scope.exception() == (flags == InvalidFlags)); if (flags == InvalidFlags) return nullptr; regExp = RegExp::create(vm, regExp->pattern(), flags); } return RegExpObject::create(vm, structure, regExp); } if (constructAsRegexp) { JSValue pattern = patternArg.get(exec, vm.propertyNames->source); RETURN_IF_EXCEPTION(scope, nullptr); if (flagsArg.isUndefined()) { flagsArg = patternArg.get(exec, vm.propertyNames->flags); RETURN_IF_EXCEPTION(scope, nullptr); } patternArg = pattern; } scope.release(); return regExpCreate(exec, globalObject, newTarget, patternArg, flagsArg); }
static JSValue JSC_HOST_CALL callRuntimeMethod(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args) { RuntimeMethod* method = static_cast<RuntimeMethod*>(function); if (method->methods()->isEmpty()) return jsUndefined(); RuntimeObjectImp* imp; if (thisValue.isObject(&RuntimeObjectImp::s_info)) { imp = static_cast<RuntimeObjectImp*>(asObject(thisValue)); } else { // If thisObj is the DOM object for a plugin, get the corresponding // runtime object from the DOM object. JSValue value = thisValue.get(exec, Identifier(exec, "__apple_runtime_object")); if (value.isObject(&RuntimeObjectImp::s_info)) imp = static_cast<RuntimeObjectImp*>(asObject(value)); else return throwError(exec, TypeError); } RefPtr<Instance> instance = imp->getInternalInstance(); if (!instance) return RuntimeObjectImp::throwInvalidAccessError(exec); instance->begin(); JSValue result = instance->invokeMethod(exec, *method->methods(), args); instance->end(); return result; }
JSValue iteratorForIterable(ExecState* state, JSValue iterable) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue iteratorFunction = iterable.get(state, state->propertyNames().iteratorSymbol); RETURN_IF_EXCEPTION(scope, JSValue()); CallData iteratorFunctionCallData; CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData); if (iteratorFunctionCallType == CallType::None) { throwTypeError(state, scope); return JSValue(); } ArgList iteratorFunctionArguments; JSValue iterator = call(state, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments); RETURN_IF_EXCEPTION(scope, JSValue()); if (!iterator.isObject()) { throwTypeError(state, scope); return JSValue(); } return iterator; }
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 JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) { VM& vm = exec->vm(); NativeCallFrameTracer tracer(&vm, 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()) { 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(baseValue.get(exec, propertyName)); }
ThenableStatus updateDeferredFromPotentialThenable(ExecState* exec, JSValue x, JSPromiseDeferred* deferred) { // 1. If Type(x) is not Object, return "not a thenable". if (!x.isObject()) return NotAThenable; // 2. Let 'then' be the result of calling Get(x, "then"). JSValue thenValue = x.get(exec, exec->vm().propertyNames->then); // 3. If then is an abrupt completion, if (exec->hadException()) { // i. Let 'rejectResult' be the result of calling the [[Call]] internal method of // deferred.[[Reject]] with undefined as thisArgument and a List containing // then.[[value]] as argumentsList. JSValue exception = exec->exception(); exec->clearException(); performDeferredReject(exec, deferred, exception); // ii. ReturnIfAbrupt(rejectResult). // NOTE: Nothing to do. // iii. Return. return WasAThenable; } // 4. Let 'then' be then.[[value]]. // Note: Nothing to do. // 5. If IsCallable(then) is false, return "not a thenable". CallData thenCallData; CallType thenCallType = getCallData(thenValue, thenCallData); if (thenCallType == CallTypeNone) return NotAThenable; // 6. Let 'thenCallResult' be the result of calling the [[Call]] internal method of // 'then' passing x as thisArgument and a List containing deferred.[[Resolve]] and // deferred.[[Reject]] as argumentsList. MarkedArgumentBuffer thenArguments; thenArguments.append(deferred->resolve()); thenArguments.append(deferred->reject()); call(exec, thenValue, thenCallType, thenCallData, x, thenArguments); // 7. If 'thenCallResult' is an abrupt completion, if (exec->hadException()) { // i. Let 'rejectResult' be the result of calling the [[Call]] internal method of // deferred.[[Reject]] with undefined as thisArgument and a List containing // thenCallResult.[[value]] as argumentsList. JSValue exception = exec->exception(); exec->clearException(); performDeferredReject(exec, deferred, exception); // ii. ReturnIfAbrupt(rejectResult). // NOTE: Nothing to do. } return WasAThenable; }
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 }; }
static EncodedJSValue JSC_HOST_CALL constructWeakSet(ExecState* exec) { JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject(); Structure* weakSetStructure = globalObject->weakSetStructure(); JSWeakSet* weakSet = JSWeakSet::create(exec, weakSetStructure); JSValue iterable = exec->argument(0); if (iterable.isUndefinedOrNull()) return JSValue::encode(weakSet); JSValue adderFunction = weakSet->JSObject::get(exec, exec->propertyNames().add); if (exec->hadException()) return JSValue::encode(jsUndefined()); CallData adderFunctionCallData; CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData); if (adderFunctionCallType == CallTypeNone) return JSValue::encode(throwTypeError(exec)); JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol); if (exec->hadException()) return JSValue::encode(jsUndefined()); CallData iteratorFunctionCallData; CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData); if (iteratorFunctionCallType == CallTypeNone) return JSValue::encode(throwTypeError(exec)); ArgList iteratorFunctionArguments; JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (!iterator.isObject()) return JSValue::encode(throwTypeError(exec)); while (true) { JSValue next = iteratorStep(exec, iterator); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (next.isFalse()) return JSValue::encode(weakSet); JSValue nextValue = iteratorValue(exec, next); if (exec->hadException()) return JSValue::encode(jsUndefined()); MarkedArgumentBuffer arguments; arguments.append(nextValue); call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakSet, arguments); if (exec->hadException()) { iteratorClose(exec, iterator); return JSValue::encode(jsUndefined()); } } RELEASE_ASSERT_NOT_REACHED(); return JSValue::encode(weakSet); }
AbstractModuleRecord* AbstractModuleRecord::hostResolveImportedModule(ExecState* exec, const Identifier& moduleName) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue moduleNameValue = identifierToJSValue(vm, moduleName); JSValue entry = m_dependenciesMap->JSMap::get(exec, moduleNameValue); RETURN_IF_EXCEPTION(scope, nullptr); RELEASE_AND_RETURN(scope, jsCast<AbstractModuleRecord*>(entry.get(exec, Identifier::fromString(exec, "module")))); }
EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName) { JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); return JSValue::encode(baseValue.get(exec, *propertyName, slot)); }
// 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]]) EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec) { JSGlobalObject* globalObject = exec->callee()->globalObject(); // Let Target be the this value. JSValue target = exec->hostThisValue(); // If IsCallable(Target) is false, throw a TypeError exception. CallData callData; CallType callType = getCallData(target, callData); if (callType == CallTypeNone) return throwVMTypeError(exec); // Primitive values are not callable. ASSERT(target.isObject()); JSObject* targetObject = asObject(target); // Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order. size_t numBoundArgs = exec->argumentCount() > 1 ? exec->argumentCount() - 1 : 0; JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->globalData(), globalObject->arrayStructure(), numBoundArgs); if (!boundArgs) return JSValue::encode(throwOutOfMemoryError(exec)); for (size_t i = 0; i < numBoundArgs; ++i) boundArgs->initializeIndex(exec->globalData(), i, exec->argument(i + 1)); boundArgs->completeInitialization(numBoundArgs); // If the [[Class]] internal property of Target is "Function", then ... // Else set the length own property of F to 0. unsigned length = 0; if (targetObject->inherits(&JSFunction::s_info)) { ASSERT(target.get(exec, exec->propertyNames().length).isNumber()); // a. Let L be the length property of Target minus the length of A. // b. Set the length own property of F to either 0 or L, whichever is larger. unsigned targetLength = (unsigned)target.get(exec, exec->propertyNames().length).asNumber(); if (targetLength > numBoundArgs) length = targetLength - numBoundArgs; } Identifier name(exec, target.get(exec, exec->propertyNames().name).toString(exec)->value(exec)); return JSValue::encode(JSBoundFunction::create(exec, globalObject, targetObject, exec->argument(0), boundArgs, length, name)); }
EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress) { JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); JSValue result = baseValue.get(exec, *propertyName, slot); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo); return JSValue::encode(result); }
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 JSIDBObjectStore::createIndex(ExecState* exec) { ScriptExecutionContext* context = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext(); if (!context) return exec->vm().throwException(exec, createReferenceError(exec, "IDBObjectStore script execution context is unavailable")); if (exec->argumentCount() < 2) return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); String name = exec->argument(0).toString(exec)->value(exec); if (exec->hadException()) return jsUndefined(); IDBKeyPath keyPath = idbKeyPathFromValue(exec, exec->argument(1)); if (exec->hadException()) return jsUndefined(); JSValue optionsValue = exec->argument(2); if (!optionsValue.isUndefinedOrNull() && !optionsValue.isObject()) return throwTypeError(exec, "Not an object."); bool unique = false; bool multiEntry = false; if (!optionsValue.isUndefinedOrNull()) { unique = optionsValue.get(exec, Identifier(exec, "unique")).toBoolean(exec); if (exec->hadException()) return jsUndefined(); multiEntry = optionsValue.get(exec, Identifier(exec, "multiEntry")).toBoolean(exec); if (exec->hadException()) return jsUndefined(); } ExceptionCode ec = 0; JSValue result = toJS(exec, globalObject(), impl().createIndex(context, name, keyPath, unique, multiEntry, ec).get()); setDOMException(exec, ec); return result; }
EncodedJSValue operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) { JSValue baseValue = JSValue::decode(encodedBase); JSValue property = JSValue::decode(encodedProperty); if (LIKELY(baseValue.isCell())) { JSCell* base = baseValue.asCell(); if (property.isUInt32()) { JSGlobalData* globalData = &exec->globalData(); uint32_t i = property.asUInt32(); // FIXME: the JIT used to handle these in compiled code! if (isJSArray(globalData, base) && asArray(base)->canGetIndex(i)) return JSValue::encode(asArray(base)->getIndex(i)); // FIXME: the JITstub used to relink this to an optimized form! if (isJSString(globalData, base) && asString(base)->canGetIndex(i)) return JSValue::encode(asString(base)->getIndex(exec, i)); // FIXME: the JITstub used to relink this to an optimized form! if (isJSByteArray(globalData, base) && asByteArray(base)->canAccessIndex(i)) return JSValue::encode(asByteArray(base)->getIndex(exec, i)); return JSValue::encode(baseValue.get(exec, i)); } if (property.isString()) { Identifier propertyName(exec, asString(property)->value(exec)); PropertySlot slot(base); if (base->fastGetOwnPropertySlot(exec, propertyName, slot)) return JSValue::encode(slot.getValue(exec, propertyName)); } } Identifier ident(exec, property.toString(exec)); return JSValue::encode(baseValue.get(exec, ident)); }
EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress) { JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); JSValue result = baseValue.get(exec, *propertyName, slot); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo); return JSValue::encode(result); }
EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress) { JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); JSValue result = baseValue.get(exec, *propertyName, slot); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); if (stubInfo.seen) dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo); else stubInfo.seen = true; return JSValue::encode(result); }
JSValue JSIDBDatabase::createObjectStore(ExecState* exec) { if (exec->argumentCount() < 1) return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); String name = exec->argument(0).toString(exec)->value(exec); if (exec->hadException()) return jsUndefined(); JSValue optionsValue = exec->argument(1); if (!optionsValue.isUndefinedOrNull() && !optionsValue.isObject()) return throwTypeError(exec, "Not an object."); IDBKeyPath keyPath; bool autoIncrement = false; if (!optionsValue.isUndefinedOrNull()) { JSValue keyPathValue = optionsValue.get(exec, Identifier(exec, "keyPath")); if (exec->hadException()) return jsUndefined(); if (!keyPathValue.isUndefinedOrNull()) { keyPath = idbKeyPathFromValue(exec, keyPathValue); if (exec->hadException()) return jsUndefined(); } autoIncrement = optionsValue.get(exec, Identifier(exec, "autoIncrement")).toBoolean(exec); if (exec->hadException()) return jsUndefined(); } ExceptionCode ec = 0; JSValue result = toJS(exec, globalObject(), impl()->createObjectStore(name, keyPath, autoIncrement, ec).get()); setDOMException(exec, ec); return result; }
EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncAll(ExecState* exec) { // -- Promise.all(iterable) -- JSValue iterable = exec->argument(0); VM& vm = exec->vm(); // 1. Let 'C' be the this value. JSValue C = exec->thisValue(); // 2. Let 'deferred' be the result of calling GetDeferred(C). JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C); // 3. ReturnIfAbrupt(deferred). if (exec->hadException()) return JSValue::encode(jsUndefined()); // NOTE: A non-abrupt completion of createJSPromiseDeferredFromConstructor implies that // C and deferredValue are objects. JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue); // 4. Let 'iterator' be the result of calling GetIterator(iterable). JSValue iteratorFunction = iterable.get(exec, vm.propertyNames->iteratorSymbol); if (exec->hadException()) return JSValue::encode(abruptRejection(exec, deferred)); CallData iteratorFunctionCallData; CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData); if (iteratorFunctionCallType == CallTypeNone) { throwTypeError(exec); return JSValue::encode(abruptRejection(exec, deferred)); } ArgList iteratorFunctionArguments; JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments); // 5. RejectIfAbrupt(iterator, deferred). if (exec->hadException()) return JSValue::encode(abruptRejection(exec, deferred)); JSValue result = performPromiseAll(exec, iterator, C, deferred); if (exec->hadException()) { iteratorClose(exec, iterator); if (exec->hadException()) return JSValue::encode(abruptRejection(exec, deferred)); } return JSValue::encode(result); }
EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index) { VM& vm = exec->vm(); NativeCallFrameTracer tracer(&vm, exec); JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue(); // If there are no arguments, and we're accessing out of bounds, then we have to create the // arguments in case someone has installed a getter on a numeric property. if (!argumentsValue) { JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr(); exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec, lexicalEnvironment); } return JSValue::encode(argumentsValue.get(exec, index)); }
// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.get EncodedJSValue JSC_HOST_CALL reflectObjectGet(ExecState* exec) { JSValue target = exec->argument(0); if (!target.isObject()) return JSValue::encode(throwTypeError(exec, ASCIILiteral("Reflect.get requires the first argument be an object"))); const Identifier propertyName = exec->argument(1).toPropertyKey(exec); if (exec->hadException()) return JSValue::encode(jsNull()); JSValue receiver = target; if (exec->argumentCount() >= 3) receiver = exec->argument(2); PropertySlot slot(receiver); return JSValue::encode(target.get(exec, propertyName, slot)); }
void iteratorClose(ExecState* exec, JSValue iterator) { VM& vm = exec->vm(); auto throwScope = DECLARE_THROW_SCOPE(vm); auto catchScope = DECLARE_CATCH_SCOPE(vm); Exception* exception = nullptr; if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); } JSValue returnFunction = iterator.get(exec, vm.propertyNames->returnKeyword); RETURN_IF_EXCEPTION(throwScope, void()); if (returnFunction.isUndefined()) { if (exception) throwException(exec, throwScope, exception); return; } CallData returnFunctionCallData; CallType returnFunctionCallType = getCallData(returnFunction, returnFunctionCallData); if (returnFunctionCallType == CallType::None) { if (exception) throwException(exec, throwScope, exception); else throwTypeError(exec, throwScope); return; } MarkedArgumentBuffer returnFunctionArguments; JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterator, returnFunctionArguments); if (exception) { throwException(exec, throwScope, exception); return; } RETURN_IF_EXCEPTION(throwScope, void()); if (!innerResult.isObject()) { throwTypeError(exec, throwScope, ASCIILiteral("Iterator result interface is not an object.")); return; } }
EncodedJSValue JIT_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, StringImpl* uid, ReturnAddressPtr returnAddress) { VM* vm = &exec->vm(); NativeCallFrameTracer tracer(vm, exec); Identifier ident(vm, uid); StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress); AccessType accessType = static_cast<AccessType>(stubInfo.accessType); JSValue baseValue = JSValue::decode(base); PropertySlot slot(baseValue); JSValue result = baseValue.get(exec, ident, slot); if (accessType == static_cast<AccessType>(stubInfo.accessType)) buildGetByIDList(exec, baseValue, ident, slot, stubInfo); return JSValue::encode(result); }
void iteratorClose(ExecState* exec, JSValue iterator) { Exception* exception = nullptr; if (exec->hadException()) { exception = exec->exception(); exec->clearException(); } JSValue returnFunction = iterator.get(exec, exec->vm().propertyNames->returnKeyword); if (exec->hadException()) return; if (returnFunction.isUndefined()) { if (exception) exec->vm().throwException(exec, exception); return; } CallData returnFunctionCallData; CallType returnFunctionCallType = getCallData(returnFunction, returnFunctionCallData); if (returnFunctionCallType == CallType::None) { if (exception) exec->vm().throwException(exec, exception); else throwTypeError(exec); return; } MarkedArgumentBuffer returnFunctionArguments; JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterator, returnFunctionArguments); if (exception) { exec->vm().throwException(exec, exception); return; } if (exec->hadException()) return; if (!innerResult.isObject()) { throwTypeError(exec, ASCIILiteral("Iterator result interface is not an object.")); return; } }
// https://tc39.github.io/ecma262/#sec-reflect.get EncodedJSValue JSC_HOST_CALL reflectObjectGet(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue target = exec->argument(0); if (!target.isObject()) return JSValue::encode(throwTypeError(exec, scope, ASCIILiteral("Reflect.get requires the first argument be an object"))); const Identifier propertyName = exec->argument(1).toPropertyKey(exec); RETURN_IF_EXCEPTION(scope, encodedJSValue()); JSValue receiver = target; if (exec->argumentCount() >= 3) receiver = exec->argument(2); PropertySlot slot(receiver, PropertySlot::InternalMethodType::Get); scope.release(); return JSValue::encode(target.get(exec, propertyName, slot)); }
short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) const { JSLock lock(SilenceAssertionsOnly); if (!m_filter) return NodeFilter::FILTER_ACCEPT; // Exec is null if we've been called from a non-JavaScript language and the document // is no longer able to run JavaScript (e.g., it's disconnected from its frame). if (!exec) return NodeFilter::FILTER_REJECT; JSValue filter = m_filter.get(); CallData callData; CallType callType = getCallData(filter, callData); if (callType == CallTypeNone) { filter = filter.get(exec, Identifier(exec, "acceptNode")); callType = getCallData(filter, callData); if (callType == CallTypeNone) { throwError(exec, createTypeError(exec, "NodeFilter object does not have an acceptNode function")); return NodeFilter::FILTER_REJECT; } } MarkedArgumentBuffer args; // FIXME: The node should have the prototype chain that came from its document, not // whatever prototype chain might be on the window this filter came from. Bug 27662 args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), filterNode)); if (exec->hadException()) return NodeFilter::FILTER_REJECT; JSValue result = JSMainThreadExecState::call(exec, filter, callType, callData, m_filter.get(), args); if (exec->hadException()) return NodeFilter::FILTER_REJECT; int intResult = result.toInt32(exec); if (exec->hadException()) return NodeFilter::FILTER_REJECT; return intResult; }
JSValue iteratorNext(ExecState* exec, JSValue iterator, JSValue value) { JSValue nextFunction = iterator.get(exec, exec->vm().propertyNames->next); if (exec->hadException()) return jsUndefined(); CallData nextFunctionCallData; CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData); if (nextFunctionCallType == CallType::None) return throwTypeError(exec); MarkedArgumentBuffer nextFunctionArguments; if (!value.isEmpty()) nextFunctionArguments.append(value); JSValue result = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments); if (exec->hadException()) return jsUndefined(); if (!result.isObject()) return throwTypeError(exec, ASCIILiteral("Iterator result interface is not an object.")); return result; }
JSValue iteratorNext(ExecState* exec, JSValue iterator, JSValue value) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue nextFunction = iterator.get(exec, vm.propertyNames->next); RETURN_IF_EXCEPTION(scope, JSValue()); CallData nextFunctionCallData; CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData); if (nextFunctionCallType == CallType::None) return throwTypeError(exec, scope); MarkedArgumentBuffer nextFunctionArguments; if (!value.isEmpty()) nextFunctionArguments.append(value); JSValue result = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments); RETURN_IF_EXCEPTION(scope, JSValue()); if (!result.isObject()) return throwTypeError(exec, scope, ASCIILiteral("Iterator result interface is not an object.")); return result; }
static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, bool dump) { const char* script; String fileName; Vector<char> scriptBuffer; if (dump) JSC::Options::dumpGeneratedBytecodes() = true; VM& vm = globalObject->vm(); #if ENABLE(SAMPLING_FLAGS) SamplingFlags::start(); #endif bool success = true; for (size_t i = 0; i < scripts.size(); i++) { if (scripts[i].isFile) { fileName = scripts[i].argument; if (!fillBufferWithContentsOfFile(fileName, scriptBuffer)) return false; // fail early so we can catch missing files script = scriptBuffer.data(); } else { script = scripts[i].argument; fileName = "[Command Line]"; } vm.startSampling(); JSValue evaluationException; JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(script, fileName), JSValue(), &evaluationException); success = success && !evaluationException; if (dump && !evaluationException) printf("End: %s\n", returnValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data()); if (evaluationException) { printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data()); Identifier stackID(globalObject->globalExec(), "stack"); JSValue stackValue = evaluationException.get(globalObject->globalExec(), stackID); if (!stackValue.isUndefinedOrNull()) printf("%s\n", stackValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data()); } vm.stopSampling(); globalObject->globalExec()->clearException(); } #if ENABLE(SAMPLING_FLAGS) SamplingFlags::stop(); #endif #if ENABLE(SAMPLING_REGIONS) SamplingRegion::dump(); #endif vm.dumpSampleData(globalObject->globalExec()); #if ENABLE(SAMPLING_COUNTERS) AbstractSamplingCounter::dump(); #endif #if ENABLE(REGEXP_TRACING) vm.dumpRegExpTrace(); #endif return success; }