QV4::Value method_dayName(QV4::SimpleCallContext *ctx);
QV4::Value method_standaloneDayName(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_firstDayOfWeek(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_measurementSystem(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_textDirection(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_weekDays(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_uiLanguages(QV4::SimpleCallContext *ctx);
+
+ QV4::Value method_get_name(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_nativeLanguageName(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_nativeCountryName(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_decimalPoint(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_groupSeparator(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_percent(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_zeroDigit(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_negativeSign(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_positiveSign(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_exponential(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_amText(QV4::SimpleCallContext *ctx);
+ QV4::Value method_get_pmText(QV4::SimpleCallContext *ctx);
+
private:
static void destroy(Managed *that)
{
if (!r) \
V4THROW_ERROR("Not a valid Locale object")
-#define V8_GET_LOCALE_DATA_RESOURCE(OBJECT) \
- GET_LOCALE_DATA_RESOURCE((OBJECT).As<v8::Value>()->v4Value())
-
-static bool isLocaleObject(v8::Handle<v8::Value> val)
+static bool isLocaleObject(const QV4::Value &val)
{
- if (!val->IsObject())
+ QV4::Object *obj = val.asObject();
+ if (!obj)
return false;
- v8::Handle<v8::Object> localeObj = val->ToObject();
- return localeObj->Has(v8::String::New("nativeLanguageName")); //XXX detect locale object properly
+ return obj->asQmlLocale();
}
//--------------
//--------------
// Locale object
-static v8::Handle<v8::Value> locale_get_firstDayOfWeek(v8::Handle<v8::String>, const v8::AccessorInfo &info)
+QV4::Value QQmlLocaleData::method_get_firstDayOfWeek(QV4::SimpleCallContext*)
{
- V8_GET_LOCALE_DATA_RESOURCE(info.This());
- int fdow = int(r->locale.firstDayOfWeek());
+ int fdow = int(locale.firstDayOfWeek());
if (fdow == 7)
fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date
- return v8::Integer::New(fdow);
+ return QV4::Value::fromInt32(fdow);
}
-static v8::Handle<v8::Value> locale_get_measurementSystem(v8::Handle<v8::String>, const v8::AccessorInfo &info)
+QV4::Value QQmlLocaleData::method_get_measurementSystem(QV4::SimpleCallContext*)
{
- V8_GET_LOCALE_DATA_RESOURCE(info.This());
- return v8::Integer::New(r->locale.measurementSystem());
+ return QV4::Value::fromInt32(locale.measurementSystem());
}
-static v8::Handle<v8::Value> locale_get_textDirection(v8::Handle<v8::String>, const v8::AccessorInfo &info)
+QV4::Value QQmlLocaleData::method_get_textDirection(QV4::SimpleCallContext*)
{
- V8_GET_LOCALE_DATA_RESOURCE(info.This());
- return v8::Integer::New(r->locale.textDirection());
+ return QV4::Value::fromInt32(locale.textDirection());
}
-static v8::Handle<v8::Value> locale_get_weekDays(v8::Handle<v8::String>, const v8::AccessorInfo &info)
+QV4::Value QQmlLocaleData::method_get_weekDays(QV4::SimpleCallContext* ctx)
{
- V8_GET_LOCALE_DATA_RESOURCE(info.This());
-
- QList<Qt::DayOfWeek> days = r->locale.weekdays();
+ QList<Qt::DayOfWeek> days = locale.weekdays();
- v8::Handle<v8::Array> result = v8::Array::New(days.size());
+ QV4::ArrayObject *result = ctx->engine->newArrayObject();
+ result->arrayReserve(days.size());
for (int i = 0; i < days.size(); ++i) {
int day = days.at(i);
if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)
day = 0;
- result->Set(i, v8::Integer::New(day));
+ result->arrayData[i].value = QV4::Value::fromInt32(day);
}
+ result->setArrayLengthUnchecked(days.size());
- return result;
+ return QV4::Value::fromObject(result);
}
-static v8::Handle<v8::Value> locale_get_uiLanguages(v8::Handle<v8::String>, const v8::AccessorInfo &info)
+QV4::Value QQmlLocaleData::method_get_uiLanguages(QV4::SimpleCallContext *ctx)
{
- V8_GET_LOCALE_DATA_RESOURCE(info.This());
-
- QStringList langs = r->locale.uiLanguages();
- v8::Handle<v8::Array> result = v8::Array::New(langs.size());
- for (int i = 0; i < langs.size(); ++i) {
- result->Set(i, r->engine->toString(langs.at(i)));
- }
-
- return result;
+ QStringList langs = locale.uiLanguages();
+ QV4::ArrayObject *result = ctx->engine->newArrayObject();
+ result->arrayReserve(langs.size());
+ for (int i = 0; i < langs.size(); ++i)
+ result->arrayData[i].value = QV4::Value::fromString(ctx, langs.at(i));
+ result->setArrayLengthUnchecked(langs.size());
+
+ return QV4::Value::fromObject(result);
}
QV4::Value QQmlLocaleData::method_currencySymbol(QV4::SimpleCallContext *ctx)
LOCALE_FORMATTED_DAYNAME(dayName)
LOCALE_FORMATTED_DAYNAME(standaloneDayName)
-#define LOCALE_STRING_PROPERTY(VARIABLE) static v8::Handle<v8::Value> locale_get_ ## VARIABLE (v8::Handle<v8::String>, const v8::AccessorInfo &info) \
+#define LOCALE_STRING_PROPERTY(VARIABLE) QV4::Value QQmlLocaleData::method_get_ ## VARIABLE (QV4::SimpleCallContext* ctx) \
{ \
- V8_GET_LOCALE_DATA_RESOURCE(info.This()); \
- return r->engine->toString(r->locale. VARIABLE());\
+ return QV4::Value::fromString(ctx, locale. VARIABLE());\
}
-#define LOCALE_REGISTER_STRING_ACCESSOR(FT, VARIABLE) \
- FT ->PrototypeTemplate()->SetAccessor( v8::String::New( #VARIABLE ), locale_get_ ## VARIABLE )
-
-
LOCALE_STRING_PROPERTY(name)
LOCALE_STRING_PROPERTY(nativeLanguageName)
LOCALE_STRING_PROPERTY(nativeCountryName)
~QV8LocaleDataDeletable();
QV4::PersistentValue prototype;
- QV4::PersistentValue v4Prototype;
};
QV8LocaleDataDeletable::QV8LocaleDataDeletable(QV8Engine *engine)
{
- v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetHasExternalResource(true);
-
- LOCALE_REGISTER_STRING_ACCESSOR(ft, name);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeLanguageName);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, nativeCountryName);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, decimalPoint);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, groupSeparator);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, percent);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, zeroDigit);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, negativeSign);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, positiveSign);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, exponential);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, amText);
- LOCALE_REGISTER_STRING_ACCESSOR(ft, pmText);
-
- ft->PrototypeTemplate()->SetAccessor(v8::String::New("firstDayOfWeek"), locale_get_firstDayOfWeek);
- ft->PrototypeTemplate()->SetAccessor(v8::String::New("weekDays"), locale_get_weekDays);
- ft->PrototypeTemplate()->SetAccessor(v8::String::New("measurementSystem"), locale_get_measurementSystem);
- ft->PrototypeTemplate()->SetAccessor(v8::String::New("textDirection"), locale_get_textDirection);
- ft->PrototypeTemplate()->SetAccessor(v8::String::New("uiLanguages"), locale_get_uiLanguages);
-
- prototype = QV4::Value::fromObject(ft->GetFunction()->NewInstance()->v4Value().asObject()->prototype);
-
QV4::ExecutionEngine *eng = QV8Engine::getV4(engine);
- v4Prototype = QV4::Value::fromObject(eng->newObject());
- QQmlLocaleData::initClass(eng, v4Prototype.value());
- prototype.value().asObject()->prototype->prototype = v4Prototype.value().asObject();
+ prototype = QV4::Value::fromObject(eng->newObject());
+ QQmlLocaleData::initClass(eng, prototype.value());
}
QV8LocaleDataDeletable::~QV8LocaleDataDeletable()
static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value &value);
};
+template <typename T, int ManagedType>
+class MemberAccessorGetter : public FunctionObject
+{
+public:
+ typedef Value (T::*GetterFunction)(QV4::SimpleCallContext *ctx);
+
+ MemberAccessorGetter(ExecutionContext *scope, GetterFunction getter)
+ : FunctionObject(scope)
+ {
+ this->vtbl = &static_vtbl;
+ this->getter = getter;
+ }
+
+ static QV4::Value call(Managed *that, ExecutionContext *context, const QV4::Value &thisObject, QV4::Value *args, int argc)
+ {
+ MemberAccessorGetter<T, ManagedType> *getter = static_cast<MemberAccessorGetter<T, ManagedType> *>(that);
+
+ Object *thisO = thisObject.asObject();
+ if (!thisO || thisO->internalType() != ManagedType)
+ context->throwTypeError();
+
+ T *o = reinterpret_cast<T *>(thisO);
+
+ QV4::SimpleCallContext ctx;
+ ctx.type = ExecutionContext::Type_SimpleCallContext;
+ ctx.strictMode = true;
+ ctx.marked = false;
+ ctx.thisObject = thisObject;
+ ctx.engine = context->engine;
+ ctx.arguments = args;
+ ctx.argumentCount = argc;
+ context->engine->pushContext(&ctx);
+
+ QV4::Value result = QV4::Value::undefinedValue();
+ try {
+ result = (o->* getter->getter)(&ctx);
+ } catch (QV4::Exception &ex) {
+ ex.partiallyUnwindContext(context);
+ throw;
+ }
+ context->engine->popContext();
+ return result;
+ }
+protected:
+ GetterFunction getter;
+ static const ManagedVTable static_vtbl;
+};
+
}
QT_END_NAMESPACE
def isClassMethod(self):
return self.static
+ def isGetter(self):
+ return self.name.startswith("get_")
+
+ def isSetter(self):
+ return self.name.startswith("set_")
+
+ def isAccessor(self):
+ return self.isGetter() or self.isSetter()
+
+ def nameWithoutGetterSetterPrefix(self):
+ return self.name[4:]
+
+ def fullMethodName(self):
+ return self.methodPrefix + "_" + self.name
+
def generateBinding(self, out, objectPrefix = ""):
length = 0
def __init__(self, name):
self.name = name
self.options = {}
- self.methods = []
- self.ctor_methods = []
+ self.methods = {}
+ self.ctor_methods = {}
+ self.accessors = {}
def needsConstructor(self):
return len(self.ctor_methods) > 0
return self.options[name]
return None
+class Accessor():
+ def __init__(self, name):
+ self.name = name
+ self.getter = None
+ self.setter = None
+
+ def generateBinding(self, out, parsedClass, obj):
+ out.write(" {\n")
+ out.write(" QV4::FunctionObject *wrappedGetter = 0;\n")
+ out.write(" QV4::FunctionObject *wrappedSetter = 0;\n")
+ out.write("\n")
+ if self.getter:
+ out.write(" wrappedGetter = new (engine->memoryManager) %s_AccessorGetter(engine->rootContext, &%s::%s);\n" % (parsedClass.name, parsedClass.name, self.getter.fullMethodName()))
+ if self.setter:
+ out.write(" wrappedSetter = new (engine->memoryManager) %s_AccessorSetter(engine->rootContext, &%s::%s);\n" % (parsedClass.name, parsedClass.name, self.setter.fullMethodName()))
+ out.write(" QV4::PropertyAttributes attrs = QV4::Attr_Accessor;\n")
+ out.write(" QV4::Property *pd = %sinsertMember(engine->newIdentifier(QStringLiteral(\"%s\")), attrs);\n" % (obj, self.name));
+ out.write(" pd->setGetter(wrappedGetter);\n");
+ out.write(" pd->setSetter(wrappedSetter);\n");
+ out.write(" }\n");
+
def parseOptions(options):
options = options.split(" ")
result = {}
methodMatch = methodPattern.match(line)
if methodMatch:
method = parseMethod(line, methodMatch, "method")
- currentClass.methods.append(method)
+ if method.isAccessor():
+ name = method.nameWithoutGetterSetterPrefix()
+ acc = currentClass.accessors.setdefault(name, Accessor(name))
+ if method.isSetter():
+ acc.setter = method
+ else:
+ acc.getter = method
+ else:
+ currentClass.methods[method.name] = method
continue
ctorMethodMatch = ctorMethodPattern.match(line)
if ctorMethodMatch:
method = parseMethod(line, ctorMethodMatch, "ctor_method")
- currentClass.ctor_methods.append(method)
+ currentClass.ctor_methods[method.name] = method
continue
annotateMatch = annotatePattern.match(line)
out.write("};\n\n");
out.write("const QV4::ManagedVTable %s::static_vtbl = {\n" % ctorClass);
- ctorOverrides = set()
- for method in parsedClass.ctor_methods:
- ctorOverrides.add(method.name)
+ ctorOverrides = set(parsedClass.ctor_methods.keys())
for method in vtableEntries:
entry = "FunctionObject::" + method
out.write(" return new (scope->engine->memoryManager) %s(scope);\n" % ctorClass)
out.write("}\n\n")
- for method in parsedClass.methods:
+ if len(parsedClass.accessors) > 0:
+ typename = "%s_AccessorGetter" % parsedClass.name
+ out.write("typedef QV4::MemberAccessorGetter<%s, QV4::Managed::Type_%s> %s;\n" % (parsedClass.name, parsedClass.managedTypeName(), typename))
+ out.write("template<>\n")
+ out.write("DEFINE_MANAGED_VTABLE(%s);" % typename)
+ out.write("\n\n")
+
+ for method in parsedClass.methods.values():
if not method.isClassMethod():
method.generateMemberFunctionWrapper(out, parsedClass)
- for method in parsedClass.ctor_methods:
+ for method in parsedClass.ctor_methods.values():
if not method.isClassMethod():
method.generateMemberFunctionWrapper(out, parsedClass)
out.write(" %sdefineReadonlyProperty(engine->id_length, QV4::Value::fromInt32(%s));\n" % (ctor, ctorLength))
out.write("\n")
- for method in parsedClass.ctor_methods:
+ for method in parsedClass.ctor_methods.values():
if method.name == "construct" or method.name == "call":
continue
method.generateBinding(out, ctor);
out.write("\n")
- for method in parsedClass.methods:
+ for method in parsedClass.methods.values():
method.generateBinding(out, obj)
+ for accessor in parsedClass.accessors.values():
+ accessor.generateBinding(out, parsedClass, obj)
+
out.write("}\n")
def extractManagedVTableLayout(basePath):