bool JSObjectSetPrivate(JSObjectRef object, void* data)
{
    JSObject* jsObject = uncheckedToJS(object);
    VM& vm = *jsObject->vm();

    const ClassInfo* classInfo = classInfoPrivate(jsObject);
    
    // Get wrapped object if proxied
    if (classInfo->isSubClassOf(JSProxy::info())) {
        jsObject = static_cast<JSProxy*>(jsObject)->target();
        classInfo = jsObject->classInfo(vm);
    }

    if (classInfo->isSubClassOf(JSCallbackObject<JSGlobalObject>::info())) {
        static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivate(data);
        return true;
    }
    if (classInfo->isSubClassOf(JSCallbackObject<JSDestructibleObject>::info())) {
        static_cast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivate(data);
        return true;
    }
#if JSC_OBJC_API_ENABLED
    if (classInfo->isSubClassOf(JSCallbackObject<JSAPIWrapperObject>::info())) {
        static_cast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->setPrivate(data);
        return true;
    }
#endif
        
    return false;
}
Beispiel #2
0
EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSValue thisValue = exec->thisValue();
    if (thisValue.inherits(JSFunction::info())) {
        JSFunction* function = jsCast<JSFunction*>(thisValue);
        if (function->isHostOrBuiltinFunction()) {
            scope.release();
            return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(vm), "() {\n    [native code]\n}"));
        }

        FunctionExecutable* executable = function->jsExecutable();
        if (executable->isClass()) {
            StringView classSource = executable->classSource().view();
            return JSValue::encode(jsString(exec, classSource.toStringWithoutCopying()));
        }

        if (thisValue.inherits(JSAsyncFunction::info())) {
            String functionHeader = executable->isArrowFunction() ? "async " : "async function ";

            StringView source = executable->source().provider()->getRange(
                executable->parametersStartOffset(),
                executable->parametersStartOffset() + executable->source().length());
            return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(vm), source));
        }

        String functionHeader = executable->isArrowFunction() ? "" : "function ";
        
        StringView source = executable->source().provider()->getRange(
            executable->parametersStartOffset(),
            executable->parametersStartOffset() + executable->source().length());
        scope.release();
        return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(vm), source));
    }

    if (thisValue.inherits(InternalFunction::info())) {
        InternalFunction* function = asInternalFunction(thisValue);
        scope.release();
        return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(), "() {\n    [native code]\n}"));
    }

    if (thisValue.isObject()) {
        JSObject* object = asObject(thisValue);
        if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
            CallData callData;
            if (object->methodTable(vm)->getCallData(object, callData) != CallType::None) {
                if (auto* classInfo = object->classInfo()) {
                    scope.release();
                    return JSValue::encode(jsMakeNontrivialString(exec, "function ", classInfo->className, "() {\n    [native code]\n}"));
                }
            }
        }
    }

    return throwVMTypeError(exec, scope);
}
static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec)
{
    ArgList args(exec);

    JSValue prototype = JSValue();
    JSObject* newTarget = exec->newTarget().getObject();
    if (newTarget->classInfo() != ArrayConstructor::info())
        prototype = newTarget->get(exec, exec->propertyNames().prototype);

    return JSValue::encode(constructArrayWithSizeQuirk(exec, args, prototype));
}
Beispiel #4
0
// Variant value must be released with NPReleaseVariantValue()
void convertValueToNPVariant(ExecState *exec, JSValue *value, NPVariant *result)
{
    JSLock lock;
    
    JSType type = value->type();
    
    VOID_TO_NPVARIANT(*result);

    if (type == StringType) {
        UString ustring = value->toString(exec);
        CString cstring = ustring.UTF8String();
        NPString string = { (const NPUTF8 *)cstring.c_str(), static_cast<uint32_t>(cstring.size()) };
        NPN_InitializeVariantWithStringCopy(result, &string);
    } else if (type == NumberType) {
        DOUBLE_TO_NPVARIANT(value->toNumber(exec), *result);
    } else if (type == BooleanType) {
        BOOLEAN_TO_NPVARIANT(value->toBoolean(exec), *result);
    } else if (type == UnspecifiedType) {
        VOID_TO_NPVARIANT(*result);
    } else if (type == NullType) {
        NULL_TO_NPVARIANT(*result);
    } else if (type == ObjectType) {
        JSObject* object = static_cast<JSObject*>(value);
        if (object->classInfo() == &RuntimeObjectImp::info) {
            RuntimeObjectImp* imp = static_cast<RuntimeObjectImp *>(value);
            CInstance* instance = static_cast<CInstance*>(imp->getInternalInstance());
            if (instance) {
                NPObject* obj = instance->getObject();
                _NPN_RetainObject(obj);
                OBJECT_TO_NPVARIANT(obj, *result);
            }
        } else {
            Interpreter* originInterpreter = exec->dynamicInterpreter();
            RootObject* originRootObject = findRootObject(originInterpreter);

            Interpreter* interpreter = 0;
            if (originInterpreter->isGlobalObject(value)) {
                interpreter = originInterpreter->interpreterForGlobalObject(value);
            }

            if (!interpreter)
                interpreter = originInterpreter;

            RootObject* rootObject = findRootObject(interpreter);
            if (rootObject) {
                NPObject* npObject = _NPN_CreateScriptObject(0, object, originRootObject, rootObject);
                OBJECT_TO_NPVARIANT(npObject, *result);
            }
        }
    }
}
JSTypedArrayType JSObjectGetTypedArrayType(JSContextRef ctx, JSObjectRef object) {
    ExecState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    JSObject* jsObject = toJS(object);
    JSTypedArrayType type = kJSTypedArrayTypeNone;
    if( jsObject->inherits(JSArrayBufferView::info()) ) {
        type = TypedArrayTypes[jsObject->classInfo()->typedArrayStorageType];
    }
    else if( jsObject->inherits(JSArrayBuffer::info()) ) {
        type = kJSTypedArrayTypeArrayBuffer;
    }
    return type;
}
JSDOMWindow* toJSDOMWindow(JSValue value)
{
    if (!value.isObject())
        return 0;
    while (!value.isNull()) {
        JSObject* object = asObject(value);
        const ClassInfo* classInfo = object->classInfo();
        if (classInfo == JSDOMWindow::info())
            return jsCast<JSDOMWindow*>(object);
        if (classInfo == JSDOMWindowShell::info())
            return jsCast<JSDOMWindowShell*>(object)->window();
        value = object->prototype();
    }
    return 0;
}
Beispiel #7
0
JSTypedArrayType JSTypedArrayGetType(JSContextRef ctx, JSValueRef value) {
    ExecState* exec = toJS(ctx);
	JSLockHolder locker(exec);

    JSValue jsValue = toJS(exec, value);
	JSTypedArrayType type = JSTypedArrayType::NotTypedArray;
	if( jsValue.inherits(JSArrayBufferView::info()) ) {
        JSObject* object = jsValue.getObject();
        type = (JSTypedArrayType) object->classInfo()->typedArrayStorageType;
    }
	else if( jsValue.inherits(JSArrayBuffer::info()) ) {
        type = JSTypedArrayType::TypeDataView;
    }
    return type;
}
// Variant value must be released with NPReleaseVariantValue()
void convertValueToNPVariant(ExecState* exec, JSValue value, NPVariant* result)
{
    JSLock lock(SilenceAssertionsOnly);

    VOID_TO_NPVARIANT(*result);

    if (value.isString()) {
        UString ustring = value.toString(exec);
        CString cstring = ustring.utf8();
        NPString string = { (const NPUTF8*)cstring.data(), static_cast<uint32_t>(cstring.length()) };
        NPN_InitializeVariantWithStringCopy(result, &string);
    } else if (value.isNumber()) {
        DOUBLE_TO_NPVARIANT(value.toNumber(exec), *result);
    } else if (value.isBoolean()) {
        BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), *result);
    } else if (value.isNull()) {
        NULL_TO_NPVARIANT(*result);
    } else if (value.isObject()) {
        JSObject* object = asObject(value);
        if (object->classInfo() == &CRuntimeObject::s_info) {
            CRuntimeObject* runtimeObject = static_cast<CRuntimeObject*>(object);
            CInstance* instance = runtimeObject->getInternalCInstance();
            if (instance) {
                NPObject* obj = instance->getObject();
                _NPN_RetainObject(obj);
                OBJECT_TO_NPVARIANT(obj, *result);
            }
        } else {
#ifdef ANDROID
            RootObject* rootObject = findRootObject(exec->dynamicGlobalObject());
            if (!rootObject)
                rootObject = findRootObject(exec->lexicalGlobalObject());
#else
            JSGlobalObject* globalObject = exec->dynamicGlobalObject();

            RootObject* rootObject = findRootObject(globalObject);
#endif
            if (rootObject) {
                NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject);
                OBJECT_TO_NPVARIANT(npObject, *result);
            }
        }
    }
}
// Variant value must be released with NPReleaseVariantValue()
void convertValueToNPVariant(ExecState* exec, JSValuePtr value, NPVariant* result)
{
    JSLock lock(false);

    VOID_TO_NPVARIANT(*result);

    if (value.isString()) {
        UString ustring = value.toString(exec);
        CString cstring = ustring.UTF8String();
        NPString string = { (const NPUTF8*)cstring.c_str(), static_cast<uint32_t>(cstring.size()) };
        NPN_InitializeVariantWithStringCopy(result, &string);
    } else if (value.isNumber()) {
        DOUBLE_TO_NPVARIANT(value.toNumber(exec), *result);
    } else if (value.isBoolean()) {
        BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), *result);
    } else if (value.isNull()) {
        NULL_TO_NPVARIANT(*result);
    } else if (value.isObject()) {
        JSObject* object = asObject(value);
        if (object->classInfo() == &RuntimeObjectImp::s_info) {
            RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(object);
            CInstance* instance = static_cast<CInstance*>(imp->getInternalInstance());
            if (instance) {
                NPObject* obj = instance->getObject();
                _NPN_RetainObject(obj);
                OBJECT_TO_NPVARIANT(obj, *result);
            }
        } else {
            JSGlobalObject* globalObject = exec->dynamicGlobalObject();

            RootObject* rootObject = findRootObject(globalObject);
            if (rootObject) {
                NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject);
                OBJECT_TO_NPVARIANT(npObject, *result);
            }
        }
    }
}
Beispiel #10
0
jvalue convertValueToJValue(ExecState* exec, RootObject* rootObject, JSValue value, JavaType javaType, const char* javaClassName)
{
    JSLock lock(SilenceAssertionsOnly);

    jvalue result;
    memset(&result, 0, sizeof(jvalue));

    switch (javaType) {
    case JavaTypeArray:
    case JavaTypeObject:
        {
            // FIXME: JavaJSObject::convertValueToJObject functionality is almost exactly the same,
            // these functions should use common code.

            if (value.isObject()) {
                JSObject* object = asObject(value);
                if (object->inherits(&JavaRuntimeObject::s_info)) {
                    // Unwrap a Java instance.
                    JavaRuntimeObject* runtimeObject = static_cast<JavaRuntimeObject*>(object);
                    JavaInstance* instance = runtimeObject->getInternalJavaInstance();
                    if (instance)
                        result.l = instance->javaInstance();
                } else if (object->classInfo() == &RuntimeArray::s_info) {
                    // Input is a JavaScript Array that was originally created from a Java Array
                    RuntimeArray* imp = static_cast<RuntimeArray*>(object);
                    JavaArray* array = static_cast<JavaArray*>(imp->getConcreteArray());
                    result.l = array->javaArray();
                } else if (object->classInfo() == &JSArray::s_info) {
                    // Input is a Javascript Array. We need to create it to a Java Array.
                    result.l = convertArrayInstanceToJavaArray(exec, asArray(value), javaClassName);
                } else if ((!result.l && (!strcmp(javaClassName, "java.lang.Object")))
                           || (!strcmp(javaClassName, "netscape.javascript.JSObject"))) {
                    // Wrap objects in JSObject instances.
                    JNIEnv* env = getJNIEnv();
                    jclass jsObjectClass = env->FindClass("sun/plugin/javascript/webkit/JSObject");
                    jmethodID constructorID = env->GetMethodID(jsObjectClass, "<init>", "(J)V");
                    if (constructorID) {
                        jlong nativeHandle = ptr_to_jlong(object);
                        rootObject->gcProtect(object);
                        result.l = env->NewObject(jsObjectClass, constructorID, nativeHandle);
                    }
                }
            }

            // Create an appropriate Java object if target type is java.lang.Object.
            if (!result.l && !strcmp(javaClassName, "java.lang.Object")) {
                if (value.isString()) {
                    UString stringValue = asString(value)->value(exec);
                    JNIEnv* env = getJNIEnv();
                    jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.characters(), stringValue.length());
                    result.l = javaString;
                } else if (value.isNumber()) {
                    double doubleValue = value.asNumber();
                    JNIEnv* env = getJNIEnv();
                    jclass clazz = env->FindClass("java/lang/Double");
                    jmethodID constructor = env->GetMethodID(clazz, "<init>", "(D)V");
                    jobject javaDouble = env->functions->NewObject(env, clazz, constructor, doubleValue);
                    result.l = javaDouble;
                } else if (value.isBoolean()) {
                    bool boolValue = value.asBoolean();
                    JNIEnv* env = getJNIEnv();
                    jclass clazz = env->FindClass("java/lang/Boolean");
                    jmethodID constructor = env->GetMethodID(clazz, "<init>", "(Z)V");
                    jobject javaBoolean = env->functions->NewObject(env, clazz, constructor, boolValue);
                    result.l = javaBoolean;
                } else if (value.isUndefined()) {
                    UString stringValue = "undefined";
                    JNIEnv* env = getJNIEnv();
                    jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.characters(), stringValue.length());
                    result.l = javaString;
                }
            }

            // Convert value to a string if the target type is a java.lang.String, and we're not
            // converting from a null.
            if (!result.l && !strcmp(javaClassName, "java.lang.String")) {
                if (!value.isNull()) {
                    UString stringValue = value.toString(exec);
                    JNIEnv* env = getJNIEnv();
                    jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.characters(), stringValue.length());
                    result.l = javaString;
                }
            }
        }
        break;

    case JavaTypeBoolean:
        {
            result.z = (jboolean)value.toNumber(exec);
        }
        break;

    case JavaTypeByte:
        {
            result.b = (jbyte)value.toNumber(exec);
        }
        break;

    case JavaTypeChar:
        {
            result.c = (jchar)value.toNumber(exec);
        }
        break;

    case JavaTypeShort:
        {
            result.s = (jshort)value.toNumber(exec);
        }
        break;

    case JavaTypeInt:
        {
            result.i = (jint)value.toNumber(exec);
        }
        break;

    case JavaTypeLong:
        {
            result.j = (jlong)value.toNumber(exec);
        }
        break;

    case JavaTypeFloat:
        {
            result.f = (jfloat)value.toNumber(exec);
        }
        break;

    case JavaTypeDouble:
        {
            result.d = (jdouble)value.toNumber(exec);
        }
        break;

    case JavaTypeInvalid:
    case JavaTypeVoid:
        break;
    }
    return result;
}
jvalue convertValueToJValue(ExecState* exec, JSValue value, JNIType jniType, const char* javaClassName)
{
    JSLock lock(SilenceAssertionsOnly);

    jvalue result;

    switch (jniType) {
    case array_type:
    case object_type:
        {
            result.l = (jobject)0;

            // First see if we have a Java instance.
            if (value.isObject()) {
                JSObject* objectImp = asObject(value);
                if (objectImp->classInfo() == &RuntimeObjectImp::s_info) {
                    RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(objectImp);
                    JavaInstance* instance = static_cast<JavaInstance*>(imp->getInternalInstance());
                    if (instance)
                        result.l = instance->javaInstance();
                } else if (objectImp->classInfo() == &RuntimeArray::s_info) {
                    // Input is a JavaScript Array that was originally created from a Java Array
                    RuntimeArray* imp = static_cast<RuntimeArray*>(objectImp);
                    JavaArray* array = static_cast<JavaArray*>(imp->getConcreteArray());
                    result.l = array->javaArray();
                } else if (objectImp->classInfo() == &JSArray::info) {
                    // Input is a Javascript Array. We need to create it to a Java Array.
                    result.l = convertArrayInstanceToJavaArray(exec, asArray(value), javaClassName);
                }
            }

            // Now convert value to a string if the target type is a java.lang.string, and we're not
            // converting from a Null.
            if (!result.l && !strcmp(javaClassName, "java.lang.String")) {
#ifdef CONVERT_NULL_TO_EMPTY_STRING
                if (value->isNull()) {
                    JNIEnv* env = getJNIEnv();
                    jchar buf[2];
                    jobject javaString = env->functions->NewString(env, buf, 0);
                    result.l = javaString;
                } else
#else
                if (!value.isNull())
#endif
                {
                    UString stringValue = value.toString(exec);
                    JNIEnv* env = getJNIEnv();
                    jobject javaString = env->functions->NewString(env, (const jchar *)stringValue.data(), stringValue.size());
                    result.l = javaString;
                }
            } else if (!result.l)
                // ANDROID
                memset(&result, 0, sizeof(jvalue)); // Handle it the same as a void case
        }
        break;

    case boolean_type:
        {
            result.z = (jboolean)value.toNumber(exec);
        }
        break;

    case byte_type:
        {
            result.b = (jbyte)value.toNumber(exec);
        }
        break;

    case char_type:
        {
            result.c = (jchar)value.toNumber(exec);
        }
        break;

    case short_type:
        {
            result.s = (jshort)value.toNumber(exec);
        }
        break;

    case int_type:
        {
            result.i = (jint)value.toNumber(exec);
        }
        break;

    case long_type:
        {
            result.j = (jlong)value.toNumber(exec);
        }
        break;

    case float_type:
        {
            result.f = (jfloat)value.toNumber(exec);
        }
        break;

    case double_type:
        {
            result.d = (jdouble)value.toNumber(exec);
        }
        break;

        break;

    case invalid_type:
    default:
    case void_type:
        {
            // ANDROID
            memset(&result, 0, sizeof(jvalue));
        }
        break;
    }
    return result;
}