aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-04-27 21:21:44 +0200
committerLars Knoll <lars.knoll@digia.com>2013-05-06 14:47:45 +0200
commitf227c3392beda68beb2792eb9fec467d9a0794da (patch)
treef89d559d26d19935b5ddae85b01e326f6eb65e0d
parent0328241012fc2dc00f4384d37184e2ba7525fb39 (diff)
Simplify JS bindings generation
Added a little helper script that can generate the code to set up the prototype properties Change-Id: I957ed4419c8b16398720fea4203c1a00434c4fba Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--.gitignore2
-rw-r--r--src/qml/qml/v4/qv4dateobject.cpp74
-rw-r--r--src/qml/qml/v4/qv4dateobject_p.h60
-rw-r--r--src/qml/qml/v4/qv4engine.cpp2
-rw-r--r--src/qml/qml/v4/qv4object_p.h5
-rw-r--r--src/qml/qml/v4/v4.pri10
-rwxr-xr-xsrc/qml/qml/v4/v4classgen225
7 files changed, 279 insertions, 99 deletions
diff --git a/.gitignore b/.gitignore
index fa221a5ede..c5cbc02951 100644
--- a/.gitignore
+++ b/.gitignore
@@ -274,3 +274,5 @@ src/qml/RegExpJitTables.h
src/qml/udis86_itab.c
src/qml/udis86_itab.h
+# Generated V4 JS bindings
+*_jsclass.cpp
diff --git a/src/qml/qml/v4/qv4dateobject.cpp b/src/qml/qml/v4/qv4dateobject.cpp
index 6d78e479e3..c67d686a1d 100644
--- a/src/qml/qml/v4/qv4dateobject.cpp
+++ b/src/qml/qml/v4/qv4dateobject.cpp
@@ -651,15 +651,7 @@ QDateTime DateObject::toQDateTime() const
return ToDateTime(value.asDouble(), Qt::LocalTime);
}
-DEFINE_MANAGED_VTABLE(DateCtor);
-
-DateCtor::DateCtor(ExecutionContext *scope)
- : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Date")))
-{
- vtbl = &static_vtbl;
-}
-
-Value DateCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
+Value DatePrototype::ctor_method_construct(Managed *, ExecutionContext *ctx, Value *args, int argc)
{
double t = 0;
@@ -697,7 +689,7 @@ Value DateCtor::construct(Managed *, ExecutionContext *ctx, Value *args, int arg
return Value::fromObject(d);
}
-Value DateCtor::call(Managed *, ExecutionContext *ctx, const Value &, Value *, int)
+Value DatePrototype::ctor_method_call(Managed *, ExecutionContext *ctx, const Value &, Value *, int)
{
double t = currentTime();
return Value::fromString(ctx, ToString(t));
@@ -705,61 +697,9 @@ Value DateCtor::call(Managed *, ExecutionContext *ctx, const Value &, Value *, i
void DatePrototype::init(ExecutionContext *ctx, const Value &ctor)
{
- ctor.objectValue()->defineReadonlyProperty(ctx->engine->id_prototype, Value::fromObject(this));
- ctor.objectValue()->defineReadonlyProperty(ctx->engine->id_length, Value::fromInt32(7));
LocalTZA = getLocalTZA();
- ctor.objectValue()->defineDefaultProperty(ctx, QStringLiteral("parse"), method_parse, 1);
- ctor.objectValue()->defineDefaultProperty(ctx, QStringLiteral("UTC"), method_UTC, 7);
- ctor.objectValue()->defineDefaultProperty(ctx, QStringLiteral("now"), method_now, 0);
-
- defineDefaultProperty(ctx, QStringLiteral("constructor"), ctor);
- defineDefaultProperty(ctx, QStringLiteral("toString"), method_toString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toDateString"), method_toDateString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toTimeString"), method_toTimeString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toLocaleString"), method_toLocaleString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toLocaleDateString"), method_toLocaleDateString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString, 0);
- defineDefaultProperty(ctx, QStringLiteral("valueOf"), method_valueOf, 0);
- defineDefaultProperty(ctx, QStringLiteral("getTime"), method_getTime, 0);
- defineDefaultProperty(ctx, QStringLiteral("getYear"), method_getYear, 0);
- defineDefaultProperty(ctx, QStringLiteral("getFullYear"), method_getFullYear, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCFullYear"), method_getUTCFullYear, 0);
- defineDefaultProperty(ctx, QStringLiteral("getMonth"), method_getMonth, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCMonth"), method_getUTCMonth, 0);
- defineDefaultProperty(ctx, QStringLiteral("getDate"), method_getDate, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCDate"), method_getUTCDate, 0);
- defineDefaultProperty(ctx, QStringLiteral("getDay"), method_getDay, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCDay"), method_getUTCDay, 0);
- defineDefaultProperty(ctx, QStringLiteral("getHours"), method_getHours, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCHours"), method_getUTCHours, 0);
- defineDefaultProperty(ctx, QStringLiteral("getMinutes"), method_getMinutes, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCMinutes"), method_getUTCMinutes, 0);
- defineDefaultProperty(ctx, QStringLiteral("getSeconds"), method_getSeconds, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCSeconds"), method_getUTCSeconds, 0);
- defineDefaultProperty(ctx, QStringLiteral("getMilliseconds"), method_getMilliseconds, 0);
- defineDefaultProperty(ctx, QStringLiteral("getUTCMilliseconds"), method_getUTCMilliseconds, 0);
- defineDefaultProperty(ctx, QStringLiteral("getTimezoneOffset"), method_getTimezoneOffset, 0);
- defineDefaultProperty(ctx, QStringLiteral("setTime"), method_setTime, 1);
- defineDefaultProperty(ctx, QStringLiteral("setMilliseconds"), method_setMilliseconds, 1);
- defineDefaultProperty(ctx, QStringLiteral("setUTCMilliseconds"), method_setUTCMilliseconds, 1);
- defineDefaultProperty(ctx, QStringLiteral("setSeconds"), method_setSeconds, 2);
- defineDefaultProperty(ctx, QStringLiteral("setUTCSeconds"), method_setUTCSeconds, 2);
- defineDefaultProperty(ctx, QStringLiteral("setMinutes"), method_setMinutes, 3);
- defineDefaultProperty(ctx, QStringLiteral("setUTCMinutes"), method_setUTCMinutes, 3);
- defineDefaultProperty(ctx, QStringLiteral("setHours"), method_setHours, 4);
- defineDefaultProperty(ctx, QStringLiteral("setUTCHours"), method_setUTCHours, 4);
- defineDefaultProperty(ctx, QStringLiteral("setDate"), method_setDate, 1);
- defineDefaultProperty(ctx, QStringLiteral("setUTCDate"), method_setUTCDate, 1);
- defineDefaultProperty(ctx, QStringLiteral("setMonth"), method_setMonth, 2);
- defineDefaultProperty(ctx, QStringLiteral("setUTCMonth"), method_setUTCMonth, 2);
- defineDefaultProperty(ctx, QStringLiteral("setYear"), method_setYear, 1);
- defineDefaultProperty(ctx, QStringLiteral("setFullYear"), method_setFullYear, 3);
- defineDefaultProperty(ctx, QStringLiteral("setUTCFullYear"), method_setUTCFullYear, 3);
- defineDefaultProperty(ctx, QStringLiteral("toUTCString"), method_toUTCString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toGMTString"), method_toUTCString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toISOString"), method_toISOString, 0);
- defineDefaultProperty(ctx, QStringLiteral("toJSON"), method_toJSON, 1);
+ initClass(ctx->engine, ctor);
}
double DatePrototype::getThisDate(ExecutionContext *ctx)
@@ -772,12 +712,12 @@ double DatePrototype::getThisDate(ExecutionContext *ctx)
}
}
-Value DatePrototype::method_parse(SimpleCallContext *ctx)
+Value DatePrototype::ctor_method_parse(SimpleCallContext *ctx)
{
return Value::fromDouble(ParseString(ctx->argument(0).toString(ctx)->toQString()));
}
-Value DatePrototype::method_UTC(SimpleCallContext *ctx)
+Value DatePrototype::ctor_method_UTC(SimpleCallContext *ctx)
{
const int numArgs = ctx->argumentCount;
if (numArgs >= 2) {
@@ -797,7 +737,7 @@ Value DatePrototype::method_UTC(SimpleCallContext *ctx)
return Value::undefinedValue();
}
-Value DatePrototype::method_now(SimpleCallContext *ctx)
+Value DatePrototype::ctor_method_now(SimpleCallContext *ctx)
{
Q_UNUSED(ctx);
double t = currentTime();
@@ -1308,3 +1248,5 @@ Value DatePrototype::method_toJSON(SimpleCallContext *ctx)
return toIso->call(ctx, ctx->thisObject, 0, 0);
}
+
+#include "qv4dateobject_p_jsclass.cpp"
diff --git a/src/qml/qml/v4/qv4dateobject_p.h b/src/qml/qml/v4/qv4dateobject_p.h
index 629dfa57e7..ecb7384d99 100644
--- a/src/qml/qml/v4/qv4dateobject_p.h
+++ b/src/qml/qml/v4/qv4dateobject_p.h
@@ -59,27 +59,23 @@ struct DateObject: Object {
QDateTime toQDateTime() const;
};
-struct DateCtor: FunctionObject
+struct QV4_JS_CLASS(DatePrototype): DateObject
{
- DateCtor(ExecutionContext *scope);
+ QV4_ANNOTATE(argc 7)
- static Value construct(Managed *, ExecutionContext *context, Value *args, int argc);
- static Value call(Managed *that, ExecutionContext *, const Value &, Value *, int);
-
-protected:
- static const ManagedVTable static_vtbl;
-};
-
-struct DatePrototype: DateObject
-{
DatePrototype(ExecutionEngine *engine): DateObject(engine, Value::fromDouble(qSNaN())) {}
void init(ExecutionContext *ctx, const Value &ctor);
+ void initClass(ExecutionEngine *ctx, const Value &ctor);
+ static Object *newConstructor(ExecutionContext *scope);
static double getThisDate(ExecutionContext *ctx);
- static Value method_parse(SimpleCallContext *ctx);
- static Value method_UTC(SimpleCallContext *ctx);
- static Value method_now(SimpleCallContext *ctx);
+ static Value ctor_method_construct(Managed *, ExecutionContext *context, Value *args, int argc);
+ static Value ctor_method_call(Managed *that, ExecutionContext *, const Value &, Value *, int);
+
+ static Value ctor_method_parse(SimpleCallContext *ctx) QV4_ARGC(1);
+ static Value ctor_method_UTC(SimpleCallContext *ctx) QV4_ARGC(7);
+ static Value ctor_method_now(SimpleCallContext *ctx);
static Value method_toString(SimpleCallContext *ctx);
static Value method_toDateString(SimpleCallContext *ctx);
@@ -107,25 +103,25 @@ struct DatePrototype: DateObject
static Value method_getMilliseconds(SimpleCallContext *ctx);
static Value method_getUTCMilliseconds(SimpleCallContext *ctx);
static Value method_getTimezoneOffset(SimpleCallContext *ctx);
- static Value method_setTime(SimpleCallContext *ctx);
- static Value method_setMilliseconds(SimpleCallContext *ctx);
- static Value method_setUTCMilliseconds(SimpleCallContext *ctx);
- static Value method_setSeconds(SimpleCallContext *ctx);
- static Value method_setUTCSeconds(SimpleCallContext *ctx);
- static Value method_setMinutes(SimpleCallContext *ctx);
- static Value method_setUTCMinutes(SimpleCallContext *ctx);
- static Value method_setHours(SimpleCallContext *ctx);
- static Value method_setUTCHours(SimpleCallContext *ctx);
- static Value method_setDate(SimpleCallContext *ctx);
- static Value method_setUTCDate(SimpleCallContext *ctx);
- static Value method_setMonth(SimpleCallContext *ctx);
- static Value method_setUTCMonth(SimpleCallContext *ctx);
- static Value method_setYear(SimpleCallContext *ctx);
- static Value method_setFullYear(SimpleCallContext *ctx);
- static Value method_setUTCFullYear(SimpleCallContext *ctx);
- static Value method_toUTCString(SimpleCallContext *ctx);
+ static Value method_setTime(SimpleCallContext *ctx) QV4_ARGC(1);
+ static Value method_setMilliseconds(SimpleCallContext *ctx) QV4_ARGC(1);
+ static Value method_setUTCMilliseconds(SimpleCallContext *ctx) QV4_ARGC(1);
+ static Value method_setSeconds(SimpleCallContext *ctx) QV4_ARGC(2);
+ static Value method_setUTCSeconds(SimpleCallContext *ctx) QV4_ARGC(2);
+ static Value method_setMinutes(SimpleCallContext *ctx) QV4_ARGC(3);
+ static Value method_setUTCMinutes(SimpleCallContext *ctx) QV4_ARGC(3);
+ static Value method_setHours(SimpleCallContext *ctx) QV4_ARGC(4);
+ static Value method_setUTCHours(SimpleCallContext *ctx) QV4_ARGC(4);
+ static Value method_setDate(SimpleCallContext *ctx) QV4_ARGC(1);
+ static Value method_setUTCDate(SimpleCallContext *ctx) QV4_ARGC(1);
+ static Value method_setMonth(SimpleCallContext *ctx) QV4_ARGC(2);
+ static Value method_setUTCMonth(SimpleCallContext *ctx) QV4_ARGC(2);
+ static Value method_setYear(SimpleCallContext *ctx) QV4_ARGC(1);
+ static Value method_setFullYear(SimpleCallContext *ctx) QV4_ARGC(3);
+ static Value method_setUTCFullYear(SimpleCallContext *ctx) QV4_ARGC(3);
+ static Value method_toUTCString(SimpleCallContext *ctx) QV4_ANNOTATE(alias toGMTString);
static Value method_toISOString(SimpleCallContext *ctx);
- static Value method_toJSON(SimpleCallContext *ctx);
+ static Value method_toJSON(SimpleCallContext *ctx) QV4_ARGC(1);
};
}
diff --git a/src/qml/qml/v4/qv4engine.cpp b/src/qml/qml/v4/qv4engine.cpp
index a507cab13c..c2c14ef5b2 100644
--- a/src/qml/qml/v4/qv4engine.cpp
+++ b/src/qml/qml/v4/qv4engine.cpp
@@ -151,7 +151,7 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
booleanCtor = Value::fromObject(new (memoryManager) BooleanCtor(rootContext));
arrayCtor = Value::fromObject(new (memoryManager) ArrayCtor(rootContext));
functionCtor = Value::fromObject(new (memoryManager) FunctionCtor(rootContext));
- dateCtor = Value::fromObject(new (memoryManager) DateCtor(rootContext));
+ dateCtor = Value::fromObject(DatePrototype::newConstructor(rootContext));
regExpCtor = Value::fromObject(new (memoryManager) RegExpCtor(rootContext));
errorCtor = Value::fromObject(new (memoryManager) ErrorCtor(rootContext));
evalErrorCtor = Value::fromObject(new (memoryManager) EvalErrorCtor(rootContext));
diff --git a/src/qml/qml/v4/qv4object_p.h b/src/qml/qml/v4/qv4object_p.h
index b8d3b1c23d..ac5ca07a01 100644
--- a/src/qml/qml/v4/qv4object_p.h
+++ b/src/qml/qml/v4/qv4object_p.h
@@ -420,6 +420,11 @@ inline void Object::setArrayLengthUnchecked(uint l)
}
+// Macros used for JS class annotation
+#define QV4_JS_CLASS(ClassName) ClassName
+#define QV4_ANNOTATE(...)
+#define QV4_ARGC(...)
+
QT_END_NAMESPACE
#endif // QMLJS_OBJECTS_H
diff --git a/src/qml/qml/v4/v4.pri b/src/qml/qml/v4/v4.pri
index 92f13ab92f..b50602b026 100644
--- a/src/qml/qml/v4/v4.pri
+++ b/src/qml/qml/v4/v4.pri
@@ -94,6 +94,16 @@ HEADERS += \
$$PWD/qv4util_p.h \
$$PWD/qv4executableallocator_p.h
+JS_CLASS_SOURCES = $$PWD/qv4dateobject_p.h
+
+js_class_bindings.output = ${QMAKE_FILE_BASE}_jsclass.cpp
+js_class_bindings.input = JS_CLASS_SOURCES
+js_class_bindings.script = $$PWD/v4classgen
+js_class_bindings.commands = python $$js_class_bindings.script ${QMAKE_FILE_IN} --output ${QMAKE_FILE_OUT}
+js_class_bindings.depends += $$js_class_bindings.script $$PWD/qv4managed_p.h
+js_class_bindings.CONFIG += no_link
+QMAKE_EXTRA_COMPILERS += js_class_bindings
+
llvm-libs {
SOURCES += \
diff --git a/src/qml/qml/v4/v4classgen b/src/qml/qml/v4/v4classgen
new file mode 100755
index 0000000000..5f046668fd
--- /dev/null
+++ b/src/qml/qml/v4/v4classgen
@@ -0,0 +1,225 @@
+#!/usr/bin/python
+
+import re, sys, os
+import argparse
+
+class ParsedMethod():
+ def __init__(self, name, methodPrefix):
+ self.name = name
+ self.methodPrefix = methodPrefix
+ self.options = {}
+
+ def generateBinding(self, out, objectPrefix = ""):
+ length = 0
+ if "argc" in self.options:
+ length = self.options["argc"]
+ out.write(" %sdefineDefaultProperty(engine, QStringLiteral(\"%s\"), %s_%s, %s);\n" % (objectPrefix, self.name, self.methodPrefix, self.name, length))
+ if "alias" in self.options:
+ out.write(" %sdefineDefaultProperty(engine, QStringLiteral(\"%s\"), %s_%s, %s);\n" % (objectPrefix, self.options["alias"], self.methodPrefix, self.name, length))
+
+class ParsedClass():
+ def __init__(self, name):
+ self.name = name
+ self.options = {}
+ self.methods = []
+ self.ctor_methods = []
+
+ def needsConstructor(self):
+ return len(self.ctor_methods) > 0
+
+def parseOptions(options):
+ options = options.split(" ")
+ result = {}
+ for opt in [options[i : i + 2] for i in range(0, len(options), 2)]:
+ result[opt[0]] = opt[1]
+ return result
+
+def parseMethod(line, match, methodPrefix):
+ annotatePattern = re.compile(r".*QV4_ANNOTATE\((?P<Options>.+)\).*")
+ argcPattern = re.compile(r".*QV4_ARGC\((?P<count>\d+)\).*")
+
+ method = ParsedMethod(match.group("MethodName"), methodPrefix)
+
+ annotateMatch = annotatePattern.match(line)
+ if annotateMatch:
+ method.options = parseOptions(annotateMatch.group("Options"))
+
+ argcMatch = argcPattern.match(line)
+ if argcMatch:
+ method.options["argc"] = argcMatch.group("count")
+
+ return method
+
+def parse(lines):
+ classes = []
+ currentClass = None
+ classPattern = re.compile(r".*QV4_JS_CLASS\((?P<ClassName>\w+)\).*")
+ annotatePattern = re.compile(r".*QV4_ANNOTATE\((?P<Options>.+)\).*")
+ methodPattern = re.compile(r".*\smethod_(?P<MethodName>\w+)\(.*\).*;")
+ ctorMethodPattern = re.compile(r".*\sctor_method_(?P<MethodName>\w+)\(.*\).*;")
+
+ for line in lines:
+ line = line.strip()
+ classMatch = classPattern.match(line)
+ if classMatch:
+ name = classMatch.group("ClassName")
+ if currentClass != None:
+ classes.append(currentClass)
+ currentClass = ParsedClass(name)
+ continue
+
+ if currentClass == None:
+ continue
+
+ methodMatch = methodPattern.match(line)
+ if methodMatch:
+ method = parseMethod(line, methodMatch, "method")
+ currentClass.methods.append(method)
+ continue
+
+ ctorMethodMatch = ctorMethodPattern.match(line)
+ if ctorMethodMatch:
+ method = parseMethod(line, ctorMethodMatch, "ctor_method")
+ currentClass.ctor_methods.append(method)
+ continue
+
+ annotateMatch = annotatePattern.match(line)
+ if annotateMatch:
+ currentClass.options = parseOptions(annotateMatch.group("Options"))
+ continue
+
+ if currentClass != None:
+ classes.append(currentClass)
+ return classes
+
+def generateBinding(out, parsedClass, vtableEntries):
+ if parsedClass.needsConstructor():
+ ctorClass = parsedClass.name.replace("Prototype", "Ctor")
+
+ out.write("class %s: public QV4::FunctionObject {\n" % ctorClass);
+ out.write("public:\n");
+ out.write(" %s(QV4::ExecutionContext *scope)\n" % ctorClass);
+ out.write(" : QV4::FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral(\"%s\")))\n" % ctorClass.replace("Ctor", ""));
+ out.write(" { vtbl = &static_vtbl; }\n");
+ out.write("\n");
+ out.write("protected:\n");
+ out.write(" static const QV4::ManagedVTable static_vtbl;\n");
+ 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)
+
+ for method in vtableEntries:
+ entry = "FunctionObject::" + method
+ if method in ctorOverrides:
+ entry = parsedClass.name + "::ctor_method_" + method
+ out.write(" " + entry + ",\n")
+ out.write(" \"%s\"\n" % parsedClass.name.replace("Prototype", "Ctor"));
+ out.write("};\n\n")
+
+ out.write("QV4::Object *%s::newConstructor(QV4::ExecutionContext *scope)\n" % parsedClass.name)
+ out.write("{\n")
+ out.write(" return new (scope->engine->memoryManager) %s(scope);\n" % ctorClass)
+ out.write("}\n\n")
+
+ ctorSignature = ""
+ if parsedClass.needsConstructor():
+ ctorSignature = ", const Value &ctor"
+
+ out.write("void %s::initClass(QV4::ExecutionEngine *engine%s)\n" % (parsedClass.name, ctorSignature))
+ out.write("{\n")
+
+ if parsedClass.needsConstructor():
+ ctor = "ctor.objectValue()->"
+ ctorLength = 0
+ if "argc" in parsedClass.options:
+ ctorLength = parsedClass.options["argc"]
+
+ out.write(" %sdefineReadonlyProperty(engine->id_prototype, QV4::Value::fromObject(this));\n" % ctor)
+ out.write(" %sdefineReadonlyProperty(engine->id_length, QV4::Value::fromInt32(%s));\n" % (ctor, ctorLength))
+ out.write("\n")
+
+ for method in parsedClass.ctor_methods:
+ if method.name == "construct" or method.name == "call":
+ continue
+ method.generateBinding(out, ctor);
+
+ out.write("\n")
+ out.write(" defineDefaultProperty(engine, QStringLiteral(\"constructor\"), ctor);\n");
+
+ out.write("\n")
+
+ for method in parsedClass.methods:
+ method.generateBinding(out)
+
+ out.write("}\n")
+
+def extractManagedVTableLayout(basePath):
+ def VTableDefintionIterator(lines):
+ i = 0
+ while i < len(lines):
+ if lines[i].strip().startswith("#define DEFINE_MANAGED_VTABLE(classname)"):
+ break;
+ i = i + 1
+ if i >= len(lines):
+ return
+ i = i + 1
+ if not lines[i].strip().startswith("const ManagedVTable classname::static_vtbl ="):
+ print("Expected static_vtbl definition at line %s" % i)
+ return
+ i = i + 1
+ if not lines[i].strip().startswith("{"):
+ print("Expected static_vtbl definition at line %s" % i)
+ return
+ i = i + 1
+ while i < len(lines):
+ line = lines[i].strip()
+ if "#classname" in line:
+ break
+ yield line.split(",")[0]
+ i = i + 1
+ return
+
+ qv4managedHeader = basePath + "/qv4managed_p.h"
+ fields = []
+ try:
+ header = open(qv4managedHeader, "r")
+ it = VTableDefintionIterator(header.read().splitlines())
+ for entry in it:
+ fields.append(entry)
+ header.close()
+ except IOError:
+ print("Could not open qv4managed_p.h at %s" % qv4managedHeader)
+ sys.exit(1)
+ return fields
+
+parser = argparse.ArgumentParser(description="Generate V4 JS class bindings")
+parser.add_argument("input")
+parser.add_argument("--output")
+options = parser.parse_args()
+
+vtableEntries = extractManagedVTableLayout(os.path.dirname(os.path.abspath(options.input)))
+if len(vtableEntries) == 0:
+ print("Could not parse vtable layout from qv4managed_p.h")
+ sys.exit(1)
+
+f = open(options.input)
+
+out = sys.stdout
+if options.output != None:
+ out = open(options.output, 'w')
+
+lines = f.read().splitlines()
+classes = parse(lines)
+f.close()
+
+out.write("/* Generated file, do not edit */\n")
+out.write("#include \"%s\"\n" % options.input)
+
+for parsedClass in classes:
+ out.write("\n")
+ generateBinding(out, parsedClass, vtableEntries)
+
+out.close()