servo: Integrate codegen into the build system.

Source-Repo: https://github.com/servo/servo
Source-Revision: 134be0dae051f2d4d86d3ed7a4cb0362c0525919
This commit is contained in:
Josh Matthews 2013-03-04 16:34:59 -05:00
parent c7a9c6ea7a
commit 953b73f09d
12 changed files with 189 additions and 130 deletions

6
servo/.gitignore vendored
View File

@ -15,3 +15,9 @@ build
config.mk
config.stamp
parser.out
src/servo/dom/bindings/codegen/*.rs
src/servo/dom/bindings/codegen/_cache/
src/servo/dom/bindings/codegen/test/*.rs
src/servo/dom/bindings/codegen/PrototypeList.h
src/servo/dom/bindings/codegen/UnionTypes.h
src/servo/dom/bindings/codegen/UnionConversions.h

View File

@ -154,7 +154,9 @@ DEPS_servo_gfx = $(CRATE_servo_gfx) $(SRC_servo_gfx) $(DONE_SUBMODULES)
RFLAGS_servo = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/servo-gfx
SRC_servo = $(call rwildcard,$(S)src/servo/,*.rs)
WEBIDL_servo = $(call rwildcard,$(S)src/servo/,*.webidl)
AUTOGEN_SRC_servo = $(patsubst %.webidl, %Binding.rs, $(WEBIDL_servo))
SRC_servo = $(call rwildcard,$(S)src/servo/,*.rs) $(AUTOGEN_SRC_servo)
CRATE_servo = $(S)src/servo/servo.rc
DEPS_servo = $(CRATE_servo) $(SRC_servo) $(DONE_SUBMODULES) $(DONE_servo_gfx)
@ -172,6 +174,35 @@ all: servo package
$(DONE_servo_gfx): $(DEPS_servo_gfx)
$(RUSTC) $(RFLAGS_servo_gfx) -o $@ $< && touch $@
BINDINGS_SRC = $(S)/src/servo/dom/bindings/codegen
CACHE_DIR = $(BINDINGS_SRC)/_cache
bindinggen_dependencies := $(addprefix $(BINDINGS_SRC)/, BindingGen.py Bindings.conf Configuration.py CodegenRust.py parser/WebIDL.py ParserResults.pkl)
$(AUTOGEN_SRC_servo): %Binding.rs: $(bindinggen_dependencies) \
%.webidl
PYTHONDONTWRITEBYTECODE=1 python $(BINDINGS_SRC)/pythonpath.py \
-I$(BINDINGS_SRC)/parser -I$(BINDINGS_SRC)/ply \
-D$(BINDINGS_SRC) \
$(BINDINGS_SRC)/BindingGen.py rs \
$(BINDINGS_SRC)/Bindings.conf $*Binding $*.webidl
globalgen_dependencies := $(addprefix $(BINDINGS_SRC)/, GlobalGen.py Bindings.conf Configuration.py CodegenRust.py parser/WebIDL.py) $(CACHE_DIR)/.done
$(CACHE_DIR)/.done:
mkdir -p $(CACHE_DIR)
@touch $@
$(BINDINGS_SRC)/ParserResults.pkl: $(globalgen_dependencies) \
$(WEBIDL_servo)
PYTHONDONTWRITEBYTECODE=1 python $(BINDINGS_SRC)/pythonpath.py \
-I$(BINDINGS_SRC)/parser -I$(BINDINGS_SRC)/ply \
-D$(BINDINGS_SRC) \
$(BINDINGS_SRC)/GlobalGen.py $(BINDINGS_SRC)/Bindings.conf . \
--cachedir=$(CACHE_DIR) \
$(WEBIDL_servo)
# Servo binaries
servo: $(DEPS_servo)

View File

@ -1,6 +1,6 @@
use content::content_task::task_from_context;
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, OpaqueBindingReference};
use dom::bindings::ClientRectBinding;
use dom::bindings::codegen::ClientRectBinding;
use js::jsapi::{JSObject, JSContext};
pub trait ClientRect {

View File

@ -1,6 +1,6 @@
use content::content_task::task_from_context;
use dom::bindings::clientrect::{ClientRect, ClientRectImpl};
use dom::bindings::ClientRectListBinding;
use dom::bindings::codegen::ClientRectListBinding;
use dom::bindings::utils::{WrapperCache, CacheableWrapper, BindingObject, OpaqueBindingReference};
use dom::window::Window;
use dom::bindings::window::Window;

View File

@ -69,6 +69,14 @@ builtinNames = {
IDLType.Tags.double: 'f64'
}
numericTags = [
IDLType.Tags.int8, IDLType.Tags.uint8,
IDLType.Tags.int16, IDLType.Tags.uint16,
IDLType.Tags.int32, IDLType.Tags.uint32,
IDLType.Tags.int64, IDLType.Tags.uint64,
IDLType.Tags.float, IDLType.Tags.double
]
class CastableObjectUnwrapper():
"""
A class for unwrapping an object named by the "source" argument
@ -193,11 +201,15 @@ class CGMethodCall(CGThing):
signature[1][argCount].optional and
(argCount+1) in allowedArgCounts and
len(method.signaturesForArgCount(argCount+1)) == 1):
argCountCases.append(
CGCase(str(argCount), None, True))
#XXXjdm unfinished
pass
#argCountCases.append(
# CGCase(str(argCount), None, True))
else:
argCountCases.append(
CGCase(str(argCount), getPerSignatureCall(signature)))
pass
#XXXjdm unfinished
#argCountCases.append(
# CGCase(str(argCount), getPerSignatureCall(signature)))
continue
distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
@ -342,17 +354,19 @@ class CGMethodCall(CGThing):
caseBody.append(CGGeneric("return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);" %
toStringBool(not descriptor.workers)))
argCountCases.append(CGCase(str(argCount),
CGList(caseBody, "\n")))
#XXXjdm unfinished
#argCountCases.append(CGCase(str(argCount),
# CGList(caseBody, "\n")))
overloadCGThings = []
overloadCGThings.append(
CGGeneric("unsigned argcount = NS_MIN(argc, %du);" %
maxArgCount))
overloadCGThings.append(
CGSwitch("argcount",
argCountCases,
CGGeneric("return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n" % methodName)))
#XXXjdm unfinished
#overloadCGThings.append(
# CGSwitch("argcount",
# argCountCases,
# CGGeneric("return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n" % methodName)))
overloadCGThings.append(
CGGeneric('MOZ_NOT_REACHED("We have an always-returning default case");\n'
'return false;'))
@ -371,6 +385,27 @@ class FakeCastableDescriptor():
self.name = descriptor.name
self.hasXPConnectImpls = descriptor.hasXPConnectImpls
def dictionaryHasSequenceMember(dictionary):
return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in
dictionary.members) or
(dictionary.parent and
dictionaryHasSequenceMember(dictionary.parent)))
def typeIsSequenceOrHasSequenceMember(type):
if type.nullable():
type = type.inner
if type.isSequence():
return True
if type.isArray():
elementType = type.inner
return typeIsSequenceOrHasSequenceMember(elementType)
if type.isDictionary():
return dictionaryHasSequenceMember(type.inner)
if type.isUnion():
return any(typeIsSequenceOrHasSequenceMember(m.type) for m in
type.flatMemberTypes)
return False
def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
isDefinitelyObject=False,
isMember=False,
@ -871,11 +906,14 @@ for (uint32_t i = 0; i < length; ++i) {
"${declName}",
failureCode))
else:
templateBody += str(FailureFatalCastableObjectUnwrapper(
descriptor,
"&${val}.toObject()",
"${declName}"))
elif descriptor.interface.isCallback():
pass
#XXXjdm unfinished
#templateBody += str(FailureFatalCastableObjectUnwrapper(
# descriptor,
# "&${val}.toObject()",
# "${declName}"))
elif descriptor.interface.isCallback() and False:
#XXXjdm unfinished
templateBody += str(CallbackObjectUnwrapper(
descriptor,
"&${val}.toObject()",
@ -1077,10 +1115,11 @@ for (uint32_t i = 0; i < length; ++i) {
if defaultValue is not None:
assert(defaultValue.type.tag() == IDLType.Tags.domstring)
template = handleDefault(template,
("${declName} = %sValues::%s" %
(enum,
getEnumValueName(defaultValue.value))))
template = "" #XXXjdm unfinished
#template = handleDefault(template,
# ("${declName} = %sValues::%s" %
# (enum,
# getEnumValueName(defaultValue.value))))
return (template, CGGeneric(enum), None, isOptional)
if type.isCallback():
@ -1139,8 +1178,9 @@ for (uint32_t i = 0; i < length; ++i) {
# should be able to assume not isOptional here.
assert not isOptional
typeName = CGDictionary.makeDictionaryName(type.inner,
descriptorProvider.workers)
typeName = "" #XXXjdm unfinished
#typeName = CGDictionary.makeDictionaryName(type.inner,
# descriptorProvider.workers)
actualTypeName = typeName
selfRef = "${declName}"
@ -2550,7 +2590,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
idsToInit = []
# There is no need to init any IDs in workers, because worker bindings
# don't have Xrays.
if not self.descriptor.workers:
if False and not self.descriptor.workers: #XXXjdm don't need xray stuff yet
for var in self.properties.xrayRelevantArrayNames():
props = getattr(self.properties, var)
# We only have non-chrome ids to init if we have no chrome ids.
@ -2559,6 +2599,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
elif props.hasNonChromeOnly():
idsToInit.append(props.variableName(False))
if len(idsToInit) > 0:
setup = CGList([CGGeneric("let content = task_from_context(aCx);"),
CGList([CGGeneric("let %s_ids_mut = (*content).dom_static.attribute_ids.get(&(prototypes::id::%s as uint));" % (varname, self.descriptor.name)) for varname in idsToInit], '\n')], '\n')
initIds = CGList(
[CGGeneric("!InitIds(aCx, %s, *%s_ids_mut)" % (varname, varname)) for
varname in idsToInit], ' ||\n')
@ -2569,8 +2611,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
"\n")
initIds = CGWrapper(initIds, pre="if ", post=" {", reindent=True)
initIds = CGList(
[CGGeneric("let content = task_from_context(aCx);\n" +
"let sAttributes_ids_mut = (*content).dom_static.attribute_ids.get(&(prototypes::id::%s as uint));" % self.descriptor.name),
[setup,
initIds,
CGGeneric((" %s_ids_mut[0] = JSID_VOID;\n"
" return ptr::null();") % idsToInit[0]),
@ -2816,6 +2857,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
body += """ (*content).dom_static.attribute_ids.insert(prototypes::id::%s as uint,
vec::cast_to_mut(vec::from_slice(sAttributes_ids)));
""" % self.descriptor.name
body = "" #XXXjdm xray stuff isn't necessary yet
return (body + " let global: *JSObject = JS_GetGlobalForObject(aCx, aReceiver);\n" +
CheckPref(self.descriptor, "global", "*aEnabled", "false") +
@ -3247,8 +3289,8 @@ class CGXrayHelper(CGAbstractExternMethod):
methods = self.properties.methods
if methods.hasNonChromeOnly() or methods.hasChromeOnly():
methodArgs = """// %(methods)s has an end-of-list marker at the end that we ignore
%(methods)s, %(methods)s_ids, %(methods)s_specs, ArrayLength(%(methods)s) - 1""" % varNames
methodArgs = "Some(vec::zip_slice(%(methods)s, *method_ids))" % varNames
setup += "let method_ids = (*content).dom_static.method_ids.get(&(prototypes::id::ClientRect as uint));\n"
else:
methodArgs = "None"
methodArgs = CGGeneric(methodArgs)
@ -3263,8 +3305,8 @@ class CGXrayHelper(CGAbstractExternMethod):
consts = self.properties.consts
if consts.hasNonChromeOnly() or consts.hasChromeOnly():
constArgs = """// %(consts)s has an end-of-list marker at the end that we ignore
%(consts)s, %(consts)s_ids, %(consts)s_specs, ArrayLength(%(consts)s) - 1""" % varNames
constArgs = "Some(vec::zip_slice(%(consts)s, *const_ids))" % varNames
setup += "let const_ids = (*content).dom_static.const_ids.get(&(prototypes::id::ClientRect as uint));\n"
else:
constArgs = "None"
constArgs = CGGeneric(constArgs)
@ -3414,7 +3456,7 @@ if expando.is_not_null() {
getIndexedOrExpando = getFromExpando + "\n"
namedGetter = self.descriptor.operations['NamedGetter']
if namedGetter:
if namedGetter and False: #XXXjdm unfinished
getNamed = ("if (JSID_IS_STRING(id)) {\n" +
" JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" +
" FakeDependentString name;\n"

View File

@ -1,59 +0,0 @@
/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */
#ifndef mozilla_dom_PrototypeList_h__
#define mozilla_dom_PrototypeList_h__
namespace mozilla {
namespace dom {
namespace prototypes {
namespace id {
enum ID
{
ClientRect = 0,
_ID_Count
};
} // namespace id
typedef id::ID ID;
const unsigned MaxProtoChainLength = 1;
} // namespace prototypes
} // namespace dom
} // namespace mozilla
namespace mozilla {
namespace dom {
namespace constructors {
namespace id {
enum ID
{
_ID_Count
};
} // namespace id
typedef id::ID ID;
} // namespace constructors
} // namespace dom
} // namespace mozilla
namespace mozilla {
namespace dom {
template <prototypes::ID PrototypeID>
struct PrototypeTraits;
template <class ConcreteClass>
struct PrototypeIDMap;
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PrototypeList_h__

View File

@ -1,16 +0,0 @@
#ifndef mozilla_dom_UnionConversions_h__
#define mozilla_dom_UnionConversions_h__
#include "mozilla/dom/UnionTypes.h"
#include "nsDOMQS.h"
#include "nsDebug.h"
namespace mozilla {
namespace dom {
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_UnionConversions_h__

View File

@ -1,12 +0,0 @@
#ifndef mozilla_dom_UnionTypes_h__
#define mozilla_dom_UnionTypes_h__
#include "mozilla/dom/BindingUtils.h"
namespace mozilla {
namespace dom {
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_UnionTypes_h__

View File

@ -0,0 +1,60 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Run a python script, adding extra directories to the python path.
"""
def main(args):
def usage():
print >>sys.stderr, "pythonpath.py -I directory script.py [args...]"
sys.exit(150)
paths = []
while True:
try:
arg = args[0]
except IndexError:
usage()
if arg == '-I':
args.pop(0)
try:
path = args.pop(0)
except IndexError:
usage()
paths.append(os.path.abspath(path))
continue
if arg.startswith('-I'):
paths.append(os.path.abspath(args.pop(0)[2:]))
continue
if arg.startswith('-D'):
os.chdir(args.pop(0)[2:])
continue
break
script = args[0]
sys.path[0:0] = [os.path.abspath(os.path.dirname(script))] + paths
sys.argv = args
sys.argc = len(args)
frozenglobals['__name__'] = '__main__'
frozenglobals['__file__'] = script
execfile(script, frozenglobals)
# Freeze scope here ... why this makes things work I have no idea ...
frozenglobals = globals()
import sys, os
if __name__ == '__main__':
main(sys.argv[1:])

View File

@ -30,13 +30,17 @@ const TOSTRING_NAME_RESERVED_SLOT: u64 = 1;
struct GlobalStaticData {
mut proxy_handlers: linear::LinearMap<uint, *libc::c_void>,
mut attribute_ids: linear::LinearMap<uint, ~[mut jsid]>
mut attribute_ids: linear::LinearMap<uint, ~[mut jsid]>,
mut method_ids: linear::LinearMap<uint, ~[mut jsid]>,
mut constant_ids: linear::LinearMap<uint, ~[mut jsid]>
}
pub fn GlobalStaticData() -> GlobalStaticData {
GlobalStaticData {
proxy_handlers: linear::LinearMap::new(),
attribute_ids: linear::LinearMap::new()
attribute_ids: linear::LinearMap::new(),
method_ids: linear::LinearMap::new(),
constant_ids: linear::LinearMap::new()
}
}
@ -326,7 +330,7 @@ pub struct ConstantSpec {
pub struct DOMClass {
// A list of interfaces that this object implements, in order of decreasing
// derivedness.
interface_chain: [prototypes::id::Prototype * 1 /*prototypes::id::_ID_Count*/],
interface_chain: [prototypes::id::Prototype * 2 /*prototypes::id::_ID_Count*/],
unused: bool, // DOMObjectIsISupports (always false)
native_hooks: *NativePropertyHooks

View File

@ -3,6 +3,7 @@
//
use dom::bindings;
use dom::bindings::codegen;
use dom::bindings::utils::WrapperCache;
use dom::document::Document;
use dom::element::{Element, ElementTypeId, HTMLImageElement, HTMLImageElementTypeId};
@ -381,10 +382,10 @@ pub fn define_bindings(compartment: @mut Compartment, doc: @Document, win: @Wind
bindings::element::init(compartment);
bindings::utils::initialize_global(compartment.global_obj.ptr);
let mut unused = false;
assert bindings::ClientRectBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused);
assert bindings::ClientRectListBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused);
assert codegen::ClientRectBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused);
assert codegen::ClientRectListBinding::DefineDOMInterface(compartment.cx.ptr,
compartment.global_obj.ptr,
&mut unused);
}

View File

@ -49,8 +49,10 @@ pub mod dom {
pub mod proxyhandler;
pub mod clientrect;
pub mod clientrectlist;
pub mod ClientRectBinding;
pub mod ClientRectListBinding;
pub mod codegen {
pub mod ClientRectBinding;
pub mod ClientRectListBinding;
}
}
pub mod document;
pub mod element;