Beispiel #1
0
UString JSObject::toString(ExecState* exec) const
{
    JSValuePtr primitive = toPrimitive(exec, PreferString);
    if (exec->hadException())
        return "";
    return primitive->toString(exec);
}
Beispiel #2
0
JSValuePtr errorProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
    JSObject* thisObj = thisValue->toThisObject(exec);

    UString s = "Error";

    JSValuePtr v = thisObj->get(exec, exec->propertyNames().name);
    if (!v->isUndefined())
        s = v->toString(exec);

    v = thisObj->get(exec, exec->propertyNames().message);
    if (!v->isUndefined()) {
        // Mozilla-compatible format.
        s += ": ";
        s += v->toString(exec);
    }

    return jsNontrivialString(exec, s);
}
Beispiel #3
0
void reportException(JSC::ExecState* exec, JSValuePtr 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();
    scriptExecutionContext->reportException(errorMessage, lineNumber, exceptionSourceURL);
}
Beispiel #4
0
JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    JSLock lock(exec);

    JSValuePtr jsValue = toJS(value);
    
    RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
        stringRef.clear();
    }
    return stringRef.release().releaseRef();
}
Beispiel #5
0
void JSDocument::setLocation(ExecState* exec, JSValuePtr value)
{
    Frame* frame = static_cast<Document*>(impl())->frame();
    if (!frame)
        return;

    String str = value->toString(exec);

    // IE and Mozilla both resolve the URL relative to the source frame,
    // not the target frame.
    Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
    if (activeFrame)
        str = activeFrame->document()->completeURL(str).string();

    bool userGesture = activeFrame->script()->processingUserGesture();
    frame->loader()->scheduleLocationChange(str, activeFrame->loader()->outgoingReferrer(), false, userGesture);
}
// 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 #7
0
void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValuePtr value)
{
    asRegExpConstructor(baseObject)->setInput(value->toString(exec));
}
Beispiel #8
0
UString valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValuePtr value)
{
    if (value.isUndefinedOrNull())
        return UString();
    return value.toString(exec);
}
JSValuePtr JavaInstance::invokeMethod (ExecState *exec, const MethodList &methodList, const ArgList &args)
{
    int i, count = args.size();
    jvalue *jArgs;
    JSValuePtr resultValue;
    Method *method = 0;
    size_t numMethods = methodList.size();
    
    // Try to find a good match for the overloaded method.  The 
    // fundamental problem is that JavaScript doesn have the
    // notion of method overloading and Java does.  We could 
    // get a bit more sophisticated and attempt to does some
    // type checking as we as checking the number of parameters.
    Method *aMethod;
    for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) {
        aMethod = methodList[methodIndex];
        if (aMethod->numParameters() == count) {
            method = aMethod;
            break;
        }
    }
    if (method == 0) {
        JS_LOG ("unable to find an appropiate method\n");
        return jsUndefined();
    }
    
    const JavaMethod *jMethod = static_cast<const JavaMethod*>(method);
    JS_LOG ("call %s %s on %p\n", UString(jMethod->name()).UTF8String().c_str(), jMethod->signature(), _instance->_instance);
    
    if (count > 0) {
        jArgs = (jvalue *)malloc (count * sizeof(jvalue));
    }
    else
        jArgs = 0;
        
    for (i = 0; i < count; i++) {
        JavaParameter* aParameter = jMethod->parameterAt(i);
        jArgs[i] = convertValueToJValue(exec, args.at(exec, i), aParameter->getJNIType(), aParameter->type());
        JS_LOG("arg[%d] = %s\n", i, args.at(exec, i).toString(exec).ascii());
    }
        
    jvalue result;

    // Try to use the JNI abstraction first, otherwise fall back to
    // nornmal JNI.  The JNI dispatch abstraction allows the Java plugin
    // to dispatch the call on the appropriate internal VM thread.
    RootObject* rootObject = this->rootObject();
    if (!rootObject)
        return jsUndefined();

    bool handled = false;
    if (rootObject->nativeHandle()) {
        jobject obj = _instance->_instance;
        JSValuePtr exceptionDescription = noValue();
        const char *callingURL = 0;  // FIXME, need to propagate calling URL to Java
        handled = dispatchJNICall(exec, rootObject->nativeHandle(), obj, jMethod->isStatic(), jMethod->JNIReturnType(), jMethod->methodID(obj), jArgs, result, callingURL, exceptionDescription);
        if (exceptionDescription) {
            throwError(exec, GeneralError, exceptionDescription.toString(exec));
            free (jArgs);
            return jsUndefined();
        }
    }
    
    // The following code can be conditionally removed once we have a Tiger update that
    // contains the new Java plugin.  It is needed for builds prior to Tiger.
    if (!handled) {    
        jobject obj = _instance->_instance;
        switch (jMethod->JNIReturnType()){
            case void_type:
                callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs);
                break;            
            case object_type:
                result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs);
                break;
            case boolean_type:
                result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs);
                break;
            case byte_type:
                result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs);
                break;
            case char_type:
                result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs);
                break;            
            case short_type:
                result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs);
                break;
            case int_type:
                result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs);
                break;
            
            case long_type:
                result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs);
                break;
            case float_type:
                result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs);
                break;
            case double_type:
                result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs);
                break;
            case invalid_type:
            default:
                break;
        }
    }
        
    switch (jMethod->JNIReturnType()){
        case void_type: {
            resultValue = jsUndefined();
        }
        break;
        
        case object_type: {
            if (result.l != 0) {
                const char *arrayType = jMethod->returnType();
                if (arrayType[0] == '[') {
                    resultValue = JavaArray::convertJObjectToArray(exec, result.l, arrayType, rootObject);
                }
                else {
                    resultValue = JavaInstance::create(result.l, rootObject)->createRuntimeObject(exec);
                }
            }
            else {
                resultValue = jsUndefined();
            }
        }
        break;
        
        case boolean_type: {
            resultValue = jsBoolean(result.z);
        }
        break;
        
        case byte_type: {
            resultValue = jsNumber(exec, result.b);
        }
        break;
        
        case char_type: {
            resultValue = jsNumber(exec, result.c);
        }
        break;
        
        case short_type: {
            resultValue = jsNumber(exec, result.s);
        }
        break;
        
        case int_type: {
            resultValue = jsNumber(exec, result.i);
        }
        break;
        
        case long_type: {
            resultValue = jsNumber(exec, result.j);
        }
        break;
        
        case float_type: {
            resultValue = jsNumber(exec, result.f);
        }
        break;
        
        case double_type: {
            resultValue = jsNumber(exec, result.d);
        }
        break;

        case invalid_type:
        default: {
            resultValue = jsUndefined();
        }
        break;
    }

    free (jArgs);

    return resultValue;
}
Beispiel #10
0
jvalue convertValueToJValue(ExecState* exec, JSValuePtr value, JNIType _JNIType, const char* javaClassName)
{
    JSLock lock(false);
    
    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 == 0 && strcmp(javaClassName, "java.lang.String") == 0) {
#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 == 0) 
                bzero (&result, 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: {
            bzero (&result, sizeof(jvalue));
        }
        break;
    }
    return result;
}
Beispiel #11
0
static jobject convertArrayInstanceToJavaArray(ExecState* exec, JSArray* jsArray, const char* javaClassName)
{
    JNIEnv *env = getJNIEnv();
    // As JS Arrays can contain a mixture of objects, assume we can convert to
    // the requested Java Array type requested, unless the array type is some object array
    // other than a string.
    unsigned length = jsArray->length();
    jobjectArray jarray = 0;
    
    // Build the correct array type
    switch (JNITypeFromPrimitiveType(javaClassName[1])) { 
        case object_type: {
        // Only support string object types
        if (0 == strcmp("[Ljava.lang.String;", javaClassName)) {
            jarray = (jobjectArray)env->NewObjectArray(length,
                env->FindClass("java/lang/String"),
                env->NewStringUTF(""));
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                UString stringValue = item->toString(exec);
                env->SetObjectArrayElement(jarray,i,
                    env->functions->NewString(env, (const jchar *)stringValue.data(), stringValue.size()));
                }
            }
            break;
        }
        
        case boolean_type: {
            jarray = (jobjectArray)env->NewBooleanArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                jboolean value = (jboolean)item->toNumber(exec);
                env->SetBooleanArrayRegion((jbooleanArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }
        
        case byte_type: {
            jarray = (jobjectArray)env->NewByteArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                jbyte value = (jbyte)item->toNumber(exec);
                env->SetByteArrayRegion((jbyteArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }

        case char_type: {
            jarray = (jobjectArray)env->NewCharArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                UString stringValue = item->toString(exec);
                jchar value = 0;
                if (stringValue.size() > 0)
                    value = ((const jchar*)stringValue.data())[0];
                env->SetCharArrayRegion((jcharArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }

        case short_type: {
            jarray = (jobjectArray)env->NewShortArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                jshort value = (jshort)item->toNumber(exec);
                env->SetShortArrayRegion((jshortArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }

        case int_type: {
            jarray = (jobjectArray)env->NewIntArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                jint value = (jint)item->toNumber(exec);
                env->SetIntArrayRegion((jintArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }

        case long_type: {
            jarray = (jobjectArray)env->NewLongArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                jlong value = (jlong)item->toNumber(exec);
                env->SetLongArrayRegion((jlongArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }

        case float_type: {
            jarray = (jobjectArray)env->NewFloatArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                jfloat value = (jfloat)item->toNumber(exec);
                env->SetFloatArrayRegion((jfloatArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }
    
        case double_type: {
            jarray = (jobjectArray)env->NewDoubleArray(length);
            for(unsigned i = 0; i < length; i++) {
                JSValuePtr item = jsArray->get(exec, i);
                jdouble value = (jdouble)item->toNumber(exec);
                env->SetDoubleArrayRegion((jdoubleArray)jarray, (jsize)i, (jsize)1, &value);
            }
            break;
        }
        
        case array_type: // don't handle embedded arrays
        case void_type: // Don't expect arrays of void objects
        case invalid_type: // Array of unknown objects
            break;
    }
    
    // if it was not one of the cases handled, then null is returned
    return jarray;
}