Beispiel #1
0
// 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)));
}
Beispiel #2
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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));
}
Beispiel #6
0
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"))));
}
Beispiel #11
0
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));
}
Beispiel #13
0
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));
}
Beispiel #17
0
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);
}
Beispiel #18
0
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);
}
Beispiel #21
0
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));
}
Beispiel #22
0
// 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));
}
Beispiel #23
0
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;
    }
}
Beispiel #24
0
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);
}
Beispiel #25
0
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;
    }
}
Beispiel #26
0
// 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;
}
Beispiel #28
0
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;
}
Beispiel #29
0
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;
}
Beispiel #30
0
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;
}