EncodedJSValue RuntimeArray::lengthGetter(ExecState* exec, JSObject*, EncodedJSValue thisValue, PropertyName) { RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(JSValue::decode(thisValue)); if (!thisObject) return throwVMTypeError(exec); return JSValue::encode(jsNumber(thisObject->getLength())); }
void RuntimeArray::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (index >= thisObject->getLength()) { exec->vm().throwException(exec, createRangeError(exec, "Range error")); return; } thisObject->getConcreteArray()->setValueAt(exec, index, value); }
EncodedJSValue RuntimeArray::lengthGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); RuntimeArray* thisObject = jsDynamicDowncast<RuntimeArray*>(JSValue::decode(thisValue)); if (!thisObject) return throwVMTypeError(exec, scope); return JSValue::encode(jsNumber(thisObject->getLength())); }
bool RuntimeArray::getOwnPropertySlotByIndex(JSCell* cell, ExecState *exec, unsigned index, PropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (index < thisObject->getLength()) { slot.setCustomIndex(thisObject, index, thisObject->indexGetter); return true; } return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot); }
bool RuntimeArray::getOwnPropertySlotByIndex(JSObject* object, ExecState *exec, unsigned index, PropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(object); if (index < thisObject->getLength()) { slot.setValue(thisObject, DontDelete | DontEnum, thisObject->getConcreteArray()->valueAt(exec, index)); return true; } return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot); }
void RuntimeArray::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(object); unsigned length = thisObject->getLength(); for (unsigned i = 0; i < length; ++i) propertyNames.add(Identifier::from(exec, i)); if (mode.includeDontEnumProperties()) propertyNames.add(exec->propertyNames().length); JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); }
bool RuntimeArray::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (index >= thisObject->getLength()) { throwException(exec, scope, createRangeError(exec, "Range error")); return false; } return thisObject->getConcreteArray()->setValueAt(exec, index, value); }
void RuntimeArray::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { exec->vm().throwException(exec, createRangeError(exec, "Range error")); return; } if (Optional<uint32_t> index = parseIndex(propertyName)) { thisObject->getConcreteArray()->setValueAt(exec, index.value(), value); return; } JSObject::put(thisObject, exec, propertyName, value, slot); }
bool RuntimeArray::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { throwException(exec, scope, createRangeError(exec, "Range error")); return false; } if (Optional<uint32_t> index = parseIndex(propertyName)) return thisObject->getConcreteArray()->setValueAt(exec, index.value(), value); return JSObject::put(thisObject, exec, propertyName, value, slot); }
void RuntimeArray::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { throwError(exec, createRangeError(exec, "Range error")); return; } unsigned index = propertyName.asIndex(); if (index != PropertyName::NotAnIndex) { thisObject->getConcreteArray()->setValueAt(exec, index, value); return; } JSObject::put(thisObject, exec, propertyName, value, slot); }
bool RuntimeArray::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(object); if (propertyName == exec->propertyNames().length) { slot.setCacheableCustom(thisObject, DontDelete | ReadOnly | DontEnum, thisObject->lengthGetter); return true; } Optional<uint32_t> index = parseIndex(propertyName); if (index && index.value() < thisObject->getLength()) { slot.setValue(thisObject, DontDelete | DontEnum, thisObject->getConcreteArray()->valueAt(exec, index.value())); return true; } return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); }
void RuntimeArray::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { RuntimeArray* thisObject = static_cast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { throwError(exec, createRangeError(exec, "Range error")); return; } bool ok; unsigned index = propertyName.toArrayIndex(ok); if (ok) { thisObject->getConcreteArray()->setValueAt(exec, index, value); return; } JSObject::put(thisObject, exec, propertyName, value, slot); }
bool RuntimeArray::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { slot.setCacheableCustom(thisObject, thisObject->lengthGetter); return true; } unsigned index = propertyName.asIndex(); if (index < thisObject->getLength()) { ASSERT(index != PropertyName::NotAnIndex); slot.setCustomIndex(thisObject, index, thisObject->indexGetter); return true; } return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); }
bool RuntimeArray::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { RuntimeArray* thisObject = static_cast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { slot.setCacheableCustom(thisObject, thisObject->lengthGetter); return true; } bool ok; unsigned index = propertyName.toArrayIndex(ok); if (ok) { if (index < thisObject->getLength()) { slot.setCustomIndex(thisObject, index, thisObject->indexGetter); return true; } } return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); }
bool RuntimeArray::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(object); if (propertyName == exec->propertyNames().length) { PropertySlot slot; slot.setCustom(thisObject, lengthGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } unsigned index = propertyName.asIndex(); if (index < thisObject->getLength()) { ASSERT(index != PropertyName::NotAnIndex); PropertySlot slot; slot.setCustomIndex(thisObject, index, indexGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | DontEnum); return true; } return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); }
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; }
JSValue* RuntimeArray::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { RuntimeArray* thisObj = static_cast<RuntimeArray*>(asObject(slot.slotBase())); return jsNumber(exec, thisObj->getLength()); }
JSValue* RuntimeArray::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { RuntimeArray* thisObj = static_cast<RuntimeArray*>(asObject(slot.slotBase())); return thisObj->getConcreteArray()->valueAt(exec, slot.index()); }
EncodedJSValue RuntimeArray::lengthGetter(ExecState*, EncodedJSValue slotBase, EncodedJSValue, PropertyName) { RuntimeArray* thisObj = jsCast<RuntimeArray*>(JSValue::decode(slotBase)); return JSValue::encode(jsNumber(thisObj->getLength())); }
EncodedJSValue RuntimeArray::indexGetter(ExecState* exec, EncodedJSValue slotBase, EncodedJSValue, unsigned index) { RuntimeArray* thisObj = jsCast<RuntimeArray*>(JSValue::decode(slotBase)); return JSValue::encode(thisObj->getConcreteArray()->valueAt(exec, index)); }
JSValue RuntimeArray::indexGetter(ExecState* exec, JSValue slotBase, unsigned index) { RuntimeArray* thisObj = static_cast<RuntimeArray*>(asObject(slotBase)); return thisObj->getConcreteArray()->valueAt(exec, index); }
JSValue RuntimeArray::lengthGetter(ExecState*, JSValue slotBase, PropertyName) { RuntimeArray* thisObj = static_cast<RuntimeArray*>(asObject(slotBase)); return jsNumber(thisObj->getLength()); }
JSValue RuntimeArray::lengthGetter(ExecState*, JSValue slotBase, const Identifier&) { RuntimeArray* thisObj = static_cast<RuntimeArray*>(asObject(slotBase)); return jsNumber(thisObj->getLength()); }
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; }