// ECMA 15.2.2
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
{
    JSValue arg = args.at(0);
    if (arg.isUndefinedOrNull())
        return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
    return arg.toObject(exec);
}
示例#2
0
static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValue value)
{
    // Create default options.
    RefPtr<PositionOptions> options = PositionOptions::create();

    // Argument is optional (hence undefined is allowed), and null is allowed.
    if (value.isUndefinedOrNull()) {
        // Use default options.
        return options.release();
    }

    // Given the above test, this will always yield an object.
    JSObject* object = value.toObject(exec);

    // Create the dictionary wrapper from the initializer object.
    JSDictionary dictionary(exec, object);

    if (!dictionary.tryGetProperty("enableHighAccuracy", options.get(), setEnableHighAccuracy))
        return 0;
    if (!dictionary.tryGetProperty("timeout", options.get(), setTimeout))
        return 0;
    if (!dictionary.tryGetProperty("maximumAge", options.get(), setMaximumAge))
        return 0;

    return options.release();
}
示例#3
0
static std::error_code getTypeFlags(ExecState& exec, const JSValue& typeValue, ResourceFlags& flags, uint16_t (*stringToType)(const String&))
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (!typeValue.isObject())
        return { };

    const JSObject* object = typeValue.toObject(&exec);
    ASSERT(!scope.exception());
    if (!isJSArray(object))
        return ContentExtensionError::JSONInvalidTriggerFlagsArray;

    const JSArray* array = jsCast<const JSArray*>(object);
    
    unsigned length = array->length();
    for (unsigned i = 0; i < length; ++i) {
        const JSValue value = array->getIndex(&exec, i);
        if (scope.exception() || !value)
            return ContentExtensionError::JSONInvalidObjectInTriggerFlagsArray;
        
        String name = value.toWTFString(&exec);
        uint16_t type = stringToType(name);
        if (!type)
            return ContentExtensionError::JSONInvalidStringInTriggerFlagsArray;

        flags |= type;
    }

    return { };
}
示例#4
0
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);
}
示例#5
0
template<> EncodedJSValue JSC_HOST_CALL JSTestEventConstructorConstructor::construct(ExecState* state)
{
    auto* jsConstructor = jsCast<JSTestEventConstructorConstructor*>(state->callee());

    if (!jsConstructor->scriptExecutionContext())
        return throwVMError(state, createReferenceError(state, "Constructor associated execution context is unavailable"));

    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, createNotEnoughArgumentsError(state));

    AtomicString eventType = state->argument(0).toString(state)->toAtomicString(state);
    if (UNLIKELY(state->hadException()))
        return JSValue::encode(jsUndefined());

    TestEventConstructorInit eventInit;

    JSValue initializerValue = state->argument(1);
    if (!initializerValue.isUndefinedOrNull()) {
        // Given the above test, this will always yield an object.
        JSObject* initializerObject = initializerValue.toObject(state);
        ASSERT(!state->hadException());

        // Create the dictionary wrapper from the initializer object.
        JSDictionary dictionary(state, initializerObject);

        // Attempt to fill in the EventInit.
        if (!fillTestEventConstructorInit(eventInit, dictionary))
            return JSValue::encode(jsUndefined());
    }

    Ref<TestEventConstructor> event = TestEventConstructor::createForBindings(eventType, eventInit);
    return JSValue::encode(toJS(state, jsConstructor->globalObject(), event));
}
示例#6
0
// ECMA 15.2.2
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
{
    JSValue* arg = args.at(exec, 0);
    if (arg->isUndefinedOrNull())
        return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
    return arg->toObject(exec);
}
EncodedJSValue JSC_HOST_CALL JSKeyboardEventConstructor::constructJSKeyboardEvent(ExecState* exec)
{
    JSKeyboardEventConstructor* jsConstructor = jsCast<JSKeyboardEventConstructor*>(exec->callee());

    ScriptExecutionContext* executionContext = jsConstructor->scriptExecutionContext();
    if (!executionContext)
        return throwVMError(exec, createReferenceError(exec, "Constructor associated execution context is unavailable"));

    AtomicString eventType = exec->argument(0).toString(exec)->value(exec);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    KeyboardEventInit eventInit;

    JSValue initializerValue = exec->argument(1);
    if (!initializerValue.isUndefinedOrNull()) {
        // Given the above test, this will always yield an object.
        JSObject* initializerObject = initializerValue.toObject(exec);

        // Create the dictionary wrapper from the initializer object.
        JSDictionary dictionary(exec, initializerObject);

        // Attempt to fill in the EventInit.
        if (!fillKeyboardEventInit(eventInit, dictionary))
            return JSValue::encode(jsUndefined());
    }

    RefPtr<KeyboardEvent> event = KeyboardEvent::create(eventType, eventInit);
    return JSValue::encode(toJS(exec, jsConstructor->globalObject(), event.get()));
}
示例#8
0
EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec)
{
    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
    auto propertyName = exec->argument(0).toPropertyKey(exec);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());
    return JSValue::encode(jsBoolean(thisValue.toObject(exec)->hasOwnProperty(exec, propertyName)));
}
示例#9
0
double valueToDate(ExecState* exec, JSValue value)
{
    if (value.isNumber())
        return value.asNumber();
    if (!value.inherits(DateInstance::info()))
        return std::numeric_limits<double>::quiet_NaN();
    return static_cast<DateInstance*>(value.toObject(exec))->internalNumber();
}
示例#10
0
static std::error_code loadEncodedRules(ExecState& exec, const String& rules, Vector<ContentExtensionRule>& ruleList)
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    // FIXME: JSONParse should require callbacks instead of an ExecState.
    const JSValue decodedRules = JSONParse(&exec, rules);

    if (scope.exception() || !decodedRules)
        return ContentExtensionError::JSONInvalid;

    if (!decodedRules.isObject())
        return ContentExtensionError::JSONTopLevelStructureNotAnObject;

    const JSObject* topLevelObject = decodedRules.toObject(&exec);
    if (!topLevelObject || scope.exception())
        return ContentExtensionError::JSONTopLevelStructureNotAnObject;
    
    if (!isJSArray(topLevelObject))
        return ContentExtensionError::JSONTopLevelStructureNotAnArray;

    const JSArray* topLevelArray = jsCast<const JSArray*>(topLevelObject);

    Vector<ContentExtensionRule> localRuleList;

    unsigned length = topLevelArray->length();
    const unsigned maxRuleCount = 50000;
    if (length > maxRuleCount)
        return ContentExtensionError::JSONTooManyRules;
    for (unsigned i = 0; i < length; ++i) {
        const JSValue value = topLevelArray->getIndex(&exec, i);
        if (scope.exception() || !value)
            return ContentExtensionError::JSONInvalidObjectInTopLevelArray;

        const JSObject* ruleObject = value.toObject(&exec);
        if (!ruleObject || scope.exception())
            return ContentExtensionError::JSONInvalidRule;

        auto error = loadRule(exec, *ruleObject, localRuleList);
        if (error)
            return error;
    }

    ruleList = WTFMove(localRuleList);
    return { };
}
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec)
{
    JSGlobalObject* globalObject = exec->callee()->globalObject();
    ArgList args(exec);
    JSValue arg = args.at(0);
    if (arg.isUndefinedOrNull())
        return constructEmptyObject(exec, globalObject->objectPrototype());
    return arg.toObject(exec, globalObject);
}
示例#12
0
JSObject* BalRuntimeObjectImp::construct(ExecState* exec, const ArgList& args)
{
    // ECMA 15.2.2.1 (?)
    CallData callData;
    CallType callType = getCallData(callData);
    JSValue* val = call(exec, this, callType, callData, this, args);

    if (!val || val->type() == NullType || val->type() == UndefinedType)
        return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype()->prototype());
    else
        return val->toObject(exec);
}
示例#13
0
void reportException(ExecState* exec, JSValue exception, CachedScript* cachedScript)
{
    if (isTerminatedExecutionException(exception))
        return;

    Interpreter::ErrorHandlingMode mode(exec);

    RefPtr<ScriptCallStack> callStack(createScriptCallStackFromException(exec, exception, ScriptCallStack::maxCallStackSizeToCapture));
    exec->clearException();
    exec->clearSupplementaryExceptionInfo();

    JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
    if (JSDOMWindow* window = jsDynamicCast<JSDOMWindow*>(globalObject)) {
        if (!window->impl()->isCurrentlyDisplayedInFrame())
            return;
    }

    int lineNumber = 0;
    int columnNumber = 0;
    String exceptionSourceURL;
    if (callStack->size()) {
        const ScriptCallFrame& frame = callStack->at(0);
        lineNumber = frame.lineNumber();
        columnNumber = frame.columnNumber();
        exceptionSourceURL = frame.sourceURL();
    } else {
        // There may not be an exceptionStack for a <script> SyntaxError. Fallback to getting at least the line and sourceURL from the exception.
        JSObject* exceptionObject = exception.toObject(exec);
        JSValue lineValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "line"));
        lineNumber = lineValue && lineValue.isNumber() ? int(lineValue.toNumber(exec)) : 0;
        JSValue columnValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "column"));
        columnNumber = columnValue && columnValue.isNumber() ? int(columnValue.toNumber(exec)) : 0;
        JSValue sourceURLValue = exceptionObject->getDirect(exec->vm(), Identifier(exec, "sourceURL"));
        exceptionSourceURL = sourceURLValue && sourceURLValue.isString() ? sourceURLValue.toString(exec)->value(exec) : ASCIILiteral("undefined");
    }

    String errorMessage;
    if (ExceptionBase* exceptionBase = toExceptionBase(exception))
        errorMessage = exceptionBase->message() + ": "  + exceptionBase->description();
    else {
        // FIXME: <http://webkit.org/b/115087> Web Inspector: WebCore::reportException should not evaluate JavaScript handling exceptions
        // If this is a custon exception object, call toString on it to try and get a nice string representation for the exception.
        errorMessage = exception.toString(exec)->value(exec);
        exec->clearException();
        exec->clearSupplementaryExceptionInfo();
    }

    ScriptExecutionContext* scriptExecutionContext = globalObject->scriptExecutionContext();
    scriptExecutionContext->reportException(errorMessage, lineNumber, columnNumber, exceptionSourceURL, callStack->size() ? callStack : 0, cachedScript);
}
示例#14
0
EXPORT
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
    JSLock lock;
    ExecState* exec = toJS(ctx);
    JSValue* jsValue = toJS(value);
    
    JSObjectRef objectRef = toRef(jsValue->toObject(exec));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
        objectRef = 0;
    }
    return objectRef;
}    
示例#15
0
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
    if (!ctx) {
        ASSERT_NOT_REACHED();
        return 0;
    }
    ExecState* exec = toJS(ctx);
    JSLockHolder locker(exec);

    JSValue jsValue = toJS(exec, value);
    
    JSObjectRef objectRef = toRef(jsValue.toObject(exec));
    if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow)
        objectRef = 0;
    return objectRef;
}
示例#16
0
文件: JSValueRef.cpp 项目: Afreeca/qt
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    JSValue jsValue = toJS(exec, value);
    
    JSObjectRef objectRef = toRef(jsValue.toObject(exec));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
        objectRef = 0;
    }
    return objectRef;
}    
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    JSLock lock(exec);

    JSValue jsValue = toJS(exec, value);
    
    JSObjectRef objectRef = toRef(jsValue.toObject(exec));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
        objectRef = 0;
    }
    return objectRef;
}    
示例#18
0
JSValue InjectedScriptHost::jsWrapper(ExecState* exec, JSGlobalObject* globalObject)
{
    auto key = std::make_pair(exec, globalObject);
    auto it = m_wrappers.find(key);
    if (it != m_wrappers.end())
        return it->value.get();

    JSValue jsValue = toJS(exec, globalObject, this);
    if (!jsValue.isObject())
        return jsValue;

    JSObject* jsObject = jsValue.toObject(exec, globalObject);
    Strong<JSObject> wrapper(exec->vm(), jsObject);
    m_wrappers.add(key, wrapper);

    return jsValue;
}
示例#19
0
// ECMA 15.2.2
JSObject* ObjectObjectImp::construct(ExecState* exec, const List& args)
{
  JSValue* arg = args[0];
  switch (arg->type()) {
  case StringType:
  case BooleanType:
  case NumberType:
  case ObjectType:
      return arg->toObject(exec);
  case NullType:
  case UndefinedType:
      return new JSObject(exec->lexicalInterpreter()->builtinObjectPrototype());
  default:
      //### ASSERT_NOT_REACHED();
      return 0;
  }
}
EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec)
{
    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
    JSObject* thisObj = thisValue.toObject(exec);

    if (!exec->argument(0).isObject())
        return JSValue::encode(jsBoolean(false));

    JSValue v = asObject(exec->argument(0))->prototype();

    while (true) {
        if (!v.isObject())
            return JSValue::encode(jsBoolean(false));
        if (v == thisObj)
            return JSValue::encode(jsBoolean(true));
        v = asObject(v)->prototype();
    }
}
示例#21
0
void reportException(ExecState* exec, JSValue exception)
{
    UString errorMessage = exception.toString(exec);
    JSObject* exceptionObject = exception.toObject(exec);
    int lineNumber = exceptionObject->get(exec, Identifier(exec, "line")).toInt32(exec);
    UString exceptionSourceURL = exceptionObject->get(exec, Identifier(exec, "sourceURL")).toString(exec);
    exec->clearException();

    ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();
    ASSERT(scriptExecutionContext);

    // Crash data indicates null-dereference crashes at this point in the Safari 4 Public Beta.
    // It's harmless to return here without reporting the exception to the log and the debugger in this case.
    if (!scriptExecutionContext)
        return;

    scriptExecutionContext->reportException(errorMessage, lineNumber, exceptionSourceURL);
}
示例#22
0
EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec)
{
    JSValue thisValue = exec->hostThisValue().toThis(exec, StrictMode);
    if (thisValue.isUndefinedOrNull())
        return JSValue::encode(jsNontrivialString(exec, String(thisValue.isUndefined() ? ASCIILiteral("[object Undefined]") : ASCIILiteral("[object Null]"))));
    JSObject* thisObject = thisValue.toObject(exec);

    JSString* result = thisObject->structure()->objectToStringValue();
    if (!result) {
        RefPtr<StringImpl> newString = WTF::tryMakeString("[object ", thisObject->methodTable()->className(thisObject), "]");
        if (!newString)
            return JSValue::encode(throwOutOfMemoryError(exec));

        result = jsNontrivialString(exec, newString.release());
        thisObject->structure()->setObjectToStringValue(exec->vm(), thisObject, result);
    }
    return JSValue::encode(result);
}
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);

    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);
}
示例#24
0
static void get3DContextAttributes(ExecState* exec, RefPtr<CanvasContextAttributes>& attrs)
{
    JSValue initializerValue = exec->argument(1);
    if (initializerValue.isUndefinedOrNull())
        return;
    
    JSObject* initializerObject = initializerValue.toObject(exec);
    JSDictionary dictionary(exec, initializerObject);
    
    GraphicsContext3D::Attributes graphicsAttrs;
    
    dictionary.tryGetProperty("alpha", graphicsAttrs.alpha);
    dictionary.tryGetProperty("depth", graphicsAttrs.depth);
    dictionary.tryGetProperty("stencil", graphicsAttrs.stencil);
    dictionary.tryGetProperty("antialias", graphicsAttrs.antialias);
    dictionary.tryGetProperty("premultipliedAlpha", graphicsAttrs.premultipliedAlpha);
    dictionary.tryGetProperty("preserveDrawingBuffer", graphicsAttrs.preserveDrawingBuffer);
    
    attrs = WebGLContextAttributes::create(graphicsAttrs);
}
示例#25
0
bool UserObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
    if (!fJSUserObject)
        return false;

    CFStringRef cfPropName = IdentifierToCFString(propertyName);
    JSUserObject *jsResult = fJSUserObject->CopyProperty(cfPropName);
    ReleaseCFType(cfPropName);
    if (jsResult) {
        slot.setCustom(this, userObjectGetter);
        jsResult->Release();
        return true;
    } else {
        JSValue *kjsValue = toPrimitive(exec);
        if (kjsValue->type() != NullType && kjsValue->type() != UndefinedType) {
            JSObject *kjsObject = kjsValue->toObject(exec);
            if (kjsObject->getPropertySlot(exec, propertyName, slot))
                return true;
        }
    }
    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
示例#26
0
static RefPtr<DeviceMotionData::RotationRate> readRotationRateArgument(JSValue value, ExecState& state)
{
    if (value.isUndefinedOrNull())
        return nullptr;

    // Given the above test, this will always yield an object.
    JSObject* object = value.toObject(&state);

    JSValue alphaValue = object->get(&state, Identifier::fromString(&state, "alpha"));
    if (state.hadException())
        return nullptr;
    bool canProvideAlpha = !alphaValue.isUndefinedOrNull();
    double alpha = alphaValue.toNumber(&state);
    if (state.hadException())
        return nullptr;

    JSValue betaValue = object->get(&state, Identifier::fromString(&state, "beta"));
    if (state.hadException())
        return nullptr;
    bool canProvideBeta = !betaValue.isUndefinedOrNull();
    double beta = betaValue.toNumber(&state);
    if (state.hadException())
        return nullptr;

    JSValue gammaValue = object->get(&state, Identifier::fromString(&state, "gamma"));
    if (state.hadException())
        return nullptr;
    bool canProvideGamma = !gammaValue.isUndefinedOrNull();
    double gamma = gammaValue.toNumber(&state);
    if (state.hadException())
        return nullptr;

    if (!canProvideAlpha && !canProvideBeta && !canProvideGamma)
        return nullptr;

    return DeviceMotionData::RotationRate::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
}
示例#27
0
static RefPtr<DeviceMotionData::Acceleration> readAccelerationArgument(JSValue value, ExecState& state)
{
    if (value.isUndefinedOrNull())
        return nullptr;

    // Given the above test, this will always yield an object.
    JSObject* object = value.toObject(&state);

    JSValue xValue = object->get(&state, Identifier::fromString(&state, "x"));
    if (state.hadException())
        return nullptr;
    bool canProvideX = !xValue.isUndefinedOrNull();
    double x = xValue.toNumber(&state);
    if (state.hadException())
        return nullptr;

    JSValue yValue = object->get(&state, Identifier::fromString(&state, "y"));
    if (state.hadException())
        return nullptr;
    bool canProvideY = !yValue.isUndefinedOrNull();
    double y = yValue.toNumber(&state);
    if (state.hadException())
        return nullptr;

    JSValue zValue = object->get(&state, Identifier::fromString(&state, "z"));
    if (state.hadException())
        return nullptr;
    bool canProvideZ = !zValue.isUndefinedOrNull();
    double z = zValue.toNumber(&state);
    if (state.hadException())
        return nullptr;

    if (!canProvideX && !canProvideY && !canProvideZ)
        return nullptr;

    return DeviceMotionData::Acceleration::create(canProvideX, x, canProvideY, y, canProvideZ, z);
}
static EncodedJSValue JSC_HOST_CALL callIntlDateTimeFormat(ExecState* state)
{
    // 12.1.2 Intl.DateTimeFormat ([locales [, options]]) (ECMA-402 2.0)
    // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
    // NewTarget is always undefined when called as a function.

    VM& vm = state->vm();
    IntlDateTimeFormatConstructor* callee = jsCast<IntlDateTimeFormatConstructor*>(state->callee());

    // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns.
    JSValue thisValue = state->thisValue();
    IntlDateTimeFormat* dateTimeFormat = jsDynamicCast<IntlDateTimeFormat*>(thisValue);
    if (!dateTimeFormat) {
        JSValue prototype = callee->getDirect(vm, vm.propertyNames->prototype);
        if (JSObject::defaultHasInstance(state, thisValue, prototype)) {
            JSObject* thisObject = thisValue.toObject(state);
            if (state->hadException())
                return JSValue::encode(jsUndefined());

            dateTimeFormat = IntlDateTimeFormat::create(vm, callee);
            dateTimeFormat->initializeDateTimeFormat(*state, state->argument(0), state->argument(1));
            if (state->hadException())
                return JSValue::encode(jsUndefined());

            thisObject->putDirect(vm, vm.propertyNames->intlSubstituteValuePrivateName, dateTimeFormat);
            return JSValue::encode(thisValue);
        }
    }

    // 2. Let dateTimeFormat be OrdinaryCreateFromConstructor(newTarget, %DateTimeFormatPrototype%).
    // 3. ReturnIfAbrupt(dateTimeFormat).
    dateTimeFormat = IntlDateTimeFormat::create(vm, callee);

    // 4. Return InitializeDateTimeFormat(dateTimeFormat, locales, options).
    dateTimeFormat->initializeDateTimeFormat(*state, state->argument(0), state->argument(1));
    return JSValue::encode(dateTimeFormat);
}
示例#29
0
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
    if (!ctx) {
        ASSERT_NOT_REACHED();
        return 0;
    }
    ExecState* exec = toJS(ctx);
    JSLockHolder locker(exec);

    JSValue jsValue = toJS(exec, value);
    
    JSObjectRef objectRef = toRef(jsValue.toObject(exec));
    if (exec->hadException()) {
        JSValue exceptionValue = exec->exception();
        if (exception)
            *exception = toRef(exec, exceptionValue);
        exec->clearException();
#if ENABLE(REMOTE_INSPECTOR)
        exec->vmEntryGlobalObject()->inspectorController().reportAPIException(exec, exceptionValue);
#endif
        objectRef = 0;
    }
    return objectRef;
}
示例#30
0
//--------------------------------------------------------------------------
// KJSValueToCFTypeInternal
//--------------------------------------------------------------------------
// Caller is responsible for releasing the returned CFTypeRef
CFTypeRef KJSValueToCFTypeInternal(JSValue inValue, ExecState *exec, ObjectImpList* inImps)
{
    if (!inValue)
        return 0;

    CFTypeRef result = 0;

    JSGlueAPIEntry entry;

        if (inValue.isBoolean())
            {
                result = inValue.toBoolean(exec) ? kCFBooleanTrue : kCFBooleanFalse;
                RetainCFType(result);
                return result;
            }

        if (inValue.isString())
            {
                UString uString = inValue.toString(exec);
                result = UStringToCFString(uString);
                return result;
            }

        if (inValue.isNumber())
            {
                double number1 = inValue.toNumber(exec);
                double number2 = (double)inValue.toInteger(exec);
                if (number1 ==  number2)
                {
                    int intValue = (int)number2;
                    result = CFNumberCreate(0, kCFNumberIntType, &intValue);
                }
                else
                {
                    result = CFNumberCreate(0, kCFNumberDoubleType, &number1);
                }
                return result;
            }

        if (inValue.isObject())
            {
                if (inValue.inherits(&UserObjectImp::info)) {
                    UserObjectImp* userObjectImp = static_cast<UserObjectImp *>(asObject(inValue));
                    JSUserObject* ptr = userObjectImp->GetJSUserObject();
                    if (ptr)
                    {
                        result = ptr->CopyCFValue();
                    }
                }
                else
                {
                    JSObject *object = inValue.toObject(exec);
                    UInt8 isArray = false;

                    // if two objects reference each
                    JSObject* imp = object;
                    ObjectImpList* temp = inImps;
                    while (temp) {
                        if (imp == temp->imp) {
                            return CFRetain(GetCFNull());
                        }
                        temp = temp->next;
                    }

                    ObjectImpList imps;
                    imps.next = inImps;
                    imps.imp = imp;


//[...] HACK since we do not have access to the class info we use class name instead
#if 0
                    if (object->inherits(&ArrayInstanceImp::info))
#else
                    if (object->className() == "Array")
#endif
                    {
                        isArray = true;
                        JSGlueGlobalObject* globalObject = static_cast<JSGlueGlobalObject*>(exec->dynamicGlobalObject());
                        if (globalObject && (globalObject->Flags() & kJSFlagConvertAssociativeArray)) {
                            PropertyNameArray propNames(exec);
                            object->getPropertyNames(exec, propNames);
                            PropertyNameArray::const_iterator iter = propNames.begin();
                            PropertyNameArray::const_iterator end = propNames.end();
                            while(iter != end && isArray)
                            {
                                Identifier propName = *iter;
                                UString ustr = propName.ustring();
                                const UniChar* uniChars = (const UniChar*)ustr.characters();
                                int size = ustr.length();
                                while (size--) {
                                    if (uniChars[size] < '0' || uniChars[size] > '9') {
                                        isArray = false;
                                        break;
                                    }
                                }
                                iter++;
                            }
                        }
                    }

                    if (isArray)
                    {
                        // This is an KJS array
                        unsigned int length = object->get(exec, Identifier(exec, "length")).toUInt32(exec);
                        result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
                        if (result)
                        {
                            for (unsigned i = 0; i < length; i++)
                            {
                                CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, i), exec, &imps);
                                CFArrayAppendValue((CFMutableArrayRef)result, cfValue);
                                ReleaseCFType(cfValue);
                            }
                        }
                    }
                    else
                    {
                        // Not an array, just treat it like a dictionary which contains (property name, property value) pairs
                        PropertyNameArray propNames(exec);
                        object->getPropertyNames(exec, propNames);
                        {
                            result = CFDictionaryCreateMutable(0,
                                                               0,
                                                               &kCFTypeDictionaryKeyCallBacks,
                                                               &kCFTypeDictionaryValueCallBacks);
                            if (result)
                            {
                                PropertyNameArray::const_iterator iter = propNames.begin();
                                PropertyNameArray::const_iterator end = propNames.end();
                                while(iter != end)
                                {
                                    Identifier propName = *iter;
                                    if (object->hasProperty(exec, propName))
                                    {
                                        CFStringRef cfKey = IdentifierToCFString(propName);
                                        CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, propName), exec, &imps);
                                        if (cfKey && cfValue)
                                        {
                                            CFDictionaryAddValue((CFMutableDictionaryRef)result, cfKey, cfValue);
                                        }
                                        ReleaseCFType(cfKey);
                                        ReleaseCFType(cfValue);
                                    }
                                    iter++;
                                }
                            }
                        }
                    }
                }
                return result;
            }

    if (inValue.isUndefinedOrNull())
        {
            result = RetainCFType(GetCFNull());
            return result;
        }

    ASSERT_NOT_REACHED();
    return 0;
}